refactor: i18n

This commit is contained in:
codytseng
2025-03-02 16:36:18 +08:00
parent a2dd56d475
commit e81ab6d0bd
5 changed files with 40 additions and 57 deletions

View File

@@ -1,5 +1,5 @@
import dayjs from 'dayjs' import dayjs from 'dayjs'
import i18n from 'i18next' import i18n, { Resource } from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector' import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next' import { initReactI18next } from 'react-i18next'
import ar from './locales/ar' import ar from './locales/ar'
@@ -13,32 +13,29 @@ import pt from './locales/pt'
import ru from './locales/ru' import ru from './locales/ru'
import zh from './locales/zh' import zh from './locales/zh'
export const LocalizedLanguageNames = { const languages = {
en: 'English', en: { resource: en, name: 'English' },
zh: '简体中文', zh: { resource: zh, name: '简体中文' },
pl: 'Polski', pl: { resource: pl, name: 'Polski' },
es: 'Español', es: { resource: es, name: 'Español' },
fr: 'Français', fr: { resource: fr, name: 'Français' },
de: 'Deutsch', de: { resource: de, name: 'Deutsch' },
ja: '日本語', ja: { resource: ja, name: '日本語' },
ru: 'Русский', ru: { resource: ru, name: 'Русский' },
pt: 'Português', pt: { resource: pt, name: 'Português' },
ar: 'العربية' ar: { resource: ar, name: 'العربية' }
} } as const
const resources = { export type TLanguage = keyof typeof languages
en, export const LocalizedLanguageNames: { [key in TLanguage]?: string } = {}
zh, const resources: { [key in TLanguage]?: Resource } = {}
pl, const supportedLanguages: TLanguage[] = []
es, for (const [key, value] of Object.entries(languages)) {
fr, const lang = key as TLanguage
de, LocalizedLanguageNames[lang] = value.name
ja, resources[lang] = value.resource
ru, supportedLanguages.push(lang)
pt,
ar
} }
const supportedLanguages = Object.keys(resources)
i18n i18n
.use(LanguageDetector) .use(LanguageDetector)
@@ -58,34 +55,22 @@ i18n
}) })
i18n.services.formatter?.add('date', (timestamp, lng) => { i18n.services.formatter?.add('date', (timestamp, lng) => {
if (lng?.startsWith('zh')) { switch (lng) {
case 'zh':
case 'ja':
return dayjs(timestamp).format('YYYY年MM月DD日') return dayjs(timestamp).format('YYYY年MM月DD日')
} case 'pl':
if (lng?.startsWith('pl')) { case 'de':
case 'ru':
return dayjs(timestamp).format('DD.MM.YYYY') return dayjs(timestamp).format('DD.MM.YYYY')
} case 'es':
if (lng?.startsWith('ja')) { case 'fr':
return dayjs(timestamp).format('YYYY年MM月DD日') case 'pt':
} case 'ar':
if (lng?.startsWith('de')) {
return dayjs(timestamp).format('DD.MM.YYYY')
}
if (lng?.startsWith('ru')) {
return dayjs(timestamp).format('DD.MM.YYYY')
}
if (lng?.startsWith('es')) {
return dayjs(timestamp).format('DD/MM/YYYY') return dayjs(timestamp).format('DD/MM/YYYY')
} default:
if (lng?.startsWith('fr')) {
return dayjs(timestamp).format('DD/MM/YYYY')
}
if (lng?.startsWith('pt')) {
return dayjs(timestamp).format('DD/MM/YYYY')
}
if (lng?.startsWith('ar')) {
return dayjs(timestamp).format('DD/MM/YYYY')
}
return dayjs(timestamp).format('MMM D, YYYY') return dayjs(timestamp).format('MMM D, YYYY')
}
}) })
export default i18n export default i18n

View File

@@ -202,6 +202,5 @@ export default {
'تبرعك يساعد في صيانة Jumble وتحسينه! 😊', 'تبرعك يساعد في صيانة Jumble وتحسينه! 😊',
'Earlier notifications': 'الإشعارات السابقة', 'Earlier notifications': 'الإشعارات السابقة',
'Temporarily display this note': 'عرض هذه الملاحظة مؤقتاً' 'Temporarily display this note': 'عرض هذه الملاحظة مؤقتاً'
// ...existing code...
} }
} }

View File

@@ -81,7 +81,7 @@ export default {
'Display replies': 'Antworten anzeigen', 'Display replies': 'Antworten anzeigen',
Notes: 'Notizen', Notes: 'Notizen',
Replies: 'Antworten', Replies: 'Antworten',
Notifications: 'Benachr.', // shortened from 'Benachrichtigungen' Notifications: 'Benachr.',
'no more notifications': 'keine weiteren Benachrichtigungen', 'no more notifications': 'keine weiteren Benachrichtigungen',
'Using private key login is insecure. It is recommended to use a browser extension for login, such as alby, nostr-keyx or nos2x.': 'Using private key login is insecure. It is recommended to use a browser extension for login, such as alby, nostr-keyx or nos2x.':
'Die Anmeldung mit privatem Schlüssel ist unsicher. Es wird empfohlen, eine Browsererweiterung wie alby, nostr-keyx oder nos2x zu verwenden.', 'Die Anmeldung mit privatem Schlüssel ist unsicher. Es wird empfohlen, eine Browsererweiterung wie alby, nostr-keyx oder nos2x zu verwenden.',

View File

@@ -22,7 +22,7 @@ export default {
'n h': '{{n}}h', 'n h': '{{n}}h',
'n days ago': 'hace {{n}} días', 'n days ago': 'hace {{n}} días',
'n d': '{{n}}d', 'n d': '{{n}}d',
date: '{{timestamp, date}}', // ...existing code... date: '{{timestamp, date}}',
Follow: 'Seguir', Follow: 'Seguir',
Unfollow: 'Dejar de seguir', Unfollow: 'Dejar de seguir',
'Follow failed': 'Error al seguir', 'Follow failed': 'Error al seguir',

View File

@@ -1,14 +1,13 @@
import AboutInfoDialog from '@/components/AboutInfoDialog' import AboutInfoDialog from '@/components/AboutInfoDialog'
import Donation from '@/components/Donation' import Donation from '@/components/Donation'
import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select' import { Select, SelectContent, SelectItem, SelectTrigger } from '@/components/ui/select'
import { LocalizedLanguageNames } from '@/i18n' import { LocalizedLanguageNames, TLanguage } from '@/i18n'
import SecondaryPageLayout from '@/layouts/SecondaryPageLayout' import SecondaryPageLayout from '@/layouts/SecondaryPageLayout'
import { toRelaySettings, toWallet } from '@/lib/link' import { toRelaySettings, toWallet } from '@/lib/link'
import { cn } from '@/lib/utils' import { cn } from '@/lib/utils'
import { useSecondaryPage } from '@/PageManager' import { useSecondaryPage } from '@/PageManager'
import { useNostr } from '@/providers/NostrProvider' import { useNostr } from '@/providers/NostrProvider'
import { useTheme } from '@/providers/ThemeProvider' import { useTheme } from '@/providers/ThemeProvider'
import { TLanguage } from '@/types'
import { SelectValue } from '@radix-ui/react-select' import { SelectValue } from '@radix-ui/react-select'
import { import {
Check, Check,