@@ -16,23 +16,27 @@
1616
1717import QtQuick 2.4
1818import Ubuntu.Components 1.3
19+import "." 0.1
1920
2021FocusScope {
2122 id: root
2223
24+ property alias background: coverPage.background
25+ property alias backgroundTopMargin: coverPage.backgroundTopMargin
2326 property alias dragHandleLeftMargin: coverPage.dragHandleLeftMargin
27+ property alias infographicModel: coverPage.infographicModel
2428 property alias launcherOffset: coverPage.launcherOffset
25− property alias currentIndex: loginList.currentIndex
29+ property alias loginListShown: loginAreaLoader.loginListShown
30+ property int currentIndex // Set from outside
2631 property int delayMinutes // TODO
27− property alias backgroundTopMargin: coverPage.backgroundTopMargin
28− property alias background: coverPage.background
32+ property bool alphanumeric // unused
2933 property bool locked
30− property alias alphanumeric: loginList.alphanumeric
31− property alias userModel: loginList.model
32− property alias infographicModel: coverPage.infographicModel
34+ property alias sessionToStart: loginAreaLoader.currentSession
35+ property var userModel // Set from outside
36+
37+ readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
3338 readonly property bool fullyShown: coverPage.showProgress === 1
3439 readonly property bool required: coverPage.required
35− readonly property bool animating: coverPage.showAnimation.running || coverPage.hideAnimation.running
3640
3741 // so that it can be replaced in tests with a mock object
3842 property var inputMethod: Qt.inputMethod
@@ -43,38 +47,39 @@ FocusScope {
4347 signal tease()
4448 signal emergencyCall() // unused
4549
46− function showMessage(html) {
47− loginList.showMessage(html);
48− }
49−
50− function showPrompt(text, isSecret, isDefaultPrompt) {
51− loginList.showPrompt(text, isSecret, isDefaultPrompt);
52− }
53−
54− function showLastChance() {
55− // TODO
50+ /***** Functions that depend on LoginList being loaded *****/
51+ // A decorator to only call LoginList functions when its shown
52+ function ifLoginlistShownThen(f) {
53+ return function() {
54+ if (loginListShown) f.apply(this, arguments);
55+ }
5656 }
5757
58− function hide() {
59− coverPage.hide();
58+ readonly property var notifyAuthenticationFailed: ifLoginlistShownThen(doNotifyAuthenticationFailed);
59+ function doNotifyAuthenticationFailed() {
60+ loginAreaLoader.item.showError();
6061 }
6162
62− function notifyAuthenticationSucceeded() {
63− // Nothing needed
63+ readonly property var reset: ifLoginlistShownThen(doReset);
64+ function doReset() {
65+ loginAreaLoader.item.reset();
6466 }
6567
66− function notifyAuthenticationFailed() {
67− loginList.showError();
68+ readonly property var showMessage: ifLoginlistShownThen(doShowMessage);
69+ function doShowMessage(html) {
70+ loginAreaLoader.item.showMessage(html);
6871 }
6972
70− function reset() {
71− loginList.reset();
73+ readonly property var showPrompt: ifLoginlistShownThen(doShowPrompt);
74+ function doShowPrompt(text, isSecret, isDefaultPrompt) {
75+ loginAreaLoader.item.showPrompt(text, isSecret, isDefaultPrompt);
7276 }
7377
74− function tryToUnlock(toTheRight) {
78+ readonly property var tryToUnlock: ifLoginlistShownThen(doTryToUnlock);
79+ function doTryToUnlock(toTheRight) {
7580 if (root.locked) {
7681 coverPage.show();
77− loginList.tryToUnlock();
82+ loginAreaLoader.item.tryToUnlock();
7883 return false;
7984 } else {
8085 var coverChanged = coverPage.shown;
@@ -87,6 +92,19 @@ FocusScope {
8792 }
8893 }
8994
95+ /***** Functions that are agnostic of what object is loaded *****/
96+ function hide() {
97+ coverPage.hide();
98+ }
99+
100+ function notifyAuthenticationSucceeded() {
101+ // Nothing needed
102+ }
103+
104+ function showLastChance() {
105+ // TODO
106+ }
107+
90108 Rectangle {
91109 anchors.fill: parent
92110 color: "black"
@@ -102,7 +120,7 @@ FocusScope {
102120
103121 infographics {
104122 height: 0.75 * parent.height
105− anchors.leftMargin: loginList.x + loginList.width
123+ anchors.leftMargin: loginAreaLoader.x + loginAreaLoader.width
106124 }
107125
108126 onTease: root.tease()
@@ -113,25 +131,98 @@ FocusScope {
113131 }
114132 }
115133
116− LoginList {
117− id: loginList
118− objectName: "loginList"
134+ Loader {
135+ id: loginAreaLoader
136+ objectName: "loginAreaLoader"
137+
138+ // True when LoginList is shown, false when SessionList is shown
139+ property bool loginListShown: true
140+ property bool sessionUpdated: false
141+ property string currentSession: LightDMService.sessions.defaultSession // Set as soon as LoginList is loaded
142+
143+ source: loginListShown ? "LoginList.qml" : "SessionsList.qml"
144+ onSourceChanged: loadingAnimation.running = true
119145
120146 anchors {
121147 left: parent.left
122148 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
123149 top: parent.top
124150 }
151+
125152 width: units.gu(29)
126− height: inputMethod && inputMethod.visible ? parent.height - inputMethod.keyboardRectangle.height
127− : parent.height
153+ height: inputMethod && inputMethod.visible ?
154+ parent.height - inputMethod.keyboardRectangle.height : parent.height
155+
128156 Behavior on height { UbuntuNumberAnimation {} }
129157
130− locked: root.locked
158+ UbuntuNumberAnimation {
159+ id: loadingAnimation
160+ target: loginAreaLoader.item
161+ property: "x"
162+ from: loader.item ? loader.item.width : 0
163+ to: 0
164+ running: false
165+ }
131166
132− onPromptlessLogin: root.promptlessLogin()
133− onSelected: root.selected(index)
134− onResponded: root.responded(response)
167+ Binding {
168+ target: loginAreaLoader.item
169+ property: "currentIndex"
170+ value: loginListShown ? root.currentIndex : null
171+ }
172+
173+ Binding {
174+ target: loginAreaLoader.item
175+ property: "locked"
176+ value: root.locked
177+ }
178+
179+ Binding {
180+ target: loginAreaLoader.item
181+ property: "model"
182+ value: loginListShown ? root.userModel : null
183+ }
184+
185+ // Only inform LoginList if the session isn't the user's default session
186+ // because LoginList gets the default session on its own
187+ Binding {
188+ target: loginAreaLoader.item
189+ property: "selectedSession"
190+ value: loginListShown && loginAreaLoader.sessionUpdated ?
191+ loginAreaLoader.currentSession : null
192+ }
193+
194+ Binding {
195+ target: loginAreaLoader.item
196+ property: "initiallySelectedSession"
197+ value: !loginListShown ? loginAreaLoader.currentSession : null
198+ }
199+
200+ Connections {
201+ target: loginListShown ? loginAreaLoader.item : null
202+ onSelected: root.selected(index)
203+ onResponded: root.responded(response)
204+ // The initially selected session lags behind the component completion
205+ // so this provides the initial session name when available
206+ onLoginListSessionChanged: {
207+ if (loginListShown && !loginAreaLoader.sessionUpdated) {
208+ loginAreaLoader.currentSession = loginAreaLoader.item.currentSession
209+ }
210+ }
211+ onPromptlessLogin: root.promptlessLogin()
212+
213+ onSessionChooserButtonClicked: loginListShown = false;
214+ ignoreUnknownSignals: true
215+ }
216+
217+ Connections {
218+ target: !loginListShown ? loginAreaLoader.item : null
219+ onSessionSelected: {
220+ loginAreaLoader.loginListShown = true
221+ loginAreaLoader.sessionUpdated = true
222+ loginAreaLoader.currentSession = sessionName
223+ }
224+ ignoreUnknownSignals: true
225+ }
135226 }
136227 }
137228}