diff --git a/src/components/Timeline.vue b/src/components/Timeline.vue
index e892672..c816fb2 100644
--- a/src/components/Timeline.vue
+++ b/src/components/Timeline.vue
@@ -21,7 +21,7 @@
- Created {{ proj.name }} {{ proj.started_at | date_diff }} ago
+ Created {{ proj.name }} {{ elapsed(proj.started_at) }}
@@ -61,7 +61,7 @@
- Project stopped in {{ proj.stopped_at | short_date }} {{ proj.stopped_at | date_diff }} ago
+ Project stopped in {{ proj.stopped_at | short_date }} {{ elapsed(proj.stopped_at) }}
Project still active
@@ -84,23 +84,44 @@ import { tID } from '../model/skills';
import * as projects from '../service/projects';
import * as scroller from '../service/scroller';
-function pluralize(n: number, s: string): string {
- n = Math.floor(Math.abs(n));
- const plural = (n > 1);
+interface TimeDiff {
+ diff: number;
+ one: string; // singular translation label
+ plural: string; // plural translation label
+}
- switch (s) {
- case 'second':
- return plural ? `${n} seconds` : `1 second`;
- case 'minute':
- return plural ? `${n} minutes` : `1 minute`;
- case 'day':
- return plural ? `${n} days` : `1 day`;
- case 'month':
- return plural ? `${n} months` : `1 month`;
- case 'year':
- return plural ? `${n} years` : `1 year`;
+// returns a TimeDiff from a date. Holds the time elapsed until now in the most
+// broad unit that is greater than 0.
+function getTimeDiff(date: Date): TimeDiff {
+ const minute = 60 * 1000;
+ const hour = 60 * minute;
+ const day = 24 * hour;
+ const month = 30 * day;
+ const year = 365 * day;
+
+ const now = new Date();
+ const diff = now.getTime() - date.getTime();
+
+ if ( diff < 0 ) {
+ return {diff: 0, one: 'time.some', plural: 'time.some'};
}
- return '';
+
+ if ( diff < minute ) {
+ return {diff: diff, one: 'time.second', plural: 'time.seconds'};
+ }
+ if ( diff < hour ) {
+ return {diff: diff / minute, one: 'time.minute', plural: 'time.minutes'};
+ }
+ if ( diff < day ) {
+ return {diff: diff / hour, one: 'time.hour', plural: 'time.hours'};
+ }
+ if ( diff < month ) {
+ return {diff: diff / day, one: 'time.day', plural: 'time.days'};
+ }
+ if ( diff < year ) {
+ return {diff: diff / month, one: 'time.month', plural: 'time.months'};
+ }
+ return {diff: diff / year, one: 'time.year', plural: 'time.years'};
}
@Component({
@@ -109,38 +130,7 @@ function pluralize(n: number, s: string): string {
},
filters: {
short_date(date: Date): string {
- return date.toLocaleDateString('en-US', { month: 'short', year: 'numeric' });
- },
- date_diff(date: Date): string {
- const minute = 60 * 1000;
- const hour = 60 * minute;
- const day = 24 * hour;
- const month = 30 * day;
- const year = 365 * day;
-
- const now = new Date();
- const diff = now.getTime() - date.getTime();
-
- if ( diff < 0 ) {
- return 'sometime';
- }
-
- if ( diff < minute ) {
- return pluralize(diff, 'second');
- }
- if ( diff < hour ) {
- return pluralize(diff / minute, 'minute');
- }
- if ( diff < day ) {
- return pluralize(diff / hour, 'hour');
- }
- if ( diff < month ) {
- return pluralize(diff / day, 'day');
- }
- if ( diff < year ) {
- return pluralize(diff / month, 'month');
- }
- return pluralize(diff / year, 'year');
+ return date.toLocaleDateString(navigator.language, { month: 'short', year: 'numeric' });
},
},
})
@@ -161,6 +151,23 @@ export default class Timeline extends Vue {
document.body.addEventListener('scroll', this.onScroll, { passive: true });
}
+ protected elapsed(date: Date): string {
+ const fmt = 'time.diff-format';
+ const td = getTimeDiff(date);
+
+ const diff = Math.floor(td.diff);
+
+ if( diff == 0 ){
+ return this.$t(fmt, { elapsed: this.$t(td.one) }).toString();
+ }
+
+ if( diff > 1 ){ // plural
+ return this.$t(fmt, { elapsed: this.$t(td.plural, { n: diff }) }).toString();
+ }
+ // singular
+ return this.$t(fmt, { elapsed: this.$t(td.one, { n: diff }) }).toString();
+ }
+
private onScroll(e: Event) {
const target = e.target as HTMLElement;
const header = this.$refs.header as HTMLElement;
diff --git a/src/locales/en.json b/src/locales/en.json
index ffa35c4..262871f 100644
--- a/src/locales/en.json
+++ b/src/locales/en.json
@@ -72,5 +72,15 @@
"skill.inkscape": "Inkscape",
"skill.rnd": "R&D",
+ "time.diff-format": "{elapsed} ago",
+
+ "time.some": "sometime",
+ "time.second": "{n} second", "time.seconds": "{n} seconds",
+ "time.minute": "{n} minute", "time.minutes": "{n} minutes",
+ "time.hour": "{n} hour", "time.hours": "{n} hours",
+ "time.day": "{n} day", "time.days": "{n} days",
+ "time.month": "{n} month", "time.months": "{n} months",
+ "time.year": "{n} year", "time.years": "{n} years",
+
"end": ""
}
\ No newline at end of file
diff --git a/src/locales/fr.json b/src/locales/fr.json
index 935a3fd..d9107cb 100644
--- a/src/locales/fr.json
+++ b/src/locales/fr.json
@@ -33,5 +33,16 @@
"skill.opti": "Optimization",
"skill.concurrency": "Programmation Concurrente",
+
+ "time.diff-format": "il y a {elapsed}",
+
+ "time.some": "un moment",
+ "time.second": "{n} seconde", "time.seconds": "{n} secondes",
+ "time.minute": "{n} minute", "time.minutes": "{n} minutes",
+ "time.hour": "{n} heure", "time.hours": "{n} heures",
+ "time.day": "{n} jour", "time.days": "{n} jours",
+ "time.month": "{n} mois", "time.months": "{n} mois",
+ "time.year": "{n} an", "time.years": "{n} ans",
+
"end": ""
}
\ No newline at end of file