Files
Domipoke 955801c666 noctalia
2026-06-25 19:58:23 +02:00

257 lines
9.1 KiB
QML

import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Quickshell
import qs.Commons
import qs.Widgets
ColumnLayout {
id: root
property var pluginApi: null
readonly property var pluginSettings: pluginApi?.pluginSettings ?? pluginApi?.manifest?.metadata?.defaultSettings ?? ({})
readonly property var main: pluginApi?.mainInstance ?? null
readonly property var vpnList: main ? main.vpnList : []
// Local state
property string editDisplayMode: root.pluginSettings.displayMode ?? ""
property string editConnectedColor: root.pluginSettings.connectedColor ?? ""
property string editDisconnectedColor: root.pluginSettings.disconnectedColor ?? ""
property bool disableToastNotifications: root.pluginSettings?.disableToastNotifications ?? false
property string pendingDeleteUuid: ""
property string pendingDeleteName: ""
readonly property var displayModeModel: [{
"key": "onhover",
"name": I18n.tr("display-modes.on-hover")
}, {
"key": "alwaysShow",
"name": I18n.tr("display-modes.always-show")
}, {
"key": "alwaysHide",
"name": I18n.tr("display-modes.always-hide")
}]
function saveSettings() {
pluginApi.pluginSettings.displayMode = root.editDisplayMode;
pluginApi.pluginSettings.connectedColor = root.editConnectedColor;
pluginApi.pluginSettings.disconnectedColor = root.editDisconnectedColor;
pluginApi.pluginSettings.disableToastNotifications = root.disableToastNotifications;
pluginApi.saveSettings();
Logger.i("NetworkManagerVpn", "Settings saved successfully");
}
NComboBox {
label: I18n.tr("common.display-mode")
description: I18n.tr("bar.volume.display-mode-description")
minimumWidth: 200
model: root.displayModeModel
currentKey: root.editDisplayMode
onSelected: (key) => {
root.editDisplayMode = key;
}
}
NColorChoice {
label: pluginApi?.tr("settings.connectedColor")
description: pluginApi?.tr("settings.connectedColorDescription")
currentKey: root.editConnectedColor
onSelected: (key) => {
root.editConnectedColor = key;
}
}
NColorChoice {
label: pluginApi?.tr("settings.disconnectedColor")
description: pluginApi?.tr("settings.disconnectedColorDescription")
currentKey: root.editDisconnectedColor
onSelected: (key) => {
root.editDisconnectedColor = key;
}
}
NToggle {
Layout.fillWidth: true
label: pluginApi?.tr("settings.disableToastNotifications")
description: pluginApi?.tr("settings.disableToastNotificationsDescription")
checked: root.disableToastNotifications
onToggled: checked => {
root.disableToastNotifications = checked;
}
}
NBox {
Layout.fillWidth: true
Layout.topMargin: Style.marginM
Layout.preferredHeight: Math.round(vpnSection.implicitHeight + Style.marginL * 2)
ColumnLayout {
id: vpnSection
anchors.fill: parent
anchors.margins: Style.marginM
spacing: Style.marginM
NLabel {
label: pluginApi?.tr("settings.vpnConnections")
Layout.fillWidth: true
}
NText {
visible: root.vpnList.length === 0
text: pluginApi?.tr("settings.noVpnConnections")
pointSize: Style.fontSizeS
color: Color.mOnSurfaceVariant
Layout.leftMargin: Style.marginXS
}
Repeater {
model: root.vpnList
NBox {
id: vpnRow
readonly property bool confirmingDelete: root.pendingDeleteUuid === modelData.uuid
Layout.fillWidth: true
Layout.leftMargin: Style.marginXS
Layout.rightMargin: Style.marginXS
implicitHeight: Math.round(rowContent.implicitHeight + Style.marginL)
color: vpnRow.confirmingDelete ? Qt.alpha(Color.mError, 0.12) : Color.mSurface
ColumnLayout {
id: rowContent
anchors.fill: parent
anchors.leftMargin: Style.marginM
anchors.rightMargin: Style.marginM
anchors.topMargin: Style.marginS
anchors.bottomMargin: Style.marginS
spacing: Style.marginS
RowLayout {
Layout.fillWidth: true
spacing: Style.marginS
NIcon {
icon: "router"
pointSize: Style.fontSizeXXL
color: modelData.connected ? Color.mPrimary : Color.mOnSurfaceVariant
}
ColumnLayout {
Layout.fillWidth: true
spacing: 2
NText {
text: modelData.name
pointSize: Style.fontSizeM
font.weight: Style.fontWeightMedium
color: Color.mOnSurface
elide: Text.ElideRight
Layout.fillWidth: true
}
NText {
text: modelData.type || "vpn"
pointSize: Style.fontSizeXXS
color: Color.mOnSurfaceVariant
}
}
NIconButton {
visible: !vpnRow.confirmingDelete
icon: "edit"
tooltipText: pluginApi?.tr("common.edit")
baseSize: Style.baseWidgetSize * 0.75
onClicked: {
main.editConnection(modelData.uuid);
close();
}
}
NIconButton {
visible: !vpnRow.confirmingDelete
icon: "trash-x"
tooltipText: pluginApi?.tr("common.delete")
baseSize: Style.baseWidgetSize * 0.75
onClicked: {
root.pendingDeleteUuid = modelData.uuid;
root.pendingDeleteName = modelData.name;
}
}
NButton {
visible: vpnRow.confirmingDelete
text: pluginApi?.tr("common.delete")
fontSize: Style.fontSizeXS
backgroundColor: Color.mError
outlined: false
onClicked: {
main.removeConnection(root.pendingDeleteUuid);
root.pendingDeleteUuid = "";
root.pendingDeleteName = "";
}
}
NButton {
visible: vpnRow.confirmingDelete
text: pluginApi?.tr("common.cancel")
fontSize: Style.fontSizeXS
outlined: true
onClicked: {
root.pendingDeleteUuid = "";
root.pendingDeleteName = "";
}
}
}
}
}
}
RowLayout {
Layout.fillWidth: true
Layout.topMargin: Style.marginXS
spacing: Style.marginS
Item {
Layout.fillWidth: true
}
NButton {
text: pluginApi?.tr("settings.addVpn")
icon: "add"
fontSize: Style.fontSizeS
outlined: true
onClicked: {
main.addConnection("vpn");
close();
}
}
NButton {
text: pluginApi?.tr("settings.addWireguard")
icon: "add"
fontSize: Style.fontSizeS
outlined: true
onClicked: {
main.addConnection("wireguard");
close();
}
}
}
}
}
}