@@ -12,6 +12,33 @@ ColumnLayout {
1212 id: root
1313 spacing: Common .Appearance .spacing .medium
1414
15+ // Password dialog state
16+ property string selectedSsid: " "
17+ property string selectedSecurity: " "
18+ property bool showPasswordDialog: false
19+
20+ function showPasswordPrompt (ssid , security ) {
21+ selectedSsid = ssid
22+ selectedSecurity = security
23+ showPasswordDialog = true
24+ passwordField .text = " "
25+ passwordField .forceActiveFocus ()
26+ }
27+
28+ function hidePasswordPrompt () {
29+ showPasswordDialog = false
30+ selectedSsid = " "
31+ selectedSecurity = " "
32+ passwordField .text = " "
33+ }
34+
35+ function connectWithPassword () {
36+ if (passwordField .text .length > 0 ) {
37+ Services .Network .connectToNetwork (selectedSsid, passwordField .text )
38+ hidePasswordPrompt ()
39+ }
40+ }
41+
1542 // Refresh when view opens
1643 Component .onCompleted : {
1744 Services .Network .refresh ()
@@ -60,6 +87,206 @@ ColumnLayout {
6087 }
6188 }
6289
90+ // ===== Password Input Dialog =====
91+ Rectangle {
92+ visible: root .showPasswordDialog
93+ Layout .fillWidth : true
94+ Layout .preferredHeight : passwordContent .implicitHeight + Common .Appearance .spacing .medium * 2
95+ radius: Common .Appearance .rounding .large
96+ color: Common .Appearance .m3colors .primaryContainer
97+
98+ ColumnLayout {
99+ id: passwordContent
100+ anchors .fill : parent
101+ anchors .margins : Common .Appearance .spacing .medium
102+ spacing: Common .Appearance .spacing .small
103+
104+ // Header
105+ RowLayout {
106+ Layout .fillWidth : true
107+ spacing: Common .Appearance .spacing .small
108+
109+ Common .Icon {
110+ name: Common .Icons .icons .wifi
111+ size: Common .Appearance .sizes .iconMedium
112+ color: Common .Appearance .m3colors .onPrimaryContainer
113+ }
114+
115+ ColumnLayout {
116+ Layout .fillWidth : true
117+ spacing: 2
118+
119+ Text {
120+ text: root .selectedSsid
121+ font .family : Common .Appearance .fonts .main
122+ font .pixelSize : Common .Appearance .fontSize .normal
123+ font .weight : Font .Medium
124+ color: Common .Appearance .m3colors .onPrimaryContainer
125+ elide: Text .ElideRight
126+ Layout .fillWidth : true
127+ }
128+
129+ Text {
130+ text: " Enter password to connect"
131+ font .family : Common .Appearance .fonts .main
132+ font .pixelSize : Common .Appearance .fontSize .small
133+ color: Common .Appearance .m3colors .onPrimaryContainer
134+ opacity: 0.8
135+ }
136+ }
137+
138+ MouseArea {
139+ Layout .preferredWidth : 28
140+ Layout .preferredHeight : 28
141+ cursorShape: Qt .PointingHandCursor
142+ onClicked: root .hidePasswordPrompt ()
143+
144+ Rectangle {
145+ anchors .fill : parent
146+ radius: Common .Appearance .rounding .small
147+ color: parent .containsMouse ? Common .Appearance .m3colors .primary : " transparent"
148+ opacity: 0.2
149+ }
150+
151+ Common .Icon {
152+ anchors .centerIn : parent
153+ name: Common .Icons .icons .close
154+ size: Common .Appearance .sizes .iconSmall
155+ color: Common .Appearance .m3colors .onPrimaryContainer
156+ }
157+ }
158+ }
159+
160+ // Password field
161+ Rectangle {
162+ Layout .fillWidth : true
163+ Layout .preferredHeight : 44
164+ radius: Common .Appearance .rounding .medium
165+ color: Common .Appearance .m3colors .surface
166+ border .width : passwordField .activeFocus ? 2 : 1
167+ border .color : passwordField .activeFocus
168+ ? Common .Appearance .m3colors .primary
169+ : Common .Appearance .m3colors .outline
170+
171+ RowLayout {
172+ anchors .fill : parent
173+ anchors .leftMargin : Common .Appearance .spacing .medium
174+ anchors .rightMargin : Common .Appearance .spacing .small
175+ spacing: Common .Appearance .spacing .small
176+
177+ Common .Icon {
178+ name: Common .Icons .icons .lock
179+ size: Common .Appearance .sizes .iconSmall
180+ color: Common .Appearance .m3colors .onSurfaceVariant
181+ }
182+
183+ TextInput {
184+ id: passwordField
185+ Layout .fillWidth : true
186+ Layout .fillHeight : true
187+ verticalAlignment: TextInput .AlignVCenter
188+ font .family : Common .Appearance .fonts .main
189+ font .pixelSize : Common .Appearance .fontSize .normal
190+ color: Common .Appearance .m3colors .onSurface
191+ echoMode: showPasswordButton .checked ? TextInput .Normal : TextInput .Password
192+ clip: true
193+
194+ Keys .onReturnPressed : root .connectWithPassword ()
195+ Keys .onEscapePressed : root .hidePasswordPrompt ()
196+
197+ Text {
198+ anchors .fill : parent
199+ anchors .leftMargin : 0
200+ verticalAlignment: Text .AlignVCenter
201+ visible: ! passwordField .text && ! passwordField .activeFocus
202+ text: " Password"
203+ font .family : Common .Appearance .fonts .main
204+ font .pixelSize : Common .Appearance .fontSize .normal
205+ color: Common .Appearance .m3colors .onSurfaceVariant
206+ }
207+ }
208+
209+ MouseArea {
210+ id: showPasswordButton
211+ property bool checked: false
212+ Layout .preferredWidth : 28
213+ Layout .preferredHeight : 28
214+ cursorShape: Qt .PointingHandCursor
215+ onClicked: checked = ! checked
216+
217+ Common .Icon {
218+ anchors .centerIn : parent
219+ name: showPasswordButton .checked ? Common .Icons .icons .eyeOff : Common .Icons .icons .eye
220+ size: Common .Appearance .sizes .iconSmall
221+ color: Common .Appearance .m3colors .onSurfaceVariant
222+ }
223+ }
224+ }
225+ }
226+
227+ // Buttons
228+ RowLayout {
229+ Layout .fillWidth : true
230+ spacing: Common .Appearance .spacing .small
231+
232+ Item { Layout .fillWidth : true }
233+
234+ MouseArea {
235+ Layout .preferredWidth : cancelText .implicitWidth + Common .Appearance .spacing .medium * 2
236+ Layout .preferredHeight : 36
237+ cursorShape: Qt .PointingHandCursor
238+ hoverEnabled: true
239+ onClicked: root .hidePasswordPrompt ()
240+
241+ Rectangle {
242+ anchors .fill : parent
243+ radius: Common .Appearance .rounding .medium
244+ color: parent .containsMouse ? Common .Appearance .m3colors .surface : " transparent"
245+ }
246+
247+ Text {
248+ id: cancelText
249+ anchors .centerIn : parent
250+ text: " Cancel"
251+ font .family : Common .Appearance .fonts .main
252+ font .pixelSize : Common .Appearance .fontSize .normal
253+ font .weight : Font .Medium
254+ color: Common .Appearance .m3colors .onPrimaryContainer
255+ }
256+ }
257+
258+ MouseArea {
259+ Layout .preferredWidth : connectText .implicitWidth + Common .Appearance .spacing .medium * 2
260+ Layout .preferredHeight : 36
261+ cursorShape: passwordField .text .length > 0 ? Qt .PointingHandCursor : Qt .ArrowCursor
262+ hoverEnabled: true
263+ enabled: passwordField .text .length > 0
264+ onClicked: root .connectWithPassword ()
265+
266+ Rectangle {
267+ anchors .fill : parent
268+ radius: Common .Appearance .rounding .medium
269+ color: passwordField .text .length > 0
270+ ? (parent .containsMouse ? Qt .darker (Common .Appearance .m3colors .primary , 1.1 ) : Common .Appearance .m3colors .primary )
271+ : Common .Appearance .m3colors .surfaceVariant
272+ }
273+
274+ Text {
275+ id: connectText
276+ anchors .centerIn : parent
277+ text: " Connect"
278+ font .family : Common .Appearance .fonts .main
279+ font .pixelSize : Common .Appearance .fontSize .normal
280+ font .weight : Font .Medium
281+ color: passwordField .text .length > 0
282+ ? Common .Appearance .m3colors .onPrimary
283+ : Common .Appearance .m3colors .onSurfaceVariant
284+ }
285+ }
286+ }
287+ }
288+ }
289+
63290 // ===== Interface List =====
64291 Repeater {
65292 id: interfaceRepeater
@@ -401,10 +628,10 @@ ColumnLayout {
401628 saved: modelData .saved
402629 isConnected: Services .Network .ssid === modelData .ssid && Services .Network .connected
403630 onConnectClicked: {
404- if (modelData .saved || ! modelData .security ) {
631+ if (modelData .saved || ! modelData .security || modelData . security === " -- " ) {
405632 Services .Network .connectToNetwork (modelData .ssid )
406633 } else {
407- console . log ( " Need password for " , modelData .ssid )
634+ root . showPasswordPrompt ( modelData . ssid , modelData .security )
408635 }
409636 }
410637 onForgetClicked: Services .Network .forgetNetwork (modelData .ssid )
0 commit comments