import type { MaybeRef } from '@vueuse/shared' import type { MaybeComputedRef, UseTimeAgoOptions } from '@vueuse/core' const formatter = Intl.NumberFormat() const humanReadableNumber = ( num: number, { k, m }: { k: string; m: string } = { k: 'K', m: 'M' }, useFormatter: Intl.NumberFormat = formatter, ) => { if (num < 10000) return useFormatter.format(num) // show 1 decimal: we cannot use toFixed(1), it is a string if (num < 1000000) return `${useFormatter.format(Math.floor(num / 100) / 10)}${k}` // show 2 decimals: we cannot use toFixed(2), it is a string return `${useFormatter.format(Math.floor(num / 10000) / 100)}${m}` } export const formattedNumber = (num: number, useFormatter: Intl.NumberFormat = formatter) => { return useFormatter.format(num) } export const useHumanReadableNumber = () => { const i18n = useI18n() const numberFormatter = $computed(() => Intl.NumberFormat(i18n.locale.value)) return { formatHumanReadableNumber: (num: MaybeRef) => { return humanReadableNumber( unref(num), { k: i18n.t('common.kiloSuffix'), m: i18n.t('common.megaSuffix') }, numberFormatter, ) }, formatNumber: (num: MaybeRef) => { return formattedNumber( unref(num), numberFormatter, ) }, forSR: (num: MaybeRef) => { return unref(num) > 10000 }, } } export const useFormattedDateTime = ( value: MaybeComputedRef, options: Intl.DateTimeFormatOptions = { dateStyle: 'long', timeStyle: 'medium' }, ) => { const { locale } = useI18n() const formatter = $computed(() => Intl.DateTimeFormat(locale.value, options)) return computed(() => { const v = resolveUnref(value) return v ? formatter.format(new Date(v)) : '' }) } export const useTimeAgoOptions = (short = false): UseTimeAgoOptions => { const { d, t } = useI18n() const prefix = short ? 'short_' : '' return { rounding: 'floor', showSecond: !short, updateInterval: short ? 60_000 : 1_000, messages: { justNow: t('time_ago_options.just_now'), // just return the value past: n => n, // just return the value future: n => n, second: (n, p) => t(`time_ago_options.${prefix}second_${p ? 'past' : 'future'}`, n), minute: (n, p) => t(`time_ago_options.${prefix}minute_${p ? 'past' : 'future'}`, n), hour: (n, p) => t(`time_ago_options.${prefix}hour_${p ? 'past' : 'future'}`, n), day: (n, p) => t(`time_ago_options.${prefix}day_${p ? 'past' : 'future'}`, n), week: (n, p) => t(`time_ago_options.${prefix}week_${p ? 'past' : 'future'}`, n), month: (n, p) => t(`time_ago_options.${prefix}month_${p ? 'past' : 'future'}`, n), year: (n, p) => t(`time_ago_options.${prefix}year_${p ? 'past' : 'future'}`, n), invalid: '', }, fullDateFormatter(date) { return d(date, short ? 'short' : 'long') }, } }