summaryrefslogtreecommitdiff
path: root/raveos-hyprland-theme/theme-data/DankMaterialShell/quickshell/Widgets/VpnDetailContent.qml
blob: 0ca0e56b9f1bcf2edfb55024ef1bf1ec6ef800ea (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import QtQuick
import QtQuick.Layouts
import Quickshell
import qs.Common
import qs.Modals.Common
import qs.Modals.FileBrowser
import qs.Services
import qs.Widgets

Rectangle {
    id: root

    LayoutMirroring.enabled: I18n.isRtl
    LayoutMirroring.childrenInherit: true

    property var parentPopout: null
    property string expandedUuid: ""
    property int listHeight: 180

    implicitHeight: 32 + 1 + listHeight + Theme.spacingS * 4 + Theme.spacingM * 2
    radius: Theme.cornerRadius
    color: Theme.withAlpha(Theme.surfaceContainerHigh, Theme.popupTransparency)

    FileBrowserSurfaceModal {
        id: fileBrowser
        browserTitle: I18n.tr("Import VPN")
        browserIcon: "vpn_key"
        browserType: "vpn"
        fileExtensions: VPNService.getFileFilter()
        parentPopout: root.parentPopout

        onFileSelected: path => {
            VPNService.importVpn(path.replace("file://", ""));
        }
    }

    ConfirmModal {
        id: deleteConfirm
    }

    Column {
        id: contentColumn
        anchors.fill: parent
        anchors.margins: Theme.spacingM
        spacing: Theme.spacingS

        RowLayout {
            spacing: Theme.spacingS
            width: parent.width

            StyledText {
                text: {
                    if (!DMSNetworkService.connected)
                        return I18n.tr("Active: None");
                    const names = DMSNetworkService.activeNames || [];
                    if (names.length <= 1)
                        return I18n.tr("Active: %1").arg(names[0] || "VPN");
                    return I18n.tr("Active: %1 +%2").arg(names[0]).arg(names.length - 1);
                }
                font.pixelSize: Theme.fontSizeMedium
                color: Theme.surfaceText
                font.weight: Font.Medium
                elide: Text.ElideRight
                wrapMode: Text.NoWrap
                Layout.fillWidth: true
            }

            Rectangle {
                height: 28
                radius: 14
                color: importArea.containsMouse ? Theme.primaryHoverLight : Theme.surfaceLight
                width: 90
                Layout.alignment: Qt.AlignVCenter
                opacity: VPNService.importing ? 0.5 : 1.0

                Row {
                    anchors.centerIn: parent
                    spacing: Theme.spacingXS

                    DankIcon {
                        name: VPNService.importing ? "sync" : "add"
                        size: Theme.fontSizeSmall
                        color: Theme.primary
                    }

                    StyledText {
                        text: I18n.tr("Import")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.primary
                        font.weight: Font.Medium
                    }
                }

                MouseArea {
                    id: importArea
                    anchors.fill: parent
                    hoverEnabled: true
                    cursorShape: VPNService.importing ? Qt.BusyCursor : Qt.PointingHandCursor
                    enabled: !VPNService.importing
                    onClicked: fileBrowser.open()
                }
            }

            Rectangle {
                height: 28
                radius: 14
                color: discAllArea.containsMouse ? Theme.errorHover : Theme.surfaceLight
                visible: DMSNetworkService.connected
                width: 100
                Layout.alignment: Qt.AlignVCenter
                opacity: DMSNetworkService.isBusy ? 0.5 : 1.0

                Row {
                    anchors.centerIn: parent
                    spacing: Theme.spacingXS

                    DankIcon {
                        name: "link_off"
                        size: Theme.fontSizeSmall
                        color: Theme.surfaceText
                    }

                    StyledText {
                        text: I18n.tr("Disconnect")
                        font.pixelSize: Theme.fontSizeSmall
                        color: Theme.surfaceText
                        font.weight: Font.Medium
                    }
                }

                MouseArea {
                    id: discAllArea
                    anchors.fill: parent
                    hoverEnabled: true
                    cursorShape: DMSNetworkService.isBusy ? Qt.BusyCursor : Qt.PointingHandCursor
                    enabled: !DMSNetworkService.isBusy
                    onClicked: DMSNetworkService.disconnectAllActive()
                }
            }

            DankActionButton {
                Layout.alignment: Qt.AlignVCenter
                iconName: "settings"
                buttonSize: 28
                iconSize: 16
                iconColor: Theme.surfaceVariantText
                onClicked: {
                    PopoutService.closeControlCenter();
                    PopoutService.openSettingsWithTab("network");
                }
            }
        }

        Rectangle {
            height: 1
            width: parent.width
            color: Qt.rgba(Theme.outline.r, Theme.outline.g, Theme.outline.b, 0.12)
        }

        Item {
            width: parent.width
            height: root.listHeight

            Column {
                anchors.centerIn: parent
                spacing: Theme.spacingS
                visible: DMSNetworkService.profiles.length === 0

                DankIcon {
                    name: "vpn_key_off"
                    size: 36
                    color: Theme.surfaceVariantText
                    anchors.horizontalCenter: parent.horizontalCenter
                }

                StyledText {
                    text: I18n.tr("No VPN profiles")
                    font.pixelSize: Theme.fontSizeMedium
                    color: Theme.surfaceVariantText
                    anchors.horizontalCenter: parent.horizontalCenter
                }

                StyledText {
                    text: I18n.tr("Click Import to add a .ovpn or .conf")
                    font.pixelSize: Theme.fontSizeSmall
                    color: Theme.surfaceVariantText
                    anchors.horizontalCenter: parent.horizontalCenter
                }
            }

            DankListView {
                id: vpnListView
                anchors.fill: parent
                visible: DMSNetworkService.profiles.length > 0
                spacing: 4
                cacheBuffer: 200
                clip: true

                model: ScriptModel {
                    values: DMSNetworkService.profiles
                    objectProp: "uuid"
                }

                delegate: VpnProfileDelegate {
                    required property var modelData
                    width: vpnListView.width
                    profile: modelData
                    isExpanded: root.expandedUuid === modelData.uuid
                    onToggleExpand: {
                        if (root.expandedUuid === modelData.uuid) {
                            root.expandedUuid = "";
                            return;
                        }
                        root.expandedUuid = modelData.uuid;
                        VPNService.getConfig(modelData.uuid);
                    }
                    onDeleteRequested: {
                        deleteConfirm.showWithOptions({
                            "title": I18n.tr("Delete VPN"),
                            "message": I18n.tr("Delete \"%1\"?").arg(modelData.name),
                            "confirmText": I18n.tr("Delete"),
                            "confirmColor": Theme.error,
                            "onConfirm": () => VPNService.deleteVpn(modelData.uuid)
                        });
                    }
                }
            }
        }

        Item {
            width: 1
            height: Theme.spacingS
        }
    }
}