Merge lp:~dgadomski/ubuntu-calculator-app/relative-time-formatting into lp:~ubuntu-calculator-dev/ubuntu-calculator-app/old_trunk

Proposed by Dariusz Gadomski
Status: Merged
Approved by: Gustavo Pichorim Boiko
Approved revision: 117
Merged at revision: 118
Proposed branch: lp:~dgadomski/ubuntu-calculator-app/relative-time-formatting
Merge into: lp:~ubuntu-calculator-dev/ubuntu-calculator-app/old_trunk
Diff against target: 213 lines (+104/-60)
3 files modified
Simple/SimplePage.qml (+3/-2)
Storage.qml (+2/-58)
dateutils.js (+99/-0)
To merge this branch: bzr merge lp:~dgadomski/ubuntu-calculator-app/relative-time-formatting
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Gustavo Pichorim Boiko (community) Approve
Riccardo Padovani Approve
David Planella Pending
Review via email: mp+177651@code.launchpad.net

Commit message

Reusing relative time formatting implemented for ubuntu-rssreader-app.

Description of the change

As agreed with David Planella I have prepared a common framework for relative time formatting for the rssreader-app (https://code.launchpad.net/~dgadomski/ubuntu-rssreader-app/relative-time-formatting/+merge/176435) and calculator-app.

Please take time to review it. Thanks.

To post a comment you must log in.
Revision history for this message
Riccardo Padovani (rpadovani) wrote :

Looks good, thank you very much for your contribute Dariusz!

review: Approve
Revision history for this message
Dariusz Gadomski (dgadomski) wrote :

You're welcome. I'm glad to help.

I have just one question: this merge request remains in Needs Review state. Does it still need an approval from someone else?

Thanks.

Revision history for this message
Mihir Soni (mihirsoni) wrote :

Jenkins Bot will automatically merge your request..you don't need to do it manually :)

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

Yes, someone (you?) asks explicitly to dpm to review it. As far as I know David will return next week, so we have to wait

Revision history for this message
Dariusz Gadomski (dgadomski) wrote :

Oh, I see. I added him because providing a consistent implementations for both: rssreader and calculator was his idea. Thanks for the info. Let's wait for him :)

Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

I am verifying why the jenkins' continuous integration didn't run on this branch, after CI passes, I will approve (as the code looks good), and top approve it so that it gets merged.

Revision history for this message
Gustavo Pichorim Boiko (boiko) wrote :

So, CI won't run for this MR, and as the code looks good, I'll approve it.

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Simple/SimplePage.qml'
2--- Simple/SimplePage.qml 2013-06-09 07:15:44 +0000
3+++ Simple/SimplePage.qml 2013-07-30 17:09:30 +0000
4@@ -20,6 +20,7 @@
5 import Ubuntu.Components 0.1
6 import "../engine.js" as CALC
7 import "../formula.js" as F
8+import "../dateutils.js" as DateUtils
9
10 Page {
11
12@@ -172,10 +173,10 @@
13 onDateUpdate: {
14 // If is in database
15 if (memory.get(index).dbId !== -1)
16- memory.get(index).dateText = storage.fromDateToString(storage.fromIdToDate(memory.get(index).dbId));
17+ memory.get(index).dateText = DateUtils.formatRelativeTime(i18n, storage.fromIdToDate(memory.get(index).dbId));
18 // If is in memory but not in database
19 else if (memory.get(index).timeStamp)
20- memory.get(index).dateText = storage.fromDateToString(memory.get(index).timeStamp);
21+ memory.get(index).dateText = DateUtils.formatRelativeTime(i18n, memory.get(index).timeStamp);
22 }
23
24 onLabelTextUpdated: {
25
26=== modified file 'Storage.qml'
27--- Storage.qml 2013-05-25 13:04:23 +0000
28+++ Storage.qml 2013-07-30 17:09:30 +0000
29@@ -18,6 +18,7 @@
30
31 import QtQuick 2.0
32 import QtQuick.LocalStorage 2.0
33+import "./dateutils.js" as DateUtils
34
35 Item {
36
37@@ -53,7 +54,7 @@
38 for(var i=res.rows.length - 1; i >= 0; i--){
39 var obj = JSON.parse(res.rows.item(i).calc);
40 obj.dbId = res.rows.item(i).id;
41- obj.dateText = fromDateToString(res.rows.item(i).insertDate);
42+ obj.dateText = DateUtils.formatRelativeTime(i18n, res.rows.item(i).insertDate);
43
44 if (!('mainLabel' in obj))
45 obj.mainLabel = ''
46@@ -88,63 +89,6 @@
47 });
48 }
49
50- /*
51- * Function fromDateToString
52- *
53- * Given an input object recovers its timestamp and
54- * returns a string based on how much time has passed
55- */
56- function fromDateToString(time) {
57- // TODO: see in settings if user wants AM/PM or 24h
58- // Now all strings are in AM/PM
59- // Below every string there is a comment with string in 24h
60- var then = new Date(time);
61- var now = new Date();
62- var daysElapsed = now.getDate() - then.getDate();
63- var hoursElapsed = now.getHours() - then.getHours();
64- var minutesElapsed = now.getMinutes() - then.getMinutes();
65- var issameMonth = (now.getMonth() === then.getMonth());
66- var relativeTime;
67-
68- // Today
69- if (daysElapsed === 0 && issameMonth) {
70- // Between 0 & 59 minutes
71- if (hoursElapsed < 1 || (hoursElapsed === 1 && then.getMinutes() > now.getMinutes())) {
72- // This is for different hours e.g. datestamp 11:58 now 12:02 prints "4 minutes ago"
73- minutesElapsed = minutesElapsed > 0 ? minutesElapsed : minutesElapsed + 60;
74- relativeTime = i18n.tr("%1 minute ago", "%1 minutes ago", minutesElapsed).arg(minutesElapsed);
75-
76- // Less than one minute
77- if (minutesElapsed < 1 && minutesElapsed >= 0 )
78- relativeTime = i18n.tr("A few seconds ago...");
79-
80- return relativeTime;
81- }
82-
83- // > 1 hour ago
84- relativeTime = i18n.tr("%1 hour ago", "%1 hours ago", hoursElapsed).arg(hoursElapsed);
85- }
86-
87- // Between two days and one week ago
88- else if (daysElapsed > 1 && daysElapsed < 7 && issameMonth) {
89- relativeTime = Qt.formatDateTime(then, "ddd, hh:mm AP");
90- }
91-
92- // Yesterday
93- else if (daysElapsed === 1 && issameMonth) {
94- // FIXME: we need a way to not split this string
95- // TRANSLATORS: What comes after 'at' is a time, e.g. 'Yesterday at 05:55 PM'
96- relativeTime = i18n.tr("Yesterday at %1").arg(Qt.formatDateTime(then, "hh:mm AP"))
97- }
98-
99- // More than one week ago
100- else {
101- relativeTime = Qt.formatDateTime(then, "MMM dd, hh:mm AP");
102- }
103-
104- return relativeTime
105- }
106-
107 // Function to have time from an ID
108 function fromIdToDate (dbId) {
109 var time;
110
111=== added file 'dateutils.js'
112--- dateutils.js 1970-01-01 00:00:00 +0000
113+++ dateutils.js 2013-07-30 17:09:30 +0000
114@@ -0,0 +1,99 @@
115+/*
116+ * Copyright 2013 Canonical Ltd.
117+ *
118+ * This file is part of ubuntu-rssreader-app.
119+ *
120+ * ubuntu-calculator-app is free software; you can redistribute it and/or modify
121+ * it under the terms of the GNU General Public License as published by
122+ * the Free Software Foundation; version 3.
123+ *
124+ * ubuntu-calculator-app is distributed in the hope that it will be useful,
125+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
126+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
127+ * GNU General Public License for more details.
128+ *
129+ * You should have received a copy of the GNU General Public License
130+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
131+ */
132+
133+.pragma library
134+
135+var SECONDS_LIMIT = 60 * 1000; // used as reference
136+var MINUTES_LIMIT = 60 * SECONDS_LIMIT; // print minutes up to 1h
137+var HOURS_LIMIT = 12 * MINUTES_LIMIT; // print hours up to 12h
138+var DAY_LIMIT = 24 * MINUTES_LIMIT; // print '<val> days ago' up to 30 days back
139+var DAYS_LIMIT = 30 * DAY_LIMIT; // print '<val> days ago' up to 30 days back
140+
141+function parseDate(dateAsStr) {
142+ return new Date(dateAsStr);
143+}
144+
145+function formatRelativeTime(i18n, dateAsStr) {
146+ // fallback if none of the other formatters matched
147+ function defaultFallbackFormat(then) {
148+ return Qt.formatDateTime(then, i18n.tr("MMMM d"))
149+ }
150+
151+ // Simple matches all diffs < limit, formats using the format function.
152+ function SimpleFormatter(limit, format) {
153+ this.matches = function (now, then, diff) { return diff < limit }
154+ this.format = format
155+ }
156+
157+ // Matches yesterday date
158+ function YesterdayFormatter() {
159+ this.matches = function (now, then, diff) {
160+ return diff < DAY_LIMIT && now.getDate() !== then.getDate();
161+ }
162+ this.format = function (now, then, diff) {
163+ return i18n.tr("Yesterday at %1").arg(
164+ Qt.formatDateTime(then, i18n.tr("h:mm AP")))
165+ }
166+ }
167+
168+ // Matches up to 7 days ago (formats date as a weekday + time)
169+ function WeekFormatter() {
170+ this.matches = function (now, then, diff) {
171+ return diff < 7 * DAY_LIMIT
172+ }
173+ this.format = function (now, then, diff) {
174+ return Qt.formatDateTime(then, i18n.tr("ddd, h:mm AP"));
175+ }
176+ }
177+
178+ // An array of formatting object processed from 0 up to a matching object.
179+ // If none of the object matches a default fallback formatter will be used.
180+ var FORMATTERS = [
181+ new SimpleFormatter(SECONDS_LIMIT, function (now, then, diff) { return i18n.tr("A few seconds ago...") }),
182+ new SimpleFormatter(MINUTES_LIMIT, function (now, then, diff) {
183+ var val = Math.floor(diff / SECONDS_LIMIT)
184+ return i18n.tr("%1 minute ago", "%1 minutes ago", val).arg(val)
185+ }),
186+ new SimpleFormatter(HOURS_LIMIT, function (now, then, diff) {
187+ var val = Math.floor(diff / MINUTES_LIMIT)
188+ return i18n.tr("%1 hour ago", "%1 hours ago", val).arg(val)
189+ }),
190+ new YesterdayFormatter(),
191+ new WeekFormatter(),
192+ new SimpleFormatter(DAYS_LIMIT, function (now, then, diff) {
193+ var val = Math.floor(diff / DAY_LIMIT)
194+ return i18n.tr("%1 day ago", "%1 days ago", val).arg(val)
195+ })
196+ ]
197+
198+ function formatDiff(now, then, diff) {
199+ for (var i=0; i<FORMATTERS.length; ++i) {
200+ var formatter = FORMATTERS[i]
201+ if (formatter.matches(now, then, diff)) {
202+ return formatter.format(now, then, diff)
203+ }
204+ }
205+ return defaultFallbackFormat(then)
206+ }
207+
208+ var now = new Date();
209+ var then = parseDate(dateAsStr);
210+ var diff = now - then;
211+ var formattedDiff = formatDiff(now, then, diff);
212+ return formattedDiff;
213+}

Subscribers

People subscribed via source and target branches