feat(i18n): plurals support (#278)
This commit is contained in:
parent
0f7de38c24
commit
c4cf3fb371
17 changed files with 234 additions and 91 deletions
|
@ -12,7 +12,7 @@ const loaded = $ref(false)
|
|||
<img
|
||||
:key="account.avatar"
|
||||
:src="account.avatar"
|
||||
:alt="account.username"
|
||||
:alt="$t('account.avatar_description', [account.username])"
|
||||
loading="lazy"
|
||||
rounded-full
|
||||
:class="loaded ? 'bg-gray' : 'bg-gray:10'"
|
||||
|
|
|
@ -6,6 +6,8 @@ const { account } = defineProps<{
|
|||
command?: boolean
|
||||
}>()
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const createdAt = $(useFormattedDateTime(() => account.createdAt, {
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
|
@ -43,13 +45,16 @@ function getFieldNameIcon(fieldName: string) {
|
|||
if (fieldNameIcons[name])
|
||||
return fieldNameIcons[name]
|
||||
}
|
||||
function getFieldIconTitle(fieldName: string) {
|
||||
return fieldName === 'Joined' ? t('account.joined') : fieldName
|
||||
}
|
||||
|
||||
function previewHeader() {
|
||||
openMediaPreview([{
|
||||
id: `${account.acct}:header`,
|
||||
type: 'image',
|
||||
previewUrl: account.header,
|
||||
description: `${account.username}'s profile header`,
|
||||
description: t('account.profile_description', [account.username]),
|
||||
}])
|
||||
}
|
||||
|
||||
|
@ -58,7 +63,7 @@ function previewAvatar() {
|
|||
id: `${account.acct}:avatar`,
|
||||
type: 'image',
|
||||
previewUrl: account.avatar,
|
||||
description: `${account.username}'s avatar`,
|
||||
description: t('account.avatar_description', [account.username]),
|
||||
}])
|
||||
}
|
||||
|
||||
|
@ -86,7 +91,7 @@ watchEffect(() => {
|
|||
<template>
|
||||
<div flex flex-col>
|
||||
<button border="b base" z-1>
|
||||
<img h-50 w-full object-cover :src="account.header" :alt="`${account.username}'s profile header`" @click="previewHeader">
|
||||
<img h-50 w-full object-cover :src="account.header" :alt="t('account.profile_description', [account.username])" @click="previewHeader">
|
||||
</button>
|
||||
<div p4 mt--18 flex flex-col gap-4>
|
||||
<div relative>
|
||||
|
@ -122,7 +127,7 @@ watchEffect(() => {
|
|||
</div>
|
||||
<div v-if="iconFields.length" flex="~ wrap gap-4">
|
||||
<div v-for="field in iconFields" :key="field.name" flex="~ gap-1" items-center>
|
||||
<div text-secondary :class="getFieldNameIcon(field.name)" :title="field.name" />
|
||||
<div text-secondary :class="getFieldNameIcon(field.name)" :title="getFieldIconTitle(field.name)" />
|
||||
<ContentRich text-sm filter-saturate-0 :content="field.value" :emojis="account.emojis" />
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,31 +1,46 @@
|
|||
<script setup lang="ts">
|
||||
import type { Account } from 'masto'
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
account: Account
|
||||
}>()
|
||||
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
|
||||
|
||||
const statusesCount = $computed(() => formatNumber(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>
|
||||
<div flex gap-5>
|
||||
<NuxtLink :to="getAccountRoute(account)" text-secondary exact-active-class="text-primary">
|
||||
<template #default="{ isExactActive }">
|
||||
<i18n-t keypath="account.posts_count">
|
||||
<span font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ formattedNumber(account.statusesCount) }}</span>
|
||||
<i18n-t keypath="account.posts_count" :plural="account.statusesCount">
|
||||
<span font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ statusesCount }}</span>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</NuxtLink>
|
||||
<NuxtLink :to="getAccountFollowingRoute(account)" text-secondary exact-active-class="text-primary">
|
||||
<template #default="{ isExactActive }">
|
||||
<i18n-t keypath="account.following_count">
|
||||
<span font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ humanReadableNumber(account.followingCount) }}</span>
|
||||
<span v-if="followingCountSR">
|
||||
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followingCount }}</span>
|
||||
<span sr-only font-bold>{{ account.followingCount }}</span>
|
||||
</span>
|
||||
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followingCount }}</span>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</NuxtLink>
|
||||
<NuxtLink :to="getAccountFollowersRoute(account)" text-secondary exact-active-class="text-primary">
|
||||
<template #default="{ isExactActive }">
|
||||
<i18n-t keypath="account.followers_count">
|
||||
<span font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ humanReadableNumber(account.followersCount) }}</span>
|
||||
<i18n-t keypath="account.followers_count" :plural="account.followersCount">
|
||||
<span v-if="followersCountSR">
|
||||
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followersCount }}</span>
|
||||
<span sr-only font-bold>{{ account.followersCount }}</span>
|
||||
</span>
|
||||
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followersCount }}</span>
|
||||
</i18n-t>
|
||||
</template>
|
||||
</NuxtLink>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue