feat: impl changing network via nexus

This commit is contained in:
2 * r + 2 * t 2026-06-06 02:17:29 +10:00
parent db3093b5d1
commit 027ab59ee5
2 changed files with 101 additions and 5 deletions

View file

@ -13,6 +13,8 @@ import qs.modules.nexus.common
PageBase {
id: root
signal networkSelected(ap: Nmcli.AccessPoint)
title: qsTr("Network")
ColumnLayout {
@ -106,6 +108,9 @@ PageBase {
id: network
required property Nmcli.AccessPoint modelData
readonly property Component rightComp: Nmcli.connectingSsid() === modelData.ssid ? loadingComp : iconComp
property bool isComplete
property real textOpacity: disabled ? 0.5 : 1
anchors.left: networkList.contentItem.left
anchors.right: networkList.contentItem.right
@ -113,6 +118,66 @@ PageBase {
radius: Tokens.rounding.extraSmall
anchors.fill: undefined
onClicked: {
if (!modelData.active) {
NetworkConnection.handleConnect(modelData);
disabled = true;
root.networkSelected(modelData);
}
}
Component.onCompleted: isComplete = true
onRightCompChanged: {
if (isComplete)
rightCompAnim.restart();
}
Behavior on textOpacity {
Anim {
type: Anim.DefaultEffects
}
}
Connections {
function onActiveChanged(): void {
if (network.modelData.active)
network.disabled = false;
}
target: network.modelData
}
Connections {
function onNetworkSelected(ap: Nmcli.AccessPoint): void {
if (ap !== network.modelData)
network.disabled = false;
}
target: root
}
SequentialAnimation {
id: rightCompAnim
running: false
Anim {
target: rightLoader
property: "opacity"
to: 0
type: Anim.FastEffects
}
ScriptAction {
script: rightLoader.sourceComponent = network.rightComp
}
Anim {
target: rightLoader
property: "opacity"
to: 1
type: Anim.DefaultEffects
}
}
RowLayout {
id: networkLayout
@ -126,11 +191,13 @@ PageBase {
text: Icons.getNetworkIcon(network.modelData.strength)
color: network.modelData.active ? Colours.palette.m3primary : Colours.tPalette.m3onSurfaceVariant
font: Tokens.font.icon.medium
opacity: network.textOpacity
}
ColumnLayout {
Layout.fillWidth: true
spacing: 0
opacity: network.textOpacity
StyledText {
Layout.fillWidth: true
@ -148,11 +215,30 @@ PageBase {
}
}
Loader {
id: rightLoader
asynchronous: true
sourceComponent: iconComp
Component {
id: iconComp
MaterialIcon {
visible: network.modelData.isSecure
text: network.modelData.active ? "settings" : "lock"
color: network.modelData.active ? Colours.palette.m3primary : Colours.tPalette.m3onSurfaceVariant
font: Tokens.font.icon.medium
opacity: network.textOpacity
}
}
Component {
id: loadingComp
LoadingIndicator {
implicitSize: Math.round(Tokens.font.icon.medium.pointSize * 1.3)
}
}
}
}
}

View file

@ -12,6 +12,7 @@ Singleton {
property var wirelessInterfaces: []
property var ethernetInterfaces: []
property bool isConnected: false
readonly property bool connecting: wirelessInterfaces.some(i => isConnectingState(i.state))
property string activeInterface: ""
property string activeConnection: ""
property bool wifiEnabled: true
@ -166,6 +167,15 @@ Singleton {
return state === "100 (connected)" || state === "connected" || state.startsWith("connected");
}
function isConnectingState(state: string): bool {
return !!state && state.startsWith("connecting");
}
function connectingSsid(): string {
const iface = root.wirelessInterfaces.find(i => isConnectingState(i.state));
return iface ? iface.connection : "";
}
function executeCommand(args: list<string>, callback: var): void {
const proc = commandProc.createObject(root);
proc.cmdArgs = ["nmcli", ...args];