mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-01-30 00:12:50 -05:00
network: big feature enrichment
- Dedicated view in settings - VPN profile management - Ethernet disconnection - Turn prompts into floating windows
This commit is contained in:
220
quickshell/Services/VPNService.qml
Normal file
220
quickshell/Services/VPNService.qml
Normal file
@@ -0,0 +1,220 @@
|
||||
pragma Singleton
|
||||
pragma ComponentBehavior: Bound
|
||||
|
||||
import QtQuick
|
||||
import Quickshell
|
||||
import qs.Common
|
||||
|
||||
Singleton {
|
||||
id: root
|
||||
|
||||
readonly property bool available: DMSNetworkService.vpnAvailable
|
||||
|
||||
property var plugins: []
|
||||
property var allExtensions: []
|
||||
property bool importing: false
|
||||
property string importError: ""
|
||||
|
||||
property var editConfig: null
|
||||
property bool configLoading: false
|
||||
|
||||
property bool pluginsLoading: false
|
||||
|
||||
signal importComplete(string uuid, string name)
|
||||
signal configLoaded(var config)
|
||||
signal configUpdated
|
||||
signal vpnDeleted(string uuid)
|
||||
|
||||
Component.onCompleted: {
|
||||
if (available) {
|
||||
fetchPlugins();
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: DMSNetworkService
|
||||
function onVpnAvailableChanged() {
|
||||
if (DMSNetworkService.vpnAvailable && plugins.length === 0) {
|
||||
fetchPlugins();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function fetchPlugins() {
|
||||
if (!available || pluginsLoading)
|
||||
return;
|
||||
pluginsLoading = true;
|
||||
|
||||
DMSService.sendRequest("network.vpn.plugins", null, response => {
|
||||
pluginsLoading = false;
|
||||
if (response.error) {
|
||||
console.warn("VPNService: Failed to fetch plugins:", response.error);
|
||||
return;
|
||||
}
|
||||
if (!response.result)
|
||||
return;
|
||||
plugins = response.result;
|
||||
const extSet = new Set();
|
||||
for (const plugin of response.result) {
|
||||
for (const ext of plugin.fileExtensions || []) {
|
||||
extSet.add(ext);
|
||||
}
|
||||
}
|
||||
allExtensions = Array.from(extSet);
|
||||
});
|
||||
}
|
||||
|
||||
function importVpn(filePath, name = "") {
|
||||
if (!available || importing)
|
||||
return;
|
||||
importing = true;
|
||||
importError = "";
|
||||
|
||||
const params = {
|
||||
file: filePath
|
||||
};
|
||||
if (name)
|
||||
params.name = name;
|
||||
|
||||
DMSService.sendRequest("network.vpn.import", params, response => {
|
||||
importing = false;
|
||||
|
||||
if (response.error) {
|
||||
importError = response.error;
|
||||
ToastService.showError(I18n.tr("Failed to import VPN"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!response.result)
|
||||
return;
|
||||
if (response.result.success) {
|
||||
ToastService.showInfo(I18n.tr("VPN imported: ") + (response.result.name || ""));
|
||||
DMSNetworkService.refreshVpnProfiles();
|
||||
importComplete(response.result.uuid || "", response.result.name || "");
|
||||
return;
|
||||
}
|
||||
|
||||
importError = response.result.error || "Import failed";
|
||||
ToastService.showError(importError);
|
||||
});
|
||||
}
|
||||
|
||||
function getConfig(uuidOrName) {
|
||||
if (!available)
|
||||
return;
|
||||
configLoading = true;
|
||||
editConfig = null;
|
||||
|
||||
DMSService.sendRequest("network.vpn.getConfig", {
|
||||
uuid: uuidOrName
|
||||
}, response => {
|
||||
configLoading = false;
|
||||
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to load VPN config"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.result) {
|
||||
editConfig = response.result;
|
||||
configLoaded(response.result);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function updateConfig(uuid, updates) {
|
||||
if (!available)
|
||||
return;
|
||||
const params = {
|
||||
uuid: uuid
|
||||
};
|
||||
if (updates.name !== undefined)
|
||||
params.name = updates.name;
|
||||
if (updates.autoconnect !== undefined)
|
||||
params.autoconnect = updates.autoconnect;
|
||||
if (updates.data !== undefined)
|
||||
params.data = updates.data;
|
||||
|
||||
DMSService.sendRequest("network.vpn.updateConfig", params, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to update VPN"));
|
||||
return;
|
||||
}
|
||||
ToastService.showInfo(I18n.tr("VPN configuration updated"));
|
||||
DMSNetworkService.refreshVpnProfiles();
|
||||
configUpdated();
|
||||
});
|
||||
}
|
||||
|
||||
function deleteVpn(uuidOrName) {
|
||||
if (!available)
|
||||
return;
|
||||
DMSService.sendRequest("network.vpn.delete", {
|
||||
uuid: uuidOrName
|
||||
}, response => {
|
||||
if (response.error) {
|
||||
ToastService.showError(I18n.tr("Failed to delete VPN"));
|
||||
return;
|
||||
}
|
||||
ToastService.showInfo(I18n.tr("VPN deleted"));
|
||||
DMSNetworkService.refreshVpnProfiles();
|
||||
vpnDeleted(uuidOrName);
|
||||
});
|
||||
}
|
||||
|
||||
function getFileFilter() {
|
||||
if (allExtensions.length === 0) {
|
||||
return ["*.ovpn", "*.conf"];
|
||||
}
|
||||
return allExtensions.map(e => "*" + e);
|
||||
}
|
||||
|
||||
function getExtensionsForPlugin(serviceType) {
|
||||
const plugin = plugins.find(p => p.serviceType === serviceType);
|
||||
if (!plugin)
|
||||
return ["*.conf"];
|
||||
return (plugin.fileExtensions || [".conf"]).map(e => "*" + e);
|
||||
}
|
||||
|
||||
function getPluginName(serviceType) {
|
||||
if (!serviceType)
|
||||
return "VPN";
|
||||
|
||||
const plugin = plugins.find(p => p.serviceType === serviceType);
|
||||
if (plugin)
|
||||
return plugin.name;
|
||||
|
||||
const svc = serviceType.toLowerCase();
|
||||
if (svc.includes("openvpn"))
|
||||
return "OpenVPN";
|
||||
if (svc.includes("wireguard"))
|
||||
return "WireGuard";
|
||||
if (svc.includes("openconnect"))
|
||||
return "OpenConnect";
|
||||
if (svc.includes("fortissl") || svc.includes("forti"))
|
||||
return "Fortinet";
|
||||
if (svc.includes("strongswan"))
|
||||
return "IPsec (strongSwan)";
|
||||
if (svc.includes("libreswan"))
|
||||
return "IPsec (Libreswan)";
|
||||
if (svc.includes("l2tp"))
|
||||
return "L2TP/IPsec";
|
||||
if (svc.includes("pptp"))
|
||||
return "PPTP";
|
||||
if (svc.includes("vpnc"))
|
||||
return "Cisco (vpnc)";
|
||||
if (svc.includes("sstp"))
|
||||
return "SSTP";
|
||||
|
||||
const parts = serviceType.split('.');
|
||||
return parts[parts.length - 1] || "VPN";
|
||||
}
|
||||
|
||||
function getVpnTypeFromProfile(profile) {
|
||||
if (!profile)
|
||||
return "VPN";
|
||||
if (profile.type === "wireguard")
|
||||
return "WireGuard";
|
||||
return getPluginName(profile.serviceType);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user