refactor: extract common code for number localization (#903)
parent
71b19dbe68
commit
46c4fe1e5a
|
@ -132,7 +132,7 @@ You can run this code in your browser console to see how it works:
|
||||||
#### Custom Plural Number Formatting Entries
|
#### Custom Plural Number Formatting Entries
|
||||||
|
|
||||||
**Warning**:
|
**Warning**:
|
||||||
Either **{0}**, **{v}** or **{followers}** should be used with the exception being custom plurals entries using the `{n}` placeholder.
|
Either **{0}** or **{v}** should be used with the exception being custom plurals entries using the `{n}` placeholder.
|
||||||
|
|
||||||
This is the full list of entries that will be available for number formatting in Elk:
|
This is the full list of entries that will be available for number formatting in Elk:
|
||||||
- `action.boost_count` (no need to be included, we should use always `en-US` entry): `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
- `action.boost_count` (no need to be included, we should use always `en-US` entry): `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
||||||
|
@ -142,7 +142,7 @@ This is the full list of entries that will be available for number formatting in
|
||||||
- `account.following_count`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
- `account.following_count`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
||||||
- `account.posts_count`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
- `account.posts_count`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
||||||
- `compose.drafts`: `{v}` for formatted number and `{n}` for raw number - **{v} should be use**
|
- `compose.drafts`: `{v}` for formatted number and `{n}` for raw number - **{v} should be use**
|
||||||
- `notification.followed_you_count`: `{followers}` for formatted number and `{n}` for raw number - **{followers} should be use**
|
- `notification.followed_you_count`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
||||||
- `status.poll.count`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
- `status.poll.count`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**
|
||||||
- `time_ago_options.*`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**: since numbers will be always small, we can also use `{n}`
|
- `time_ago_options.*`: `{0}` for formatted number and `{n}` for raw number - **{0} should be use**: since numbers will be always small, we can also use `{n}`
|
||||||
- `timeline.show_new_items`: `{v}` for formatted number and `{n}` for raw number - **{v} should be use**
|
- `timeline.show_new_items`: `{v}` for formatted number and `{n}` for raw number - **{v} should be use**
|
||||||
|
|
|
@ -1,17 +1,9 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import type { mastodon } from 'masto'
|
import type { mastodon } from 'masto'
|
||||||
|
|
||||||
const props = defineProps<{
|
defineProps<{
|
||||||
account: mastodon.v1.Account
|
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>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -21,48 +13,42 @@ const followersCountSR = $computed(() => forSR(props.account.followersCount))
|
||||||
replace
|
replace
|
||||||
text-secondary
|
text-secondary
|
||||||
exact-active-class="text-primary"
|
exact-active-class="text-primary"
|
||||||
:class="statusesCountSR ? 'flex gap-x-1' : null"
|
|
||||||
>
|
>
|
||||||
<template #default="{ isExactActive }">
|
<template #default="{ isExactActive }">
|
||||||
<i18n-t keypath="account.posts_count" :plural="account.statusesCount">
|
<CommonLocalizedNumber
|
||||||
<CommonTooltip v-if="statusesCountSR" :content="formatNumber(account.statusesCount)" placement="bottom">
|
keypath="account.posts_count"
|
||||||
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ statusesCount }}</span>
|
:count="account.statusesCount"
|
||||||
<span sr-only font-bold>{{ formatNumber(account.statusesCount) }}</span>
|
font-bold
|
||||||
</CommonTooltip>
|
:class="isExactActive ? 'text-primary' : 'text-base'"
|
||||||
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ statusesCount }}</span>
|
/>
|
||||||
</i18n-t>
|
|
||||||
</template>
|
</template>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
:to="getAccountFollowingRoute(account)"
|
:to="getAccountFollowingRoute(account)"
|
||||||
replace
|
replace
|
||||||
text-secondary exact-active-class="text-primary"
|
text-secondary exact-active-class="text-primary"
|
||||||
:class="followingCountSR ? 'flex gap-x-1' : null"
|
|
||||||
>
|
>
|
||||||
<template #default="{ isExactActive }">
|
<template #default="{ isExactActive }">
|
||||||
<i18n-t keypath="account.following_count" :plural="account.followingCount">
|
<CommonLocalizedNumber
|
||||||
<CommonTooltip v-if="followingCountSR" :content="formatNumber(account.followingCount)" placement="bottom">
|
keypath="account.following_count"
|
||||||
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followingCount }}</span>
|
:count="account.followingCount"
|
||||||
<span sr-only font-bold>{{ formatNumber(account.followingCount) }}</span>
|
font-bold
|
||||||
</CommonTooltip>
|
:class="isExactActive ? 'text-primary' : 'text-base'"
|
||||||
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followingCount }}</span>
|
/>
|
||||||
</i18n-t>
|
|
||||||
</template>
|
</template>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
<NuxtLink
|
<NuxtLink
|
||||||
:to="getAccountFollowersRoute(account)"
|
:to="getAccountFollowersRoute(account)"
|
||||||
replace
|
replace
|
||||||
text-secondary exact-active-class="text-primary"
|
text-secondary exact-active-class="text-primary"
|
||||||
:class="followersCountSR ? 'flex gap-x-1' : null"
|
|
||||||
>
|
>
|
||||||
<template #default="{ isExactActive }">
|
<template #default="{ isExactActive }">
|
||||||
<i18n-t keypath="account.followers_count" :plural="account.followersCount">
|
<CommonLocalizedNumber
|
||||||
<CommonTooltip v-if="followersCountSR" :content="formatNumber(account.followersCount)" placement="bottom">
|
keypath="account.followers_count"
|
||||||
<span aria-hidden="true" font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followersCount }}</span>
|
:count="account.followersCount"
|
||||||
<span sr-only font-bold>{{ formatNumber(account.followersCount) }}</span>
|
font-bold
|
||||||
</CommonTooltip>
|
:class="isExactActive ? 'text-primary' : 'text-base'"
|
||||||
<span v-else font-bold :class="isExactActive ? 'text-primary' : 'text-base'">{{ followersCount }}</span>
|
/>
|
||||||
</i18n-t>
|
|
||||||
</template>
|
</template>
|
||||||
</NuxtLink>
|
</NuxtLink>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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>
|
|
@ -5,10 +5,7 @@ const { items } = defineProps<{
|
||||||
items: GroupedNotifications
|
items: GroupedNotifications
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
const { formatHumanReadableNumber, forSR } = useHumanReadableNumber()
|
|
||||||
|
|
||||||
const count = $computed(() => items.items.length)
|
const count = $computed(() => items.items.length)
|
||||||
const addSR = $computed(() => forSR(count))
|
|
||||||
const isExpanded = ref(false)
|
const isExpanded = ref(false)
|
||||||
const lang = $computed(() => {
|
const lang = $computed(() => {
|
||||||
return count > 1 || count === 0 ? undefined : items.items[0].status?.language
|
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 flex items-center top-0 left-2 pt-2 px-3>
|
||||||
<div i-ri:user-follow-fill me-3 color-primary aria-hidden="true" />
|
<div i-ri:user-follow-fill me-3 color-primary aria-hidden="true" />
|
||||||
<template v-if="count > 1">
|
<template v-if="count > 1">
|
||||||
<template v-if="addSR">
|
<CommonLocalizedNumber
|
||||||
<span
|
keypath="notification.followed_you_count"
|
||||||
aria-hidden="true"
|
:count="count"
|
||||||
>
|
/>
|
||||||
{{ $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>
|
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<AccountDisplayName
|
<AccountDisplayName
|
||||||
|
|
|
@ -20,8 +20,6 @@ const {
|
||||||
toggleReblog,
|
toggleReblog,
|
||||||
} = $(useStatusActions(props))
|
} = $(useStatusActions(props))
|
||||||
|
|
||||||
const { formatHumanReadableNumber, formatNumber, forSR } = useHumanReadableNumber()
|
|
||||||
|
|
||||||
const reply = () => {
|
const reply = () => {
|
||||||
if (!checkLogin())
|
if (!checkLogin())
|
||||||
return
|
return
|
||||||
|
@ -44,13 +42,10 @@ const reply = () => {
|
||||||
@click="reply"
|
@click="reply"
|
||||||
>
|
>
|
||||||
<template v-if="status.repliesCount" #text>
|
<template v-if="status.repliesCount" #text>
|
||||||
<i18n-t keypath="action.reply_count" :plural="status.repliesCount">
|
<CommonLocalizedNumber
|
||||||
<CommonTooltip v-if="forSR(status.repliesCount)" :content="formatNumber(status.repliesCount)" placement="bottom">
|
keypath="action.reply_count"
|
||||||
<span aria-hidden="true">{{ formatHumanReadableNumber(status.repliesCount) }}</span>
|
:count="status.repliesCount"
|
||||||
<span sr-only>{{ formatNumber(status.repliesCount) }}</span>
|
/>
|
||||||
</CommonTooltip>
|
|
||||||
<span v-else>{{ formatHumanReadableNumber(status.repliesCount) }}</span>
|
|
||||||
</i18n-t>
|
|
||||||
</template>
|
</template>
|
||||||
</StatusActionButton>
|
</StatusActionButton>
|
||||||
</div>
|
</div>
|
||||||
|
@ -68,13 +63,10 @@ const reply = () => {
|
||||||
@click="toggleReblog()"
|
@click="toggleReblog()"
|
||||||
>
|
>
|
||||||
<template v-if="status.reblogsCount" #text>
|
<template v-if="status.reblogsCount" #text>
|
||||||
<i18n-t keypath="action.boost_count" :plural="status.reblogsCount">
|
<CommonLocalizedNumber
|
||||||
<CommonTooltip v-if="forSR(status.reblogsCount)" :content="formatNumber(status.reblogsCount)" placement="bottom">
|
keypath="action.boost_count"
|
||||||
<span aria-hidden="true">{{ formatHumanReadableNumber(status.reblogsCount) }}</span>
|
:count="status.reblogsCount"
|
||||||
<span sr-only>{{ formatNumber(status.reblogsCount) }}</span>
|
/>
|
||||||
</CommonTooltip>
|
|
||||||
<span v-else>{{ formatHumanReadableNumber(status.reblogsCount) }}</span>
|
|
||||||
</i18n-t>
|
|
||||||
</template>
|
</template>
|
||||||
</StatusActionButton>
|
</StatusActionButton>
|
||||||
</div>
|
</div>
|
||||||
|
@ -92,13 +84,10 @@ const reply = () => {
|
||||||
@click="toggleFavourite()"
|
@click="toggleFavourite()"
|
||||||
>
|
>
|
||||||
<template v-if="status.favouritesCount" #text>
|
<template v-if="status.favouritesCount" #text>
|
||||||
<i18n-t keypath="action.favourite_count" :plural="status.favouritesCount">
|
<CommonLocalizedNumber
|
||||||
<CommonTooltip v-if="forSR(status.favouritesCount)" :content="formatNumber(status.favouritesCount)" placement="bottom">
|
keypath="action.favourite_count"
|
||||||
<span aria-hidden="true">{{ formatHumanReadableNumber(status.favouritesCount) }}</span>
|
:count="status.favouritesCount"
|
||||||
<span sr-only>{{ formatNumber(status.favouritesCount) }}</span>
|
/>
|
||||||
</CommonTooltip>
|
|
||||||
<span v-else>{{ formatHumanReadableNumber(status.favouritesCount) }}</span>
|
|
||||||
</i18n-t>
|
|
||||||
</template>
|
</template>
|
||||||
</StatusActionButton>
|
</StatusActionButton>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -13,7 +13,7 @@ function toPercentage(num: number) {
|
||||||
const timeAgoOptions = useTimeAgoOptions()
|
const timeAgoOptions = useTimeAgoOptions()
|
||||||
const expiredTimeAgo = useTimeAgo(poll.expiresAt!, timeAgoOptions)
|
const expiredTimeAgo = useTimeAgo(poll.expiresAt!, timeAgoOptions)
|
||||||
const expiredTimeFormatted = useFormattedDateTime(poll.expiresAt!)
|
const expiredTimeFormatted = useFormattedDateTime(poll.expiresAt!)
|
||||||
const { formatHumanReadableNumber, formatNumber, formatPercentage, forSR } = useHumanReadableNumber()
|
const { formatPercentage } = useHumanReadableNumber()
|
||||||
|
|
||||||
const masto = useMasto()
|
const masto = useMasto()
|
||||||
async function vote(e: Event) {
|
async function vote(e: Event) {
|
||||||
|
@ -34,9 +34,6 @@ async function vote(e: Event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
const votersCount = $computed(() => poll.votersCount ?? 0)
|
const votersCount = $computed(() => poll.votersCount ?? 0)
|
||||||
const votersCountHR = $computed(() => formatHumanReadableNumber(votersCount))
|
|
||||||
const votersCountNumber = $computed(() => formatNumber(votersCount))
|
|
||||||
const votersCountSR = $computed(() => forSR(votersCount))
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
@ -65,13 +62,10 @@ const votersCountSR = $computed(() => forSR(votersCount))
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<div text-sm flex="~ inline" gap-x-1>
|
<div text-sm flex="~ inline" gap-x-1>
|
||||||
<i18n-t keypath="status.poll.count" :plural="votersCount">
|
<CommonLocalizedNumber
|
||||||
<CommonTooltip v-if="votersCountSR" :content="votersCountNumber" placement="bottom">
|
keypath="status.poll.count"
|
||||||
<span aria-hidden="true">{{ votersCountHR }}</span>
|
:count="poll.votesCount"
|
||||||
<span sr-only>{{ votersCountNumber }}</span>
|
/>
|
||||||
</CommonTooltip>
|
|
||||||
<span v-else>{{ votersCountNumber }}</span>
|
|
||||||
</i18n-t>
|
|
||||||
·
|
·
|
||||||
<CommonTooltip :content="expiredTimeFormatted" class="inline-block" placement="right">
|
<CommonTooltip :content="expiredTimeFormatted" class="inline-block" placement="right">
|
||||||
<time :datetime="poll.expiresAt!">{{ $t(poll.expired ? 'status.poll.finished' : 'status.poll.ends', [expiredTimeAgo]) }}</time>
|
<time :datetime="poll.expiresAt!">{{ $t(poll.expired ? 'status.poll.finished' : 'status.poll.ends', [expiredTimeAgo]) }}</time>
|
||||||
|
|
|
@ -154,7 +154,7 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"favourited_post": "أُعجِب بمنشورك",
|
"favourited_post": "أُعجِب بمنشورك",
|
||||||
"followed_you": "بدأ في متابعتك",
|
"followed_you": "بدأ في متابعتك",
|
||||||
"followed_you_count": "لم يتبعك أحد|تبعك شخص واحد|تبعك شخصان|تبعك {followers} أشخاص|تبعك {followers} شخص| تبعك {followers} شخص",
|
"followed_you_count": "لم يتبعك أحد|تبعك شخص واحد|تبعك شخصان|تبعك {0} أشخاص|تبعك {0} شخص| تبعك {0} شخص",
|
||||||
"missing_type": "MISSING notification.type:",
|
"missing_type": "MISSING notification.type:",
|
||||||
"reblogged_post": "اعاد نشر منشورك",
|
"reblogged_post": "اعاد نشر منشورك",
|
||||||
"request_to_follow": "طلب(ت) متابعتك",
|
"request_to_follow": "طلب(ت) متابعتك",
|
||||||
|
|
|
@ -162,7 +162,7 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"favourited_post": "favourited your post",
|
"favourited_post": "favourited your post",
|
||||||
"followed_you": "followed you",
|
"followed_you": "followed you",
|
||||||
"followed_you_count": "{followers} people followed you|{followers} person followed you|{followers} people followed you",
|
"followed_you_count": "{0} people followed you|{0} person followed you|{0} people followed you",
|
||||||
"missing_type": "MISSING notification.type:",
|
"missing_type": "MISSING notification.type:",
|
||||||
"reblogged_post": "reblogged your post",
|
"reblogged_post": "reblogged your post",
|
||||||
"request_to_follow": "requested to follow you",
|
"request_to_follow": "requested to follow you",
|
||||||
|
|
|
@ -187,7 +187,7 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"favourited_post": "favorited your post",
|
"favourited_post": "favorited your post",
|
||||||
"followed_you": "followed you",
|
"followed_you": "followed you",
|
||||||
"followed_you_count": "{followers} people followed you|{followers} person followed you|{followers} people followed you",
|
"followed_you_count": "{0} people followed you|{0} person followed you|{0} people followed you",
|
||||||
"missing_type": "MISSING notification.type:",
|
"missing_type": "MISSING notification.type:",
|
||||||
"reblogged_post": "reblogged your post",
|
"reblogged_post": "reblogged your post",
|
||||||
"request_to_follow": "requested to follow you",
|
"request_to_follow": "requested to follow you",
|
||||||
|
|
|
@ -187,7 +187,7 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"favourited_post": "marcó tu publicación como favorito",
|
"favourited_post": "marcó tu publicación como favorito",
|
||||||
"followed_you": "te ha seguido",
|
"followed_you": "te ha seguido",
|
||||||
"followed_you_count": "{followers} personas te siguieron|{followers} persona te siguió|{followers} personas te siguieron",
|
"followed_you_count": "{0} personas te siguieron|{0} persona te siguió|{0} personas te siguieron",
|
||||||
"missing_type": "MISSING notification.type:",
|
"missing_type": "MISSING notification.type:",
|
||||||
"reblogged_post": "retooteó tu publicación",
|
"reblogged_post": "retooteó tu publicación",
|
||||||
"request_to_follow": "ha solicitado seguirte",
|
"request_to_follow": "ha solicitado seguirte",
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"favourited_post": "aime votre message",
|
"favourited_post": "aime votre message",
|
||||||
"followed_you": "vous suit",
|
"followed_you": "vous suit",
|
||||||
"followed_you_count": "{followers} personnes vous suivent|{followers} personne vous suit|{followers} personnes vous suivent",
|
"followed_you_count": "{0} personnes vous suivent|{0} personne vous suit|{0} personnes vous suivent",
|
||||||
"missing_type": "MISSING notification.type:",
|
"missing_type": "MISSING notification.type:",
|
||||||
"reblogged_post": "a relayé votre message",
|
"reblogged_post": "a relayé votre message",
|
||||||
"request_to_follow": "vous demande de le suivre",
|
"request_to_follow": "vous demande de le suivre",
|
||||||
|
|
|
@ -166,7 +166,7 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"favourited_post": "vindt jou post favoriet",
|
"favourited_post": "vindt jou post favoriet",
|
||||||
"followed_you": "volgt jou",
|
"followed_you": "volgt jou",
|
||||||
"followed_you_count": "{followers} mensen hebben je gevolgd|{followers} persoon heeft je gevold|{followers} mensen hebben je gevolgd",
|
"followed_you_count": "{0} mensen hebben je gevolgd|{0} persoon heeft je gevold|{0} mensen hebben je gevolgd",
|
||||||
"missing_type": "MISSEND notificatie.type:",
|
"missing_type": "MISSEND notificatie.type:",
|
||||||
"reblogged_post": "herblogd je post",
|
"reblogged_post": "herblogd je post",
|
||||||
"request_to_follow": "vraagt om jou te volgen",
|
"request_to_follow": "vraagt om jou te volgen",
|
||||||
|
|
|
@ -184,7 +184,7 @@
|
||||||
"notification": {
|
"notification": {
|
||||||
"favourited_post": "додали ваший допис до вибраного",
|
"favourited_post": "додали ваший допис до вибраного",
|
||||||
"followed_you": "підписались на вас",
|
"followed_you": "підписались на вас",
|
||||||
"followed_you_count": "{followers} людей підписалися на вас|{followers} людина підписалися на вас|{followers} людини підписалися на вас|{followers} людей підписалися на вас",
|
"followed_you_count": "{0} людей підписалися на вас|{0} людина підписалися на вас|{0} людини підписалися на вас|{0} людей підписалися на вас",
|
||||||
"missing_type": "ВІДСУТНІЙ notification.type:",
|
"missing_type": "ВІДСУТНІЙ notification.type:",
|
||||||
"reblogged_post": "поширили ваш допис",
|
"reblogged_post": "поширили ваш допис",
|
||||||
"request_to_follow": "попросили підписатися на вас",
|
"request_to_follow": "попросили підписатися на вас",
|
||||||
|
|
Loading…
Reference in New Issue