104 lines
2.3 KiB
JavaScript
104 lines
2.3 KiB
JavaScript
import Component from '@glimmer/component';
|
|
import { inject as service } from '@ember/service';
|
|
|
|
const MILLISECOND = 1;
|
|
const SECOND = MILLISECOND * 1000;
|
|
const MINUTE = SECOND * 60;
|
|
const HOUR = MINUTE * 60;
|
|
const DAY = HOUR * 24;
|
|
const MONTH = DAY * 31;
|
|
const YEAR = MONTH * 12;
|
|
|
|
// common time intervals in milliseconds
|
|
const unitMappings = [
|
|
{
|
|
unit: 'second',
|
|
value: SECOND,
|
|
},
|
|
{
|
|
unit: 'minute',
|
|
value: MINUTE,
|
|
},
|
|
{
|
|
unit: 'hour',
|
|
value: HOUR,
|
|
},
|
|
{
|
|
unit: 'day',
|
|
value: DAY,
|
|
},
|
|
{
|
|
unit: 'month',
|
|
value: MONTH,
|
|
},
|
|
{
|
|
unit: 'year',
|
|
value: YEAR,
|
|
},
|
|
];
|
|
|
|
export default class RelativeDatetimeLiveComponent extends Component {
|
|
// =services
|
|
|
|
@service clockTick;
|
|
@service intl;
|
|
|
|
// =properties
|
|
|
|
/**
|
|
* The difference in milliseconds between the date argument and the
|
|
* current time.
|
|
* @type {number}
|
|
*/
|
|
get delta() {
|
|
return this.args.date.valueOf() - this.clockTick.now;
|
|
}
|
|
|
|
/**
|
|
* The greatest meaningful unit is the unit which delta is equal to or
|
|
* greater than. For example, the unit of a delta equivalent of 59 seconds is
|
|
* 'second' while 60 seconds is 'minute', 36 hours is 'day', etc.
|
|
* @type {object}
|
|
*/
|
|
get greatestMeaningfulUnit() {
|
|
return unitMappings.reduce((currentValue, previousValue) => {
|
|
return Math.abs(this.delta) >= previousValue.value
|
|
? previousValue
|
|
: currentValue;
|
|
}, unitMappings[0]);
|
|
}
|
|
|
|
/**
|
|
* The delta value scaled to the greatest meaningful unit. For example, if
|
|
* the delta is 1000 ms, the scaled value is 1, which corresponds to
|
|
* a GMU of 'second'. A delta of 60000 ms is also 1, corresponding to a GMU
|
|
* of 'minute'.
|
|
* @type {number}
|
|
*/
|
|
get scaledDelta() {
|
|
if (this.delta < 0) {
|
|
return Math.ceil(this.delta / this.greatestMeaningfulUnit.value);
|
|
}
|
|
return Math.floor(this.delta / this.greatestMeaningfulUnit.value);
|
|
}
|
|
|
|
/**
|
|
* A string representation of the greatest meaningful unit.
|
|
* @type {string}
|
|
*/
|
|
get unit() {
|
|
return this.greatestMeaningfulUnit.unit;
|
|
}
|
|
|
|
/**
|
|
* A localizd relative datetime. E.g. "30 seconds ago".
|
|
* @type {string}
|
|
*/
|
|
get formatted() {
|
|
return this.intl.formatRelative(this.scaledDelta, {
|
|
unit: this.unit,
|
|
numeric: 'auto',
|
|
});
|
|
}
|
|
}
|