diff options
Diffstat (limited to 'desktop')
| -rw-r--r-- | desktop/modules/network/NetworkPage.qml | 68 | ||||
| -rw-r--r-- | desktop/modules/network/NetworkRow.qml | 144 |
2 files changed, 211 insertions, 1 deletions
diff --git a/desktop/modules/network/NetworkPage.qml b/desktop/modules/network/NetworkPage.qml index 0c79ef6..3a6362a 100644 --- a/desktop/modules/network/NetworkPage.qml +++ b/desktop/modules/network/NetworkPage.qml @@ -11,9 +11,9 @@ import Quickshell.Networking import QtQuick +import QtQuick.Controls import "../.." -// The wired half. Sibling of NetworkPage's wifi half, added in Task 2. Column { id: page @@ -29,6 +29,8 @@ Column { : "disconnected"; } + // --- Wired --- + Text { visible: page.net.wiredDevices.length > 0 text: "Wired" @@ -63,4 +65,68 @@ Column { } } } + + Rectangle { width: page.width; height: 1; color: Qt.alpha(Theme.text, 0.12) } + + // --- Wifi --- + + Item { + width: page.width + implicitHeight: Math.max(wifiLabel.implicitHeight, wifiSwitch.implicitHeight) + + Text { + id: wifiLabel + anchors.verticalCenter: parent.verticalCenter + text: "Wi-Fi" + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 1; bold: true } + color: Theme.text + } + + Switch { + id: wifiSwitch + anchors { right: parent.right; verticalCenter: parent.verticalCenter } + enabled: Networking.wifiHardwareEnabled + checked: page.net.wifiOn + onToggled: Networking.wifiEnabled = checked + } + } + + Text { + width: page.width + visible: !page.net.wifiOn + text: "Wi-Fi off" + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + color: Theme.subtext + } + + Row { + width: page.width + visible: page.net.wifiOn + spacing: 8 + + Button { + text: page.net.wifiDevice && page.net.wifiDevice.scannerEnabled ? "Scanning…" : "Scan" + onClicked: if (page.net.wifiDevice) page.net.wifiDevice.scannerEnabled = true + } + } + + Repeater { + model: page.net.wifiOn ? page.net.wifiNetworksSorted : [] + + NetworkRow { + required property var modelData + net: page.net + entry: modelData + width: page.width + } + } + + Text { + width: page.width + visible: page.net.error !== "" + wrapMode: Text.Wrap + text: page.net.error + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 3 } + color: Theme.red + } } diff --git a/desktop/modules/network/NetworkRow.qml b/desktop/modules/network/NetworkRow.qml new file mode 100644 index 0000000..34c134b --- /dev/null +++ b/desktop/modules/network/NetworkRow.qml @@ -0,0 +1,144 @@ +// Copyright (C) 2026 Danilo M. <danix@danix.xyz> +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License version 2 as +// published by the Free Software Foundation. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +import Quickshell.Networking +import QtQuick +import "../.." + +// One wifi network. A row click connects; a secured unknown network reveals +// an inline password field instead. The click area is declared first so the +// buttons and the field, declared later, sit above it. +Rectangle { + id: row + + required property var net + required property var entry + property bool prompting: false + property string psk: "" + + implicitHeight: col.implicitHeight + 16 + radius: 8 + color: entry.connected ? Qt.alpha(Theme.accent, 0.10) : Qt.alpha(Theme.surface, 0.35) + + MouseArea { + anchors.fill: parent + enabled: !row.prompting + cursorShape: Qt.PointingHandCursor + onClicked: row.activate() + } + + Column { + id: col + anchors { left: parent.left; right: parent.right; top: parent.top; margins: 10 } + spacing: 8 + + Item { + width: parent.width + implicitHeight: Math.max(nameText.implicitHeight, actions.implicitHeight) + + Text { + id: nameText + anchors { left: parent.left; right: actions.left; rightMargin: 8; verticalCenter: parent.verticalCenter } + elide: Text.ElideRight + text: row.entry.name + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2; bold: row.entry.connected } + color: row.entry.connected ? Theme.accent : Theme.text + } + + Row { + id: actions + anchors { right: parent.right; verticalCenter: parent.verticalCenter } + spacing: 6 + + Text { + anchors.verticalCenter: parent.verticalCenter + visible: row.secured() + text: "\uf023" + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + color: Theme.overlay + } + + Text { + anchors.verticalCenter: parent.verticalCenter + text: Math.round((row.entry.signalStrength ?? 0) * 100) + "%" + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 4 } + color: Theme.overlay + } + + Button { + visible: row.entry.connected + text: "Disconnect" + onClicked: row.net.disconnectNetwork(row.entry) + } + + Button { + visible: !row.entry.connected && row.entry.known + text: "Forget" + danger: true + onClicked: row.net.forget(row.entry) + } + } + } + + Row { + width: parent.width + spacing: 8 + visible: row.prompting + + TextInput { + id: pskField + width: parent.width - connectBtn.width - parent.spacing + echoMode: TextInput.Password + text: row.psk + onTextChanged: row.psk = text + font { family: Theme.fontFamily; pixelSize: Theme.fontSize - 2 } + color: Theme.text + Component.onCompleted: forceActiveFocus() + Keys.onReturnPressed: row.submit() + Keys.onEscapePressed: { row.prompting = false; row.psk = ""; } + + Rectangle { + anchors.fill: parent + anchors.margins: -5 + z: -1 + radius: 6 + color: Qt.alpha(Theme.surface, 0.9) + border.width: 1 + border.color: Qt.alpha(Theme.text, 0.15) + } + } + + Button { + id: connectBtn + text: "Connect" + onClicked: row.submit() + } + } + } + + function secured() { + return entry.security !== WifiSecurityType.Open && entry.security !== WifiSecurityType.Owe; + } + + function activate() { + if (entry.connected) { net.disconnectNetwork(entry); return; } + if (entry.known || !secured()) { net.connect(entry); return; } + row.prompting = true; + pskField.forceActiveFocus(); + } + + function submit() { + if (row.psk === "") return; + net.connectWithPsk(entry, row.psk); + row.psk = ""; + row.prompting = false; + } +} |
