@@ -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
29− property bool locked
3032 property bool alphanumeric // unused
31− property alias userModel: loginList.model
32− property alias infographicModel: coverPage.infographicModel
33+ property bool locked
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
@@ -42,38 +46,39 @@ FocusScope {
4246 signal tease()
4347 signal emergencyCall() // unused
4448
45− function showMessage(html) {
46− loginList.showMessage(html);
47− }
48−
49− function showPrompt(text, isSecret, isDefaultPrompt) {
50− loginList.showPrompt(text, isSecret, isDefaultPrompt);
49+ /***** Functions that depend on LoginList being loaded *****/
50+ // A decorator to only call LoginList functions when its shown
51+ function ifLoginlistShownThen(f) {
52+ return function() {
53+ if (loginListShown) f.apply(this, arguments);
54+ }
5155 }
5256
53− function showLastChance() {
54− // TODO
57+ readonly property var notifyAuthenticationFailed: ifLoginlistShownThen(doNotifyAuthenticationFailed);
58+ function doNotifyAuthenticationFailed() {
59+ loginAreaLoader.item.showError();
5560 }
5661
57− function hide() {
58− coverPage.hide();
62+ readonly property var reset: ifLoginlistShownThen(doReset);
63+ function doReset() {
64+ loginAreaLoader.item.reset();
5965 }
6066
61− function notifyAuthenticationSucceeded() {
62− // Nothing needed
67+ readonly property var showMessage: ifLoginlistShownThen(doShowMessage);
68+ function doShowMessage(html) {
69+ loginAreaLoader.item.showMessage(html);
6370 }
6471
65− function notifyAuthenticationFailed() {
66− loginList.showError();
72+ readonly property var showPrompt: ifLoginlistShownThen(doShowPrompt);
73+ function doShowPrompt(text, isSecret, isDefaultPrompt) {
74+ loginAreaLoader.item.showPrompt(text, isSecret, isDefaultPrompt);
6775 }
6876
69− function reset() {
70− loginList.reset();
71− }
72−
73− function tryToUnlock(toTheRight) {
77+ readonly property var tryToUnlock: ifLoginlistShownThen(doTryToUnlock);
78+ function doTryToUnlock(toTheRight) {
7479 if (root.locked) {
7580 coverPage.show();
76− loginList.tryToUnlock();
81+ loginAreaLoader.item.tryToUnlock();
7782 return false;
7883 } else {
7984 var coverChanged = coverPage.shown;
@@ -86,6 +91,19 @@ FocusScope {
8691 }
8792 }
8893
94+ /***** Functions that are agnostic of what object is loaded *****/
95+ function hide() {
96+ coverPage.hide();
97+ }
98+
99+ function notifyAuthenticationSucceeded() {
100+ // Nothing needed
101+ }
102+
103+ function showLastChance() {
104+ // TODO
105+ }
106+
89107 Rectangle {
90108 anchors.fill: parent
91109 color: "black"
@@ -101,7 +119,7 @@ FocusScope {
101119
102120 infographics {
103121 height: 0.75 * parent.height
104− anchors.leftMargin: loginList.x + loginList.width
122+ anchors.leftMargin: loginAreaLoader.x + loginAreaLoader.width
105123 }
106124
107125 onTease: root.tease()
@@ -112,24 +130,96 @@ FocusScope {
112130 }
113131 }
114132
115− LoginList {
116− id: loginList
117− objectName: "loginList"
133+ Loader {
134+ id: loginAreaLoader
135+
136+ // True when LoginList is shown, false when SessionList is shown
137+ property bool loginListShown: true
138+ property bool sessionUpdated: false
139+ property string currentSession // Set as soon as LoginList is loaded
140+
141+ source: loginListShown ? "LoginList.qml" : "SessionsList.qml"
142+ onSourceChanged: loadingAnimation.running = true
118143
119144 anchors {
120145 left: parent.left
121146 leftMargin: Math.min(parent.width * 0.16, units.gu(20))
122147 top: parent.top
123148 }
149+
124150 width: units.gu(29)
125− height: inputMethod && inputMethod.visible ? parent.height - inputMethod.keyboardRectangle.height
126− : parent.height
151+ height: inputMethod && inputMethod.visible ?
152+ parent.height - inputMethod.keyboardRectangle.height : parent.height
153+
127154 Behavior on height { UbuntuNumberAnimation {} }
128155
129− locked: root.locked
156+ UbuntuNumberAnimation {
157+ id: loadingAnimation
158+ target: loginAreaLoader.item
159+ property: "x"
160+ from: loader.item.width
161+ to: 0
162+ running: false
163+ }
164+
165+ Binding {
166+ target: loginAreaLoader.item
167+ property: "currentIndex"
168+ value: loginListShown ? root.currentIndex : null
169+ }
170+
171+ Binding {
172+ target: loginAreaLoader.item
173+ property: "locked"
174+ value: root.locked
175+ }
130176
131− onSelected: root.selected(index)
132− onResponded: root.responded(response)
177+ Binding {
178+ target: loginAreaLoader.item
179+ property: "model"
180+ value: loginListShown ? root.userModel : null
181+ }
182+
183+ // Only inform LoginList if the session isn't the user's default session
184+ // because LoginList gets the default session on its own
185+ Binding {
186+ target: loginAreaLoader.item
187+ property: "selectedSession"
188+ value: loginListShown && loginAreaLoader.sessionUpdated ?
189+ loginAreaLoader.currentSession : null
190+ }
191+
192+ Binding {
193+ target: loginAreaLoader.item
194+ property: "initiallySelectedSession"
195+ value: !loginListShown ? loginAreaLoader.currentSession : null
196+ }
197+
198+ Connections {
199+ target: loginListShown ? loginAreaLoader.item : null
200+ onSelected: root.selected(index)
201+ onResponded: root.responded(response)
202+ // The initially selected session lags behind the component completion
203+ // so this provides the initial session name when available
204+ onLoginListSessionChanged: {
205+ if (loginListShown && !loginAreaLoader.sessionUpdated) {
206+ loginAreaLoader.currentSession = loginAreaLoader.item.currentSession
207+ }
208+ }
209+
210+ onSessionChooserButtonClicked: loginListShown = false;
211+ ignoreUnknownSignals: true
212+ }
213+
214+ Connections {
215+ target: !loginListShown ? loginAreaLoader.item : null
216+ onSessionSelected: {
217+ loginAreaLoader.loginListShown = true
218+ loginAreaLoader.sessionUpdated = true
219+ loginAreaLoader.currentSession = sessionName
220+ }
221+ ignoreUnknownSignals: true
222+ }
133223 }
134224 }
135225}