Files
z-bar-qt/Modules/Settings/Pages/Network/AddNetwork.qml
T
Inorishio 6391bc85c4
C++ / fmt (pull_request) Successful in 5s
C++ / build (pull_request) Successful in 2m10s
JS/TS / fmt (pull_request) Successful in 16s
JS/TS / lint (pull_request) Successful in 17s
Python / static (pull_request) Successful in 44s
C++ / clang-tidy (pull_request) Successful in 3m37s
Rust / build (pull_request) Successful in 1m3s
Rust / fmt (pull_request) Failing after 15m10s
Python / verify (pull_request) Failing after 16m16s
Rust / clippy (pull_request) Successful in 45s
Moved network related files, added network sub pages
2026-10-18 16:29:12 +02:00

257 lines
6.1 KiB
QML

pragma ComponentBehavior: Bound
import QtQuick
import QtQuick.Layouts
import Quickshell
import ZShell.Config
import ZShell.Internal
import ZShell.Blobs
import ZShell.Services
import ZShell.Components
import qs.Components
import qs.Modules.Settings.Common
PageBase {
id: root
property bool connecting: false
property bool failed: false
// Security model: index 0 = none, 1 = WPA/WPA2/WPA3 personal.
readonly property bool secured: securitySelect.active !== noneItem
property bool success: false
function submit(): void {
const ssid = ssidField.text.trim();
if (ssid.length === 0) {
ssidField.isError = true;
ssidField.forceActiveFocus();
return;
}
if (root.secured && passwordField.text.length < 8) {
passwordField.isError = true;
passwordField.forceActiveFocus();
return;
}
root.failed = false;
root.connecting = true;
Nmcli.addHiddenNetwork(ssid, root.secured ? passwordField.text : "", root.secured ? "wpa" : "none", hiddenToggle.checked, result => {
root.connecting = false;
if (result && result.success) {
root.success = true;
root.nState.closeSubPage();
} else {
root.failed = true;
if (root.secured)
passwordField.isError = true;
// Clean up the half-created profile so a retry starts fresh.
Nmcli.forgetNetwork(ssid);
}
});
}
isSubPage: true
title: Tr.tr("Add network")
ColumnLayout {
anchors.horizontalCenter: parent.horizontalCenter
anchors.top: parent.top
spacing: Tokens.spacing.large
width: root.cappedWidth
Connections {
function onSubPageClosed(): void {
if (root.success)
return;
const ssid = ssidField.text.trim();
if (ssid)
Nmcli.forgetNetwork(ssid);
}
target: root.nState
}
CustomText {
Layout.fillWidth: true
Layout.leftMargin: Tokens.padding.extraSmall
color: Colours.palette.m3onSurfaceVariant
font: Tokens.font.body.small
text: Tr.tr("Enter the details below to manually connect to a network.")
wrapMode: Text.WordWrap
}
CustomTextField {
id: ssidField
Layout.fillWidth: true
Layout.topMargin: Tokens.spacing.extraSmall
errorText: Tr.tr("Network name is required")
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhNoPredictiveText
leadingIcon: "wifi"
// TRANSLATORS: SSID is a protocol term, leave it untranslated
placeholderText: Tr.tr("Network name (SSID)")
// TRANSLATORS: sample network name, translate the e.g. but the name is a placeholder
supportingText: Tr.tr("e.g. MyHiddenNetwork")
onAccepted: root.secured ? passwordField.forceActiveFocus() : root.submit()
}
ToggleRow {
id: hiddenToggle
checked: true
first: true
subtext: Tr.tr("Actively probe for a network that doesn't broadcast its name")
text: Tr.tr("Hidden network")
}
SelectRow {
id: securitySelect
Layout.topMargin: Tokens.spacing.extraSmall / 2 - parent.spacing
fallbackIcon: "lock"
// TRANSLATORS: WPA/WPA2/WPA3 are protocol names, leave them untranslated
fallbackText: Tr.tr("WPA/WPA2/WPA3 Personal")
// label: Tr.tr("Security")
last: !root.secured
Behavior on bottomLeftRadius {
Anim {
type: Anim.DefaultEffects
}
}
Behavior on bottomRightRadius {
Anim {
type: Anim.DefaultEffects
}
}
menuItems: [
MenuItem {
icon: "lock"
// TRANSLATORS: WPA/WPA2/WPA3 are protocol names, leave them untranslated
text: Tr.tr("WPA/WPA2/WPA3 Personal")
},
MenuItem {
id: noneItem
icon: "lock_open"
text: Tr.trCtx("None (open)", "wifi security type")
}
]
}
Item {
Layout.bottomMargin: root.secured ? 0 : -parent.spacing
Layout.fillWidth: true
implicitHeight: root.secured ? passwordField.implicitHeight : 0
opacity: root.secured ? 1 : 0
Behavior on Layout.bottomMargin {
Anim {
type: Anim.DefaultEffects
}
}
Behavior on implicitHeight {
Anim {
type: Anim.DefaultEffects
}
}
Behavior on opacity {
Anim {
type: Anim.DefaultEffects
}
}
CustomTextField {
id: passwordField
anchors.left: parent.left
anchors.right: parent.right
echoMode: TextInput.Password
enabled: root.secured
errorText: root.failed ? Tr.tr("Connection failed — check the password") : Tr.tr("Password must be at least 8 characters")
leadingIcon: "key"
placeholderText: Tr.tr("Password")
// TRANSLATORS: WPA is a protocol name, leave it untranslated
supportingText: Tr.tr("WPA passwords are at least 8 characters")
onAccepted: root.submit()
}
}
RowLayout {
Layout.alignment: Qt.AlignRight
Layout.topMargin: Tokens.spacing.extraSmall - parent.spacing
spacing: Tokens.spacing.small
TextButton {
Layout.fillHeight: true
horizontalPadding: Tokens.padding.extraLarge
isRound: true
text: Tr.trCtx("Cancel", "button")
type: TextButton.Tonal
onClicked: root.nState.closeSubPage()
}
// Connect button — swaps to a loading spinner while connecting,
// matching the Wi-Fi list connect animation.
ButtonBase {
id: connectBtn
implicitHeight: connectMetrics.height + Tokens.padding.medium * 2
implicitWidth: connectMetrics.width + Tokens.padding.extraLarge * 2
// inactiveColour: Colours.palette.m3primary
// inactiveOnColour: Colours.palette.m3onPrimary
isRound: true
shapeMorph: true
// stateLayer.disabled: root.connecting || ssidField.text.trim().length === 0
onClicked: {
if (!root.connecting && ssidField.text.trim().length > 0)
root.submit();
}
TextMetrics {
id: connectMetrics
font: connectBtn.font
text: Tr.tr("Connect")
}
Anim {
id: connectContent
// anchors.centerIn: parent
// inAnimType: Anim.SlowEffects
// outAnimType: Anim.SlowEffects
// sourceComp: root.connecting ? connectLoadingComp : connectTextComp
}
Component {
id: connectLoadingComp
LoadingIndicator {
color: connectBtn.onColour
implicitSize: Math.round(Tokens.font.body.medium.pointSize * 1.4)
}
}
Component {
id: connectTextComp
CustomText {
color: connectBtn.onColour
font: connectBtn.font
text: connectMetrics.text
}
}
}
}
}
}