mirror of
https://github.com/chylex/Nextcloud-News.git
synced 2025-04-25 20:15:47 +02:00
Reimplement relative time formatting as a filter, dropping dependency on deprecated moment.js
Signed-off-by: Alec Kojaev <alec@kojaev.name>
This commit is contained in:
parent
691c42bdbc
commit
65c15dac38
CHANGELOG.md
js
templates
@ -7,6 +7,8 @@ The format is almost based on [Keep a Changelog](https://keepachangelog.com/en/1
|
||||
## [16.x.x]
|
||||
### Changed
|
||||
- Added vue and ng-vue packages
|
||||
- Reimplemented relative time formatting as a filter
|
||||
|
||||
### Fixed
|
||||
|
||||
## [15.x.x]
|
||||
|
@ -25,7 +25,6 @@
|
||||
"jquery": true,
|
||||
"globals": {
|
||||
"angular": true,
|
||||
"moment": true,
|
||||
"app": true,
|
||||
"OC": true,
|
||||
"csrfToken": true,
|
||||
|
@ -198,15 +198,6 @@ app.controller('ContentController', function (Publisher, FeedResource, ItemResou
|
||||
});
|
||||
};
|
||||
|
||||
this.getRelativeDate = function (timestamp) {
|
||||
if (timestamp !== undefined && timestamp !== '') {
|
||||
var languageCode = SettingsResource.get('language');
|
||||
return moment.unix(timestamp).locale(languageCode).fromNow() + '';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
};
|
||||
|
||||
this.refresh = function () {
|
||||
$route.reload();
|
||||
};
|
||||
|
58
js/filter/RelativeTimestamp.js
Normal file
58
js/filter/RelativeTimestamp.js
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* Nextcloud - News
|
||||
*
|
||||
* This file is licensed under the Affero General Public License version 3 or
|
||||
* later. See the COPYING file.
|
||||
*
|
||||
* @author Alec Kojaev <alec@kojaev.name>
|
||||
* @copyright Alec Kojaev 2021
|
||||
*/
|
||||
app.filter('relativeTimestamp', ['SettingsResource', function (SettingsResource) {
|
||||
'use strict';
|
||||
|
||||
const languageCode = SettingsResource.get('language');
|
||||
const relFormat = Intl.RelativeTimeFormat ?
|
||||
new Intl.RelativeTimeFormat(languageCode, { numeric: 'auto' }) : null;
|
||||
const maxRelDistance = 90*86400*1000;
|
||||
const relLimits = [
|
||||
[ 7*86400*1000, 'week' ],
|
||||
[ 86400*1000, 'day' ],
|
||||
[ 3600*1000, 'hour' ],
|
||||
[ 60*1000, 'minute' ],
|
||||
[ 1*1000, 'second' ]
|
||||
];
|
||||
const absLimits = [
|
||||
[ 7*86400*1000, { hour: '2-digit', minute: '2-digit', dayPeriod: 'narrow',
|
||||
year: 'numeric', month: 'short', day: 'numeric' } ],
|
||||
[ 43200*1000, { hour: '2-digit', minute: '2-digit', dayPeriod: 'narrow',
|
||||
weekday: 'long' } ],
|
||||
[ 0, { hour: '2-digit', minute: '2-digit', dayPeriod: 'narrow' } ]
|
||||
];
|
||||
|
||||
return function (timestamp) {
|
||||
if (!Number.isFinite(timestamp)) {
|
||||
return timestamp;
|
||||
}
|
||||
const ts = new Date(timestamp);
|
||||
const dist = ts.getTime() - Date.now();
|
||||
const absDist = Math.abs(dist);
|
||||
if (relFormat && absDist < maxRelDistance) {
|
||||
for (const [ scale, unit ] of relLimits) {
|
||||
const value = Math.trunc(dist / scale);
|
||||
if (value !== 0) {
|
||||
return relFormat.format(value, unit);
|
||||
}
|
||||
}
|
||||
// We arrive here only if distance from now is less than 1 second
|
||||
return relFormat.format(0, 'second');
|
||||
} else {
|
||||
for (const [ limit, options ] of absLimits) {
|
||||
if (absDist >= limit) {
|
||||
return ts.toLocaleString(languageCode, options);
|
||||
}
|
||||
}
|
||||
// We shouldn't be here
|
||||
return ts.toLocaleString(languageCode, absLimits[absLimits.length - 1][1]);
|
||||
}
|
||||
};
|
||||
}]);
|
@ -30,7 +30,6 @@ const sources = [
|
||||
'node_modules/angular-animate/angular-animate.min.js',
|
||||
'node_modules/angular-route/angular-route.min.js',
|
||||
'node_modules/angular-sanitize/angular-sanitize.min.js',
|
||||
'node_modules/moment/min/moment-with-locales.min.js',
|
||||
'node_modules/masonry-layout/dist/masonry.pkgd.min.js',
|
||||
'node_modules/vue/dist/vue.js',
|
||||
'node_modules/ngVue/build/index.js',
|
||||
|
@ -17,7 +17,6 @@ module.exports = function (config) {
|
||||
// list of files / patterns to load in the browser
|
||||
files: [
|
||||
'node_modules/jquery/dist/jquery.js',
|
||||
'node_modules/moment/min/moment-with-locales.js',
|
||||
'node_modules/angular/angular.js',
|
||||
'node_modules/angular-mocks/angular-mocks.js',
|
||||
'node_modules/angular-route/angular-route.js',
|
||||
|
5
js/package-lock.json
generated
5
js/package-lock.json
generated
@ -5601,11 +5601,6 @@
|
||||
"minimist": "1.2.5"
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.29.1",
|
||||
"resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz",
|
||||
"integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ=="
|
||||
},
|
||||
"move-concurrently": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz",
|
||||
|
@ -63,7 +63,6 @@
|
||||
"angular-sanitize": "^1.8.2",
|
||||
"debug": "^4.3.2",
|
||||
"masonry-layout": "^4.2.2",
|
||||
"moment": "^2.29.1",
|
||||
"ngVue": "^1.7.8",
|
||||
"vue": "^2.6.14"
|
||||
}
|
||||
|
@ -513,27 +513,6 @@ describe('ContentController', function () {
|
||||
expect(ctrl.autoPagingEnabled()).toBe(true);
|
||||
}));
|
||||
|
||||
|
||||
it('should return relative date', inject(function ($controller,
|
||||
SettingsResource) {
|
||||
|
||||
SettingsResource.receive({language: 'en'});
|
||||
var ctrl = $controller('ContentController', {
|
||||
data: {},
|
||||
});
|
||||
|
||||
expect(ctrl.getRelativeDate(12)).not.toBe('');
|
||||
}));
|
||||
|
||||
|
||||
it('should return relative date empty', inject(function ($controller) {
|
||||
var ctrl = $controller('ContentController', {
|
||||
data: {}
|
||||
});
|
||||
|
||||
expect(ctrl.getRelativeDate('')).toBe('');
|
||||
}));
|
||||
|
||||
it('should refresh the page', inject(function ($controller) {
|
||||
var route = {
|
||||
current: {
|
||||
|
@ -50,7 +50,7 @@
|
||||
date:'yyyy-MM-dd HH:mm:ss' }}"
|
||||
datetime="{{ item.pubDate*1000 |
|
||||
date:'yyyy-MM-ddTHH:mm:ssZ' }}">
|
||||
{{ Content.getRelativeDate(item.pubDate) }}
|
||||
{{ item.pubDate*1000 | relativeTimestamp }}
|
||||
</time>
|
||||
</li>
|
||||
<li ng-click="Content.toggleStar(item.id)"
|
||||
@ -176,7 +176,7 @@
|
||||
date:'yyyy-MM-dd HH:mm:ss' }}"
|
||||
datetime="{{ item.pubDate*1000 |
|
||||
date:'yyyy-MM-ddTHH:mm:ssZ' }}">
|
||||
{{ Content.getRelativeDate(item.pubDate) }}
|
||||
{{ item.pubDate*1000 | relativeTimestamp }}
|
||||
</time>
|
||||
<h1 ng-attr-dir="{{item.rtl && 'rtl'}}">
|
||||
<a class="external"
|
||||
|
Loading…
Reference in New Issue
Block a user