pragma ComponentBehavior: Bound import QtQuick import QtQuick.Layouts import Quickshell import ZShell.Config import qs.Modules.Settings.Common import qs.Modules.Bar.Popouts.Network import qs.Components import qs.Helpers import qs.Services PageBase { id: root title: qsTr("Network") ColumnLayout { id: networkContent anchors.horizontalCenter: parent.horizontalCenter anchors.top: parent.top spacing: Tokens.spacing.extraSmall / 2 width: root.cappedWidth Toggle { Layout.preferredHeight: visible ? implicitHeight : 0 checked: Network.wifiEnabled first: true last: connected.count === 0 subtext: qsTr("Toggle WiFi device state") text: checked ? qsTr("Enabled") : qsTr("Disabled") onToggled: Network.setWifi(checked) } Repeater { id: connected visible: Network.connectedNetworks.length > 0 model: ScriptModel { values: [...Network.connectedNetworks].sort((a, b) => { return b.signalStrength - a.signalStrength; }) } NetworkItem { first: false known: true repeater: connected } } } component NetworkItem: ConnectedRect { id: networkItem readonly property bool connecting: Network.connectingNetwork === modelData property int horizontalPadding: Tokens.padding.largeIncreased required property int index readonly property bool isSecure: Network.isSecure(modelData.security) required property bool known required property var modelData required property Repeater repeater Layout.fillWidth: true Layout.preferredHeight: visible ? rowLayout.implicitHeight + Tokens.padding.smaller * 2 : 0 first: index === 0 last: index === (repeater.count - 1) radius: Tokens.rounding.small RowLayout { id: rowLayout anchors.fill: parent anchors.leftMargin: networkItem.horizontalPadding anchors.rightMargin: networkItem.horizontalPadding Column { id: column Layout.fillWidth: true CustomText { Layout.fillWidth: true Layout.leftMargin: Tokens.spacing.extraSmall Layout.rightMargin: Tokens.spacing.extraSmall color: networkItem.modelData.active ? Colors.palette.m3primary : Colors.palette.m3onSurface elide: Text.ElideRight text: networkItem.modelData.name } CustomText { id: subtext anchors.left: parent.left anchors.right: parent.right color: Colors.palette.m3outline elide: Text.ElideRight font.pointSize: Tokens.font.size.small text: qsTr("%1 strength").arg(Math.round(networkItem.modelData.signalStrength * 100) + "%") } } Item { Layout.alignment: Qt.AlignRight implicitHeight: icon.height implicitWidth: icon.width MaterialIcon { id: icon color: networkItem.modelData.active ? Colors.palette.m3primary : Colors.palette.m3onSurfaceVariant font.pointSize: Tokens.font.size.large opacity: networkItem.connecting ? 0 : 1 text: Icons.getNetworkIcon(networkItem.modelData.signalStrength * 100, networkItem.isSecure) Behavior on opacity { Anim { } } } Loader { active: opacity > 0 anchors.fill: parent opacity: networkItem.connecting ? 1 : 0 Behavior on opacity { Anim { } } sourceComponent: CircularIndicator { bgColor: "transparent" running: true } } } } StateLayer { color: networkItem.modelData.active ? Colors.palette.m3onPrimary : Colors.palette.m3onSurface onClicked: { if (networkItem.isSecure && !networkItem.known) { PopupManager.requestOpen(Qt.resolvedUrl("Network/PSKOverlay.qml"), { network: networkItem.modelData }); } else { Network.requestConnect(networkItem.modelData); } } } } component Spacer: Item { id: spacer required property Repeater repeater Layout.preferredHeight: repeater.count > 0 ? Tokens.spacing.extraSmall : 0 } component Toggle: CustomSwitch { id: toggleItem readonly property alias bg: bg property alias first: bg.first property alias last: bg.last property string subtext Layout.fillWidth: true cLayer: 2 horizontalPadding: Tokens.padding.largeIncreased implicitHeight: Math.max(implicitContentHeight, implicitIndicatorHeight) + verticalPadding * 2 implicitWidth: implicitContentWidth + implicitIndicatorWidth + horizontalPadding * 2 indicator.anchors.right: right indicator.anchors.rightMargin: toggleItem.horizontalPadding indicator.anchors.verticalCenter: verticalCenter verticalPadding: Tokens.padding.normal background: ConnectedRect { id: bg StateLayer { id: stateLayer manualPressOverride: toggleItem.pressed } } contentItem: Item { anchors.left: parent.left anchors.leftMargin: toggleItem.horizontalPadding anchors.right: toggleItem.indicator.left anchors.rightMargin: Tokens.spacing.normal implicitHeight: column.implicitHeight implicitWidth: column.implicitWidth Column { id: column anchors.left: parent.left anchors.right: parent.right anchors.verticalCenter: parent.verticalCenter spacing: 0 CustomText { id: label anchors.left: parent.left anchors.right: parent.right elide: Text.ElideRight font: { const f = Qt.font(label.font); f.pointSize = Tokens.font.size.smaller; return f; } text: toggleItem.text } CustomText { id: subtext anchors.left: parent.left anchors.right: parent.right color: Colors.palette.m3outline elide: Text.ElideRight font: { const f = Qt.font(subtext.font); f.pointSize = Tokens.font.size.small; return f; } text: toggleItem.subtext visible: toggleItem.subtext } } } onPressed: stateLayer.press(stateLayer.mouseX, stateLayer.mouseY) } }