Merge lp:~dgadomski/ubuntu-rssreader-app/relative-time-formatting into lp:~ubuntu-shorts-dev/ubuntu-rssreader-app/trunk

Proposed by Dariusz Gadomski
Status: Merged
Approved by: Joey Chan
Approved revision: 22
Merged at revision: 25
Proposed branch: lp:~dgadomski/ubuntu-rssreader-app/relative-time-formatting
Merge into: lp:~ubuntu-shorts-dev/ubuntu-rssreader-app/trunk
Diff against target: 520 lines (+116/-74)
10 files modified
ArticleFullImg.qml (+4/-3)
ArticleOneImgA.qml (+4/-3)
ArticleOneImgB.qml (+4/-3)
ArticleTextA.qml (+4/-3)
ArticleTextB.qml (+4/-3)
ArticleTwoImgA.qml (+4/-3)
ListColumnDelegate.qml (+2/-2)
ListColumnView.qml (+1/-1)
addDelegate.js (+19/-19)
dateutils.js (+70/-34)
To merge this branch: bzr merge lp:~dgadomski/ubuntu-rssreader-app/relative-time-formatting
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Ubuntu Shorts Developers Pending
Joey Chan Pending
David Planella Pending
Review via email: mp+176435@code.launchpad.net

Commit message

Improved relative time formatting utility.

Description of the change

This is my second approach to provide a more generic and flexible relative time formatting utility. This one incorporates an array of formatters which may be adjusted when needed.
There are 2 new formats added 'borrowed' from the calculator app: displaying that something happened yesterday ("Yesterday at %1") or within a week from now (by using the weekday name).

I have tested this version and it works just fine with gettext (all strings are extracted correctly for translations).

Unfortunately, since i18n is a QML context property (confirmed in Ubuntu UI toolkit source code: http://bazaar.launchpad.net/~ubuntu-sdk-team/ubuntu-ui-toolkit/trunk/view/head:/modules/Ubuntu/Components/plugin/plugin.cpp#L133) and not a function/component it cannot be simple ".import"-ed in JS. It needs to be passed there e.g. as an argument of the function.

I believe in this form it can be easily reused in ubuntu-calculator-app (it has all the features required there).

To post a comment you must log in.
Revision history for this message
Roman Shchekin (mrqtros) wrote :

Looks like all is ok, w8 while guys will review your code too :)

22. By Dariusz Gadomski

Merge with trunk.

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

Hi Dariusz,

We gonna make some changes to the database, one of the major change is, store time value in Integer, not text like before, in order to "order" articles by time value.

So, I want to ask u to separate the "formatRelativeTime" function into two parts:

1. one is convert the original time value to an Integer which is seconds from 1970-01-01 00:00
2. convert the "seconds" Integer to current output

Hope u have time to help :)
Thanks

Joey

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

Hi Joey,

I have changed the implementation to suit your needs:
https://code.launchpad.net/~dgadomski/ubuntu-rssreader-app/formatRelativeTime-uses-seconds/+merge/183714

I hope this is what you expected.

Regards,
Dariusz

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'ArticleFullImg.qml'
--- ArticleFullImg.qml 2013-07-09 16:08:27 +0000
+++ ArticleFullImg.qml 2013-07-26 15:25:31 +0000
@@ -1,12 +1,13 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem3import Ubuntu.Components.ListItems 0.1 as ListItem
4import "./dateutils.js" as DateUtils
45
5Column {6Column {
6 width: units.gu(26)7 width: units.gu(26)
7 height: units.gu(20)8 height: units.gu(20)
8 // anchors.fill: parent9 // anchors.fill: parent
9 property string rss_title: ""10 property variant rss_item
10 property variant imageArray: []11 property variant imageArray: []
11 property variant rss_model12 property variant rss_model
12 property int model_index13 property int model_index
@@ -42,7 +43,7 @@
42 Label43 Label
43 {44 {
44 id: label_title45 id: label_title
45 text: rss_title46 text: rss_item.title
46 anchors.bottom: parent.bottom47 anchors.bottom: parent.bottom
47 anchors.bottomMargin: units.gu(1)48 anchors.bottomMargin: units.gu(1)
48 anchors.horizontalCenter: parent.horizontalCenter49 anchors.horizontalCenter: parent.horizontalCenter
@@ -67,7 +68,7 @@
67 Label68 Label
68 {69 {
69 id: label_time70 id: label_time
70 text: "13 minutes ago"71 text: DateUtils.formatRelativeTime(i18n, rss_item.pubdate)
71 color: "black"72 color: "black"
72 fontSize: "medium"73 fontSize: "medium"
73 }74 }
7475
=== modified file 'ArticleOneImgA.qml'
--- ArticleOneImgA.qml 2013-07-05 13:59:01 +0000
+++ ArticleOneImgA.qml 2013-07-26 15:25:31 +0000
@@ -1,13 +1,14 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem3import Ubuntu.Components.ListItems 0.1 as ListItem
4import "./dateutils.js" as DateUtils
45
5Column {6Column {
6 id: delegate_item7 id: delegate_item
7 width: units.gu(34)8 width: units.gu(34)
8// height: units.gu(16)9// height: units.gu(16)
9// anchors.fill: parent10// anchors.fill: parent
10 property string rss_title: ""11 property variant rss_item
11 property variant imageArray: []12 property variant imageArray: []
12 property variant rss_model13 property variant rss_model
13 property int model_index14 property int model_index
@@ -21,7 +22,7 @@
21 Label22 Label
22 {23 {
23 id: label_title24 id: label_title
24 text: rss_title25 text: rss_item.title
25// anchors.horizontalCenter: parent.horizontalCenter26// anchors.horizontalCenter: parent.horizontalCenter
26 width: units.gu(14)27 width: units.gu(14)
27 wrapMode: Text.WrapAtWordBoundaryOrAnywhere28 wrapMode: Text.WrapAtWordBoundaryOrAnywhere
@@ -72,7 +73,7 @@
72 Label73 Label
73 {74 {
74 id: label_time75 id: label_time
75 text: "13 minutes ago"76 text: DateUtils.formatRelativeTime(i18n, rss_item.pubdate)
76 color: "black"77 color: "black"
77 fontSize: "medium"78 fontSize: "medium"
78 horizontalAlignment: Text.AlignRight79 horizontalAlignment: Text.AlignRight
7980
=== modified file 'ArticleOneImgB.qml'
--- ArticleOneImgB.qml 2013-07-05 13:59:01 +0000
+++ ArticleOneImgB.qml 2013-07-26 15:25:31 +0000
@@ -1,13 +1,14 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem3import Ubuntu.Components.ListItems 0.1 as ListItem
4import "./dateutils.js" as DateUtils
45
5Column {6Column {
6 id: delegate_item7 id: delegate_item
7 width: units.gu(34)8 width: units.gu(34)
8// height: units.gu(16)9// height: units.gu(16)
9// anchors.fill: parent10// anchors.fill: parent
10 property string rss_title: ""11 property variant rss_item
11 property variant imageArray: []12 property variant imageArray: []
12 property variant rss_model13 property variant rss_model
13 property int model_index14 property int model_index
@@ -59,7 +60,7 @@
59 Label60 Label
60 {61 {
61 id: label_title62 id: label_title
62 text: rss_title63 text: rss_item.title
63// anchors.horizontalCenter: parent.horizontalCenter64// anchors.horizontalCenter: parent.horizontalCenter
64 width: units.gu(14)65 width: units.gu(14)
65 wrapMode: Text.WrapAtWordBoundaryOrAnywhere66 wrapMode: Text.WrapAtWordBoundaryOrAnywhere
@@ -91,7 +92,7 @@
91 Label92 Label
92 {93 {
93 id: label_time94 id: label_time
94 text: "13 minutes ago"95 text: DateUtils.formatRelativeTime(i18n, rss_item.pubdate)
95 color: "black"96 color: "black"
96 fontSize: "medium"97 fontSize: "medium"
97 }98 }
9899
=== modified file 'ArticleTextA.qml'
--- ArticleTextA.qml 2013-07-05 13:59:01 +0000
+++ ArticleTextA.qml 2013-07-26 15:25:31 +0000
@@ -1,12 +1,13 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem3import Ubuntu.Components.ListItems 0.1 as ListItem
4import "./dateutils.js" as DateUtils
45
5Column {6Column {
6 width: units.gu(30)7 width: units.gu(30)
7// height: units.gu(15)8// height: units.gu(15)
8// anchors.fill: parent9// anchors.fill: parent
9 property string rss_title: ""10 property variant rss_item
10 property variant imageArray: []11 property variant imageArray: []
11 property variant rss_model12 property variant rss_model
12 property int model_index13 property int model_index
@@ -19,7 +20,7 @@
19 Label20 Label
20 {21 {
21 id: label_title22 id: label_title
22 text: rss_title23 text: rss_item.title
23// anchors.horizontalCenter: parent.horizontalCenter24// anchors.horizontalCenter: parent.horizontalCenter
24 width: units.gu(30)25 width: units.gu(30)
25 wrapMode: Text.WrapAtWordBoundaryOrAnywhere26 wrapMode: Text.WrapAtWordBoundaryOrAnywhere
@@ -42,7 +43,7 @@
42 Label43 Label
43 {44 {
44 id: label_time45 id: label_time
45 text: "13 minutes ago"46 text: DateUtils.formatRelativeTime(i18n, rss_item.pubdate)
46 color: "black"47 color: "black"
47 fontSize: "medium"48 fontSize: "medium"
48 width: parent.width49 width: parent.width
4950
=== modified file 'ArticleTextB.qml'
--- ArticleTextB.qml 2013-07-05 13:59:01 +0000
+++ ArticleTextB.qml 2013-07-26 15:25:31 +0000
@@ -1,12 +1,13 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem3import Ubuntu.Components.ListItems 0.1 as ListItem
4import "./dateutils.js" as DateUtils
45
5Column {6Column {
6 width: units.gu(30)7 width: units.gu(30)
7// height: units.gu(15)8// height: units.gu(15)
8// anchors.fill: parent9// anchors.fill: parent
9 property string rss_title: ""10 property variant rss_item
10 property variant imageArray: []11 property variant imageArray: []
11 property variant rss_model12 property variant rss_model
12 property int model_index13 property int model_index
@@ -19,7 +20,7 @@
19 Label20 Label
20 {21 {
21 id: label_title22 id: label_title
22 text: rss_title23 text: rss_item.title
23// anchors.horizontalCenter: parent.horizontalCenter24// anchors.horizontalCenter: parent.horizontalCenter
24 width: units.gu(30)25 width: units.gu(30)
25 wrapMode: Text.WrapAtWordBoundaryOrAnywhere26 wrapMode: Text.WrapAtWordBoundaryOrAnywhere
@@ -43,7 +44,7 @@
43 Label44 Label
44 {45 {
45 id: label_time46 id: label_time
46 text: "13 minutes ago"47 text: DateUtils.formatRelativeTime(i18n, rss_item.pubdate)
47 color: "black"48 color: "black"
48 fontSize: "medium"49 fontSize: "medium"
49 horizontalAlignment: Text.AlignRight50 horizontalAlignment: Text.AlignRight
5051
=== modified file 'ArticleTwoImgA.qml'
--- ArticleTwoImgA.qml 2013-07-05 13:59:01 +0000
+++ ArticleTwoImgA.qml 2013-07-26 15:25:31 +0000
@@ -1,13 +1,14 @@
1import QtQuick 2.01import QtQuick 2.0
2import Ubuntu.Components 0.12import Ubuntu.Components 0.1
3import Ubuntu.Components.ListItems 0.1 as ListItem3import Ubuntu.Components.ListItems 0.1 as ListItem
4import "./dateutils.js" as DateUtils
45
5Column {6Column {
6 id: delegate_item7 id: delegate_item
7 width: units.gu(34)8 width: units.gu(34)
8// height: units.gu(30)9// height: units.gu(30)
9// anchors.fill: parent10// anchors.fill: parent
10 property string rss_title: ""11 property variant rss_item
11 property variant imageArray: []12 property variant imageArray: []
12 property variant rss_model13 property variant rss_model
13 property int model_index14 property int model_index
@@ -21,7 +22,7 @@
21 Label22 Label
22 {23 {
23 id: label_title24 id: label_title
24 text: rss_title25 text: rss_item.title
25// anchors.horizontalCenter: parent.horizontalCenter26// anchors.horizontalCenter: parent.horizontalCenter
26 width: units.gu(14)27 width: units.gu(14)
27 wrapMode: Text.WrapAtWordBoundaryOrAnywhere28 wrapMode: Text.WrapAtWordBoundaryOrAnywhere
@@ -78,7 +79,7 @@
78 Label79 Label
79 {80 {
80 id: label_time81 id: label_time
81 text: "13 minutes ago"82 text: DateUtils.formatRelativeTime(i18n, rss_item.pubdate)
82 color: "black"83 color: "black"
83 fontSize: "medium"84 fontSize: "medium"
84 }85 }
8586
=== modified file 'ListColumnDelegate.qml'
--- ListColumnDelegate.qml 2013-07-13 18:28:20 +0000
+++ ListColumnDelegate.qml 2013-07-26 15:25:31 +0000
@@ -20,10 +20,10 @@
20 property real childrenMaxWidth: 020 property real childrenMaxWidth: 0
21 property int modelIndex21 property int modelIndex
2222
23 function addItem(rss_title, rss_description, model, index)23 function addItem(rss_item, rss_description, model, index)
24 {24 {
25// console.log("delegate height: ", rss_item_delegate.height) ;25// console.log("delegate height: ", rss_item_delegate.height) ;
26 var newD = AddD.addDelegate(rss_title, ImgS.separate(rss_description), model, index);26 var newD = AddD.addDelegate(rss_item, ImgS.separate(rss_description), model, index);
27 getChildrenRect() ;27 getChildrenRect() ;
28 rss_item_delegate.width = childrenMaxWidth ;28 rss_item_delegate.width = childrenMaxWidth ;
29 //console.log("childrenSumHeight, column.height: ", childrenSumHeight, rss_item_delegate.height)29 //console.log("childrenSumHeight, column.height: ", childrenSumHeight, rss_item_delegate.height)
3030
=== modified file 'ListColumnView.qml'
--- ListColumnView.qml 2013-07-13 18:28:20 +0000
+++ ListColumnView.qml 2013-07-26 15:25:31 +0000
@@ -104,7 +104,7 @@
104// model++ ;104// model++ ;
105// currentIndex = model - 1 ;105// currentIndex = model - 1 ;
106 // console.log("model index: ", i)106 // console.log("model index: ", i)
107 while (!currentItem.addItem(tempmodel.get(i).title, tempmodel.get(i).description, tempmodel, i))107 while (!currentItem.addItem(tempmodel.get(i), tempmodel.get(i).description, tempmodel, i))
108 {108 {
109// model++ ;109// model++ ;
110 column_model.append( { "nothing": "nothing" } ) ;110 column_model.append( { "nothing": "nothing" } ) ;
111111
=== modified file 'addDelegate.js'
--- addDelegate.js 2013-07-05 13:59:01 +0000
+++ addDelegate.js 2013-07-26 15:25:31 +0000
@@ -4,7 +4,7 @@
4//var mob_component;4//var mob_component;
5//var mob_sprite;5//var mob_sprite;
66
7function addDelegate(rss_title, imageArray, model, index)7function addDelegate(rss_item, imageArray, model, index)
8{8{
9// console.log("add delegate start")9// console.log("add delegate start")
10// component = undefined ;10// component = undefined ;
@@ -23,18 +23,18 @@
23 // component = Qt.createComponent("./ArticledelegateOneImgB.qml");23 // component = Qt.createComponent("./ArticledelegateOneImgB.qml");
24 // sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray});24 // sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray});
25 // console.log("delegate BBBBB")25 // console.log("delegate BBBBB")
26 newD = delegateOneImgA (rss_title, imageArray, model, index)26 newD = delegateOneImgA (rss_item, imageArray, model, index)
27 }27 }
28 else if (rand > 70)28 else if (rand > 70)
29 {29 {
30 // component = Qt.createComponent("./ArticledelegateOneImgA.qml");30 // component = Qt.createComponent("./ArticledelegateOneImgA.qml");
31 // sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray});31 // sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray});
32 // console.log("delegate AAAAA")32 // console.log("delegate AAAAA")
33 newD = delegateOneImgB (rss_title, imageArray, model, index)33 newD = delegateOneImgB (rss_item, imageArray, model, index)
34 }34 }
35 else35 else
36 {36 {
37 newD = delegateFullImg (rss_title, imageArray, model, index)37 newD = delegateFullImg (rss_item, imageArray, model, index)
38 }38 }
3939
40 }40 }
@@ -42,16 +42,16 @@
42 {42 {
43 if (rand > 50)43 if (rand > 50)
44 {44 {
45 newD = delegateTextA (rss_title/*, imageArray*/, model, index) ;45 newD = delegateTextA (rss_item/*, imageArray*/, model, index) ;
46 }46 }
47 else47 else
48 {48 {
49 newD = delegateTextB (rss_title/*, imageArray*/, model, index) ;49 newD = delegateTextB (rss_item/*, imageArray*/, model, index) ;
50 }50 }
51 }51 }
52 else52 else
53 {53 {
54 newD = delegateTwoImgA (rss_title, imageArray, model, index)54 newD = delegateTwoImgA (rss_item, imageArray, model, index)
55 }55 }
5656
57// else if (imageArray == undefined )57// else if (imageArray == undefined )
@@ -79,12 +79,12 @@
79 return newD ;79 return newD ;
80}80}
8181
82function delegateOneImgA (rss_title, imageArray, model, index)82function delegateOneImgA (rss_item, imageArray, model, index)
83{83{
84 var component;84 var component;
85 var sprite;85 var sprite;
86 component = Qt.createComponent("./ArticleOneImgA.qml");86 component = Qt.createComponent("./ArticleOneImgA.qml");
87 sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray, "rss_model": model, "model_index": index});87 sprite = component.createObject(rss_item_delegate, {"rss_item": rss_item, "imageArray": imageArray, "rss_model": model, "model_index": index});
88// console.log("delegate AAAAA")88// console.log("delegate AAAAA")
8989
90 if (sprite == null) {90 if (sprite == null) {
@@ -95,12 +95,12 @@
95 return sprite95 return sprite
96}96}
9797
98function delegateOneImgB (rss_title, imageArray, model, index)98function delegateOneImgB (rss_item, imageArray, model, index)
99{99{
100 var component;100 var component;
101 var sprite;101 var sprite;
102 component = Qt.createComponent("./ArticleOneImgB.qml");102 component = Qt.createComponent("./ArticleOneImgB.qml");
103 sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray, "rss_model": model, "model_index": index});103 sprite = component.createObject(rss_item_delegate, {"rss_item": rss_item, "imageArray": imageArray, "rss_model": model, "model_index": index});
104// console.log("delegate BBBBB")104// console.log("delegate BBBBB")
105105
106 if (sprite == null) {106 if (sprite == null) {
@@ -111,12 +111,12 @@
111 return sprite111 return sprite
112}112}
113113
114function delegateTextA (rss_title, model, index)114function delegateTextA (rss_item, model, index)
115{115{
116 var component;116 var component;
117 var sprite;117 var sprite;
118 component = Qt.createComponent("./ArticleTextA.qml");118 component = Qt.createComponent("./ArticleTextA.qml");
119 sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "rss_model": model, "model_index": index});119 sprite = component.createObject(rss_item_delegate, {"rss_item": rss_item, "rss_model": model, "model_index": index});
120// console.log("delegate CCCCC")120// console.log("delegate CCCCC")
121121
122 if (sprite == null) {122 if (sprite == null) {
@@ -127,12 +127,12 @@
127 return sprite127 return sprite
128}128}
129129
130function delegateTextB (rss_title, model, index)130function delegateTextB (rss_item, model, index)
131{131{
132 var component;132 var component;
133 var sprite;133 var sprite;
134 component = Qt.createComponent("./ArticleTextB.qml");134 component = Qt.createComponent("./ArticleTextB.qml");
135 sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "rss_model": model, "model_index": index});135 sprite = component.createObject(rss_item_delegate, {"rss_item": rss_item, "rss_model": model, "model_index": index});
136// console.log("delegate CCCCC")136// console.log("delegate CCCCC")
137137
138 if (sprite == null) {138 if (sprite == null) {
@@ -143,12 +143,12 @@
143 return sprite143 return sprite
144}144}
145145
146function delegateFullImg (rss_title, imageArray, model, index)146function delegateFullImg (rss_item, imageArray, model, index)
147{147{
148 var component;148 var component;
149 var sprite;149 var sprite;
150 component = Qt.createComponent("./ArticleFullImg.qml");150 component = Qt.createComponent("./ArticleFullImg.qml");
151 sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray, "rss_model": model, "model_index": index});151 sprite = component.createObject(rss_item_delegate, {"rss_item": rss_item, "imageArray": imageArray, "rss_model": model, "model_index": index});
152// console.log("delegate DDDDD")152// console.log("delegate DDDDD")
153153
154 if (sprite == null) {154 if (sprite == null) {
@@ -159,12 +159,12 @@
159 return sprite159 return sprite
160}160}
161161
162function delegateTwoImgA (rss_title, imageArray, model, index)162function delegateTwoImgA (rss_item, imageArray, model, index)
163{163{
164 var component;164 var component;
165 var sprite;165 var sprite;
166 component = Qt.createComponent("./ArticleTwoImgA.qml");166 component = Qt.createComponent("./ArticleTwoImgA.qml");
167 sprite = component.createObject(rss_item_delegate, {"rss_title": rss_title, "imageArray": imageArray, "rss_model": model, "model_index": index});167 sprite = component.createObject(rss_item_delegate, {"rss_item": rss_item, "imageArray": imageArray, "rss_model": model, "model_index": index});
168168
169 if (sprite == null) {169 if (sprite == null) {
170 // Error Handling170 // Error Handling
171171
=== modified file 'dateutils.js'
--- dateutils.js 2013-07-21 12:49:09 +0000
+++ dateutils.js 2013-07-26 15:25:31 +0000
@@ -18,46 +18,82 @@
1818
19.pragma library19.pragma library
2020
21var SECONDS_LIMIT = 60 * 1000;21var SECONDS_LIMIT = 60 * 1000; // used as reference
22var MINUTES_LIMIT = 60 * SECONDS_LIMIT;22var MINUTES_LIMIT = 60 * SECONDS_LIMIT; // print minutes up to 1h
23var HOURS_LIMIT = 24 * MINUTES_LIMIT;23var HOURS_LIMIT = 12 * MINUTES_LIMIT; // print hours up to 12h
24var DAYS_LIMIT = 30 * HOURS_LIMIT;24var DAY_LIMIT = 24 * MINUTES_LIMIT; // print '<val> days ago' up to 30 days back
2525var DAYS_LIMIT = 30 * DAY_LIMIT; // print '<val> days ago' up to 30 days back
26// TODO: handle i18n
27var FORMAT_LIMITS = [
28 { "limit": SECONDS_LIMIT, "formats": ["%0 second ago", "%0 seconds ago"] },
29 { "limit": MINUTES_LIMIT, "formats": ["%0 minute ago", "%0 minutes ago"] },
30 { "limit": HOURS_LIMIT, "formats": ["%0 hour ago", "%0 hours ago"] },
31 { "limit": DAYS_LIMIT, "formats": ["%0 day ago", "%0 days ago"] },
32]
33
34// fallback if none of the above formats matched
35// TODO: handle i18n
36var DEFAULT_DATE_FORMAT = "MMM Do"
3726
38function parseDate(dateAsStr) {27function parseDate(dateAsStr) {
39 return Date.parse(dateAsStr);28 return new Date(dateAsStr);
40}29}
4130
42function formatPostTime(dateAsStr, i18n) {31function formatRelativeTime(i18n, dateAsStr) {
32 // fallback if none of the other formatters matched
33 function defaultFallbackFormat(then) {
34 return Qt.formatDateTime(then, i18n.tr("MMMM d"))
35 }
36
37 // Simple matches all diffs < limit, formats using the format function.
38 function SimpleFormatter(limit, format) {
39 this.matches = function (now, then, diff) { return diff < limit }
40 this.format = format
41 }
42
43 // Matches yesterday date
44 function YesterdayFormatter() {
45 this.matches = function (now, then, diff) {
46 return diff < DAY_LIMIT && now.getDate() !== then.getDate();
47 }
48 this.format = function (now, then, diff) {
49 return i18n.tr("Yesterday at %1").arg(
50 Qt.formatDateTime(then, i18n.tr("h:mm AP")))
51 }
52 }
53
54 // Matches up to 7 days ago (formats date as a weekday + time)
55 function WeekFormatter() {
56 this.matches = function (now, then, diff) {
57 return diff < 7 * DAY_LIMIT
58 }
59 this.format = function (now, then, diff) {
60 return Qt.formatDateTime(then, i18n.tr("ddd, h:mm AP"));
61 }
62 }
63
64 // An array of formatting object processed from 0 up to a matching object.
65 // If none of the object matches a default fallback formatter will be used.
66 var FORMATTERS = [
67 new SimpleFormatter(SECONDS_LIMIT, function (now, then, diff) { return i18n.tr("A few seconds ago...") }),
68 new SimpleFormatter(MINUTES_LIMIT, function (now, then, diff) {
69 var val = Math.floor(diff / SECONDS_LIMIT)
70 return i18n.tr("%1 minute ago", "%1 minutes ago", val).arg(val)
71 }),
72 new SimpleFormatter(HOURS_LIMIT, function (now, then, diff) {
73 var val = Math.floor(diff / MINUTES_LIMIT)
74 return i18n.tr("%1 hour ago", "%1 hours ago", val).arg(val)
75 }),
76 new YesterdayFormatter(),
77 new WeekFormatter(),
78 new SimpleFormatter(DAYS_LIMIT, function (now, then, diff) {
79 var val = Math.floor(diff / DAY_LIMIT)
80 return i18n.tr("%1 day ago", "%1 days ago", val).arg(val)
81 })
82 ]
83
84 function formatDiff(now, then, diff) {
85 for (var i=0; i<FORMATTERS.length; ++i) {
86 var formatter = FORMATTERS[i]
87 if (formatter.matches(now, then, diff)) {
88 return formatter.format(now, then, diff)
89 }
90 }
91 return defaultFallbackFormat(then)
92 }
93
43 var now = new Date();94 var now = new Date();
44 var then = parseDate(dateAsStr);95 var then = parseDate(dateAsStr);
45 var diff = now - then;96 var diff = now - then;
46 var formattedDiff = formatDiff(diff, then, i18n);97 var formattedDiff = formatDiff(now, then, diff);
47 console.log("DDD DIFF", diff, formattedDiff)
48 return formattedDiff;98 return formattedDiff;
49}99}
50
51function formatDiff(diff, then, i18n) {
52 for (var i=0; i<FORMAT_LIMITS.length; ++i) {
53 var limit = FORMAT_LIMITS[i].limit;
54 if (diff < limit) {
55 // use previous limit to calculate number of current units
56 // e.g. to calculate hours divide by MINUTES_LIMIT
57 // (because MINUTES_LIMIT is 1 hours) etc.
58 var val = Math.floor(diff / (i > 1 ? FORMAT_LIMITS[i-1].limit : SECONDS_LIMIT))
59 return i18n.tr(FORMAT_LIMITS[i].formats[0], FORMAT_LIMITS[i].formats[1], val).arg(val)
60 }
61 }
62 return then.toString(i18n.tr(DEFAULT_DATE_FORMAT))
63}

Subscribers

People subscribed via source and target branches