mirror of
https://github.com/HangarMC/Hangar.git
synced 2025-03-07 15:31:00 +08:00
feat: add PrettyTime component to fix hydration issues
This commit is contained in:
parent
77b2ce3561
commit
a467a03d7b
54
frontend/src/lib/components/design/PrettyTime.vue
Normal file
54
frontend/src/lib/components/design/PrettyTime.vue
Normal file
@ -0,0 +1,54 @@
|
||||
<script lang="ts" setup>
|
||||
import { computed } from "vue";
|
||||
import { useI18n } from "vue-i18n";
|
||||
import { DateTimeFormatOptions } from "@intlify/core-base";
|
||||
|
||||
const i18n = useI18n();
|
||||
|
||||
const props = defineProps<{
|
||||
time: string | number | Date;
|
||||
long?: boolean;
|
||||
shortRelative?: boolean;
|
||||
}>();
|
||||
|
||||
const date = computed(() => (typeof props.time !== "object" ? new Date(props.time) : props.time));
|
||||
|
||||
const options = computed<DateTimeFormatOptions & { prefix?: string }>(() => {
|
||||
if (props.shortRelative) {
|
||||
const today: Date = new Date();
|
||||
const todayTime = today.getTime();
|
||||
const dateTime = date.value.getTime();
|
||||
const todayDays = Math.floor(todayTime / (1000 * 60 * 60 * 24));
|
||||
const dateDays = Math.floor(dateTime / (1000 * 60 * 60 * 24));
|
||||
// eslint-disable-next-line unicorn/prefer-switch
|
||||
if (todayDays === dateDays) {
|
||||
return { prefix: i18n.t("general.today"), hour: "numeric", minute: "numeric" };
|
||||
} else if (todayDays === dateDays + 1) {
|
||||
return { prefix: i18n.t("general.yesterday"), hour: "numeric", minute: "numeric" };
|
||||
} else if (todayDays === dateDays - 1) {
|
||||
return { prefix: i18n.t("general.tomorrow"), hour: "numeric", minute: "numeric" };
|
||||
} else if (todayDays - dateDays < 7) {
|
||||
return { weekday: "short", hour: "numeric", minute: "numeric" };
|
||||
} else {
|
||||
return { day: "numeric", month: "long", year: "numeric" };
|
||||
}
|
||||
} else if (props.long) {
|
||||
return { day: "numeric", month: "long", year: "numeric", hour: "numeric", minute: "numeric" };
|
||||
} else {
|
||||
return { day: "numeric", month: "long", year: "numeric" };
|
||||
}
|
||||
});
|
||||
|
||||
const formattedDate = computed(() => {
|
||||
const formatter = new Intl.DateTimeFormat(i18n.locale.value, options.value);
|
||||
let formatted = formatter.format(date.value);
|
||||
formatted = formatted.replace(/ at/, ","); // ???
|
||||
const prefix = options.value.prefix ? options.value.prefix + " " : "";
|
||||
return prefix + formatted;
|
||||
});
|
||||
const isoDate = computed(() => date.value.toISOString());
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<time :datetime="isoDate">{{ formattedDate }}</time>
|
||||
</template>
|
@ -1,27 +1,3 @@
|
||||
export function prettyDate(date: Date | string | number): string {
|
||||
if (typeof date === "string" || typeof date === "number") {
|
||||
date = new Date(date);
|
||||
}
|
||||
return date.toLocaleDateString(undefined, {
|
||||
day: "numeric",
|
||||
month: "long",
|
||||
year: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
export function prettyDateTime(date: Date | string | number): string {
|
||||
if (typeof date === "string" || typeof date === "number") {
|
||||
date = new Date(date);
|
||||
}
|
||||
return date.toLocaleDateString(undefined, {
|
||||
day: "numeric",
|
||||
month: "2-digit",
|
||||
year: "numeric",
|
||||
hour: "numeric",
|
||||
minute: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Requires yyyy-MM-DD format
|
||||
* @param dateString
|
||||
|
Loading…
Reference in New Issue
Block a user