on xenial help sign in
Tweak tutorial delays and start conditions
21b3b92Michael Terry
qml/Tutorial/InactivityTimer.qml+17−9
@@ -18,36 +18,44 @@ import QtQuick 2.4
18import Ubuntu.Components 1.3
18import Ubuntu.Components 1.3
19
19
20Item {
20Item {
21+ id: root
22+
21− readonly property alias running: internalTimer.running
23+ readonly property bool running: delayTimer.running || inactivityTimer.running
22− property alias interval: internalTimer.interval
24+ property int interval: 3000
23 property var page
25 property var page
24 property int lastInputTimestamp
26 property int lastInputTimestamp
25
27
26 function start() {
28 function start() {
27− internalTimer.start();
29+ delayTimer.start();
28 }
30 }
29
31
30 ////
32 ////
31
33
32 onLastInputTimestampChanged: {
34 onLastInputTimestampChanged: {
33− if (internalTimer.running) {
35+ if (inactivityTimer.running) {
34− internalTimer.restart();
36+ inactivityTimer.restart();
35 }
37 }
36 }
38 }
37
39
38 Connections {
40 Connections {
39 target: page
41 target: page
40 onIsReadyChanged: {
42 onIsReadyChanged: {
41− if (page.isReady && internalTimer.running) {
43+ if (page.isReady && inactivityTimer.running) {
42− internalTimer.restart();
44+ inactivityTimer.restart();
43 }
45 }
44 }
46 }
45 }
47 }
46
48
47 Timer {
49 Timer {
48− id: internalTimer
50+ id: delayTimer
51+ interval: Math.max(root.interval - 3000, 0)
52+ onTriggered: inactivityTimer.start()
53+ }
54+
55+ Timer {
56+ id: inactivityTimer
49
57
50− interval: 3000
58+ interval: Math.min(root.interval, 3000)
51
59
52 onTriggered: {
60 onTriggered: {
53 if (page.isReady) {
61 if (page.isReady) {
qml/Tutorial/TutorialContent.qml+18−41
@@ -88,12 +88,12 @@ Item {
88
88
89 isReady: !tutorialLeftLoader.skipped && !paused && !keyboardVisible
89 isReady: !tutorialLeftLoader.skipped && !paused && !keyboardVisible
90
90
91− // Use an idle timer here, because when constructed, all our isReady variables will be false.
91+ InactivityTimer {
92− // Qml needs a moment to copy their values from Tutorial.qml. So we idle it and recheck.
93− Timer {
94 id: tutorialLeftTimer
92 id: tutorialLeftTimer
93+ objectName: "tutorialLeftTimer"
95− interval: 0
94+ interval: 20000
96− onTriggered: if (tutorialLeft.isReady && !tutorialLeft.shown) tutorialLeft.show()
95+ lastInputTimestamp: root.lastInputTimestamp
96+ page: parent
97 }
97 }
98
98
99 onIsReadyChanged: if (isReady && !shown) tutorialLeftTimer.start()
99 onIsReadyChanged: if (isReady && !shown) tutorialLeftTimer.start()
@@ -122,19 +122,12 @@ Item {
122 skipped: tutorialLeftLongLoader.skipped
122 skipped: tutorialLeftLongLoader.skipped
123 isReady: tutorialLeftLoader.skipped && !skipped && !paused && !keyboardVisible
123 isReady: tutorialLeftLoader.skipped && !skipped && !paused && !keyboardVisible
124
124
125− Timer {
125+ InactivityTimer {
126 id: tutorialLeftLongTimer
126 id: tutorialLeftLongTimer
127 objectName: "tutorialLeftLongTimer"
127 objectName: "tutorialLeftLongTimer"
128− interval: 5000
128+ interval: 10000
129− onTriggered: {
129+ lastInputTimestamp: root.lastInputTimestamp
130− if (parent.isReady) {
131− if (!parent.shown) {
132− parent.show();
133− }
134− } else if (!parent.skipped) {
130+ page: parent
135− restart();
136− }
137− }
138 }
131 }
139
132
140 onIsReadyChanged: if (isReady && !shown) tutorialLeftLongTimer.start()
133 onIsReadyChanged: if (isReady && !shown) tutorialLeftLongTimer.start()
@@ -163,19 +156,12 @@ Item {
163 skipped: tutorialTopLoader.skipped
156 skipped: tutorialTopLoader.skipped
164 isReady: tutorialLeftLongLoader.skipped && !skipped && !paused && !keyboardVisible
157 isReady: tutorialLeftLongLoader.skipped && !skipped && !paused && !keyboardVisible
165
158
166− // We fire 30s after left edge tutorial, with at least 3s of inactivity
167−
168 InactivityTimer {
159 InactivityTimer {
169− id: tutorialTopInactivityTimer
170− lastInputTimestamp: root.lastInputTimestamp
171− page: parent
172− }
173−
174− Timer {
175 id: tutorialTopTimer
160 id: tutorialTopTimer
176 objectName: "tutorialTopTimer"
161 objectName: "tutorialTopTimer"
177− interval: 27000
162+ interval: 60000
178− onTriggered: tutorialTopInactivityTimer.start()
163+ lastInputTimestamp: root.lastInputTimestamp
164+ page: parent
179 }
165 }
180
166
181 onIsReadyChanged: if (isReady && !shown) tutorialTopTimer.start()
167 onIsReadyChanged: if (isReady && !shown) tutorialTopTimer.start()
@@ -203,27 +189,18 @@ Item {
203 paused: root.paused
189 paused: root.paused
204
190
205 skipped: tutorialRightLoader.skipped
191 skipped: tutorialRightLoader.skipped
206− isReady: tutorialTopLoader.skipped && !skipped && !paused && !keyboardVisible
192+ isReady: tutorialTopLoader.skipped && !skipped && !paused && !keyboardVisible &&
207− ApplicationManager.count >= 3
193+ ApplicationManager.count >= 4
208
194
209 InactivityTimer {
195 InactivityTimer {
210− id: tutorialRightInactivityTimer
196+ id: tutorialRightTimer
211− objectName: "tutorialRightInactivityTimer"
197+ objectName: "tutorialRightTimer"
198+ interval: 10000
212 lastInputTimestamp: root.lastInputTimestamp
199 lastInputTimestamp: root.lastInputTimestamp
213 page: parent
200 page: parent
214 }
201 }
215
202
216− Connections {
217− target: d
218− onFocusedAppChanged: {
219− if (tutorialRight.isReady && !tutorialRight.shown && d.focusedApp
220− && d.focusedApp.state === ApplicationInfoInterface.Starting) {
221− tutorialRight.show();
222− }
223− }
224− }
225−
226− onIsReadyChanged: if (isReady && !shown) tutorialRightInactivityTimer.start()
203+ onIsReadyChanged: if (isReady && !shown) tutorialRightTimer.start()
227 onFinished: AccountsService.markDemoEdgeCompleted("right")
204 onFinished: AccountsService.markDemoEdgeCompleted("right")
228 }
205 }
229 }
206 }
tests/qmltests/Tutorial/tst_Tutorial.qml+19−4
@@ -231,6 +231,8 @@ Rectangle {
231 prepareShell();
231 prepareShell();
232
232
233 var tutorialLeft = findChild(shell, "tutorialLeft");
233 var tutorialLeft = findChild(shell, "tutorialLeft");
234+ var tutorialLeftTimer = findInvisibleChild(tutorialLeft, "tutorialLeftTimer");
235+ tutorialLeftTimer.interval = 0;
234 tryCompare(tutorialLeft, "opacity", 1);
236 tryCompare(tutorialLeft, "opacity", 1);
235 }
237 }
236
238
@@ -310,12 +312,15 @@ Rectangle {
310 function openTutorialRight() {
312 function openTutorialRight() {
311 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
313 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
312 var tutorialRight = findChild(shell, "tutorialRight");
314 var tutorialRight = findChild(shell, "tutorialRight");
315+ var tutorialRightTimer = findChild(tutorialRight, "tutorialRightTimer");
313
316
314 AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
317 AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
315 ApplicationManager.startApplication("gallery-app");
318 ApplicationManager.startApplication("gallery-app");
316 ApplicationManager.startApplication("facebook-webapp");
319 ApplicationManager.startApplication("facebook-webapp");
320+ ApplicationManager.startApplication("camera-app");
317
321
318 tryCompare(tutorialLeftLoader, "active", false);
322 tryCompare(tutorialLeftLoader, "active", false);
323+ tutorialRightTimer.interval = 1;
319 tryCompare(tutorialRight, "shown", true);
324 tryCompare(tutorialRight, "shown", true);
320 tryCompare(tutorialRight, "opacity", 1);
325 tryCompare(tutorialRight, "opacity", 1);
321 }
326 }
@@ -523,16 +528,17 @@ Rectangle {
523 // Test that if we exit the top tutorial, we don't immediately
528 // Test that if we exit the top tutorial, we don't immediately
524 // jump into right tutorial.
529 // jump into right tutorial.
525 var tutorialRight = findChild(shell, "tutorialRight");
530 var tutorialRight = findChild(shell, "tutorialRight");
526− var tutorialRightTimer = findInvisibleChild(tutorialRight, "tutorialRightInactivityTimer");
531+ var tutorialRightTimer = findInvisibleChild(tutorialRight, "tutorialRightTimer");
527
532
528 tutorialRightTimer.interval = 1;
533 tutorialRightTimer.interval = 1;
529 openTutorialTop();
534 openTutorialTop();
530 ApplicationManager.startApplication("gallery-app");
535 ApplicationManager.startApplication("gallery-app");
531 ApplicationManager.startApplication("facebook-webapp");
536 ApplicationManager.startApplication("facebook-webapp");
537+ ApplicationManager.startApplication("camera-app");
532− tryCompare(ApplicationManager, "count", 3);
538+ tryCompare(ApplicationManager, "count", 4);
533
539
534 AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
540 AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
535− verify(tutorialRightTimer.running, true);
541+ verify(tutorialRightTimer.running);
536 verify(!tutorialRight.shown);
542 verify(!tutorialRight.shown);
537 tryCompare(tutorialRight, "shown", true);
543 tryCompare(tutorialRight, "shown", true);
538 }
544 }
@@ -614,7 +620,11 @@ Rectangle {
614
620
615 ApplicationManager.startApplication("dialer-app");
621 ApplicationManager.startApplication("dialer-app");
616 ApplicationManager.startApplication("camera-app");
622 ApplicationManager.startApplication("camera-app");
623+ ApplicationManager.startApplication("facebook-webapp");
617 tryCompare(tutorialRightLoader.item, "isReady", true);
624 tryCompare(tutorialRightLoader.item, "isReady", true);
625+
626+ var tutorialRightTimer = findInvisibleChild(tutorialRightLoader, "tutorialRightTimer");
627+ tutorialRightTimer.interval = 1;
618 tryCompare(tutorialRightLoader, "shown", true);
628 tryCompare(tutorialRightLoader, "shown", true);
619 }
629 }
620
630
@@ -622,8 +632,11 @@ Rectangle {
622 loadShell("desktop");
632 loadShell("desktop");
623
633
624 var tutorialRight = findChild(shell, "tutorialRight");
634 var tutorialRight = findChild(shell, "tutorialRight");
635+ var tutorialRightTimer = findInvisibleChild(tutorialRight, "tutorialRightTimer");
625 ApplicationManager.startApplication("dialer-app");
636 ApplicationManager.startApplication("dialer-app");
626 ApplicationManager.startApplication("camera-app");
637 ApplicationManager.startApplication("camera-app");
638+ ApplicationManager.startApplication("facebook-webapp");
639+ tutorialRightTimer.interval = 1;
627 tryCompare(tutorialRight, "shown", true);
640 tryCompare(tutorialRight, "shown", true);
628
641
629 var stage = findChild(shell, "stage");
642 var stage = findChild(shell, "stage");
@@ -678,7 +691,9 @@ Rectangle {
678 AccountsService.demoEdges = true;
691 AccountsService.demoEdges = true;
679 tutorialLeft = findChild(shell, "tutorialLeft");
692 tutorialLeft = findChild(shell, "tutorialLeft");
680 verify(tutorialLeft != null);
693 verify(tutorialLeft != null);
681− tryCompare(tutorialLeft, "shown", true);
694+
695+ var tutorialLeftTimer = findChild(tutorialLeft, "tutorialLeftTimer");
696+ verify(tutorialLeftTimer.running);
682 }
697 }
683 }
698 }
684}
699}