Merge lp:~nik90/ubuntu-clock-app/onetime-alarms into lp:ubuntu-clock-app

Proposed by Nekhelesh Ramananthan
Status: Merged
Approved by: Nekhelesh Ramananthan
Approved revision: 72
Merged at revision: 76
Proposed branch: lp:~nik90/ubuntu-clock-app/onetime-alarms
Merge into: lp:ubuntu-clock-app
Diff against target: 390 lines (+156/-55)
6 files modified
app/alarm/AlarmDelegate.qml (+2/-1)
app/alarm/AlarmRepeat.qml (+27/-5)
app/alarm/AlarmUtils.qml (+18/-1)
app/alarm/EditAlarmPage.qml (+35/-6)
debian/changelog (+1/-0)
tests/unit/tst_alarmRepeat.qml (+73/-42)
To merge this branch: bzr merge lp:~nik90/ubuntu-clock-app/onetime-alarms
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Ubuntu Phone Apps Jenkins Bot continuous-integration Needs Fixing
Riccardo Padovani Approve
Alan Pope 🍺🐧🐱 πŸ¦„ (community) Approve
Review via email: mp+232519@code.launchpad.net

Commit message

Added support for one-time alarms

Description of the change

Added support for one-time alarms

===== Testing =====
1. Try creating an alarm that doesn't repeat.

2. Try editing an existing saved repeating alarm and change it into a one-time alarm and vice-versa.

3. Check if when you save a one-time alarm it appears in the indicator-datetime.

4. Check if when you create a one-time alarm for a time in the past, it is automatically scheduled for tomorrow. For instance if current local time is 15:00, create an alarm for 09:00 AM and see if it set to ring tomorrow.

5. Edit the alarm in step 4, and change the time to 20:00 and see if it is set to ring today at 20:00.

What doesn't work
=================

1. When a one-time alarm rings, it is not disabled automatically thereafter. (known bug https://bugs.launchpad.net/indicator-datetime/+bug/1362341)

To post a comment you must log in.
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
63. By Nekhelesh Ramananthan

Small code cleanups

64. By Nekhelesh Ramananthan

Disable alarm save button if the date is in the past

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

1) non-repeating alarm creation works
2) It's now 11:04, I can't set an alarm for 11:01, but equally I can't set one for midnight tonight either but can set one for 23:59
3) Works fine.
4) It does
5) On one occasions the OSK failed to come up when editing the alarm name. I had to swipe out of the app, use the dash search to wake the OSK then come back in and it would appear.

Still takes ~5s to save an alarm which is disconcerting.

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

Nothing much I can do about this since it was the designer's decision to make the clock app create one-time alarms for today. If you want to set a non-repeating alarm for tomorrow or any other day, the user is supposed to use the calendar app. I personally disagree, but that's what design wants. I will create a bug report on this after the MP lands and then check up on what design would like to do.

> 2) It's now 11:04, I can't set an alarm for 11:01, but equally I can't set one
> for midnight tonight either but can set one for 23:59

Awesome. I will start fixing the QML tests which needs to be adjusted.

> 1) non-repeating alarm creation works
> 3) Works fine.
> 4) It does

Looks like a random osk bug.

> 5) On one occasions the OSK failed to come up when editing the alarm name. I
> had to swipe out of the app, use the dash search to wake the OSK then come
> back in and it would appear.
>

I have reported bug 1362548 to track this. I am pretty sure that the alarms backend EDS needs to improve and is not due to clock app.

> Still takes ~5s to save an alarm which is disconcerting.

65. By Nekhelesh Ramananthan

Updated changelog

66. By Nekhelesh Ramananthan

Fixed qml tests

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Approve (continuous-integration)
67. By Nekhelesh Ramananthan

Small changed

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
68. By Nekhelesh Ramananthan

Fixed one-time alarm functionality

69. By Nekhelesh Ramananthan

Added function get_alarm_day() to AlarmUtils

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
70. By Nekhelesh Ramananthan

merged trunk

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Alan Pope 🍺🐧🐱 πŸ¦„ (popey) wrote :

Tested latest build and this works as expected.

review: Approve
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Read all the code, done all tests, ringed a lot of alarms: looks good to me :-)

review: Approve
71. By Nekhelesh Ramananthan

qml unit test update

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
72. By Nekhelesh Ramananthan

merged trunk

Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'app/alarm/AlarmDelegate.qml'
2--- app/alarm/AlarmDelegate.qml 2014-08-24 12:47:50 +0000
3+++ app/alarm/AlarmDelegate.qml 2014-09-03 22:15:02 +0000
4@@ -68,8 +68,9 @@
5
6 fontSize: "xx-small"
7 width: parent.width
8+ visible: type === Alarm.Repeating
9 wrapMode: Text.WrapAtWordBoundaryOrAnywhere
10- text: alarmUtils.format_day_string(daysOfWeek)
11+ text: alarmUtils.format_day_string(daysOfWeek, type)
12 }
13 }
14
15
16=== modified file 'app/alarm/AlarmRepeat.qml'
17--- app/alarm/AlarmRepeat.qml 2014-08-24 12:47:50 +0000
18+++ app/alarm/AlarmRepeat.qml 2014-09-03 22:15:02 +0000
19@@ -24,11 +24,28 @@
20 id: _alarmRepeatPage
21 objectName: "alarmRepeatPage"
22
23+ // Property to set the alarm days of the week in the edit alarm page
24+ property var alarm
25+
26 visible: false
27 title: i18n.tr("Repeat")
28
29- // Property to set the alarm days of the week in the edit alarm page
30- property var alarm
31+ /*
32+ By Default, the alarm is set to Today. However if it is a one-time alarm,
33+ this should be set to none, since this page shows the days the alarm
34+ repeats on and a one-time alarm shoudn't repeat on any day. While exiting
35+ the page, if the alarm is still a one-time alarm, then the alarm is set
36+ back to its original value (Today).
37+ */
38+ Component.onCompleted: {
39+ if (alarm.type === Alarm.OneTime)
40+ alarm.daysOfWeek = 0
41+ }
42+
43+ Component.onDestruction: {
44+ if (alarm.type === Alarm.OneTime)
45+ alarm.daysOfWeek = Alarm.AutoDetect
46+ }
47
48 ListModel {
49 id: daysModel
50@@ -101,14 +118,19 @@
51 control: Switch {
52 objectName: 'daySwitch' + index
53 checked: (alarm.daysOfWeek & flag) == flag
54+ && alarm.type === Alarm.Repeating
55 onCheckedChanged: {
56 if (checked) {
57 alarm.daysOfWeek |= flag
58- }
59-
60- else {
61+ } else {
62 alarm.daysOfWeek &= ~flag
63 }
64+
65+ if (alarm.daysOfWeek > 0) {
66+ alarm.type = Alarm.Repeating
67+ } else {
68+ alarm.type = Alarm.OneTime
69+ }
70 }
71 }
72 }
73
74=== modified file 'app/alarm/AlarmUtils.qml'
75--- app/alarm/AlarmUtils.qml 2014-08-24 12:47:50 +0000
76+++ app/alarm/AlarmUtils.qml 2014-09-03 22:15:02 +0000
77@@ -26,7 +26,11 @@
78 id: alarmUtils
79
80 // Function to format the alarm days accordingly to their occurance
81- function format_day_string(value) {
82+ function format_day_string(value, type) {
83+ if (type === Alarm.OneTime) {
84+ return i18n.tr("Never")
85+ }
86+
87 var occurs = _get_day(value)
88
89 if (value === _get_weekdays()) {
90@@ -46,6 +50,19 @@
91 }
92 }
93
94+ // Function return the alarm dayOfWeek according to the day provided
95+ function get_alarm_day(day) {
96+ switch(day) {
97+ case 0: return Alarm.Sunday
98+ case 1: return Alarm.Monday
99+ case 2: return Alarm.Tuesday
100+ case 3: return Alarm.Wednesday
101+ case 4: return Alarm.Thursday
102+ case 5: return Alarm.Friday
103+ case 6: return Alarm.Saturday
104+ }
105+ }
106+
107 /*
108 INTERNAL FUNCTIONS
109 */
110
111=== modified file 'app/alarm/EditAlarmPage.qml'
112--- app/alarm/EditAlarmPage.qml 2014-08-24 12:47:50 +0000
113+++ app/alarm/EditAlarmPage.qml 2014-09-03 22:15:02 +0000
114@@ -49,6 +49,7 @@
115 }
116
117 actions: Action {
118+ id: saveAlarmButton
119 iconName: "ok"
120 objectName: "saveAlarmAction"
121 text: i18n.tr("Alarm")
122@@ -74,12 +75,13 @@
123 var alarmTime = new Date()
124 alarmTime.setHours(_timePicker.hours, _timePicker.minutes, 0)
125
126+ validateDate(alarmTime)
127+
128 /*
129- _alarm.sound, _alarm.message and _alarm.daysOfWeek have been set in
130+ _alarm.sound, _alarm.daysOfWeek and _alarm.message have been set in
131 the respective individual pages already.
132 */
133 _alarm.date = alarmTime
134- _alarm.type = Alarm.Repeating
135 _alarm.enabled = true
136 _alarm.save()
137 }
138@@ -113,9 +115,11 @@
139 var alarmTime = new Date()
140 alarmTime.setHours(_timePicker.hours, _timePicker.minutes, 0)
141
142+ validateDate(alarmTime)
143+
144 tempAlarm.message = _alarm.message
145 tempAlarm.date = alarmTime
146- tempAlarm.type = Alarm.Repeating
147+ tempAlarm.type = _alarm.type
148 tempAlarm.enabled = _alarm.enabled
149 tempAlarm.sound = _alarm.sound
150 tempAlarm.daysOfWeek = _alarm.daysOfWeek
151@@ -154,8 +158,27 @@
152 }
153 }
154
155+ function validateDate(date) {
156+ if (_alarm.type === Alarm.OneTime) {
157+ _alarm.daysOfWeek = Alarm.AutoDetect
158+
159+ if (date < new Date()) {
160+ var tomorrow = new Date()
161+ tomorrow.setDate(tomorrow.getDate() + 1)
162+ _alarm.daysOfWeek = alarmUtils.get_alarm_day(tomorrow.getDay())
163+ }
164+ }
165+ }
166+
167 Alarm {
168 id: _alarm
169+
170+ onErrorChanged: {
171+ if (error !== Alarm.NoError) {
172+ Utils.log(debugMode, "Error saving alarm, code: " + error)
173+ }
174+ }
175+
176 onStatusChanged: {
177 if (status !== Alarm.Ready)
178 return;
179@@ -164,9 +187,15 @@
180 mainStack.pop();
181 }
182 }
183+
184+ onTypeChanged: {
185+ _alarmRepeat.subText = alarmUtils.format_day_string(_alarm.daysOfWeek, type)
186+ }
187+
188 onDaysOfWeekChanged: {
189- _alarmRepeat.subText = alarmUtils.format_day_string(_alarm.daysOfWeek)
190+ _alarmRepeat.subText = alarmUtils.format_day_string(_alarm.daysOfWeek, type)
191 }
192+
193 onDateChanged: {
194 _timePicker.date = _alarm.date
195 }
196@@ -241,7 +270,7 @@
197 .split(":")[1]/5))*5,
198 0,
199 0
200- )
201+ )
202 }
203 }
204
205@@ -256,7 +285,7 @@
206 objectName: "alarmRepeat"
207
208 text: i18n.tr("Repeat")
209- subText: alarmUtils.format_day_string(_alarm.daysOfWeek)
210+ subText: alarmUtils.format_day_string(_alarm.daysOfWeek, _alarm.type)
211 onClicked: mainStack.push(Qt.resolvedUrl("AlarmRepeat.qml"),
212 {"alarm": _alarm})
213 }
214
215=== modified file 'debian/changelog'
216--- debian/changelog 2014-09-02 17:14:39 +0000
217+++ debian/changelog 2014-09-03 22:15:02 +0000
218@@ -19,6 +19,7 @@
219 * Updated QtQuick library imports to v2.3
220 * Switched bzr branch to lp:ubuntu-clock-app
221 * Updated pot file name
222+ * Enabled one-time alarms in the UI (LP: #1358320)
223 * Fixed the transition animation to alarms to be more smoother (LP: #1362081)
224
225 [Zsombor Egri]
226
227=== modified file 'tests/unit/tst_alarmRepeat.qml'
228--- tests/unit/tst_alarmRepeat.qml 2014-08-19 20:33:48 +0000
229+++ tests/unit/tst_alarmRepeat.qml 2014-09-03 22:15:02 +0000
230@@ -15,9 +15,18 @@
231 id: _alarm
232 }
233
234- AlarmRepeat {
235+ Component {
236 id: alarmRepeatPage
237- alarm: _alarm
238+ AlarmRepeat {
239+ alarm: _alarm
240+ }
241+ }
242+
243+ Loader {
244+ id: alarmRepeatPageLoader
245+ anchors.left: parent.left
246+ anchors.right: parent.right
247+ anchors.bottom: parent.bottom
248 }
249
250 UbuntuTestCase {
251@@ -30,46 +39,67 @@
252 property var backButton
253 property var repeater
254 property var today: Qt.locale().standaloneDayName(
255- new Date().getDay(), Locale.LongFormat)
256+ new Date().getDay(), Locale.LongFormat)
257
258- function initTestCase() {
259- alarmRepeatPage.visible = true
260+ function init() {
261+ alarmRepeatPageLoader.sourceComponent = alarmRepeatPage
262+ alarmRepeatPageLoader.item.visible = true
263 header = findChild(mainView, "MainView_Header")
264 backButton = findChild(header, "customBackButton")
265- repeater = findChild(alarmRepeatPage, "alarmDays")
266+ repeater = findChild(alarmRepeatPageLoader.item, "alarmDays")
267 }
268
269 function cleanup() {
270- for(var i=0; i<repeater.count; i++) {
271- var currentDaySwitch = findChild(alarmRepeatPage, "daySwitch"+i)
272- var currentDayLabel = findChild(alarmRepeatPage, "alarmDay"+i)
273-
274- if(today === currentDayLabel.text) {
275- currentDaySwitch.checked = true
276- }
277-
278- else {
279- currentDaySwitch.checked = false
280- }
281- }
282- }
283-
284- /*
285- Test to check if the checkbox for today is checked by default
286- */
287- function test_todaySwitchIsChecked() {
288- for(var i=0; i<repeater.count; i++) {
289- var currentDayLabel = findChild(alarmRepeatPage, "alarmDay"+i)
290- var currentDaySwitch = findChild(alarmRepeatPage, "daySwitch"+i)
291-
292- if(today === currentDayLabel.text) {
293- compare(currentDaySwitch.checked, true, "Today's Switch is not checked by default")
294- }
295-
296- else {
297- compare(currentDaySwitch.checked, false, "Switch for days other than today are checked incorrectly")
298- }
299- }
300+ alarmRepeatPageLoader.sourceComponent = undefined
301+ _alarm.reset()
302+ tryCompare(_alarm, "status", Alarm.Ready)
303+ }
304+
305+ /*
306+ Test to check if none of the switches are checked by default since by
307+ default an alarm is an one-time alarm and in the repeat page none of
308+ the days must be checked
309+ */
310+ function test_allSwitchesAreUncheckedByDefault() {
311+ waitForRendering(alarmRepeatPageLoader.item);
312+
313+ tryCompare(_alarm, "daysOfWeek", 0, 3000, "Alarm days of weeks is not 0 by default")
314+
315+ for(var i=0; i<repeater.count; i++) {
316+ var currentDayLabel = findChild(alarmRepeatPageLoader.item, "alarmDay"+i)
317+ var currentDaySwitch = findChild(alarmRepeatPageLoader.item, "daySwitch"+i)
318+
319+ compare(currentDaySwitch.checked, false, "All switches are not disabled by default")
320+ }
321+ }
322+
323+ /*
324+ Test to check if the alarm types are being correctly changed when
325+ toggling some of the swtiches. So if a switch is toggle, the alarm
326+ should become a repeating alarm. if no switches are enabled then
327+ it should be a one time alarm.
328+ */
329+ function test_alarmTypeSwitch() {
330+ waitForRendering(alarmRepeatPageLoader.item);
331+
332+ // TEST FAILS HERE //
333+ // Alarm should be one-time by default. By the test before this
334+ // changed the value and the alarm.reset() in the cleanup doesn't
335+ // seem to do its job.
336+
337+ // test_alarmObjectSetsSwitchStatus() is run before this test. And in
338+ // that test I set the alarm type to repeating. However the cleanup
339+ // should reset back to one-time when calling the alarm.reset() function.
340+
341+ tryCompare(_alarm, "type", Alarm.OneTime, 3000, "Alarm type is not OneTime by default")
342+
343+ var dayListItem = findChild(alarmRepeatPageLoader.item, "alarmDay"+3)
344+
345+ mouseClick(dayListItem, centerOf(dayListItem).x, centerOf(dayListItem).y)
346+ tryCompare(_alarm, "type", Alarm.Repeating, 3000, "Alarm type did not change to Repeating despite enabling a switch")
347+
348+ mouseClick(dayListItem, centerOf(dayListItem).x, centerOf(dayListItem).y)
349+ tryCompare(_alarm, "type", Alarm.OneTime, 3000, "Alarm type is not OneTime despite all switches disabled")
350 }
351
352 /*
353@@ -77,18 +107,18 @@
354 updated correctly
355 */
356 function test_switchStatusUpdatesAlarmObject() {
357- waitForRendering(alarmRepeatPage);
358+ waitForRendering(alarmRepeatPageLoader.item);
359
360 for(var i=0; i<repeater.count; i++) {
361- var dayListItem = findChild(alarmRepeatPage, "alarmDayHolder"+i)
362- var currentDaySwitch = findChild(alarmRepeatPage, "daySwitch"+i)
363+ var dayListItem = findChild(alarmRepeatPageLoader.item, "alarmDayHolder"+i)
364+ var currentDaySwitch = findChild(alarmRepeatPageLoader.item, "daySwitch"+i)
365
366 if(!currentDaySwitch.checked) {
367 mouseClick(dayListItem, dayListItem.width/2, dayListItem.height/2)
368 }
369 }
370
371- compare(alarmRepeatPage.alarm.daysOfWeek, 127, "Alarm Object daysOfWeek value is incorrect w.r.t to the UI")
372+ compare(alarmRepeatPageLoader.item.alarm.daysOfWeek, 127, "Alarm Object daysOfWeek value is incorrect w.r.t to the UI")
373 }
374
375 /*
376@@ -97,11 +127,12 @@
377 should properly show the days previously selected by the user.
378 */
379 function test_alarmObjectSetsSwitchStatus() {
380+ _alarm.type = Alarm.Repeating
381 _alarm.daysOfWeek = 96 // Enabled saturday and sunday
382
383 for(var i=0; i<repeater.count; i++) {
384- var currentDayLabel = findChild(alarmRepeatPage, "alarmDay"+i)
385- var currentDaySwitch = findChild(alarmRepeatPage, "daySwitch"+i)
386+ var currentDayLabel = findChild(alarmRepeatPageLoader.item, "alarmDay"+i)
387+ var currentDaySwitch = findChild(alarmRepeatPageLoader.item, "daySwitch"+i)
388
389 if(currentDayLabel.text === Qt.locale().standaloneDayName(6, Locale.LongFormat) ||
390 currentDayLabel.text === Qt.locale().standaloneDayName(0, Locale.LongFormat)) {

Subscribers

People subscribed via source and target branches