summaryrefslogtreecommitdiff
path: root/modules/controlcenter/network/VpnList.qml
diff options
context:
space:
mode:
Diffstat (limited to 'modules/controlcenter/network/VpnList.qml')
-rw-r--r--modules/controlcenter/network/VpnList.qml646
1 files changed, 0 insertions, 646 deletions
diff --git a/modules/controlcenter/network/VpnList.qml b/modules/controlcenter/network/VpnList.qml
deleted file mode 100644
index 665f8cc..0000000
--- a/modules/controlcenter/network/VpnList.qml
+++ /dev/null
@@ -1,646 +0,0 @@
-pragma ComponentBehavior: Bound
-
-import ".."
-import qs.components
-import qs.components.controls
-import qs.components.containers
-import qs.components.effects
-import qs.services
-import qs.config
-import qs.utils
-import Quickshell
-import QtQuick
-import QtQuick.Controls
-import QtQuick.Layouts
-import Qt5Compat.GraphicalEffects
-
-ColumnLayout {
- id: root
-
- required property Session session
- property bool showHeader: true
- property int pendingSwitchIndex: -1
-
- spacing: Appearance.spacing.normal
-
- Connections {
- target: VPN
- function onConnectedChanged() {
- if (!VPN.connected && root.pendingSwitchIndex >= 0) {
- const targetIndex = root.pendingSwitchIndex;
- root.pendingSwitchIndex = -1;
-
- const providers = [];
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- const p = Config.utilities.vpn.provider[i];
- if (typeof p === "object") {
- const newProvider = {
- name: p.name,
- displayName: p.displayName,
- interface: p.interface,
- enabled: (i === targetIndex)
- };
- providers.push(newProvider);
- } else {
- providers.push(p);
- }
- }
- Config.utilities.vpn.provider = providers;
- Config.save();
-
- Qt.callLater(function() {
- VPN.toggle();
- });
- }
- }
- }
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("+ Add VPN Provider")
- inactiveColour: Colours.palette.m3primaryContainer
- inactiveOnColour: Colours.palette.m3onPrimaryContainer
-
- onClicked: {
- vpnDialog.showProviderSelection();
- }
- }
-
- ListView {
- id: listView
-
- Layout.fillWidth: true
- Layout.preferredHeight: contentHeight
-
- interactive: false
- spacing: Appearance.spacing.smaller
-
- model: ScriptModel {
- values: Config.utilities.vpn.provider.map((provider, index) => {
- const isObject = typeof provider === "object";
- const name = isObject ? (provider.name || "custom") : String(provider);
- const displayName = isObject ? (provider.displayName || name) : name;
- const iface = isObject ? (provider.interface || "") : "";
- const enabled = isObject ? (provider.enabled === true) : false;
-
- return {
- index: index,
- name: name,
- displayName: displayName,
- interface: iface,
- provider: provider,
- enabled: enabled
- };
- })
- }
-
- delegate: Component {
- StyledRect {
- required property var modelData
- required property int index
-
- width: ListView.view ? ListView.view.width : undefined
-
- color: Qt.alpha(Colours.tPalette.m3surfaceContainer, (root.session && root.session.vpn && root.session.vpn.active === modelData) ? Colours.tPalette.m3surfaceContainer.a : 0)
- radius: Appearance.rounding.normal
-
- StateLayer {
- function onClicked(): void {
- if (root.session && root.session.vpn) {
- root.session.vpn.active = modelData;
- }
- }
- }
-
- RowLayout {
- id: rowLayout
-
- anchors.left: parent.left
- anchors.right: parent.right
- anchors.verticalCenter: parent.verticalCenter
- anchors.margins: Appearance.padding.normal
-
- spacing: Appearance.spacing.normal
-
- StyledRect {
- implicitWidth: implicitHeight
- implicitHeight: icon.implicitHeight + Appearance.padding.normal * 2
-
- radius: Appearance.rounding.normal
- color: modelData.enabled && VPN.connected ? Colours.palette.m3primaryContainer : Colours.tPalette.m3surfaceContainerHigh
-
- MaterialIcon {
- id: icon
-
- anchors.centerIn: parent
- text: modelData.enabled && VPN.connected ? "vpn_key" : "vpn_key_off"
- font.pointSize: Appearance.font.size.large
- fill: modelData.enabled && VPN.connected ? 1 : 0
- color: modelData.enabled && VPN.connected ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface
- }
- }
-
- ColumnLayout {
- Layout.fillWidth: true
-
- spacing: 0
-
- StyledText {
- Layout.fillWidth: true
- elide: Text.ElideRight
- maximumLineCount: 1
-
- text: modelData.displayName || qsTr("Unknown")
- }
-
- RowLayout {
- Layout.fillWidth: true
- spacing: Appearance.spacing.smaller
-
- StyledText {
- Layout.fillWidth: true
- text: {
- if (modelData.enabled && VPN.connected) return qsTr("Connected");
- if (modelData.enabled && VPN.connecting) return qsTr("Connecting...");
- if (modelData.enabled) return qsTr("Enabled");
- return qsTr("Disabled");
- }
- color: modelData.enabled ? (VPN.connected ? Colours.palette.m3primary : Colours.palette.m3onSurface) : Colours.palette.m3outline
- font.pointSize: Appearance.font.size.small
- font.weight: modelData.enabled && VPN.connected ? 500 : 400
- elide: Text.ElideRight
- }
- }
- }
-
- StyledRect {
- implicitWidth: implicitHeight
- implicitHeight: connectIcon.implicitHeight + Appearance.padding.smaller * 2
-
- radius: Appearance.rounding.full
- color: Qt.alpha(Colours.palette.m3primaryContainer, VPN.connected && modelData.enabled ? 1 : 0)
-
- StateLayer {
- enabled: !VPN.connecting
- function onClicked(): void {
- const clickedIndex = modelData.index;
-
- if (modelData.enabled) {
- VPN.toggle();
- } else {
- if (VPN.connected) {
- root.pendingSwitchIndex = clickedIndex;
- VPN.toggle();
- } else {
- const providers = [];
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- const p = Config.utilities.vpn.provider[i];
- if (typeof p === "object") {
- const newProvider = {
- name: p.name,
- displayName: p.displayName,
- interface: p.interface,
- enabled: (i === clickedIndex)
- };
- providers.push(newProvider);
- } else {
- providers.push(p);
- }
- }
- Config.utilities.vpn.provider = providers;
- Config.save();
-
- Qt.callLater(function() {
- VPN.toggle();
- });
- }
- }
- }
- }
-
- MaterialIcon {
- id: connectIcon
-
- anchors.centerIn: parent
- text: VPN.connected && modelData.enabled ? "link_off" : "link"
- color: VPN.connected && modelData.enabled ? Colours.palette.m3onPrimaryContainer : Colours.palette.m3onSurface
- }
- }
-
- StyledRect {
- implicitWidth: implicitHeight
- implicitHeight: deleteIcon.implicitHeight + Appearance.padding.smaller * 2
-
- radius: Appearance.rounding.full
- color: "transparent"
-
- StateLayer {
- function onClicked(): void {
- const providers = [];
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- if (i !== modelData.index) {
- providers.push(Config.utilities.vpn.provider[i]);
- }
- }
- Config.utilities.vpn.provider = providers;
- Config.save();
- }
- }
-
- MaterialIcon {
- id: deleteIcon
-
- anchors.centerIn: parent
- text: "delete"
- color: Colours.palette.m3onSurface
- }
- }
- }
-
- implicitHeight: rowLayout.implicitHeight + Appearance.padding.normal * 2
- }
- }
- }
-
- Popup {
- id: vpnDialog
-
- property string currentState: "selection"
- property int editIndex: -1
- property string providerName: ""
- property string displayName: ""
- property string interfaceName: ""
-
- parent: Overlay.overlay
- x: Math.round((parent.width - width) / 2)
- y: Math.round((parent.height - height) / 2)
- implicitWidth: Math.min(400, parent.width - Appearance.padding.large * 2)
- padding: Appearance.padding.large * 1.5
-
- modal: true
- closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
-
- opacity: 0
- scale: 0.7
-
- enter: Transition {
- ParallelAnimation {
- NumberAnimation { property: "opacity"; from: 0; to: 1; duration: Appearance.anim.durations.normal; easing.bezierCurve: Appearance.anim.curves.emphasized }
- NumberAnimation { property: "scale"; from: 0.7; to: 1; duration: Appearance.anim.durations.normal; easing.bezierCurve: Appearance.anim.curves.emphasized }
- }
- }
-
- exit: Transition {
- ParallelAnimation {
- NumberAnimation { property: "opacity"; from: 1; to: 0; duration: Appearance.anim.durations.small; easing.bezierCurve: Appearance.anim.curves.emphasized }
- NumberAnimation { property: "scale"; from: 1; to: 0.7; duration: Appearance.anim.durations.small; easing.bezierCurve: Appearance.anim.curves.emphasized }
- }
- }
-
- function showProviderSelection(): void {
- currentState = "selection";
- open();
- }
-
- function closeWithAnimation(): void {
- close();
- }
-
- function showAddForm(providerType: string, defaultDisplayName: string): void {
- editIndex = -1;
- providerName = providerType;
- displayName = defaultDisplayName;
- interfaceName = "";
-
- if (currentState === "selection") {
- transitionToForm.start();
- } else {
- currentState = "form";
- isClosing = false;
- open();
- }
- }
-
- function showEditForm(index: int): void {
- const provider = Config.utilities.vpn.provider[index];
- const isObject = typeof provider === "object";
-
- editIndex = index;
- providerName = isObject ? (provider.name || "custom") : String(provider);
- displayName = isObject ? (provider.displayName || providerName) : providerName;
- interfaceName = isObject ? (provider.interface || "") : "";
-
- currentState = "form";
- open();
- }
-
- Overlay.modal: Rectangle {
- color: Qt.rgba(0, 0, 0, 0.4 * vpnDialog.opacity)
- }
-
- onClosed: {
- currentState = "selection";
- }
-
- SequentialAnimation {
- id: transitionToForm
-
- ParallelAnimation {
- NumberAnimation {
- target: selectionContent
- property: "opacity"
- to: 0
- duration: Appearance.anim.durations.small
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
- }
-
- ScriptAction {
- script: {
- vpnDialog.currentState = "form";
- }
- }
-
- ParallelAnimation {
- NumberAnimation {
- target: formContent
- property: "opacity"
- to: 1
- duration: Appearance.anim.durations.small
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
- }
- }
-
- background: StyledRect {
- color: Colours.palette.m3surfaceContainerHigh
- radius: Appearance.rounding.large
-
- layer.enabled: true
- layer.effect: DropShadow {
- color: Qt.rgba(0, 0, 0, 0.3)
- radius: 16
- samples: 33
- verticalOffset: 4
- }
-
- Behavior on implicitHeight {
- NumberAnimation {
- duration: Appearance.anim.durations.normal
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
- }
- }
-
- contentItem: Item {
- implicitHeight: vpnDialog.currentState === "selection" ? selectionContent.implicitHeight : formContent.implicitHeight
-
- Behavior on implicitHeight {
- NumberAnimation {
- duration: Appearance.anim.durations.normal
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
- }
-
- ColumnLayout {
- id: selectionContent
-
- anchors.fill: parent
- spacing: Appearance.spacing.normal
- visible: vpnDialog.currentState === "selection"
- opacity: vpnDialog.currentState === "selection" ? 1 : 0
-
- Behavior on opacity {
- NumberAnimation {
- duration: Appearance.anim.durations.small
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
- }
-
- StyledText {
- text: qsTr("Add VPN Provider")
- font.pointSize: Appearance.font.size.large
- font.weight: 500
- }
-
- StyledText {
- Layout.fillWidth: true
- text: qsTr("Choose a provider to add")
- wrapMode: Text.WordWrap
- color: Colours.palette.m3outline
- font.pointSize: Appearance.font.size.small
- }
-
- Item { Layout.preferredHeight: Appearance.spacing.small }
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("NetBird")
- inactiveColour: Colours.tPalette.m3surfaceContainerHigh
- inactiveOnColour: Colours.palette.m3onSurface
- onClicked: {
- const providers = [];
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- providers.push(Config.utilities.vpn.provider[i]);
- }
- providers.push({ name: "netbird", displayName: "NetBird", interface: "wt0" });
- Config.utilities.vpn.provider = providers;
- Config.save();
- vpnDialog.closeWithAnimation();
- }
- }
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("Tailscale")
- inactiveColour: Colours.tPalette.m3surfaceContainerHigh
- inactiveOnColour: Colours.palette.m3onSurface
- onClicked: {
- const providers = [];
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- providers.push(Config.utilities.vpn.provider[i]);
- }
- providers.push({ name: "tailscale", displayName: "Tailscale", interface: "tailscale0" });
- Config.utilities.vpn.provider = providers;
- Config.save();
- vpnDialog.closeWithAnimation();
- }
- }
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("Cloudflare WARP")
- inactiveColour: Colours.tPalette.m3surfaceContainerHigh
- inactiveOnColour: Colours.palette.m3onSurface
- onClicked: {
- const providers = [];
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- providers.push(Config.utilities.vpn.provider[i]);
- }
- providers.push({ name: "warp", displayName: "Cloudflare WARP", interface: "CloudflareWARP" });
- Config.utilities.vpn.provider = providers;
- Config.save();
- vpnDialog.closeWithAnimation();
- }
- }
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("WireGuard (Custom)")
- inactiveColour: Colours.tPalette.m3surfaceContainerHigh
- inactiveOnColour: Colours.palette.m3onSurface
- onClicked: {
- vpnDialog.showAddForm("wireguard", "WireGuard");
- }
- }
-
- Item { Layout.preferredHeight: Appearance.spacing.small }
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("Cancel")
- inactiveColour: Colours.palette.m3secondaryContainer
- inactiveOnColour: Colours.palette.m3onSecondaryContainer
- onClicked: vpnDialog.closeWithAnimation()
- }
- }
-
- ColumnLayout {
- id: formContent
-
- anchors.fill: parent
- spacing: Appearance.spacing.normal
- visible: vpnDialog.currentState === "form"
- opacity: vpnDialog.currentState === "form" ? 1 : 0
-
- Behavior on opacity {
- NumberAnimation {
- duration: Appearance.anim.durations.small
- easing.bezierCurve: Appearance.anim.curves.emphasized
- }
- }
-
- StyledText {
- text: vpnDialog.editIndex >= 0 ? qsTr("Edit VPN Provider") : qsTr("Add %1 VPN").arg(vpnDialog.displayName)
- font.pointSize: Appearance.font.size.large
- font.weight: 500
- }
-
- ColumnLayout {
- Layout.fillWidth: true
- spacing: Appearance.spacing.smaller / 2
-
- StyledText {
- text: qsTr("Display Name")
- font.pointSize: Appearance.font.size.small
- color: Colours.palette.m3onSurfaceVariant
- }
-
- StyledRect {
- Layout.fillWidth: true
- implicitHeight: 40
- color: displayNameField.activeFocus ? Colours.layer(Colours.palette.m3surfaceContainer, 3) : Colours.layer(Colours.palette.m3surfaceContainer, 2)
- radius: Appearance.rounding.small
- border.width: 1
- border.color: displayNameField.activeFocus ? Colours.palette.m3primary : Qt.alpha(Colours.palette.m3outline, 0.3)
-
- Behavior on color { CAnim {} }
- Behavior on border.color { CAnim {} }
-
- StyledTextField {
- id: displayNameField
- anchors.centerIn: parent
- width: parent.width - Appearance.padding.normal
- horizontalAlignment: TextInput.AlignLeft
- text: vpnDialog.displayName
- onTextChanged: vpnDialog.displayName = text
- }
- }
- }
-
- ColumnLayout {
- Layout.fillWidth: true
- spacing: Appearance.spacing.smaller / 2
-
- StyledText {
- text: qsTr("Interface (e.g., wg0, torguard)")
- font.pointSize: Appearance.font.size.small
- color: Colours.palette.m3onSurfaceVariant
- }
-
- StyledRect {
- Layout.fillWidth: true
- implicitHeight: 40
- color: interfaceNameField.activeFocus ? Colours.layer(Colours.palette.m3surfaceContainer, 3) : Colours.layer(Colours.palette.m3surfaceContainer, 2)
- radius: Appearance.rounding.small
- border.width: 1
- border.color: interfaceNameField.activeFocus ? Colours.palette.m3primary : Qt.alpha(Colours.palette.m3outline, 0.3)
-
- Behavior on color { CAnim {} }
- Behavior on border.color { CAnim {} }
-
- StyledTextField {
- id: interfaceNameField
- anchors.centerIn: parent
- width: parent.width - Appearance.padding.normal
- horizontalAlignment: TextInput.AlignLeft
- text: vpnDialog.interfaceName
- onTextChanged: vpnDialog.interfaceName = text
- }
- }
- }
-
- Item { Layout.preferredHeight: Appearance.spacing.normal }
-
- RowLayout {
- Layout.fillWidth: true
- spacing: Appearance.spacing.normal
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("Cancel")
- inactiveColour: Colours.tPalette.m3surfaceContainerHigh
- inactiveOnColour: Colours.palette.m3onSurface
- onClicked: vpnDialog.closeWithAnimation()
- }
-
- TextButton {
- Layout.fillWidth: true
- text: qsTr("Save")
- enabled: vpnDialog.interfaceName.length > 0
- inactiveColour: Colours.palette.m3primaryContainer
- inactiveOnColour: Colours.palette.m3onPrimaryContainer
-
- onClicked: {
- const providers = [];
- const newProvider = {
- name: vpnDialog.providerName,
- displayName: vpnDialog.displayName || vpnDialog.interfaceName,
- interface: vpnDialog.interfaceName
- };
-
- if (vpnDialog.editIndex >= 0) {
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- if (i === vpnDialog.editIndex) {
- providers.push(newProvider);
- } else {
- providers.push(Config.utilities.vpn.provider[i]);
- }
- }
- } else {
- for (let i = 0; i < Config.utilities.vpn.provider.length; i++) {
- providers.push(Config.utilities.vpn.provider[i]);
- }
- providers.push(newProvider);
- }
-
- Config.utilities.vpn.provider = providers;
- Config.save();
- vpnDialog.closeWithAnimation();
- }
- }
- }
- }
- }
- }
-}