perf: use setInterval instead of setTimeout chain in MkTime

This commit is contained in:
tamania 2023-06-23 18:33:37 -07:00 committed by ThatOneCalculator
parent dab063cb25
commit b685fa9092
2 changed files with 60 additions and 21 deletions

View File

@ -1,21 +1,23 @@
<template>
<time :title="absolute">
<template v-if="mode === 'relative'">{{ relative }}</template>
<template v-if="invalid">{{ i18n.ts._ago.invalid }}</template>
<template v-else-if="mode === 'relative'">{{ relative }}</template>
<template v-else-if="mode === 'absolute'">{{ absolute }}</template>
<template v-else-if="mode === 'detail'"
>{{ absolute }} ({{ relative }})</template
>
<slot></slot>
</time>
</template>
<script lang="ts" setup>
import { onUnmounted } from "vue";
import { onMounted, onUnmounted } from "vue";
import { i18n } from "@/i18n";
import { dateTimeFormat } from "@/scripts/intl-const";
const props = withDefaults(
defineProps<{
time: Date | string;
time: Date | string | number | null;
origin?: Date | null;
mode?: "relative" | "absolute" | "detail";
}>(),
{
@ -24,12 +26,23 @@ const props = withDefaults(
);
const _time =
typeof props.time === "string" ? new Date(props.time) : props.time;
const absolute = _time.toLocaleString();
props.time == null
? NaN
: typeof props.time === "number"
? props.time
: (props.time instanceof Date
? props.time
: new Date(props.time)
).getTime();
const invalid = Number.isNaN(_time);
const absolute = !invalid ? dateTimeFormat.format(_time) : i18n.ts._ago.invalid;
let now = $shallowRef(new Date());
const relative = $computed(() => {
const ago = (now.getTime() - _time.getTime()) / 1000; /*ms*/
let now = $ref((props.origin ?? new Date()).getTime());
const relative = $computed<string>(() => {
if (props.mode === "absolute") return ""; // absoluterelative使
if (invalid) return i18n.ts._ago.invalid;
const ago = (now - _time) / 1000; /*ms*/
return ago >= 31536000
? i18n.t("_ago.yearsAgo", { n: Math.round(ago / 31536000).toString() })
: ago >= 2592000
@ -49,22 +62,36 @@ const relative = $computed(() => {
: i18n.ts._ago.future;
});
function tick() {
// TODO:
now = new Date();
tickId = window.setTimeout(() => {
window.requestAnimationFrame(tick);
}, 10000);
}
let tickId: number;
if (props.mode === "relative" || props.mode === "detail") {
tickId = window.requestAnimationFrame(tick);
function tick() {
const _now = new Date().getTime();
const agoPrev = (now - _time) / 1000; /*ms*/ // interval
now = _now;
const ago = (now - _time) / 1000; /*ms*/ // interval
const prev = agoPrev < 60 ? 10000 : agoPrev < 3600 ? 60000 : 180000;
const next = ago < 60 ? 10000 : ago < 3600 ? 60000 : 180000;
if (!tickId) {
tickId = window.setInterval(tick, next);
} else if (prev < next) {
window.clearInterval(tickId);
tickId = window.setInterval(tick, next);
}
}
if (
!invalid &&
props.origin === null &&
(props.mode === "relative" || props.mode === "detail")
) {
onMounted(() => {
tick();
});
onUnmounted(() => {
window.cancelAnimationFrame(tickId);
if (tickId) window.clearInterval(tickId);
});
}
</script>

View File

@ -0,0 +1,12 @@
import { lang } from "@/config";
export const versatileLang = (lang ?? "ja-JP").replace("ja-KS", "ja-JP");
export const dateTimeFormat = new Intl.DateTimeFormat(versatileLang, {
year: "numeric",
month: "numeric",
day: "numeric",
hour: "numeric",
minute: "numeric",
second: "numeric",
});
export const numberFormat = new Intl.NumberFormat(versatileLang);