Recognize time format preferences.
Bug: Issue 3779 Change-Id: I94d9e8f7a6e688d49be6c22c43b0240ca6768894
This commit is contained in:
parent
ae004a56bd
commit
290fcb6125
2
lib/BUCK
2
lib/BUCK
@ -15,6 +15,7 @@ define_license(name = 'h2')
|
||||
define_license(name = 'jgit')
|
||||
define_license(name = 'jsch')
|
||||
define_license(name = 'MPL1.1')
|
||||
define_license(name = 'moment')
|
||||
define_license(name = 'ow2')
|
||||
define_license(name = 'page.js')
|
||||
define_license(name = 'polymer')
|
||||
@ -258,4 +259,3 @@ maven_jar(
|
||||
sha1 = 'd9a09f7732226af26bf99f19e2cffe0ae219db5b',
|
||||
license = 'DO_NOT_DISTRIBUTE',
|
||||
)
|
||||
|
||||
|
22
lib/LICENSE-moment
Normal file
22
lib/LICENSE-moment
Normal file
@ -0,0 +1,22 @@
|
||||
Copyright (c) 2011-2016 Tim Wood, Iskren Chernev, Moment.js contributors
|
||||
|
||||
Permission is hereby granted, free of charge, to any person
|
||||
obtaining a copy of this software and associated documentation
|
||||
files (the "Software"), to deal in the Software without
|
||||
restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following
|
||||
conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
OTHER DEALINGS IN THE SOFTWARE.
|
@ -256,6 +256,14 @@ bower_component(
|
||||
sha1 = '5a68250d6d9abcd576f116dc4fc7312426323883',
|
||||
)
|
||||
|
||||
bower_component(
|
||||
name = 'moment',
|
||||
package = 'moment/moment',
|
||||
version = '2.12.0',
|
||||
license = 'moment',
|
||||
sha1 = '508d53de8f49ab87f03e209e5073e339107ed3e6',
|
||||
)
|
||||
|
||||
bower_component(
|
||||
name = 'neon-animation',
|
||||
package = 'polymerelements/neon-animation',
|
||||
|
@ -10,6 +10,7 @@ bower_components(
|
||||
'//lib/js:iron-input',
|
||||
'//lib/js:iron-overlay-behavior',
|
||||
'//lib/js:iron-selector',
|
||||
'//lib/js:moment',
|
||||
'//lib/js:page',
|
||||
'//lib/js:polymer',
|
||||
'//lib/js:promise-polyfill',
|
||||
|
@ -15,6 +15,9 @@ limitations under the License.
|
||||
-->
|
||||
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../gr-rest-api-interface/gr-rest-api-interface.html">
|
||||
|
||||
<script src="../../../bower_components/moment/moment.js"></script>
|
||||
|
||||
<dom-module id="gr-date-formatter">
|
||||
<template>
|
||||
@ -23,7 +26,8 @@ limitations under the License.
|
||||
display: inline;
|
||||
}
|
||||
</style>
|
||||
<span>[[_computeDateStr(dateStr)]]</span>
|
||||
<span>[[_computeDateStr(dateStr, timeFormat)]]</span>
|
||||
<gr-rest-api-interface id="restAPI"></gr-rest-api-interface>
|
||||
</template>
|
||||
<script src="gr-date-formatter.js"></script>
|
||||
</dom-module>
|
||||
|
@ -19,10 +19,12 @@
|
||||
DAY: 1000 * 60 * 60 * 24,
|
||||
};
|
||||
|
||||
var ShortMonthNames = [
|
||||
'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct',
|
||||
'Nov', 'Dec'
|
||||
];
|
||||
var TimeFormats = {
|
||||
TIME_12: 'h:mm A', // 2:14 PM
|
||||
TIME_24: 'H:mm', // 14:14
|
||||
MONTH_DAY: 'MMM DD', // Aug 29
|
||||
MONTH_DAY_YEAR: 'MMM DD, YYYY', // Aug 29, 1997
|
||||
};
|
||||
|
||||
Polymer({
|
||||
is: 'gr-date-formatter',
|
||||
@ -31,46 +33,58 @@
|
||||
dateStr: {
|
||||
type: String,
|
||||
value: null,
|
||||
notify: true
|
||||
}
|
||||
notify: true,
|
||||
},
|
||||
timeFormat: {
|
||||
type: String,
|
||||
value: 'HHMM_24',
|
||||
notify: true,
|
||||
},
|
||||
},
|
||||
|
||||
_computeDateStr: function(dateStr) {
|
||||
return this._dateStr(this._parseDateStr(dateStr), new Date());
|
||||
attached: function() {
|
||||
this._fetchPreferences();
|
||||
},
|
||||
|
||||
_parseDateStr: function(dateStr) {
|
||||
if (!dateStr) { return null; }
|
||||
return util.parseDate(dateStr);
|
||||
_fetchPreferences: function() {
|
||||
this.$.restAPI.getPreferences().then(function(preferences) {
|
||||
this.timeFormat = preferences && preferences.time_format;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
_dateStr: function(t, now) {
|
||||
if (!t) { return ''; }
|
||||
var diff = now.getTime() - t.getTime();
|
||||
if (diff < Duration.DAY && t.getDay() == now.getDay()) {
|
||||
// Within 24 hours and on the same day:
|
||||
// '2:14 AM'
|
||||
var pm = t.getHours() >= 12;
|
||||
var hours = t.getHours();
|
||||
if (hours == 0) {
|
||||
hours = 12;
|
||||
} else if (hours > 12) {
|
||||
hours = t.getHours() - 12;
|
||||
/**
|
||||
* Return true if date is within 24 hours and on the same day.
|
||||
*/
|
||||
_isWithinDay: function(now, date) {
|
||||
var diff = -date.diff(now);
|
||||
return diff < Duration.DAY && date.day() == now.getDay();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if date is from one to six months.
|
||||
*/
|
||||
_isWithinHalfYear: function(now, date) {
|
||||
var diff = -date.diff(now);
|
||||
return (date.day() != now.getDay() || diff >= Duration.DAY) &&
|
||||
diff < 180 * Duration.DAY;
|
||||
},
|
||||
|
||||
_computeDateStr: function(dateStr, timeFormat) {
|
||||
if (!dateStr) { return ''; }
|
||||
var date = moment(dateStr + 'Z');
|
||||
if (!date.isValid()) { return ''; }
|
||||
var now = new Date();
|
||||
var format = TimeFormats.MONTH_DAY_YEAR;
|
||||
if (this._isWithinDay(now, date)) {
|
||||
if (this.timeFormat == 'HHMM_12') {
|
||||
format = TimeFormats.TIME_12;
|
||||
} else {
|
||||
format = TimeFormats.TIME_24;
|
||||
}
|
||||
var minutes = t.getMinutes() < 10 ? '0' + t.getMinutes() :
|
||||
t.getMinutes();
|
||||
return hours + ':' + minutes + (pm ? ' PM' : ' AM');
|
||||
} else if ((t.getDay() != now.getDay() || diff >= Duration.DAY) &&
|
||||
diff < 180 * Duration.DAY) {
|
||||
// From one to six months:
|
||||
// 'Aug 29'
|
||||
return ShortMonthNames[t.getMonth()] + ' ' + t.getDate();
|
||||
} else if (diff >= 180 * Duration.DAY) {
|
||||
// More than six months:
|
||||
// 'Aug 29, 1997'
|
||||
return ShortMonthNames[t.getMonth()] + ' ' + t.getDate() + ', ' +
|
||||
t.getFullYear();
|
||||
} else if (this._isWithinHalfYear(now, date)) {
|
||||
format = TimeFormats.MONTH_DAY;
|
||||
}
|
||||
return date.format(format);
|
||||
},
|
||||
});
|
||||
})();
|
||||
|
@ -34,51 +34,107 @@ limitations under the License.
|
||||
suite('gr-date-formatter tests', function() {
|
||||
var element;
|
||||
|
||||
setup(function() {
|
||||
element = fixture('basic');
|
||||
});
|
||||
|
||||
test('date is parsed correctly', function() {
|
||||
assert.notOk((new Date('foo')).valueOf());
|
||||
var d = element._parseDateStr(element.getAttribute('date-str'));
|
||||
assert.isAbove(d.valueOf(), 0);
|
||||
});
|
||||
|
||||
/**
|
||||
* Parse server-formatter date and normalize into current timezone.
|
||||
*/
|
||||
function normalizedDate(dateStr) {
|
||||
var d = new Date(dateStr);
|
||||
var d = new Date(util.parseDate(dateStr));
|
||||
d.setMinutes(d.getMinutes() + d.getTimezoneOffset());
|
||||
return d;
|
||||
}
|
||||
|
||||
function testDates(nowStr, dateStr, expected) {
|
||||
var now = normalizedDate(nowStr);
|
||||
var t = normalizedDate(dateStr);
|
||||
assert.equal(element._dateStr(t, now), expected);
|
||||
// Normalize and convert the date to mimic server response.
|
||||
dateStr = normalizedDate(dateStr)
|
||||
.toJSON().replace('T', ' ').slice(0, -1);
|
||||
var clock = sinon.useFakeTimers(
|
||||
new Date(normalizedDate(nowStr)).getTime());
|
||||
element.dateStr = dateStr;
|
||||
assert.equal(element.$$('span').textContent, expected);
|
||||
clock.restore();
|
||||
}
|
||||
|
||||
test('dates strings are correct', function() {
|
||||
// Within 24 hours on same day.
|
||||
testDates('2015-07-29T20:34:00.000Z',
|
||||
'2015-07-29T15:34:00.000Z',
|
||||
'3:34 PM');
|
||||
testDates('2016-01-27T17:41:00.000Z',
|
||||
'2016-01-27T12:41:00.000Z',
|
||||
'12:41 PM');
|
||||
function stubPreferences(preferences) {
|
||||
var preferencesPromise = Promise.resolve(preferences);
|
||||
stub('gr-rest-api-interface', {
|
||||
getPreferences: sinon.stub().returns(preferencesPromise),
|
||||
});
|
||||
return preferencesPromise;
|
||||
}
|
||||
|
||||
// Within 24 hours on different days.
|
||||
testDates('2015-07-29T03:34:00.000Z',
|
||||
'2015-07-28T20:25:00.000Z',
|
||||
'Jul 28');
|
||||
suite('not signed in', function() {
|
||||
setup(function() {
|
||||
return stubPreferences(null).then(function() {
|
||||
element = fixture('basic');
|
||||
});
|
||||
});
|
||||
|
||||
// More than 24 hours. Less than six months.
|
||||
testDates('2015-07-29T20:34:00.000Z',
|
||||
'2015-06-15T03:25:00.000Z',
|
||||
'Jun 15');
|
||||
test('invalid dates are quietly rejected', function() {
|
||||
assert.notOk((new Date('foo')).valueOf());
|
||||
element.dateStr = 'foo';
|
||||
assert.equal(element.$$('span').textContent, '');
|
||||
});
|
||||
|
||||
// More than six months.
|
||||
testDates('2015-09-15T20:34:00.000Z',
|
||||
'2015-01-15T03:25:00.000Z',
|
||||
'Jan 15, 2015');
|
||||
test('Within 24 hours on same day', function() {
|
||||
testDates('2015-07-29 20:34:14.985000000',
|
||||
'2015-07-29 15:34:14.985000000',
|
||||
'15:34');
|
||||
testDates('2016-01-27 17:41:14.985000000',
|
||||
'2016-01-27 12:41:14.985000000',
|
||||
'12:41');
|
||||
});
|
||||
|
||||
test('Within 24 hours on different days', function() {
|
||||
testDates('2015-07-29 03:34:14.985000000',
|
||||
'2015-07-28 20:25:14.985000000',
|
||||
'Jul 28');
|
||||
});
|
||||
|
||||
test('More than 24 hours but less than six months', function() {
|
||||
testDates('2015-07-29 20:34:14.985000000',
|
||||
'2015-06-15 03:25:14.985000000',
|
||||
'Jun 15');
|
||||
});
|
||||
|
||||
test('More than six months', function() {
|
||||
testDates('2015-09-15 20:34:00.000000000',
|
||||
'2015-01-15 03:25:00.000000000',
|
||||
'Jan 15, 2015');
|
||||
});
|
||||
});
|
||||
|
||||
suite('signed in with 12 hours time format preference', function() {
|
||||
setup(function() {
|
||||
return stubPreferences({time_format: 'HHMM_12'}).then(function() {
|
||||
element = fixture('basic');
|
||||
});
|
||||
});
|
||||
|
||||
test('Within 24 hours on same day', function() {
|
||||
testDates('2015-07-29 20:34:14.985000000',
|
||||
'2015-07-29 15:34:14.985000000',
|
||||
'3:34 PM');
|
||||
testDates('2016-01-27 17:41:14.985000000',
|
||||
'2016-01-27 12:41:14.985000000',
|
||||
'12:41 PM');
|
||||
});
|
||||
});
|
||||
|
||||
suite('signed in with 24 hours time format preference', function() {
|
||||
setup(function() {
|
||||
return stubPreferences({time_format: 'HHMM_24'}).then(function() {
|
||||
element = fixture('basic');
|
||||
});
|
||||
});
|
||||
|
||||
test('Within 24 hours on same day', function() {
|
||||
testDates('2015-07-29 20:34:14.985000000',
|
||||
'2015-07-29 15:34:14.985000000',
|
||||
'15:34');
|
||||
testDates('2016-01-27 17:41:14.985000000',
|
||||
'2016-01-27 12:41:14.985000000',
|
||||
'12:41');
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
Loading…
Reference in New Issue
Block a user