mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2025-12-06 05:25:41 -05:00
vpn: various state management fixes
This commit is contained in:
@@ -134,6 +134,7 @@ Singleton {
|
||||
property bool weatherEnabled: true
|
||||
|
||||
property string networkPreference: "auto"
|
||||
property string vpnLastConnected: ""
|
||||
|
||||
property string iconTheme: "System Default"
|
||||
property var availableIconThemes: ["System Default"]
|
||||
@@ -1398,6 +1399,11 @@ Singleton {
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setVpnLastConnected(uuid) {
|
||||
vpnLastConnected = uuid
|
||||
saveSettings()
|
||||
}
|
||||
|
||||
function setIconTheme(themeName) {
|
||||
iconTheme = themeName
|
||||
updateGtkIconTheme(themeName)
|
||||
|
||||
16
DMSShell.qml
16
DMSShell.qml
@@ -213,10 +213,26 @@ Item {
|
||||
}
|
||||
}
|
||||
|
||||
property string lastCredentialsToken: ""
|
||||
property var lastCredentialsTime: 0
|
||||
|
||||
Connections {
|
||||
target: NetworkService
|
||||
|
||||
function onCredentialsNeeded(token, ssid, setting, fields, hints, reason, connType, connName, vpnService) {
|
||||
const now = Date.now()
|
||||
const timeSinceLastPrompt = now - lastCredentialsTime
|
||||
|
||||
if (wifiPasswordModal.shouldBeVisible && timeSinceLastPrompt < 1000) {
|
||||
NetworkService.cancelCredentials(lastCredentialsToken)
|
||||
lastCredentialsToken = token
|
||||
lastCredentialsTime = now
|
||||
wifiPasswordModal.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService)
|
||||
return
|
||||
}
|
||||
|
||||
lastCredentialsToken = token
|
||||
lastCredentialsTime = now
|
||||
wifiPasswordModal.showFromPrompt(token, ssid, setting, fields, hints, reason, connType, connName, vpnService)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ PluginComponent {
|
||||
service: DMSNetworkService
|
||||
}
|
||||
|
||||
|
||||
ccWidgetIcon: DMSNetworkService.isBusy ? "sync" : (DMSNetworkService.connected ? "vpn_lock" : "vpn_key_off")
|
||||
ccWidgetPrimaryText: "VPN"
|
||||
ccWidgetSecondaryText: {
|
||||
@@ -26,11 +27,7 @@ PluginComponent {
|
||||
ccWidgetIsActive: DMSNetworkService.connected
|
||||
|
||||
onCcWidgetToggled: {
|
||||
if (DMSNetworkService.connected) {
|
||||
DMSNetworkService.disconnectAllActive()
|
||||
} else if (DMSNetworkService.profiles.length > 0) {
|
||||
DMSNetworkService.connect(DMSNetworkService.profiles[0].uuid)
|
||||
}
|
||||
DMSNetworkService.toggleVpn()
|
||||
}
|
||||
|
||||
ccDetailContent: Component {
|
||||
@@ -62,10 +59,10 @@ PluginComponent {
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
|
||||
Item {
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
Layout.fillWidth: true
|
||||
Layout.maximumWidth: parent.width - 120
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
@@ -75,6 +72,7 @@ PluginComponent {
|
||||
visible: DMSNetworkService.connected
|
||||
width: 110
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
opacity: DMSNetworkService.isBusy ? 0.5 : 1.0
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
@@ -98,7 +96,8 @@ PluginComponent {
|
||||
id: discAllArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
cursorShape: DMSNetworkService.isBusy ? Qt.BusyCursor : Qt.PointingHandCursor
|
||||
enabled: !DMSNetworkService.isBusy
|
||||
onClicked: DMSNetworkService.disconnectAllActive()
|
||||
}
|
||||
}
|
||||
@@ -165,6 +164,7 @@ PluginComponent {
|
||||
color: rowArea.containsMouse ? Theme.primaryHoverLight : (DMSNetworkService.isActiveUuid(modelData.uuid) ? Theme.primaryPressed : Theme.surfaceLight)
|
||||
border.width: DMSNetworkService.isActiveUuid(modelData.uuid) ? 2 : 1
|
||||
border.color: DMSNetworkService.isActiveUuid(modelData.uuid) ? Theme.primary : Theme.outlineLight
|
||||
opacity: DMSNetworkService.isBusy ? 0.5 : 1.0
|
||||
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
@@ -183,11 +183,15 @@ PluginComponent {
|
||||
Column {
|
||||
spacing: 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
StyledText {
|
||||
text: modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: DMSNetworkService.isActiveUuid(modelData.uuid) ? Theme.primary : Theme.surfaceText
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
StyledText {
|
||||
@@ -233,7 +237,8 @@ PluginComponent {
|
||||
id: rowArea
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
cursorShape: DMSNetworkService.isBusy ? Qt.BusyCursor : Qt.PointingHandCursor
|
||||
enabled: !DMSNetworkService.isBusy
|
||||
onClicked: DMSNetworkService.toggle(modelData.uuid)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,15 @@ DankPopout {
|
||||
service: DMSNetworkService
|
||||
}
|
||||
|
||||
property bool wasVisible: false
|
||||
|
||||
onShouldBeVisibleChanged: {
|
||||
if (shouldBeVisible && !wasVisible) {
|
||||
DMSNetworkService.getState()
|
||||
}
|
||||
wasVisible = shouldBeVisible
|
||||
}
|
||||
|
||||
property var triggerScreen: null
|
||||
|
||||
function setTriggerPosition(x, y, width, section, screen) {
|
||||
@@ -175,11 +184,10 @@ DankPopout {
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: Theme.surfaceText
|
||||
font.weight: Font.Medium
|
||||
}
|
||||
|
||||
Item {
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
Layout.fillWidth: true
|
||||
height: 1
|
||||
Layout.maximumWidth: parent.width - 140
|
||||
}
|
||||
|
||||
// Removed Quick Connect for clarity
|
||||
@@ -198,6 +206,7 @@ DankPopout {
|
||||
Layout.alignment: Qt.AlignVCenter | Qt.AlignRight
|
||||
border.width: 0
|
||||
border.color: Theme.outlineLight
|
||||
opacity: DMSNetworkService.isBusy ? 0.5 : 1.0
|
||||
|
||||
Row {
|
||||
anchors.centerIn: parent
|
||||
@@ -223,7 +232,8 @@ DankPopout {
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
cursorShape: DMSNetworkService.isBusy ? Qt.BusyCursor : Qt.PointingHandCursor
|
||||
enabled: !DMSNetworkService.isBusy
|
||||
onClicked: DMSNetworkService.disconnectAllActive()
|
||||
}
|
||||
|
||||
@@ -295,6 +305,7 @@ DankPopout {
|
||||
color: rowArea.containsMouse ? Theme.primaryHoverLight : (DMSNetworkService.isActiveUuid(modelData.uuid) ? Theme.primaryPressed : Theme.surfaceLight)
|
||||
border.width: DMSNetworkService.isActiveUuid(modelData.uuid) ? 2 : 1
|
||||
border.color: DMSNetworkService.isActiveUuid(modelData.uuid) ? Theme.primary : Theme.outlineLight
|
||||
opacity: DMSNetworkService.isBusy ? 0.5 : 1.0
|
||||
|
||||
RowLayout {
|
||||
anchors.left: parent.left
|
||||
@@ -313,11 +324,15 @@ DankPopout {
|
||||
Column {
|
||||
spacing: 2
|
||||
Layout.alignment: Qt.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
|
||||
StyledText {
|
||||
text: modelData.name
|
||||
font.pixelSize: Theme.fontSizeMedium
|
||||
color: DMSNetworkService.isActiveUuid(modelData.uuid) ? Theme.primary : Theme.surfaceText
|
||||
elide: Text.ElideRight
|
||||
wrapMode: Text.NoWrap
|
||||
width: parent.width
|
||||
}
|
||||
|
||||
StyledText {
|
||||
@@ -391,7 +406,8 @@ DankPopout {
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
cursorShape: DMSNetworkService.isBusy ? Qt.BusyCursor : Qt.PointingHandCursor
|
||||
enabled: !DMSNetworkService.isBusy
|
||||
onClicked: DMSNetworkService.toggle(modelData.uuid)
|
||||
}
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ BasePill {
|
||||
return "sync"
|
||||
}
|
||||
|
||||
if (NetworkService.networkStatus === "ethernet") {
|
||||
if (NetworkService.networkStatus === "ethernet" || (NetworkService.networkStatus === "vpn" && NetworkService.ethernetConnected)) {
|
||||
return "lan"
|
||||
}
|
||||
|
||||
@@ -128,7 +128,7 @@ BasePill {
|
||||
return "sync";
|
||||
}
|
||||
|
||||
if (NetworkService.networkStatus === "ethernet") {
|
||||
if (NetworkService.networkStatus === "ethernet" || (NetworkService.networkStatus === "vpn" && NetworkService.ethernetConnected)) {
|
||||
return "lan";
|
||||
}
|
||||
|
||||
|
||||
@@ -25,10 +25,18 @@ BasePill {
|
||||
DankIcon {
|
||||
id: icon
|
||||
|
||||
name: DMSNetworkService.isBusy ? "sync" : (DMSNetworkService.connected ? "vpn_lock" : "vpn_key_off")
|
||||
name: DMSNetworkService.connected ? "vpn_lock" : "vpn_key_off"
|
||||
size: Theme.barIconSize(root.barThickness, -4)
|
||||
color: DMSNetworkService.connected ? Theme.primary : Theme.surfaceText
|
||||
opacity: DMSNetworkService.isBusy ? 0.5 : 1.0
|
||||
anchors.centerIn: parent
|
||||
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: Theme.shortDuration
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,8 +52,9 @@ BasePill {
|
||||
|
||||
anchors.fill: parent
|
||||
hoverEnabled: true
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
cursorShape: DMSNetworkService.isBusy ? Qt.BusyCursor : Qt.PointingHandCursor
|
||||
acceptedButtons: Qt.LeftButton
|
||||
enabled: !DMSNetworkService.isBusy
|
||||
onPressed: {
|
||||
if (popoutTarget && popoutTarget.setTriggerPosition) {
|
||||
const globalPos = root.visualContent.mapToGlobal(0, 0)
|
||||
@@ -65,9 +74,15 @@ BasePill {
|
||||
} else {
|
||||
const names = DMSNetworkService.activeNames || []
|
||||
if (names.length <= 1) {
|
||||
tooltipText = "VPN Connected • " + (names[0] || "")
|
||||
const name = names[0] || ""
|
||||
const maxLength = 25
|
||||
const displayName = name.length > maxLength ? name.substring(0, maxLength) + "..." : name
|
||||
tooltipText = "VPN Connected • " + displayName
|
||||
} else {
|
||||
tooltipText = "VPN Connected • " + names[0] + " +" + (names.length - 1)
|
||||
const name = names[0]
|
||||
const maxLength = 20
|
||||
const displayName = name.length > maxLength ? name.substring(0, maxLength) + "..." : name
|
||||
tooltipText = "VPN Connected • " + displayName + " +" + (names.length - 1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,9 @@ Singleton {
|
||||
property var vpnActive: []
|
||||
property bool vpnAvailable: false
|
||||
property bool vpnIsBusy: false
|
||||
property string lastConnectedVpnUuid: ""
|
||||
property string pendingVpnUuid: ""
|
||||
property var vpnBusyStartTime: 0
|
||||
|
||||
property alias profiles: root.vpnProfiles
|
||||
property alias activeConnections: root.vpnActive
|
||||
@@ -118,6 +121,7 @@ Singleton {
|
||||
|
||||
Component.onCompleted: {
|
||||
root.userPreference = SettingsData.networkPreference
|
||||
lastConnectedVpnUuid = SettingsData.vpnLastConnected || ""
|
||||
if (socketPath && socketPath.length > 0) {
|
||||
checkDMSCapabilities()
|
||||
}
|
||||
@@ -271,8 +275,41 @@ Singleton {
|
||||
vpnProfiles = state.vpnProfiles
|
||||
}
|
||||
|
||||
const previousVpnActive = vpnActive
|
||||
vpnActive = state.vpnActive || []
|
||||
|
||||
if (vpnConnected && activeUuid) {
|
||||
lastConnectedVpnUuid = activeUuid
|
||||
SettingsData.setVpnLastConnected(activeUuid)
|
||||
}
|
||||
|
||||
if (vpnIsBusy) {
|
||||
const busyDuration = Date.now() - vpnBusyStartTime
|
||||
const timeout = 30000
|
||||
|
||||
if (busyDuration > timeout) {
|
||||
console.warn("DMSNetworkService: VPN operation timed out after", timeout, "ms")
|
||||
vpnIsBusy = false
|
||||
pendingVpnUuid = ""
|
||||
vpnBusyStartTime = 0
|
||||
} else if (pendingVpnUuid) {
|
||||
const isPendingVpnActive = activeUuids.includes(pendingVpnUuid)
|
||||
if (isPendingVpnActive) {
|
||||
vpnIsBusy = false
|
||||
pendingVpnUuid = ""
|
||||
vpnBusyStartTime = 0
|
||||
}
|
||||
} else {
|
||||
const previousCount = previousVpnActive ? previousVpnActive.length : 0
|
||||
const currentCount = vpnActive ? vpnActive.length : 0
|
||||
|
||||
if (previousCount !== currentCount) {
|
||||
vpnIsBusy = false
|
||||
vpnBusyStartTime = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
userPreference = state.preference || "auto"
|
||||
isConnecting = state.isConnecting || false
|
||||
connectingSSID = state.connectingSSID || ""
|
||||
@@ -726,10 +763,12 @@ Singleton {
|
||||
})
|
||||
}
|
||||
|
||||
function connectVpn(uuidOrName, singleActive = false) {
|
||||
function connectVpn(uuidOrName, singleActive = true) {
|
||||
if (!vpnAvailable || vpnIsBusy) return
|
||||
|
||||
vpnIsBusy = true
|
||||
pendingVpnUuid = uuidOrName
|
||||
vpnBusyStartTime = Date.now()
|
||||
|
||||
const params = {
|
||||
uuidOrName: uuidOrName,
|
||||
@@ -737,12 +776,11 @@ Singleton {
|
||||
}
|
||||
|
||||
DMSService.sendRequest("network.vpn.connect", params, response => {
|
||||
vpnIsBusy = false
|
||||
|
||||
if (response.error) {
|
||||
vpnIsBusy = false
|
||||
pendingVpnUuid = ""
|
||||
vpnBusyStartTime = 0
|
||||
ToastService.showError(I18n.tr("Failed to connect VPN"))
|
||||
} else {
|
||||
Qt.callLater(() => getState())
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -755,18 +793,18 @@ Singleton {
|
||||
if (!vpnAvailable || vpnIsBusy) return
|
||||
|
||||
vpnIsBusy = true
|
||||
pendingVpnUuid = ""
|
||||
vpnBusyStartTime = Date.now()
|
||||
|
||||
const params = {
|
||||
uuidOrName: uuidOrName
|
||||
}
|
||||
|
||||
DMSService.sendRequest("network.vpn.disconnect", params, response => {
|
||||
vpnIsBusy = false
|
||||
|
||||
if (response.error) {
|
||||
vpnIsBusy = false
|
||||
vpnBusyStartTime = 0
|
||||
ToastService.showError(I18n.tr("Failed to disconnect VPN"))
|
||||
} else {
|
||||
Qt.callLater(() => getState())
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -779,14 +817,12 @@ Singleton {
|
||||
if (!vpnAvailable || vpnIsBusy) return
|
||||
|
||||
vpnIsBusy = true
|
||||
pendingVpnUuid = ""
|
||||
|
||||
DMSService.sendRequest("network.vpn.disconnectAll", null, response => {
|
||||
vpnIsBusy = false
|
||||
|
||||
if (response.error) {
|
||||
vpnIsBusy = false
|
||||
ToastService.showError(I18n.tr("Failed to disconnect VPNs"))
|
||||
} else {
|
||||
Qt.callLater(() => getState())
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -805,8 +841,14 @@ Singleton {
|
||||
return
|
||||
}
|
||||
|
||||
if (vpnProfiles.length > 0) {
|
||||
connectVpn(vpnProfiles[0].uuid)
|
||||
if (vpnConnected) {
|
||||
disconnectAllVpns()
|
||||
return
|
||||
}
|
||||
|
||||
const targetUuid = lastConnectedVpnUuid || (vpnProfiles.length > 0 ? vpnProfiles[0].uuid : "")
|
||||
if (targetUuid) {
|
||||
connectVpn(targetUuid)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@ Item {
|
||||
"yaml": "\u{e8eb}",
|
||||
"yml": "\u{e8eb}",
|
||||
"xml": "\u{F09EE}",
|
||||
"sql": "\u{f1c0}",
|
||||
|
||||
// --- scripts / shells ---
|
||||
"sh": "\u{F08A9}",
|
||||
|
||||
Reference in New Issue
Block a user