refactor MkTime component

Add the datetime property to the HTML5 time tag for a machine readable
timestamp.

Add the ability to display only the date or the time.

Change the computation of the relative time string to have precision
based on the format chosen based on the choice above. Also changed the
threshold for what is considered a date in the future so people do not
see "future" on notes they just created and thus try to stop them from
time traveling.
This commit is contained in:
Johann150 2022-08-14 14:14:29 +02:00
parent f0bdd9666f
commit 5548b585df
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1

View file

@ -1,5 +1,5 @@
<template> <template>
<time :title="absolute"> <time :title="absolute" :datetime="_time.toISOString()">
<template v-if="mode === 'relative'">{{ relative }}</template> <template v-if="mode === 'relative'">{{ relative }}</template>
<template v-else-if="mode === 'absolute'">{{ absolute }}</template> <template v-else-if="mode === 'absolute'">{{ absolute }}</template>
<template v-else-if="mode === 'detail'">{{ absolute }} ({{ relative }})</template> <template v-else-if="mode === 'detail'">{{ absolute }} ({{ relative }})</template>
@ -12,27 +12,52 @@ import { i18n } from '@/i18n';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
time: Date | string; time: Date | string;
format?: 'both' | 'date' | 'time';
mode?: 'relative' | 'absolute' | 'detail'; mode?: 'relative' | 'absolute' | 'detail';
}>(), { }>(), {
format: 'both',
mode: 'relative', mode: 'relative',
}); });
const _time = typeof props.time === 'string' ? new Date(props.time) : props.time; const _time = typeof props.time === 'string' ? new Date(props.time) : props.time;
const absolute = _time.toLocaleString(); const absolute = (): string => {
switch (props.format) {
case 'date': return _time.toLocaleDateString();
case 'time': return _time.toLocaleTimeString();
default: return _time.toLocaleString();
}
}();
let now = $ref(new Date()); let now = $ref(new Date());
const relative = $computed(() => { const relative = $computed(() => {
const ago = (now.getTime() - _time.getTime()) / 1000/*ms*/; const ago = (now.getTime() - _time.getTime()) / 1000/*ms*/;
return (
ago >= 31536000 ? i18n.t('_ago.yearsAgo', { n: Math.round(ago / 31536000).toString() }) : if (ago >= 31536000)
ago >= 2592000 ? i18n.t('_ago.monthsAgo', { n: Math.round(ago / 2592000).toString() }) : return i18n.t('_ago.yearsAgo', { n: Math.round(ago / 31536000).toString() });
ago >= 604800 ? i18n.t('_ago.weeksAgo', { n: Math.round(ago / 604800).toString() }) : if (ago >= 2592000)
ago >= 86400 ? i18n.t('_ago.daysAgo', { n: Math.round(ago / 86400).toString() }) : return i18n.t('_ago.monthsAgo', { n: Math.round(ago / 2592000).toString() });
ago >= 3600 ? i18n.t('_ago.hoursAgo', { n: Math.round(ago / 3600).toString() }) : if (ago >= 604800)
ago >= 60 ? i18n.t('_ago.minutesAgo', { n: (~~(ago / 60)).toString() }) : return i18n.t('_ago.weeksAgo', { n: Math.round(ago / 604800).toString() });
ago >= 10 ? i18n.t('_ago.secondsAgo', { n: (~~(ago % 60)).toString() }) : if (ago >= 86400)
ago >= -1 ? i18n.ts._ago.justNow : return i18n.t('_ago.daysAgo', { n: Math.round(ago / 86400).toString() });
i18n.ts._ago.future);
// if the format is 'date', the relative date precision is no more than days ago
if (props.format !== 'date' && ago >= 3600)
return i18n.t('_ago.hoursAgo', { n: Math.round(ago / 3600).toString() });
if (props.format !== 'date' && ago >= 60)
return i18n.t('_ago.minutesAgo', { n: (~~(ago / 60)).toString() });
if (props.format !== 'date' && ago >= 10)
return i18n.t('_ago.secondsAgo', { n: (~~(ago % 60)).toString() });
if (ago >= -5) {
if (props.format === 'date') {
// this is also the catch-all for the formats with hour/minute/second precision
return i18n.ts.today;
} else {
return i18n.ts._ago.justNow;
}
}
return i18n.ts._ago.future;
}); });
function tick() { function tick() {