refactor: extract common code for number localization (#903)

This commit is contained in:
Ivan Demchuk 2023-01-09 13:24:26 +02:00 committed by GitHub
parent 71b19dbe68
commit 46c4fe1e5a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 75 additions and 92 deletions

View file

@ -1,17 +1,9 @@
<script setup lang="ts">
import type { mastodon } from 'masto'
const props = defineProps<{
defineProps<{
account: mastodon.v1.Account
}>()
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
const statusesCount = $computed(() => formatHumanReadableNumber(props.account.statusesCount))
const statusesCountSR = $computed(() => forSR(props.account.statusesCount))
const followingCount = $computed(() => formatHumanReadableNumber(props.account.followingCount))
const followingCountSR = $computed(() => forSR(props.account.followingCount))
const followersCount = $computed(() => formatHumanReadableNumber(props.account.followersCount))
const followersCountSR = $computed(() => forSR(props.account.followersCount))
</script>
<template>
@ -21,48 +13,42 @@ const followersCountSR = $computed(() => forSR(props.account.followersCount))
replace
text-secondary
exact-active-class="text-primary"
:class="statusesCountSR ? 'flex gap-x-1' : null"
>
<template #default="{ isExactActive }">
<i18n-t keypath="account.posts_count" :plural="account.statusesCount">
<CommonTooltip v-if="statusesCountSR" :content="formatNumber(account.statusesCount)" placement="bottom">
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ statusesCount }}</span>
<span sr-only font-bold>{{ formatNumber(account.statusesCount) }}</span>
</CommonTooltip>
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ statusesCount }}</span>
</i18n-t>
<CommonLocalizedNumber
keypath="account.posts_count"
:count="account.statusesCount"
font-bold
:class="isExactActive ? 'text-primary' : 'text-base'"
/>
</template>
</NuxtLink>
<NuxtLink
:to="getAccountFollowingRoute(account)"
replace
text-secondary exact-active-class="text-primary"
:class="followingCountSR ? 'flex gap-x-1' : null"
>
<template #default="{ isExactActive }">
<i18n-t keypath="account.following_count" :plural="account.followingCount">
<CommonTooltip v-if="followingCountSR" :content="formatNumber(account.followingCount)" placement="bottom">
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followingCount }}</span>
<span sr-only font-bold>{{ formatNumber(account.followingCount) }}</span>
</CommonTooltip>
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followingCount }}</span>
</i18n-t>
<CommonLocalizedNumber
keypath="account.following_count"
:count="account.followingCount"
font-bold
:class="isExactActive ? 'text-primary' : 'text-base'"
/>
</template>
</NuxtLink>
<NuxtLink
:to="getAccountFollowersRoute(account)"
replace
text-secondary exact-active-class="text-primary"
:class="followersCountSR ? 'flex gap-x-1' : null"
>
<template #default="{ isExactActive }">
<i18n-t keypath="account.followers_count" :plural="account.followersCount">
<CommonTooltip v-if="followersCountSR" :content="formatNumber(account.followersCount)" placement="bottom">
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followersCount }}</span>
<span sr-only font-bold>{{ formatNumber(account.followersCount) }}</span>
</CommonTooltip>
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followersCount }}</span>
</i18n-t>
<CommonLocalizedNumber
keypath="account.followers_count"
:count="account.followersCount"
font-bold
:class="isExactActive ? 'text-primary' : 'text-base'"
/>
</template>
</NuxtLink>
</div>

View file

@ -0,0 +1,26 @@
<script setup lang="ts">
const props = defineProps<{
count: number
keypath: string
}>()
defineOptions({
inheritAttrs: false,
})
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
const useSR = $computed(() => forSR(props.count))
const rawNumber = $computed(() => formatNumber(props.count))
const humanReadableNumber = $computed(() => formatHumanReadableNumber(props.count))
</script>
<template>
<i18n-t :keypath="keypath" :plural="count" tag="span" class="flex gap-x-1">
<CommonTooltip v-if="useSR" :content="rawNumber" placement="bottom">
<span aria-hidden="true" v-bind="$attrs">{{ humanReadableNumber }}</span>
<span sr-only>{{ rawNumber }}</span>
</CommonTooltip>
<span v-else v-bind="$attrs">{{ humanReadableNumber }}</span>
</i18n-t>
</template>

View file

@ -5,10 +5,7 @@ const { items } = defineProps<{
items: GroupedNotifications
}>()
const { formatHumanReadableNumber, forSR } = useHumanReadableNumber()
const count = $computed(() => items.items.length)
const addSR = $computed(() => forSR(count))
const isExpanded = ref(false)
const lang = $computed(() => {
return count > 1 || count === 0 ? undefined : items.items[0].status?.language
@ -20,19 +17,10 @@ const lang = $computed(() => {
<div flex items-center top-0 left-2 pt-2 px-3>
<div i-ri:user-follow-fill me-3 color-primary aria-hidden="true" />
<template v-if="count > 1">
<template v-if="addSR">
<span
aria-hidden="true"
>
{{ $t('notification.followed_you_count', count, { named: { followers: formatHumanReadableNumber(count) } }) }}
</span>
<span sr-only>
{{ $t('notification.followed_you_count', count, { named: { followers: count } }) }}
</span>
</template>
<span v-else>
{{ $t('notification.followed_you_count', count, { named: { followers: count } }) }}
</span>
<CommonLocalizedNumber
keypath="notification.followed_you_count"
:count="count"
/>
</template>
<template v-else>
<AccountDisplayName

View file

@ -20,8 +20,6 @@ const {
toggleReblog,
} = $(useStatusActions(props))
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
const reply = () => {
if (!checkLogin())
return
@ -44,13 +42,10 @@ const reply = () => {
@click="reply"
>
<template v-if="status.repliesCount" #text>
<i18n-t keypath="action.reply_count" :plural="status.repliesCount">
<CommonTooltip v-if="forSR(status.repliesCount)" :content="formatNumber(status.repliesCount)" placement="bottom">
<span aria-hidden="true">{{ formatHumanReadableNumber(status.repliesCount) }}</span>
<span sr-only>{{ formatNumber(status.repliesCount) }}</span>
</CommonTooltip>
<span v-else>{{ formatHumanReadableNumber(status.repliesCount) }}</span>
</i18n-t>
<CommonLocalizedNumber
keypath="action.reply_count"
:count="status.repliesCount"
/>
</template>
</StatusActionButton>
</div>
@ -68,13 +63,10 @@ const reply = () => {
@click="toggleReblog()"
>
<template v-if="status.reblogsCount" #text>
<i18n-t keypath="action.boost_count" :plural="status.reblogsCount">
<CommonTooltip v-if="forSR(status.reblogsCount)" :content="formatNumber(status.reblogsCount)" placement="bottom">
<span aria-hidden="true">{{ formatHumanReadableNumber(status.reblogsCount) }}</span>
<span sr-only>{{ formatNumber(status.reblogsCount) }}</span>
</CommonTooltip>
<span v-else>{{ formatHumanReadableNumber(status.reblogsCount) }}</span>
</i18n-t>
<CommonLocalizedNumber
keypath="action.boost_count"
:count="status.reblogsCount"
/>
</template>
</StatusActionButton>
</div>
@ -92,13 +84,10 @@ const reply = () => {
@click="toggleFavourite()"
>
<template v-if="status.favouritesCount" #text>
<i18n-t keypath="action.favourite_count" :plural="status.favouritesCount">
<CommonTooltip v-if="forSR(status.favouritesCount)" :content="formatNumber(status.favouritesCount)" placement="bottom">
<span aria-hidden="true">{{ formatHumanReadableNumber(status.favouritesCount) }}</span>
<span sr-only>{{ formatNumber(status.favouritesCount) }}</span>
</CommonTooltip>
<span v-else>{{ formatHumanReadableNumber(status.favouritesCount) }}</span>
</i18n-t>
<CommonLocalizedNumber
keypath="action.favourite_count"
:count="status.favouritesCount"
/>
</template>
</StatusActionButton>
</div>

View file

@ -13,7 +13,7 @@ function toPercentage(num: number) {
const timeAgoOptions = useTimeAgoOptions()
const expiredTimeAgo = useTimeAgo(poll.expiresAt!, timeAgoOptions)
const expiredTimeFormatted = useFormattedDateTime(poll.expiresAt!)
const { formatHumanReadableNumber, formatNumber, formatPercentage, forSR } = useHumanReadableNumber()
const { formatPercentage } = useHumanReadableNumber()
const masto = useMasto()
async function vote(e: Event) {
@ -34,9 +34,6 @@ async function vote(e: Event) {
}
const votersCount = $computed(() => poll.votersCount ?? 0)
const votersCountHR = $computed(() => formatHumanReadableNumber(votersCount))
const votersCountNumber = $computed(() => formatNumber(votersCount))
const votersCountSR = $computed(() => forSR(votersCount))
</script>
<template>
@ -65,13 +62,10 @@ const votersCountSR = $computed(() => forSR(votersCount))
</div>
</template>
<div text-sm flex="~ inline" gap-x-1>
<i18n-t keypath="status.poll.count" :plural="votersCount">
<CommonTooltip v-if="votersCountSR" :content="votersCountNumber" placement="bottom">
<span aria-hidden="true">{{ votersCountHR }}</span>
<span sr-only>{{ votersCountNumber }}</span>
</CommonTooltip>
<span v-else>{{ votersCountNumber }}</span>
</i18n-t>
<CommonLocalizedNumber
keypath="status.poll.count"
:count="poll.votesCount"
/>
&middot;
<CommonTooltip :content="expiredTimeFormatted" class="inline-block" placement="right">
<time :datetime="poll.expiresAt!">{{ $t(poll.expired ? 'status.poll.finished' : 'status.poll.ends', [expiredTimeAgo]) }}</time>