Krolyxon
Branch master

Branches

Refs →

aurora.configquickshellauroraNetPage.qml

216 lines · 9.2 KB · QML

1import QtQuick
2import QtQuick.Layouts
3
4// Control panel > net (also the settings app's network section): wired / tethering, Wi-Fi radio + scan, networks.
5// Click a row = connect (a new secured one asks for its password in a pill under it).
6ColumnLayout {
7 id: page
8 property bool active: false
9 property bool cards: false // the settings app: groups on cards
10 onActiveChanged: Net.active = active
11 // the settings app creates this page already active and destroys it when leaving the section
12 Component.onCompleted: if (active) Net.active = true
13 Component.onDestruction: if (active) Net.active = false
14 spacing: cards ? 22 : 10
15
16 // wired / usb tethering (read-only status, plus a disconnect button)
17 Group {
18 visible: Net.wiredDevs.length > 0
19 flat: !page.cards
20 title: "wired"
21 keywords: "ethernet lan cable usb tethering phone"
22 Repeater {
23 model: Net.wiredDevs
24 delegate: ListRow {
25 required property var modelData
26 icon: modelData.usb ? Theme.iPhone : Theme.iEthernet
27 title: modelData.name
28 subtitle: Net.portal && Net.portalNet === modelData.name ? "sign in required"
29 : modelData.dev + (modelData.ip !== "" ? " · " + modelData.ip : "")
30 trailing: modelData.usb ? "usb" : ""
31 current: true
32 IconBtn {
33 visible: Net.portal && Net.portalNet === modelData.name
34 icon: Theme.iLogin
35 implicitHeight: 32
36 onClicked: Net.openPortal()
37 }
38 IconBtn {
39 icon: Theme.iClose
40 implicitHeight: 32
41 onClicked: Net.disconnectDev(modelData.dev)
42 }
43 }
44 }
45 }
46
47 // the radio: a card of its own in the settings app (Android's "use Wi-Fi")
48 Group {
49 flat: !page.cards
50 gap: 10
51 RowLayout {
52 Layout.fillWidth: true
53 Layout.leftMargin: page.cards ? 18 : 6
54 Layout.preferredHeight: page.cards ? 56 : -1
55 spacing: 8
56 Lb {
57 Layout.fillWidth: true
58 elide: Text.ElideRight
59 text: !Net.wifiEnabled ? "wi-fi · off"
60 : (Net.connected !== "" ? "wi-fi · " + Net.connected : "wi-fi · not connected")
61 color: Net.connected !== "" && Net.wifiEnabled ? Theme.fg : Theme.grey
62 }
63 IconBtn {
64 icon: Theme.iRefresh
65 active: Net.scanning
66 onClicked: Net.rescan()
67 }
68 IconBtn {
69 icon: Net.wifiEnabled ? Theme.iWifi : Theme.iWifiOff
70 active: Net.wifiEnabled
71 onClicked: Net.setWifi(!Net.wifiEnabled)
72 }
73 }
74
75 Lb {
76 visible: Net.message !== ""
77 Layout.fillWidth: true
78 Layout.leftMargin: page.cards ? 18 : 6
79 Layout.bottomMargin: page.cards ? 10 : 0
80 text: Net.message
81 wrapMode: Text.WordWrap
82 px: 10
83 color: Theme.err
84 }
85 }
86
87 Group {
88 title: Net.busy ? "working…" : "networks"
89 count: Net.busy || !Net.wifiEnabled ? "" : String(Net.networks.length)
90 flat: !page.cards
91 spacing: 10
92 Layout.fillHeight: true
93 // on a card: only as tall as the list, it scrolls inside once the page is full
94 Layout.maximumHeight: page.cards ? implicitHeight : Infinity
95
96 Flickable {
97 id: flick
98 Layout.fillWidth: true
99 Layout.fillHeight: true
100 Layout.preferredHeight: list.implicitHeight
101 clip: true
102 contentWidth: width
103 contentHeight: list.implicitHeight
104 boundsBehavior: Flickable.StopAtBounds
105
106 ColumnLayout {
107 id: list
108 width: flick.width
109 spacing: 2
110
111 Repeater {
112 model: Net.wifiEnabled ? Net.networks : []
113 delegate: ColumnLayout {
114 id: item
115 required property var modelData
116 Layout.fillWidth: true
117 spacing: 4
118
119 ListRow {
120 id: row
121 icon: Theme.wifiIcon(item.modelData.signal)
122 title: item.modelData.ssid
123 readonly property bool portal: item.modelData.inUse && Net.portal && Net.portalNet === item.modelData.ssid
124 subtitle: portal ? "sign in required"
125 : item.modelData.inUse ? "connected"
126 : (item.modelData.saved ? "saved"
127 : (item.modelData.security === "" ? "open" : item.modelData.security))
128 trailing: item.modelData.signal + "%"
129 current: item.modelData.inUse
130 onClicked: Net.connectTo(item.modelData)
131
132 IconBtn {
133 visible: row.portal
134 icon: Theme.iLogin
135 implicitHeight: 32
136 onClicked: Net.openPortal()
137 }
138 IconBtn {
139 visible: item.modelData.inUse
140 icon: Theme.iClose
141 implicitHeight: 32
142 onClicked: Net.disconnect()
143 }
144 IconBtn {
145 visible: item.modelData.saved
146 icon: Theme.iTrash
147 implicitHeight: 32
148 onClicked: Net.forget(item.modelData.ssid)
149 }
150 }
151
152 // password for a new secured network: a pill with white dots and the accent caret
153 Rectangle {
154 id: pwBox
155 visible: Net.askFor === item.modelData.ssid
156 Layout.fillWidth: true
157 Layout.preferredHeight: visible ? 52 : 0
158 radius: height / 2
159 color: Theme.s2
160 border.width: 1
161 border.color: pw.activeFocus ? Theme.fill : Theme.s3
162 onVisibleChanged: if (visible) { pw.text = ""; pw.forceActiveFocus() }
163
164 TextInput {
165 id: pw
166 anchors.left: parent.left
167 anchors.leftMargin: 22
168 anchors.right: go.left
169 anchors.rightMargin: 10
170 anchors.verticalCenter: parent.verticalCenter
171 echoMode: TextInput.Password
172 passwordCharacter: "•"
173 color: Theme.fg
174 selectionColor: Theme.fill
175 selectedTextColor: Theme.fillFg
176 font.family: Theme.mono
177 font.pixelSize: 15
178 font.letterSpacing: 2
179 clip: true
180 cursorDelegate: Rectangle {
181 width: 2
182 color: Theme.live
183 visible: pw.activeFocus
184 Timer {
185 running: pw.activeFocus
186 interval: 500
187 repeat: true
188 onTriggered: parent.opacity = 1 - parent.opacity
189 }
190 }
191 onAccepted: Net.connect(item.modelData.ssid, text)
192 Lb {
193 visible: !pw.text
194 anchors.verticalCenter: parent.verticalCenter
195 text: "password"
196 color: Theme.mute
197 }
198 }
199 IconBtn {
200 id: go
201 anchors.right: parent.right
202 anchors.rightMargin: 6
203 anchors.verticalCenter: parent.verticalCenter
204 implicitHeight: 40
205 icon: Theme.iCheck
206 active: pw.text !== ""
207 onClicked: Net.connect(item.modelData.ssid, pw.text)
208 }
209 }
210 }
211 }
212 }
213 }
214 }
215 Item { visible: page.cards; Layout.fillHeight: true }
216}