From 167f38b917154170105500838dc5e4e759d3b34a Mon Sep 17 00:00:00 2001 From: Mikhail Leonov Date: Thu, 13 Aug 2026 12:03:02 +0600 Subject: [PATCH 1/3] feat: add settings screen navigation and update profile menu options --- apps/mobile/app/(main)/_layout.tsx | 1 + apps/mobile/app/(main)/chat/list.tsx | 6 +++++- apps/mobile/app/(main)/settings.tsx | 20 +++++++++++++++++++ i18n/mobile/profile/en.json | 1 + .../profile-menu-sheet/src/lib/component.tsx | 17 +++++++++++++++- .../shared/utils/navigation/src/lib/config.ts | 1 + 6 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 apps/mobile/app/(main)/settings.tsx diff --git a/apps/mobile/app/(main)/_layout.tsx b/apps/mobile/app/(main)/_layout.tsx index 23ae185b..431ab460 100644 --- a/apps/mobile/app/(main)/_layout.tsx +++ b/apps/mobile/app/(main)/_layout.tsx @@ -29,6 +29,7 @@ export default function MainLayout(): ReactElement { }}> + ); } diff --git a/apps/mobile/app/(main)/chat/list.tsx b/apps/mobile/app/(main)/chat/list.tsx index e2ea7f27..7bebd6e3 100644 --- a/apps/mobile/app/(main)/chat/list.tsx +++ b/apps/mobile/app/(main)/chat/list.tsx @@ -33,6 +33,8 @@ export default function ChatListScreen(): ReactElement { const handleArchivedChatsPress = (): void => navigateOnce(`${navigationConfig.main.chat.index}/${navigationConfig.main.chat.archivedChats}`); + const handleSettingsPress = (): void => navigateOnce(navigationConfig.main.settings); + const handleFolderPress = (id: string, title: string): void => router.navigate(navigationConfig.main.folder.view({ id, title })); @@ -49,7 +51,9 @@ export default function ChatListScreen(): ReactElement { } + accessoryLeft={ + + } accessoryRight={ {isFeatureEnabled(FeatureID.CHAT_FOLDERS) && ( diff --git a/apps/mobile/app/(main)/settings.tsx b/apps/mobile/app/(main)/settings.tsx new file mode 100644 index 00000000..28a35a4f --- /dev/null +++ b/apps/mobile/app/(main)/settings.tsx @@ -0,0 +1,20 @@ +import { AppHeader, AppScreen, AppText } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; +import { useRouter } from 'expo-router'; +import { ReactElement } from 'react'; + +// TODO: Temporary solution, update when design is ready +export default function SettingsScreen(): ReactElement { + const router = useRouter(); + + return ( + }> + Settings + + ); +} diff --git a/i18n/mobile/profile/en.json b/i18n/mobile/profile/en.json index c43db1de..ae924454 100644 --- a/i18n/mobile/profile/en.json +++ b/i18n/mobile/profile/en.json @@ -3,6 +3,7 @@ "PROFILE_MENU_SHEET": { "TEXT_LOGOUT": "Logout", "TEXT_ARCHIVED_CHATS": "Archived Chats", + "TEXT_SETTINGS": "Settings", "TEXT_DELETE_ACCOUNT": "Delete Account", "TEXT_DELETE_ACCOUNT_TITLE": "Are you sure you want to delete your account?", "TEXT_DELETE_ACCOUNT_MESSAGE": "This action will result in permanent data loss if we don't hear from you in the next 30 days.", diff --git a/libs/mobile/shared/features/profile-menu-sheet/src/lib/component.tsx b/libs/mobile/shared/features/profile-menu-sheet/src/lib/component.tsx index 2cfdd786..9c83cb34 100644 --- a/libs/mobile/shared/features/profile-menu-sheet/src/lib/component.tsx +++ b/libs/mobile/shared/features/profile-menu-sheet/src/lib/component.tsx @@ -16,9 +16,14 @@ import { ToastService } from '@open-webui-react-native/shared/utils/toast-servic interface ProfileMenuSheetProps extends Pick { onArchivedChatsPress: () => void; + onSettingsPress: () => void; } -export function ProfileMenuSheet({ onArchivedChatsPress, ...restProps }: ProfileMenuSheetProps): ReactElement { +export function ProfileMenuSheet({ + onArchivedChatsPress, + onSettingsPress, + ...restProps +}: ProfileMenuSheetProps): ReactElement { const translate = useTranslation('PROFILE.PROFILE_MENU_SHEET'); const { logout, isLoading } = useLogout(); @@ -37,6 +42,11 @@ export function ProfileMenuSheet({ onArchivedChatsPress, ...restProps }: Profile onArchivedChatsPress(); }; + const handleSettingsPress = async (): Promise => { + await closeActionsSheet(); + onSettingsPress(); + }; + const handleDeleteAccountPress = (): void => { ToastService.show(translate('TEXT_ACCOUNT_DELETION_REQUEST')); }; @@ -57,6 +67,11 @@ export function ProfileMenuSheet({ onArchivedChatsPress, ...restProps }: Profile }; const actions: Array = [ + { + title: translate('TEXT_SETTINGS'), + iconName: 'moreDots', + onPress: handleSettingsPress, + }, { title: translate('TEXT_ARCHIVED_CHATS'), iconName: 'archive', diff --git a/libs/mobile/shared/utils/navigation/src/lib/config.ts b/libs/mobile/shared/utils/navigation/src/lib/config.ts index b54a31ad..523aafa4 100644 --- a/libs/mobile/shared/utils/navigation/src/lib/config.ts +++ b/libs/mobile/shared/utils/navigation/src/lib/config.ts @@ -20,6 +20,7 @@ export const navigationConfig = { }, main: { root: groups.main, + settings: 'settings', chat: { index: prefixes.chat, create: 'create', From 9dd3d72e31513aec4c7c69d754325e981edd37a6 Mon Sep 17 00:00:00 2001 From: Mikhail Leonov Date: Thu, 13 Aug 2026 13:26:34 +0600 Subject: [PATCH 2/3] feat: enhance locale management --- apps/mobile/app/(main)/settings.tsx | 33 ++++++++++++++++--- apps/mobile/app/_layout.tsx | 5 +-- apps/mobile/package.json | 2 +- apps/mobile/tsconfig.app.json | 2 +- i18n/mobile/app/en.json | 4 +++ .../shared/data-access/app-state/src/state.ts | 16 +++++++++ .../shared/data-access/storage/src/service.ts | 1 + libs/shared/utils/config/src/constants.ts | 2 ++ libs/shared/utils/config/src/index.ts | 1 + nativewind-env.d.ts | 2 +- package-lock.json | 10 +++--- package.json | 2 +- tsconfig.base.json | 1 + 13 files changed, 65 insertions(+), 16 deletions(-) diff --git a/apps/mobile/app/(main)/settings.tsx b/apps/mobile/app/(main)/settings.tsx index 28a35a4f..6e4a1098 100644 --- a/apps/mobile/app/(main)/settings.tsx +++ b/apps/mobile/app/(main)/settings.tsx @@ -1,20 +1,43 @@ -import { AppHeader, AppScreen, AppText } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; +import { Host, Picker } from '@expo/ui'; +import { useSelector } from '@legendapp/state/react'; +import { useColorScheme } from '@open-webui-react-native/mobile/shared/ui/styles'; +import { AppHeader, AppScreen, AppText, View } from '@open-webui-react-native/mobile/shared/ui/ui-kit'; +import { appState$ } from '@open-webui-react-native/shared/data-access/app-state'; +import { availableLanguages, LanguageCode } from '@open-webui-react-native/shared/utils/config'; +import { useTranslation } from '@ronas-it/react-native-common-modules/i18n'; import { useRouter } from 'expo-router'; import { ReactElement } from 'react'; // TODO: Temporary solution, update when design is ready export default function SettingsScreen(): ReactElement { const router = useRouter(); + const translate = useTranslation('APP.SETTINGS_SCREEN'); + const { colorScheme } = useColorScheme(); + const locale = useSelector(appState$.locale); + + const handleLanguageChange = (value: LanguageCode): void => { + appState$.setLocale(value); + }; return ( }> - Settings + + {translate('TEXT_LANGUAGE')} + + + {availableLanguages.map(({ code, label }) => ( + + ))} + + + ); } diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index 71483368..adcd81c2 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -101,7 +101,8 @@ function App(): ReactElement | null { } function RootLayout(): ReactElement | null { - useLanguage(constants.defaultLocale); + const locale = useSelector(appState$.locale); + useLanguage(locale); const [isFontsLoaded] = useFonts(fonts); const navigationContainerRef = useNavigationContainerRef(); @@ -136,7 +137,7 @@ function RootLayout(): ReactElement | null { }}> - + diff --git a/apps/mobile/package.json b/apps/mobile/package.json index 85f4a159..feeaeb4a 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -27,7 +27,7 @@ "@amplitude/analytics-react-native": "^1.6.8", "@expo/metro-config": "~57.0.0", "@expo/metro-runtime": "~57.0.7", - "@expo/ui": "~57.0.7", + "@expo/ui": "~57.0.10", "@gorhom/bottom-sheet": "^5.2.8", "@hookform/resolvers": "^5.1.1", "@legendapp/state": "2.1.15", diff --git a/apps/mobile/tsconfig.app.json b/apps/mobile/tsconfig.app.json index 6abaddde..087814e4 100644 --- a/apps/mobile/tsconfig.app.json +++ b/apps/mobile/tsconfig.app.json @@ -4,7 +4,7 @@ "outDir": "../../dist/out-tsc", "types": ["node"] }, - "files": ["../../node_modules/@nx/expo/typings/svg.d.ts"], + "files": ["../../node_modules/@nx/expo/typings/svg.d.ts", "./nativewind-env.d.ts"], "exclude": ["jest.config.ts", "**/*.spec.ts", "**/*.spec.tsx", "test-setup.ts"], "include": ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"] } diff --git a/i18n/mobile/app/en.json b/i18n/mobile/app/en.json index f1f752b7..2216c307 100644 --- a/i18n/mobile/app/en.json +++ b/i18n/mobile/app/en.json @@ -2,6 +2,10 @@ "APP": { "CHAT_LIST_SCREEN": { "TEXT_CHATS": "Chats" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "Settings", + "TEXT_LANGUAGE": "Language" } } } diff --git a/libs/shared/data-access/app-state/src/state.ts b/libs/shared/data-access/app-state/src/state.ts index fb5eb4f6..ed3db746 100644 --- a/libs/shared/data-access/app-state/src/state.ts +++ b/libs/shared/data-access/app-state/src/state.ts @@ -2,12 +2,23 @@ import { observable, Observable } from '@legendapp/state'; import { authState$ } from '@open-webui-react-native/shared/data-access/auth'; import { cookieService } from '@open-webui-react-native/shared/data-access/cookie'; import { appStorageService } from '@open-webui-react-native/shared/data-access/storage'; +import { constants, LanguageCode } from '@open-webui-react-native/shared/utils/config'; + +const getInitialLocale = (): LanguageCode => { + const storedLocale = appStorageService.locale.get(); + + return Object.values(LanguageCode).includes(storedLocale as LanguageCode) + ? (storedLocale as LanguageCode) + : constants.defaultLocale; +}; interface AppState { init: () => Promise; isInitialLoadingFinished: boolean; setIsOfflineMode: (isConnected: boolean) => void; isOfflineMode: boolean; + locale: LanguageCode; + setLocale: (locale: LanguageCode) => void; } export const appState$: Observable = observable({ @@ -24,6 +35,11 @@ export const appState$: Observable = observable({ setIsOfflineMode: (isOffline) => { appState$.isOfflineMode.set(isOffline); }, + setLocale: (locale) => { + appStorageService.locale.set(locale); + appState$.locale.set(locale); + }, isInitialLoadingFinished: false, isOfflineMode: false, + locale: getInitialLocale(), }); diff --git a/libs/shared/data-access/storage/src/service.ts b/libs/shared/data-access/storage/src/service.ts index d9c3e018..9fc4bdc3 100644 --- a/libs/shared/data-access/storage/src/service.ts +++ b/libs/shared/data-access/storage/src/service.ts @@ -11,6 +11,7 @@ export const storage = new MMKV({ class AppStorageService { public token = new StorageItem('token', storage); public apiUrl = new StorageItem('apiUrl', storage); + public locale = new StorageItem('locale', storage); } export const appStorageService = new AppStorageService(); diff --git a/libs/shared/utils/config/src/constants.ts b/libs/shared/utils/config/src/constants.ts index 32d9654b..83a19217 100644 --- a/libs/shared/utils/config/src/constants.ts +++ b/libs/shared/utils/config/src/constants.ts @@ -3,3 +3,5 @@ import { LanguageCode } from './enums'; export const constants = { defaultLocale: LanguageCode.ENGLISH, }; + +export const availableLanguages = [{ code: LanguageCode.ENGLISH, label: 'English' }] as const; diff --git a/libs/shared/utils/config/src/index.ts b/libs/shared/utils/config/src/index.ts index 2cd9434d..a9e57dce 100644 --- a/libs/shared/utils/config/src/index.ts +++ b/libs/shared/utils/config/src/index.ts @@ -1,2 +1,3 @@ export * from './constants'; +export * from './enums'; export * from './get-api-url'; diff --git a/nativewind-env.d.ts b/nativewind-env.d.ts index e1b556fa..533ae610 100644 --- a/nativewind-env.d.ts +++ b/nativewind-env.d.ts @@ -1,4 +1,4 @@ /// // NOTE: This file should not be edited and should be committed with your source code. It is generated by NativeWind. -declare module '*.css'; +declare module '*.css' {} diff --git a/package-lock.json b/package-lock.json index 08e46c13..c094c0cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,7 +16,7 @@ "@amplitude/analytics-react-native": "^1.6.8", "@expo/metro-config": "~57.0.0", "@expo/metro-runtime": "~57.0.7", - "@expo/ui": "~57.0.7", + "@expo/ui": "~57.0.10", "@gorhom/bottom-sheet": "^5.2.8", "@hookform/resolvers": "^5.1.1", "@legendapp/state": "2.1.15", @@ -174,7 +174,7 @@ "@amplitude/analytics-react-native": "^1.6.8", "@expo/metro-config": "~57.0.0", "@expo/metro-runtime": "~57.0.7", - "@expo/ui": "~57.0.7", + "@expo/ui": "~57.0.10", "@gorhom/bottom-sheet": "^5.2.8", "@hookform/resolvers": "^5.1.1", "@legendapp/state": "2.1.15", @@ -4608,9 +4608,9 @@ "license": "MIT" }, "node_modules/@expo/ui": { - "version": "57.0.7", - "resolved": "https://registry.npmjs.org/@expo/ui/-/ui-57.0.7.tgz", - "integrity": "sha512-WqRVabl8VpHf3+YLHVjUy7PMIuXXI6DG88Vgmavro7Nd8Ks13h9sEJH/RLSCaJE2daVnqzEKY1v797BibuY9aw==", + "version": "57.0.10", + "resolved": "https://registry.npmjs.org/@expo/ui/-/ui-57.0.10.tgz", + "integrity": "sha512-cYVo6R6JmJgza2p1jyE1lGfNPWncHJGWRxhTyOi+pLRAAdiwo8Z2LcdaArewEXVUwJTQhczLRxeXGL0i99NUwQ==", "license": "MIT", "dependencies": { "sf-symbols-typescript": "^2.1.0", diff --git a/package.json b/package.json index 2f35cda8..4bf58fc7 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "@amplitude/analytics-react-native": "^1.6.8", "@expo/metro-config": "~57.0.0", "@expo/metro-runtime": "~57.0.7", - "@expo/ui": "~57.0.7", + "@expo/ui": "~57.0.10", "@gorhom/bottom-sheet": "^5.2.8", "@hookform/resolvers": "^5.1.1", "@legendapp/state": "2.1.15", diff --git a/tsconfig.base.json b/tsconfig.base.json index 7c830cb1..0137c959 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -24,6 +24,7 @@ "ignoreDeprecations": "6.0", "baseUrl": ".", "paths": { + "@expo/ui": ["node_modules/@expo/ui/build/universal/index.d.ts"], "@open-webui-react-native/mobile/auth/features/email-sign-in-form": [ "libs/mobile/auth/features/email-sign-in-form/src/index.ts" ], From 30c3b60913c934720b4fd258040005adfa90ab31 Mon Sep 17 00:00:00 2001 From: Mikhail Leonov Date: Thu, 13 Aug 2026 14:04:19 +0600 Subject: [PATCH 3/3] feat: add support for multiple languages and improve locale detection --- apps/mobile/app/_layout.tsx | 68 ++++++- apps/mobile/package.json | 1 + i18n/mobile/app/de.json | 11 ++ i18n/mobile/app/es.json | 11 ++ i18n/mobile/app/fr.json | 11 ++ i18n/mobile/app/ja.json | 11 ++ i18n/mobile/app/pt.json | 11 ++ i18n/mobile/app/ru.json | 11 ++ i18n/mobile/app/zh.json | 11 ++ i18n/mobile/auth/de.json | 25 +++ i18n/mobile/auth/es.json | 25 +++ i18n/mobile/auth/fr.json | 25 +++ i18n/mobile/auth/ja.json | 25 +++ i18n/mobile/auth/pt.json | 25 +++ i18n/mobile/auth/ru.json | 25 +++ i18n/mobile/auth/zh.json | 25 +++ i18n/mobile/chat/de.json | 168 +++++++++++++++++ i18n/mobile/chat/es.json | 168 +++++++++++++++++ i18n/mobile/chat/fr.json | 168 +++++++++++++++++ i18n/mobile/chat/ja.json | 167 +++++++++++++++++ i18n/mobile/chat/pt.json | 168 +++++++++++++++++ i18n/mobile/chat/ru.json | 169 ++++++++++++++++++ i18n/mobile/chat/zh.json | 167 +++++++++++++++++ i18n/mobile/folder/de.json | 36 ++++ i18n/mobile/folder/es.json | 36 ++++ i18n/mobile/folder/fr.json | 36 ++++ i18n/mobile/folder/ja.json | 36 ++++ i18n/mobile/folder/pt.json | 36 ++++ i18n/mobile/folder/ru.json | 36 ++++ i18n/mobile/folder/zh.json | 36 ++++ i18n/mobile/profile/de.json | 15 ++ i18n/mobile/profile/es.json | 15 ++ i18n/mobile/profile/fr.json | 15 ++ i18n/mobile/profile/ja.json | 15 ++ i18n/mobile/profile/pt.json | 15 ++ i18n/mobile/profile/ru.json | 15 ++ i18n/mobile/profile/zh.json | 15 ++ i18n/mobile/shared/de.json | 108 +++++++++++ i18n/mobile/shared/es.json | 108 +++++++++++ i18n/mobile/shared/fr.json | 108 +++++++++++ i18n/mobile/shared/ja.json | 108 +++++++++++ i18n/mobile/shared/pt.json | 108 +++++++++++ i18n/mobile/shared/ru.json | 108 +++++++++++ i18n/mobile/shared/zh.json | 108 +++++++++++ .../shared/data-access/app-state/src/state.ts | 14 +- libs/shared/utils/config/src/constants.ts | 11 +- .../utils/config/src/enums/language-code.ts | 7 + nativewind-env.d.ts | 2 +- package-lock.json | 1 + package.json | 1 + 50 files changed, 2637 insertions(+), 8 deletions(-) create mode 100644 i18n/mobile/app/de.json create mode 100644 i18n/mobile/app/es.json create mode 100644 i18n/mobile/app/fr.json create mode 100644 i18n/mobile/app/ja.json create mode 100644 i18n/mobile/app/pt.json create mode 100644 i18n/mobile/app/ru.json create mode 100644 i18n/mobile/app/zh.json create mode 100644 i18n/mobile/auth/de.json create mode 100644 i18n/mobile/auth/es.json create mode 100644 i18n/mobile/auth/fr.json create mode 100644 i18n/mobile/auth/ja.json create mode 100644 i18n/mobile/auth/pt.json create mode 100644 i18n/mobile/auth/ru.json create mode 100644 i18n/mobile/auth/zh.json create mode 100644 i18n/mobile/chat/de.json create mode 100644 i18n/mobile/chat/es.json create mode 100644 i18n/mobile/chat/fr.json create mode 100644 i18n/mobile/chat/ja.json create mode 100644 i18n/mobile/chat/pt.json create mode 100644 i18n/mobile/chat/ru.json create mode 100644 i18n/mobile/chat/zh.json create mode 100644 i18n/mobile/folder/de.json create mode 100644 i18n/mobile/folder/es.json create mode 100644 i18n/mobile/folder/fr.json create mode 100644 i18n/mobile/folder/ja.json create mode 100644 i18n/mobile/folder/pt.json create mode 100644 i18n/mobile/folder/ru.json create mode 100644 i18n/mobile/folder/zh.json create mode 100644 i18n/mobile/profile/de.json create mode 100644 i18n/mobile/profile/es.json create mode 100644 i18n/mobile/profile/fr.json create mode 100644 i18n/mobile/profile/ja.json create mode 100644 i18n/mobile/profile/pt.json create mode 100644 i18n/mobile/profile/ru.json create mode 100644 i18n/mobile/profile/zh.json create mode 100644 i18n/mobile/shared/de.json create mode 100644 i18n/mobile/shared/es.json create mode 100644 i18n/mobile/shared/fr.json create mode 100644 i18n/mobile/shared/ja.json create mode 100644 i18n/mobile/shared/pt.json create mode 100644 i18n/mobile/shared/ru.json create mode 100644 i18n/mobile/shared/zh.json diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index adcd81c2..23138d81 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -15,14 +15,16 @@ import { queryClient } from '@open-webui-react-native/shared/data-access/query-c import { useSocket } from '@open-webui-react-native/shared/data-access/websocket'; import { useNetworkConnection } from '@open-webui-react-native/shared/features/network'; import { analyticsService } from '@open-webui-react-native/shared/utils/analytics-service'; -import { constants } from '@open-webui-react-native/shared/utils/config'; +import { constants, LanguageCode } from '@open-webui-react-native/shared/utils/config'; import { setupReactotron } from '@open-webui-react-native/shared/utils/reactotron'; -import { setLanguage } from '@ronas-it/react-native-common-modules/i18n'; +import { i18n, setLanguage } from '@ronas-it/react-native-common-modules/i18n'; import * as Sentry from '@sentry/react-native'; import { PersistQueryClientProvider } from '@tanstack/react-query-persist-client'; import Constants from 'expo-constants'; import { useFonts } from 'expo-font'; import { SplashScreen, Stack, useNavigationContainerRef } from 'expo-router'; +import { useMakePlural } from 'i18n-js'; +import { de, en, es, fr, ja, pt, ru, zh } from 'make-plural'; import { ReactElement, useEffect } from 'react'; import { GestureHandlerRootView } from 'react-native-gesture-handler'; import { KeyboardProvider } from 'react-native-keyboard-controller'; @@ -44,7 +46,7 @@ Sentry.init({ }); const translations = { - [constants.defaultLocale]: { + [LanguageCode.ENGLISH]: { ...require('i18n/mobile/app/en.json'), ...require('i18n/mobile/shared/en.json'), ...require('i18n/mobile/auth/en.json'), @@ -52,8 +54,68 @@ const translations = { ...require('i18n/mobile/profile/en.json'), ...require('i18n/mobile/folder/en.json'), }, + [LanguageCode.RUSSIAN]: { + ...require('i18n/mobile/app/ru.json'), + ...require('i18n/mobile/shared/ru.json'), + ...require('i18n/mobile/auth/ru.json'), + ...require('i18n/mobile/chat/ru.json'), + ...require('i18n/mobile/profile/ru.json'), + ...require('i18n/mobile/folder/ru.json'), + }, + [LanguageCode.SPANISH]: { + ...require('i18n/mobile/app/es.json'), + ...require('i18n/mobile/shared/es.json'), + ...require('i18n/mobile/auth/es.json'), + ...require('i18n/mobile/chat/es.json'), + ...require('i18n/mobile/profile/es.json'), + ...require('i18n/mobile/folder/es.json'), + }, + [LanguageCode.PORTUGUESE]: { + ...require('i18n/mobile/app/pt.json'), + ...require('i18n/mobile/shared/pt.json'), + ...require('i18n/mobile/auth/pt.json'), + ...require('i18n/mobile/chat/pt.json'), + ...require('i18n/mobile/profile/pt.json'), + ...require('i18n/mobile/folder/pt.json'), + }, + [LanguageCode.FRENCH]: { + ...require('i18n/mobile/app/fr.json'), + ...require('i18n/mobile/shared/fr.json'), + ...require('i18n/mobile/auth/fr.json'), + ...require('i18n/mobile/chat/fr.json'), + ...require('i18n/mobile/profile/fr.json'), + ...require('i18n/mobile/folder/fr.json'), + }, + [LanguageCode.GERMAN]: { + ...require('i18n/mobile/app/de.json'), + ...require('i18n/mobile/shared/de.json'), + ...require('i18n/mobile/auth/de.json'), + ...require('i18n/mobile/chat/de.json'), + ...require('i18n/mobile/profile/de.json'), + ...require('i18n/mobile/folder/de.json'), + }, + [LanguageCode.CHINESE]: { + ...require('i18n/mobile/app/zh.json'), + ...require('i18n/mobile/shared/zh.json'), + ...require('i18n/mobile/auth/zh.json'), + ...require('i18n/mobile/chat/zh.json'), + ...require('i18n/mobile/profile/zh.json'), + ...require('i18n/mobile/folder/zh.json'), + }, + [LanguageCode.JAPANESE]: { + ...require('i18n/mobile/app/ja.json'), + ...require('i18n/mobile/shared/ja.json'), + ...require('i18n/mobile/auth/ja.json'), + ...require('i18n/mobile/chat/ja.json'), + ...require('i18n/mobile/profile/ja.json'), + ...require('i18n/mobile/folder/ja.json'), + }, }; +Object.entries({ en, ru, es, pt, fr, de, zh, ja }).forEach(([locale, pluralizer]) => { + i18n.pluralization.register(locale, useMakePlural({ pluralizer })); +}); + const useLanguage = setLanguage(translations, constants.defaultLocale); setupReactotron('open-web-ui'); diff --git a/apps/mobile/package.json b/apps/mobile/package.json index feeaeb4a..a5d6b31a 100644 --- a/apps/mobile/package.json +++ b/apps/mobile/package.json @@ -80,6 +80,7 @@ "immer": "^10.1.1", "lodash-es": "^4.17.21", "luxon": "^3.6.1", + "make-plural": "^7.5.0", "markdown-it-math": "^5.2.1", "nativewind": "^4.1.23", "patch-package": "^8.0.0", diff --git a/i18n/mobile/app/de.json b/i18n/mobile/app/de.json new file mode 100644 index 00000000..f58c4f2d --- /dev/null +++ b/i18n/mobile/app/de.json @@ -0,0 +1,11 @@ +{ + "APP": { + "CHAT_LIST_SCREEN": { + "TEXT_CHATS": "Chats" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "Einstellungen", + "TEXT_LANGUAGE": "Sprache" + } + } +} diff --git a/i18n/mobile/app/es.json b/i18n/mobile/app/es.json new file mode 100644 index 00000000..4b8fa5cf --- /dev/null +++ b/i18n/mobile/app/es.json @@ -0,0 +1,11 @@ +{ + "APP": { + "CHAT_LIST_SCREEN": { + "TEXT_CHATS": "Chats" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "Ajustes", + "TEXT_LANGUAGE": "Idioma" + } + } +} diff --git a/i18n/mobile/app/fr.json b/i18n/mobile/app/fr.json new file mode 100644 index 00000000..3af7acbb --- /dev/null +++ b/i18n/mobile/app/fr.json @@ -0,0 +1,11 @@ +{ + "APP": { + "CHAT_LIST_SCREEN": { + "TEXT_CHATS": "Discussions" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "Paramètres", + "TEXT_LANGUAGE": "Langue" + } + } +} diff --git a/i18n/mobile/app/ja.json b/i18n/mobile/app/ja.json new file mode 100644 index 00000000..41108386 --- /dev/null +++ b/i18n/mobile/app/ja.json @@ -0,0 +1,11 @@ +{ + "APP": { + "CHAT_LIST_SCREEN": { + "TEXT_CHATS": "チャット" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "設定", + "TEXT_LANGUAGE": "言語" + } + } +} diff --git a/i18n/mobile/app/pt.json b/i18n/mobile/app/pt.json new file mode 100644 index 00000000..e068b2c6 --- /dev/null +++ b/i18n/mobile/app/pt.json @@ -0,0 +1,11 @@ +{ + "APP": { + "CHAT_LIST_SCREEN": { + "TEXT_CHATS": "Chats" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "Configurações", + "TEXT_LANGUAGE": "Idioma" + } + } +} diff --git a/i18n/mobile/app/ru.json b/i18n/mobile/app/ru.json new file mode 100644 index 00000000..94a65a9b --- /dev/null +++ b/i18n/mobile/app/ru.json @@ -0,0 +1,11 @@ +{ + "APP": { + "CHAT_LIST_SCREEN": { + "TEXT_CHATS": "Чаты" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "Настройки", + "TEXT_LANGUAGE": "Язык" + } + } +} diff --git a/i18n/mobile/app/zh.json b/i18n/mobile/app/zh.json new file mode 100644 index 00000000..d6e3c566 --- /dev/null +++ b/i18n/mobile/app/zh.json @@ -0,0 +1,11 @@ +{ + "APP": { + "CHAT_LIST_SCREEN": { + "TEXT_CHATS": "聊天" + }, + "SETTINGS_SCREEN": { + "TEXT_SETTINGS": "设置", + "TEXT_LANGUAGE": "语言" + } + } +} diff --git a/i18n/mobile/auth/de.json b/i18n/mobile/auth/de.json new file mode 100644 index 00000000..1c503583 --- /dev/null +++ b/i18n/mobile/auth/de.json @@ -0,0 +1,25 @@ +{ + "AUTH": { + "SIGN_IN": { + "TEXT_TITLE_EXTERNAL": "Anmelden", + "TEXT_YOU_LOGGED_IN": "Sie sind jetzt angemeldet.", + "EMAIL_FORM": { + "TEXT_EMAIL_ADDRESS": "E-Mail-Adresse", + "TEXT_PASSWORD": "Passwort", + "TEXT_API_URL": "API-URL", + "TEXT_ENTER_YOUR_PASSWORD": "Passwort eingeben", + "BUTTON_SIGN_IN": "Anmelden" + }, + "GOOGLE_FORM": { + "BUTTON_CONTINUE_WITH_GOOGLE": "Mit Google fortfahren" + }, + "OIDC_FORM": { + "BUTTON_CONTINUE_WITH": "Mit {{provider}} fortfahren" + }, + "OAUTH_WEB_VIEW_MODAL": { + "BUTTON_CLOSE": "Schließen", + "TEXT_THIS_SIGN_IN_METHOD_IS_UNAVAILABLE": "Diese Anmeldemethode ist nicht verfügbar. Bitte wählen Sie eine andere Option." + } + } + } +} diff --git a/i18n/mobile/auth/es.json b/i18n/mobile/auth/es.json new file mode 100644 index 00000000..3cf508cf --- /dev/null +++ b/i18n/mobile/auth/es.json @@ -0,0 +1,25 @@ +{ + "AUTH": { + "SIGN_IN": { + "TEXT_TITLE_EXTERNAL": "Iniciar sesión", + "TEXT_YOU_LOGGED_IN": "Has iniciado sesión.", + "EMAIL_FORM": { + "TEXT_EMAIL_ADDRESS": "Correo electrónico", + "TEXT_PASSWORD": "Contraseña", + "TEXT_API_URL": "URL de la API", + "TEXT_ENTER_YOUR_PASSWORD": "Introduce tu contraseña", + "BUTTON_SIGN_IN": "Iniciar sesión" + }, + "GOOGLE_FORM": { + "BUTTON_CONTINUE_WITH_GOOGLE": "Continuar con Google" + }, + "OIDC_FORM": { + "BUTTON_CONTINUE_WITH": "Continuar con {{provider}}" + }, + "OAUTH_WEB_VIEW_MODAL": { + "BUTTON_CLOSE": "Cerrar", + "TEXT_THIS_SIGN_IN_METHOD_IS_UNAVAILABLE": "Este método de inicio de sesión no está disponible. Usa otra opción para continuar." + } + } + } +} diff --git a/i18n/mobile/auth/fr.json b/i18n/mobile/auth/fr.json new file mode 100644 index 00000000..b72185d9 --- /dev/null +++ b/i18n/mobile/auth/fr.json @@ -0,0 +1,25 @@ +{ + "AUTH": { + "SIGN_IN": { + "TEXT_TITLE_EXTERNAL": "Connexion", + "TEXT_YOU_LOGGED_IN": "Vous êtes maintenant connecté.", + "EMAIL_FORM": { + "TEXT_EMAIL_ADDRESS": "Adresse e-mail", + "TEXT_PASSWORD": "Mot de passe", + "TEXT_API_URL": "URL de l’API", + "TEXT_ENTER_YOUR_PASSWORD": "Entrez votre mot de passe", + "BUTTON_SIGN_IN": "Se connecter" + }, + "GOOGLE_FORM": { + "BUTTON_CONTINUE_WITH_GOOGLE": "Continuer avec Google" + }, + "OIDC_FORM": { + "BUTTON_CONTINUE_WITH": "Continuer avec {{provider}}" + }, + "OAUTH_WEB_VIEW_MODAL": { + "BUTTON_CLOSE": "Fermer", + "TEXT_THIS_SIGN_IN_METHOD_IS_UNAVAILABLE": "Cette méthode de connexion est indisponible. Veuillez utiliser une autre option." + } + } + } +} diff --git a/i18n/mobile/auth/ja.json b/i18n/mobile/auth/ja.json new file mode 100644 index 00000000..67a2dc7a --- /dev/null +++ b/i18n/mobile/auth/ja.json @@ -0,0 +1,25 @@ +{ + "AUTH": { + "SIGN_IN": { + "TEXT_TITLE_EXTERNAL": "サインイン", + "TEXT_YOU_LOGGED_IN": "ログインしました。", + "EMAIL_FORM": { + "TEXT_EMAIL_ADDRESS": "メールアドレス", + "TEXT_PASSWORD": "パスワード", + "TEXT_API_URL": "API URL", + "TEXT_ENTER_YOUR_PASSWORD": "パスワードを入力", + "BUTTON_SIGN_IN": "サインイン" + }, + "GOOGLE_FORM": { + "BUTTON_CONTINUE_WITH_GOOGLE": "Google で続行" + }, + "OIDC_FORM": { + "BUTTON_CONTINUE_WITH": "{{provider}} で続行" + }, + "OAUTH_WEB_VIEW_MODAL": { + "BUTTON_CLOSE": "閉じる", + "TEXT_THIS_SIGN_IN_METHOD_IS_UNAVAILABLE": "このサインイン方法は利用できません。別の方法をお試しください。" + } + } + } +} diff --git a/i18n/mobile/auth/pt.json b/i18n/mobile/auth/pt.json new file mode 100644 index 00000000..b908606e --- /dev/null +++ b/i18n/mobile/auth/pt.json @@ -0,0 +1,25 @@ +{ + "AUTH": { + "SIGN_IN": { + "TEXT_TITLE_EXTERNAL": "Entrar", + "TEXT_YOU_LOGGED_IN": "Você entrou na sua conta.", + "EMAIL_FORM": { + "TEXT_EMAIL_ADDRESS": "Endereço de e-mail", + "TEXT_PASSWORD": "Senha", + "TEXT_API_URL": "URL da API", + "TEXT_ENTER_YOUR_PASSWORD": "Digite sua senha", + "BUTTON_SIGN_IN": "Entrar" + }, + "GOOGLE_FORM": { + "BUTTON_CONTINUE_WITH_GOOGLE": "Continuar com o Google" + }, + "OIDC_FORM": { + "BUTTON_CONTINUE_WITH": "Continuar com {{provider}}" + }, + "OAUTH_WEB_VIEW_MODAL": { + "BUTTON_CLOSE": "Fechar", + "TEXT_THIS_SIGN_IN_METHOD_IS_UNAVAILABLE": "Este método de login não está disponível. Use outra opção para continuar." + } + } + } +} diff --git a/i18n/mobile/auth/ru.json b/i18n/mobile/auth/ru.json new file mode 100644 index 00000000..993cbbc3 --- /dev/null +++ b/i18n/mobile/auth/ru.json @@ -0,0 +1,25 @@ +{ + "AUTH": { + "SIGN_IN": { + "TEXT_TITLE_EXTERNAL": "Вход", + "TEXT_YOU_LOGGED_IN": "Вы вошли в систему.", + "EMAIL_FORM": { + "TEXT_EMAIL_ADDRESS": "Адрес электронной почты", + "TEXT_PASSWORD": "Пароль", + "TEXT_API_URL": "API URL", + "TEXT_ENTER_YOUR_PASSWORD": "Введите пароль", + "BUTTON_SIGN_IN": "Войти" + }, + "GOOGLE_FORM": { + "BUTTON_CONTINUE_WITH_GOOGLE": "Продолжить с Google" + }, + "OIDC_FORM": { + "BUTTON_CONTINUE_WITH": "Продолжить с {{provider}}" + }, + "OAUTH_WEB_VIEW_MODAL": { + "BUTTON_CLOSE": "Закрыть", + "TEXT_THIS_SIGN_IN_METHOD_IS_UNAVAILABLE": "Этот способ входа недоступен. Пожалуйста, выберите другой вариант." + } + } + } +} diff --git a/i18n/mobile/auth/zh.json b/i18n/mobile/auth/zh.json new file mode 100644 index 00000000..eb23ec01 --- /dev/null +++ b/i18n/mobile/auth/zh.json @@ -0,0 +1,25 @@ +{ + "AUTH": { + "SIGN_IN": { + "TEXT_TITLE_EXTERNAL": "登录", + "TEXT_YOU_LOGGED_IN": "您已成功登录。", + "EMAIL_FORM": { + "TEXT_EMAIL_ADDRESS": "电子邮箱", + "TEXT_PASSWORD": "密码", + "TEXT_API_URL": "API 地址", + "TEXT_ENTER_YOUR_PASSWORD": "请输入密码", + "BUTTON_SIGN_IN": "登录" + }, + "GOOGLE_FORM": { + "BUTTON_CONTINUE_WITH_GOOGLE": "使用 Google 继续" + }, + "OIDC_FORM": { + "BUTTON_CONTINUE_WITH": "使用 {{provider}} 继续" + }, + "OAUTH_WEB_VIEW_MODAL": { + "BUTTON_CLOSE": "关闭", + "TEXT_THIS_SIGN_IN_METHOD_IS_UNAVAILABLE": "此登录方式不可用。请使用其他方式继续。" + } + } + } +} diff --git a/i18n/mobile/chat/de.json b/i18n/mobile/chat/de.json new file mode 100644 index 00000000..58a668a4 --- /dev/null +++ b/i18n/mobile/chat/de.json @@ -0,0 +1,168 @@ +{ + "CHAT": { + "CHAT_SCREEN": { + "TEXT_LOADING": "Wird geladen...", + "TEXT_SELECT_A_MODEL": "Modell auswählen" + }, + "CHAT": { + "TEXT_INPUT_PLACEHOLDER": "Nachricht senden", + "TEXT_MODEL_NOT_SELECTED": "Kein Modell ausgewählt" + }, + "CHAT_MENU_LIST": { + "PINNED_CHAT_LIST": { + "TEXT_PINNED": "Angepinnt" + }, + "TEXT_NEW_CHAT": "Neuer Chat", + "TEXT_SEARCH": "Suchen", + "TEXT_THERE_ARE_NO_CHATS": "Es gibt keine Chats" + }, + "SEARCH_CHATS_LIST": { + "TEXT_THERE_ARE_NO_CHATS": "Es gibt keine Chats" + }, + "FORM_CHAT_INPUT": { + "TEXT_MODEL_NOT_SELECTED": "Kein Modell ausgewählt", + "ATTACHMENTS_ACTIONS_POPUP": { + "TEXT_CAPTURE": "Aufnehmen", + "TEXT_CHOOSE_FROM_GALLERY": "Aus Galerie wählen", + "TEXT_UPLOAD_FILES": "Dateien hochladen", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Sie können keine leere Datei hochladen." + } + }, + "SHARE_CHAT_MODAL": { + "TEXT_SHARE_CHAT": "Chat teilen", + "TEXT_DESCRIPTION_NOT_SHARED": "Nachrichten, die Sie nach dem Erstellen des Links senden, werden nicht geteilt. Nutzer mit der URL können den geteilten Chat ansehen.", + "TEXT_DESCRIPTION_SHARED_1": "Sie haben diesen Chat geteilt", + "TEXT_BEFORE_LINK": "zuvor", + "TEXT_DESCRIPTION_SHARED_2": "Klicken Sie hier, um", + "TEXT_DELETE_LINK": "diesen Link zu löschen", + "TEXT_DESCRIPTION_SHARED_3": "und einen neuen geteilten Link zu erstellen.", + "BUTTON_COPY_LINK": "Link kopieren", + "BUTTON_UPDATE_AND_COPY_LINK": "Aktualisieren und Link kopieren", + "TEXT_LINK_COPIED": "Link in die Zwischenablage kopiert" + }, + "CREATE_CHAT": { + "TEXT_NEW_CHAT": "Neuer Chat", + "TEXT_PLACEHOLDER": "Wie kann ich Ihnen heute helfen?", + "TEXT_MODEL_NOT_SELECTED": "Kein Modell ausgewählt", + "TEXT_SELECT_A_MODEL": "Modell auswählen", + "SEARCH_MODEL_VIEW": { + "TEXT_SELECT_A_MODEL": "Modell auswählen", + "TEXT_SEARCH_MODEL": "Modell suchen" + }, + "SEARCH_FOLDER_VIEW": { + "TEXT_SEARCH_FOLDER": "Ordner suchen", + "TEXT_NO_FOLDER": "Kein Ordner", + "TEXT_CREATE_NEW_FOLDER": "Neuen Ordner erstellen" + }, + "SUGGESTIONS_LIST": { + "TEXT_SUGGESTED": "Vorschläge", + "TEXT_SUGGESTION_TITLE_1": "Hilf mir beim Lernen", + "TEXT_SUGGESTION_SUBTITLE_1": "Vokabeln für eine Aufnahmeprüfung", + "TEXT_SUGGESTION_CONTENT_1": "Hilf mir, Vokabeln zu lernen: Schreibe einen Satz mit einer Lücke, und ich versuche, die richtige Option zu wählen.", + "TEXT_SUGGESTION_TITLE_2": "Gib mir Ideen", + "TEXT_SUGGESTION_SUBTITLE_2": "was ich mit der Kunst meiner Kinder machen kann", + "TEXT_SUGGESTION_CONTENT_2": "Was sind 5 kreative Dinge, die ich mit der Kunst meiner Kinder machen könnte? Ich möchte sie nicht wegwerfen, aber sie nehmen auch so viel Platz ein.", + "TEXT_SUGGESTION_TITLE_3": "Erzähl mir eine Fun Fact", + "TEXT_SUGGESTION_SUBTITLE_3": "über das Römische Reich", + "TEXT_SUGGESTION_CONTENT_3": "Erzähl mir eine zufällige Fun Fact über das Römische Reich", + "TEXT_SUGGESTION_TITLE_4": "Zeig mir ein Code-Snippet", + "TEXT_SUGGESTION_SUBTITLE_4": "eines Sticky Headers einer Website", + "TEXT_SUGGESTION_CONTENT_4": "Zeig mir ein Code-Snippet eines Sticky Headers einer Website in CSS und JavaScript.", + "TEXT_SUGGESTION_TITLE_5": "Erkläre Optionshandel", + "TEXT_SUGGESTION_SUBTITLE_5": "wenn ich Aktienkauf und -verkauf kenne", + "TEXT_SUGGESTION_CONTENT_5": "Erkläre Optionshandel in einfachen Worten, wenn ich mit dem Kauf und Verkauf von Aktien vertraut bin.", + "TEXT_SUGGESTION_TITLE_6": "Prokrastination überwinden", + "TEXT_SUGGESTION_SUBTITLE_6": "gib mir Tipps", + "TEXT_SUGGESTION_CONTENT_6": "Könntest du zuerst nach Situationen fragen, in denen ich am meisten prokrastiniere, und mir dann einige Vorschläge geben, wie ich das überwinden kann?" + } + }, + "ATTACHED_FILE_ITEM": { + "TEXT_FILE": "Datei", + "TEXT_DOCUMENT": "Dokument", + "TEXT_COLLECTION": "Sammlung", + "FILE_INFO_MODAL": { + "TEXT_FORMATTING_DISCLAIMER": "Die Formatierung kann von der Quelle abweichen.", + "TEXT_NO_PREVIEW_AVAILABLE": "Keine Vorschau verfügbar", + "TEXT_EXTRACTED_LINES": { + "one": "{{count}} extrahierte Zeile", + "other": "{{count}} extrahierte Zeilen" + } + } + }, + "SOURCE_CITATION_MODAL": { + "TEXT_CITATION": "Zitat", + "TEXT_SOURCE": "Quelle", + "TEXT_RELEVANCE": "Relevanz", + "TEXT_CONTENT": "Inhalt", + "TEXT_NO_PREVIEW_AVAILABLE": "Keine Vorschau verfügbar" + }, + "ARCHIVED_CHATS_LIST": { + "TEXT_ARCHIVED_CHATS": "Archivierte Chats", + "TEXT_NO_CHATS": "Es gibt keine archivierten Chats.", + "CHAT_ITEM": { + "TEXT_DELETE_CHAT": "Chat löschen?", + "TEXT_THIS_WILL_DELETE": "Dadurch wird {{name}} gelöscht", + "TEXT_RESTORE": "Wiederherstellen", + "TEXT_EXPORT": "Exportieren", + "TEXT_DELETE": "Löschen", + "TEXT_KEEP": "Behalten" + }, + "ARCHIVED_CHATS_ACTIONS_SHEET": { + "TEXT_UNARCHIVE_CHATS": "Alle Chats aus dem Archiv holen?", + "TEXT_ARE_YOU_SURE": "Sind Sie sicher, dass Sie alle archivierten Chats aus dem Archiv holen möchten?", + "BUTTON_RESTORE_ALL_CHATS": "Alle Chats wiederherstellen", + "BUTTON_EXPORT_ALL_CHATS": "Alle Chats exportieren" + } + }, + "USER_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Bearbeiten", + "TEXT_COPY": "Kopieren" + }, + "AI_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Bearbeiten", + "TEXT_COPY": "Kopieren", + "TEXT_CONTINUE_RESPONSE": "Antwort fortsetzen", + "TEXT_REGENERATE": "Neu generieren", + "REGENERATE_MESSAGE_ACTION_SHEET": { + "TEXT_SUGGEST_A_CHANGE": "Änderung vorschlagen", + "TEXT_TRY_AGAIN": "Erneut versuchen", + "TEXT_ADD_DETAILS": "Details hinzufügen", + "TEXT_MORE_CONCISE": "Prägnanter" + } + }, + "EDIT_MESSAGE_INPUT": { + "TEXT_EDIT_MESSAGE": "Nachricht bearbeiten", + "BUTTON_SAVE": "Speichern", + "BUTTON_SAVE_AS_COPY": "Als Kopie speichern", + "BUTTON_SEND": "Senden", + "BUTTON_CANCEL": "Abbrechen" + }, + "SUGGEST_CHANGE_INPUT": { + "TEXT_SUGGEST_A_CHANGE": "Änderung vorschlagen", + "BUTTON_CANCEL": "Abbrechen" + }, + "ARCHIVED_CHATS_FILTERS_SHEET": { + "USE_SEARCH_FILTERS": { + "TEXT_MOST_RECENT": "Neueste", + "TEXT_OLDEST": "Älteste", + "TEXT_A-Z": "A-Z", + "TEXT_Z-A": "Z-A" + } + }, + "VOICE_MODE_MODAL": { + "TEXT_LISTENING": "Hört zu...", + "TEXT_THINKING": "Denkt nach...", + "TEXT_TALKING": "Spricht..." + }, + "MESSAGE_FOLLOW_UPS": { + "TEXT_FOLLOW_UP": "Nachfrage" + }, + "AI_MESSAGE": { + "TOOL_OUTPUT_SHEET": { + "TEXT_VIEW_RESULT_PREFIX": "Ergebnis anzeigen von", + "TEXT_INPUT": "Eingabe", + "TEXT_OUTPUT": "Ausgabe" + } + } + } +} diff --git a/i18n/mobile/chat/es.json b/i18n/mobile/chat/es.json new file mode 100644 index 00000000..5c4b823e --- /dev/null +++ b/i18n/mobile/chat/es.json @@ -0,0 +1,168 @@ +{ + "CHAT": { + "CHAT_SCREEN": { + "TEXT_LOADING": "Cargando...", + "TEXT_SELECT_A_MODEL": "Seleccionar un modelo" + }, + "CHAT": { + "TEXT_INPUT_PLACEHOLDER": "Enviar un mensaje", + "TEXT_MODEL_NOT_SELECTED": "Modelo no seleccionado" + }, + "CHAT_MENU_LIST": { + "PINNED_CHAT_LIST": { + "TEXT_PINNED": "Fijados" + }, + "TEXT_NEW_CHAT": "Nuevo chat", + "TEXT_SEARCH": "Buscar", + "TEXT_THERE_ARE_NO_CHATS": "No hay chats" + }, + "SEARCH_CHATS_LIST": { + "TEXT_THERE_ARE_NO_CHATS": "No hay chats" + }, + "FORM_CHAT_INPUT": { + "TEXT_MODEL_NOT_SELECTED": "Modelo no seleccionado", + "ATTACHMENTS_ACTIONS_POPUP": { + "TEXT_CAPTURE": "Capturar", + "TEXT_CHOOSE_FROM_GALLERY": "Elegir de la galería", + "TEXT_UPLOAD_FILES": "Subir archivos", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "No puedes subir un archivo vacío." + } + }, + "SHARE_CHAT_MODAL": { + "TEXT_SHARE_CHAT": "Compartir chat", + "TEXT_DESCRIPTION_NOT_SHARED": "Los mensajes que envíes después de crear el enlace no se compartirán. Los usuarios con la URL podrán ver el chat compartido.", + "TEXT_DESCRIPTION_SHARED_1": "Has compartido este chat", + "TEXT_BEFORE_LINK": "antes", + "TEXT_DESCRIPTION_SHARED_2": "Haz clic aquí para", + "TEXT_DELETE_LINK": "eliminar este enlace", + "TEXT_DESCRIPTION_SHARED_3": "y crear un nuevo enlace compartido.", + "BUTTON_COPY_LINK": "Copiar enlace", + "BUTTON_UPDATE_AND_COPY_LINK": "Actualizar y copiar enlace", + "TEXT_LINK_COPIED": "Enlace copiado al portapapeles" + }, + "CREATE_CHAT": { + "TEXT_NEW_CHAT": "Nuevo chat", + "TEXT_PLACEHOLDER": "¿En qué puedo ayudarte hoy?", + "TEXT_MODEL_NOT_SELECTED": "Modelo no seleccionado", + "TEXT_SELECT_A_MODEL": "Seleccionar un modelo", + "SEARCH_MODEL_VIEW": { + "TEXT_SELECT_A_MODEL": "Seleccionar un modelo", + "TEXT_SEARCH_MODEL": "Buscar modelo" + }, + "SEARCH_FOLDER_VIEW": { + "TEXT_SEARCH_FOLDER": "Buscar carpeta", + "TEXT_NO_FOLDER": "Sin carpeta", + "TEXT_CREATE_NEW_FOLDER": "Crear nueva carpeta" + }, + "SUGGESTIONS_LIST": { + "TEXT_SUGGESTED": "Sugerencias", + "TEXT_SUGGESTION_TITLE_1": "Ayúdame a estudiar", + "TEXT_SUGGESTION_SUBTITLE_1": "vocabulario para un examen de ingreso a la universidad", + "TEXT_SUGGESTION_CONTENT_1": "Ayúdame a estudiar vocabulario: escribe una oración con un espacio en blanco para que yo elija la opción correcta.", + "TEXT_SUGGESTION_TITLE_2": "Dame ideas", + "TEXT_SUGGESTION_SUBTITLE_2": "sobre qué hacer con el arte de mis hijos", + "TEXT_SUGGESTION_CONTENT_2": "¿Cuáles son 5 cosas creativas que podría hacer con el arte de mis hijos? No quiero tirarlo, pero también ocupa mucho espacio.", + "TEXT_SUGGESTION_TITLE_3": "Cuéntame un dato curioso", + "TEXT_SUGGESTION_SUBTITLE_3": "sobre el Imperio romano", + "TEXT_SUGGESTION_CONTENT_3": "Cuéntame un dato curioso aleatorio sobre el Imperio romano", + "TEXT_SUGGESTION_TITLE_4": "Muéstrame un fragmento de código", + "TEXT_SUGGESTION_SUBTITLE_4": "de un encabezado fijo de un sitio web", + "TEXT_SUGGESTION_CONTENT_4": "Muéstrame un fragmento de código de un encabezado fijo de un sitio web en CSS y JavaScript.", + "TEXT_SUGGESTION_TITLE_5": "Explica el trading de opciones", + "TEXT_SUGGESTION_SUBTITLE_5": "si ya sé comprar y vender acciones", + "TEXT_SUGGESTION_CONTENT_5": "Explica el trading de opciones en términos sencillos si ya estoy familiarizado con la compra y venta de acciones.", + "TEXT_SUGGESTION_TITLE_6": "Superar la procrastinación", + "TEXT_SUGGESTION_SUBTITLE_6": "dame consejos", + "TEXT_SUGGESTION_CONTENT_6": "¿Podrías empezar preguntándome sobre las situaciones en las que más procrastino y luego darme algunas sugerencias para superarlo?" + } + }, + "ATTACHED_FILE_ITEM": { + "TEXT_FILE": "Archivo", + "TEXT_DOCUMENT": "Documento", + "TEXT_COLLECTION": "Colección", + "FILE_INFO_MODAL": { + "TEXT_FORMATTING_DISCLAIMER": "El formato puede ser inconsistente con respecto al origen.", + "TEXT_NO_PREVIEW_AVAILABLE": "Vista previa no disponible", + "TEXT_EXTRACTED_LINES": { + "one": "{{count}} línea extraída", + "other": "{{count}} líneas extraídas" + } + } + }, + "SOURCE_CITATION_MODAL": { + "TEXT_CITATION": "Cita", + "TEXT_SOURCE": "Fuente", + "TEXT_RELEVANCE": "Relevancia", + "TEXT_CONTENT": "Contenido", + "TEXT_NO_PREVIEW_AVAILABLE": "Vista previa no disponible" + }, + "ARCHIVED_CHATS_LIST": { + "TEXT_ARCHIVED_CHATS": "Chats archivados", + "TEXT_NO_CHATS": "No hay chats archivados.", + "CHAT_ITEM": { + "TEXT_DELETE_CHAT": "¿Eliminar chat?", + "TEXT_THIS_WILL_DELETE": "Esto eliminará {{name}}", + "TEXT_RESTORE": "Restaurar", + "TEXT_EXPORT": "Exportar", + "TEXT_DELETE": "Eliminar", + "TEXT_KEEP": "Conservar" + }, + "ARCHIVED_CHATS_ACTIONS_SHEET": { + "TEXT_UNARCHIVE_CHATS": "¿Desarchivar todos los chats?", + "TEXT_ARE_YOU_SURE": "¿Estás seguro de que quieres desarchivar todos los chats archivados?", + "BUTTON_RESTORE_ALL_CHATS": "Restaurar todos los chats", + "BUTTON_EXPORT_ALL_CHATS": "Exportar todos los chats" + } + }, + "USER_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Editar", + "TEXT_COPY": "Copiar" + }, + "AI_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Editar", + "TEXT_COPY": "Copiar", + "TEXT_CONTINUE_RESPONSE": "Continuar respuesta", + "TEXT_REGENERATE": "Regenerar", + "REGENERATE_MESSAGE_ACTION_SHEET": { + "TEXT_SUGGEST_A_CHANGE": "Sugerir un cambio", + "TEXT_TRY_AGAIN": "Intentar de nuevo", + "TEXT_ADD_DETAILS": "Añadir detalles", + "TEXT_MORE_CONCISE": "Más conciso" + } + }, + "EDIT_MESSAGE_INPUT": { + "TEXT_EDIT_MESSAGE": "Editar mensaje", + "BUTTON_SAVE": "Guardar", + "BUTTON_SAVE_AS_COPY": "Guardar como copia", + "BUTTON_SEND": "Enviar", + "BUTTON_CANCEL": "Cancelar" + }, + "SUGGEST_CHANGE_INPUT": { + "TEXT_SUGGEST_A_CHANGE": "Sugerir un cambio", + "BUTTON_CANCEL": "Cancelar" + }, + "ARCHIVED_CHATS_FILTERS_SHEET": { + "USE_SEARCH_FILTERS": { + "TEXT_MOST_RECENT": "Más recientes", + "TEXT_OLDEST": "Más antiguos", + "TEXT_A-Z": "A-Z", + "TEXT_Z-A": "Z-A" + } + }, + "VOICE_MODE_MODAL": { + "TEXT_LISTENING": "Escuchando...", + "TEXT_THINKING": "Pensando...", + "TEXT_TALKING": "Hablando..." + }, + "MESSAGE_FOLLOW_UPS": { + "TEXT_FOLLOW_UP": "Seguimiento" + }, + "AI_MESSAGE": { + "TOOL_OUTPUT_SHEET": { + "TEXT_VIEW_RESULT_PREFIX": "Ver resultado de", + "TEXT_INPUT": "Entrada", + "TEXT_OUTPUT": "Salida" + } + } + } +} diff --git a/i18n/mobile/chat/fr.json b/i18n/mobile/chat/fr.json new file mode 100644 index 00000000..6c610f3a --- /dev/null +++ b/i18n/mobile/chat/fr.json @@ -0,0 +1,168 @@ +{ + "CHAT": { + "CHAT_SCREEN": { + "TEXT_LOADING": "Chargement...", + "TEXT_SELECT_A_MODEL": "Sélectionner un modèle" + }, + "CHAT": { + "TEXT_INPUT_PLACEHOLDER": "Envoyer un message", + "TEXT_MODEL_NOT_SELECTED": "Modèle non sélectionné" + }, + "CHAT_MENU_LIST": { + "PINNED_CHAT_LIST": { + "TEXT_PINNED": "Épinglés" + }, + "TEXT_NEW_CHAT": "Nouveau chat", + "TEXT_SEARCH": "Rechercher", + "TEXT_THERE_ARE_NO_CHATS": "Il n'y a aucun chat" + }, + "SEARCH_CHATS_LIST": { + "TEXT_THERE_ARE_NO_CHATS": "Il n'y a aucun chat" + }, + "FORM_CHAT_INPUT": { + "TEXT_MODEL_NOT_SELECTED": "Modèle non sélectionné", + "ATTACHMENTS_ACTIONS_POPUP": { + "TEXT_CAPTURE": "Capturer", + "TEXT_CHOOSE_FROM_GALLERY": "Choisir dans la galerie", + "TEXT_UPLOAD_FILES": "Téléverser des fichiers", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Vous ne pouvez pas téléverser un fichier vide." + } + }, + "SHARE_CHAT_MODAL": { + "TEXT_SHARE_CHAT": "Partager le chat", + "TEXT_DESCRIPTION_NOT_SHARED": "Les messages envoyés après la création du lien ne seront pas partagés. Les utilisateurs disposant de l'URL pourront consulter le chat partagé.", + "TEXT_DESCRIPTION_SHARED_1": "Vous avez partagé ce chat", + "TEXT_BEFORE_LINK": "auparavant", + "TEXT_DESCRIPTION_SHARED_2": "Cliquez ici pour", + "TEXT_DELETE_LINK": "supprimer ce lien", + "TEXT_DESCRIPTION_SHARED_3": "et créer un nouveau lien partagé.", + "BUTTON_COPY_LINK": "Copier le lien", + "BUTTON_UPDATE_AND_COPY_LINK": "Mettre à jour et copier le lien", + "TEXT_LINK_COPIED": "Lien copié dans le presse-papiers" + }, + "CREATE_CHAT": { + "TEXT_NEW_CHAT": "Nouveau chat", + "TEXT_PLACEHOLDER": "Comment puis-je vous aider aujourd'hui ?", + "TEXT_MODEL_NOT_SELECTED": "Modèle non sélectionné", + "TEXT_SELECT_A_MODEL": "Sélectionner un modèle", + "SEARCH_MODEL_VIEW": { + "TEXT_SELECT_A_MODEL": "Sélectionner un modèle", + "TEXT_SEARCH_MODEL": "Rechercher un modèle" + }, + "SEARCH_FOLDER_VIEW": { + "TEXT_SEARCH_FOLDER": "Rechercher un dossier", + "TEXT_NO_FOLDER": "Aucun dossier", + "TEXT_CREATE_NEW_FOLDER": "Créer un nouveau dossier" + }, + "SUGGESTIONS_LIST": { + "TEXT_SUGGESTED": "Suggestions", + "TEXT_SUGGESTION_TITLE_1": "Aide-moi à étudier", + "TEXT_SUGGESTION_SUBTITLE_1": "le vocabulaire pour un examen d'entrée à l'université", + "TEXT_SUGGESTION_CONTENT_1": "Aide-moi à apprendre du vocabulaire : écris une phrase avec un blanc à remplir, et j'essaierai de choisir la bonne option.", + "TEXT_SUGGESTION_TITLE_2": "Donne-moi des idées", + "TEXT_SUGGESTION_SUBTITLE_2": "sur ce que faire des dessins de mes enfants", + "TEXT_SUGGESTION_CONTENT_2": "Quelles sont 5 choses créatives que je pourrais faire avec les dessins de mes enfants ? Je ne veux pas les jeter, mais ils prennent aussi beaucoup de place.", + "TEXT_SUGGESTION_TITLE_3": "Raconte-moi un fait amusant", + "TEXT_SUGGESTION_SUBTITLE_3": "sur l'Empire romain", + "TEXT_SUGGESTION_CONTENT_3": "Raconte-moi un fait amusant au hasard sur l'Empire romain", + "TEXT_SUGGESTION_TITLE_4": "Montre-moi un extrait de code", + "TEXT_SUGGESTION_SUBTITLE_4": "d'un en-tête sticky de site web", + "TEXT_SUGGESTION_CONTENT_4": "Montre-moi un extrait de code d'un en-tête sticky de site web en CSS et JavaScript.", + "TEXT_SUGGESTION_TITLE_5": "Explique le trading d'options", + "TEXT_SUGGESTION_SUBTITLE_5": "si je connais déjà l'achat et la vente d'actions", + "TEXT_SUGGESTION_CONTENT_5": "Explique le trading d'options en termes simples si je suis déjà familiarisé avec l'achat et la vente d'actions.", + "TEXT_SUGGESTION_TITLE_6": "Surmonter la procrastination", + "TEXT_SUGGESTION_SUBTITLE_6": "donne-moi des conseils", + "TEXT_SUGGESTION_CONTENT_6": "Pourrais-tu commencer par me demander dans quelles situations je procrastine le plus, puis me donner quelques suggestions pour y remédier ?" + } + }, + "ATTACHED_FILE_ITEM": { + "TEXT_FILE": "Fichier", + "TEXT_DOCUMENT": "Document", + "TEXT_COLLECTION": "Collection", + "FILE_INFO_MODAL": { + "TEXT_FORMATTING_DISCLAIMER": "La mise en forme peut différer de la source.", + "TEXT_NO_PREVIEW_AVAILABLE": "Aucun aperçu disponible", + "TEXT_EXTRACTED_LINES": { + "one": "{{count}} ligne extraite", + "other": "{{count}} lignes extraites" + } + } + }, + "SOURCE_CITATION_MODAL": { + "TEXT_CITATION": "Citation", + "TEXT_SOURCE": "Source", + "TEXT_RELEVANCE": "Pertinence", + "TEXT_CONTENT": "Contenu", + "TEXT_NO_PREVIEW_AVAILABLE": "Aucun aperçu disponible" + }, + "ARCHIVED_CHATS_LIST": { + "TEXT_ARCHIVED_CHATS": "Chats archivés", + "TEXT_NO_CHATS": "Il n'y a aucun chat archivé.", + "CHAT_ITEM": { + "TEXT_DELETE_CHAT": "Supprimer le chat ?", + "TEXT_THIS_WILL_DELETE": "Cela supprimera {{name}}", + "TEXT_RESTORE": "Restaurer", + "TEXT_EXPORT": "Exporter", + "TEXT_DELETE": "Supprimer", + "TEXT_KEEP": "Conserver" + }, + "ARCHIVED_CHATS_ACTIONS_SHEET": { + "TEXT_UNARCHIVE_CHATS": "Désarchiver tous les chats ?", + "TEXT_ARE_YOU_SURE": "Êtes-vous sûr de vouloir désarchiver tous les chats archivés ?", + "BUTTON_RESTORE_ALL_CHATS": "Restaurer tous les chats", + "BUTTON_EXPORT_ALL_CHATS": "Exporter tous les chats" + } + }, + "USER_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Modifier", + "TEXT_COPY": "Copier" + }, + "AI_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Modifier", + "TEXT_COPY": "Copier", + "TEXT_CONTINUE_RESPONSE": "Continuer la réponse", + "TEXT_REGENERATE": "Régénérer", + "REGENERATE_MESSAGE_ACTION_SHEET": { + "TEXT_SUGGEST_A_CHANGE": "Suggérer une modification", + "TEXT_TRY_AGAIN": "Réessayer", + "TEXT_ADD_DETAILS": "Ajouter des détails", + "TEXT_MORE_CONCISE": "Plus concis" + } + }, + "EDIT_MESSAGE_INPUT": { + "TEXT_EDIT_MESSAGE": "Modifier le message", + "BUTTON_SAVE": "Enregistrer", + "BUTTON_SAVE_AS_COPY": "Enregistrer comme copie", + "BUTTON_SEND": "Envoyer", + "BUTTON_CANCEL": "Annuler" + }, + "SUGGEST_CHANGE_INPUT": { + "TEXT_SUGGEST_A_CHANGE": "Suggérer une modification", + "BUTTON_CANCEL": "Annuler" + }, + "ARCHIVED_CHATS_FILTERS_SHEET": { + "USE_SEARCH_FILTERS": { + "TEXT_MOST_RECENT": "Plus récents", + "TEXT_OLDEST": "Plus anciens", + "TEXT_A-Z": "A-Z", + "TEXT_Z-A": "Z-A" + } + }, + "VOICE_MODE_MODAL": { + "TEXT_LISTENING": "Écoute...", + "TEXT_THINKING": "Réflexion...", + "TEXT_TALKING": "Parole..." + }, + "MESSAGE_FOLLOW_UPS": { + "TEXT_FOLLOW_UP": "Suite" + }, + "AI_MESSAGE": { + "TOOL_OUTPUT_SHEET": { + "TEXT_VIEW_RESULT_PREFIX": "Voir le résultat de", + "TEXT_INPUT": "Entrée", + "TEXT_OUTPUT": "Sortie" + } + } + } +} diff --git a/i18n/mobile/chat/ja.json b/i18n/mobile/chat/ja.json new file mode 100644 index 00000000..87a27b64 --- /dev/null +++ b/i18n/mobile/chat/ja.json @@ -0,0 +1,167 @@ +{ + "CHAT": { + "CHAT_SCREEN": { + "TEXT_LOADING": "読み込み中...", + "TEXT_SELECT_A_MODEL": "モデルを選択" + }, + "CHAT": { + "TEXT_INPUT_PLACEHOLDER": "メッセージを送信", + "TEXT_MODEL_NOT_SELECTED": "モデルが選択されていません" + }, + "CHAT_MENU_LIST": { + "PINNED_CHAT_LIST": { + "TEXT_PINNED": "ピン留め" + }, + "TEXT_NEW_CHAT": "新しいチャット", + "TEXT_SEARCH": "検索", + "TEXT_THERE_ARE_NO_CHATS": "チャットはありません" + }, + "SEARCH_CHATS_LIST": { + "TEXT_THERE_ARE_NO_CHATS": "チャットはありません" + }, + "FORM_CHAT_INPUT": { + "TEXT_MODEL_NOT_SELECTED": "モデルが選択されていません", + "ATTACHMENTS_ACTIONS_POPUP": { + "TEXT_CAPTURE": "撮影", + "TEXT_CHOOSE_FROM_GALLERY": "ギャラリーから選択", + "TEXT_UPLOAD_FILES": "ファイルをアップロード", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "空のファイルはアップロードできません。" + } + }, + "SHARE_CHAT_MODAL": { + "TEXT_SHARE_CHAT": "チャットを共有", + "TEXT_DESCRIPTION_NOT_SHARED": "リンク作成後に送信したメッセージは共有されません。URL を持つユーザーは共有されたチャットを閲覧できます。", + "TEXT_DESCRIPTION_SHARED_1": "このチャットを共有しました", + "TEXT_BEFORE_LINK": "以前", + "TEXT_DESCRIPTION_SHARED_2": "ここをクリックして", + "TEXT_DELETE_LINK": "このリンクを削除", + "TEXT_DESCRIPTION_SHARED_3": "し、新しい共有リンクを作成します。", + "BUTTON_COPY_LINK": "リンクをコピー", + "BUTTON_UPDATE_AND_COPY_LINK": "更新してリンクをコピー", + "TEXT_LINK_COPIED": "リンクをクリップボードにコピーしました" + }, + "CREATE_CHAT": { + "TEXT_NEW_CHAT": "新しいチャット", + "TEXT_PLACEHOLDER": "今日はどのようにお手伝いできますか?", + "TEXT_MODEL_NOT_SELECTED": "モデルが選択されていません", + "TEXT_SELECT_A_MODEL": "モデルを選択", + "SEARCH_MODEL_VIEW": { + "TEXT_SELECT_A_MODEL": "モデルを選択", + "TEXT_SEARCH_MODEL": "モデルを検索" + }, + "SEARCH_FOLDER_VIEW": { + "TEXT_SEARCH_FOLDER": "フォルダを検索", + "TEXT_NO_FOLDER": "フォルダなし", + "TEXT_CREATE_NEW_FOLDER": "新しいフォルダを作成" + }, + "SUGGESTIONS_LIST": { + "TEXT_SUGGESTED": "おすすめ", + "TEXT_SUGGESTION_TITLE_1": "勉強を手伝って", + "TEXT_SUGGESTION_SUBTITLE_1": "大学入試の語彙", + "TEXT_SUGGESTION_CONTENT_1": "語彙の学習を手伝って:穴埋めの文を書いて、正しい選択肢を選ばせてください。", + "TEXT_SUGGESTION_TITLE_2": "アイデアをください", + "TEXT_SUGGESTION_SUBTITLE_2": "子どもの作品の活用方法", + "TEXT_SUGGESTION_CONTENT_2": "子どもの作品でできるクリエイティブなことは5つ何ですか?捨てたくはないけれど、場所も取りすぎます。", + "TEXT_SUGGESTION_TITLE_3": "おもしろい豆知識を教えて", + "TEXT_SUGGESTION_SUBTITLE_3": "ローマ帝国について", + "TEXT_SUGGESTION_CONTENT_3": "ローマ帝国に関するランダムなおもしろい豆知識を教えて", + "TEXT_SUGGESTION_TITLE_4": "コードスニペットを見せて", + "TEXT_SUGGESTION_SUBTITLE_4": "ウェブサイトのスティッキーヘッダーの", + "TEXT_SUGGESTION_CONTENT_4": "ウェブサイトのスティッキーヘッダーのコードスニペットを CSS と JavaScript で見せてください。", + "TEXT_SUGGESTION_TITLE_5": "オプション取引を説明して", + "TEXT_SUGGESTION_SUBTITLE_5": "株式の売買に慣れている場合", + "TEXT_SUGGESTION_CONTENT_5": "株式の売買に慣れている前提で、オプション取引をわかりやすく説明してください。", + "TEXT_SUGGESTION_TITLE_6": "先延ばしを克服する", + "TEXT_SUGGESTION_SUBTITLE_6": "ヒントをください", + "TEXT_SUGGESTION_CONTENT_6": "まず、最も先延ばししがちな場面について聞いてから、克服のための提案をいくつかくれますか?" + } + }, + "ATTACHED_FILE_ITEM": { + "TEXT_FILE": "ファイル", + "TEXT_DOCUMENT": "ドキュメント", + "TEXT_COLLECTION": "コレクション", + "FILE_INFO_MODAL": { + "TEXT_FORMATTING_DISCLAIMER": "書式は元のソースと一致しない場合があります。", + "TEXT_NO_PREVIEW_AVAILABLE": "プレビューはありません", + "TEXT_EXTRACTED_LINES": { + "other": "{{count}} 行を抽出" + } + } + }, + "SOURCE_CITATION_MODAL": { + "TEXT_CITATION": "引用", + "TEXT_SOURCE": "ソース", + "TEXT_RELEVANCE": "関連度", + "TEXT_CONTENT": "内容", + "TEXT_NO_PREVIEW_AVAILABLE": "プレビューはありません" + }, + "ARCHIVED_CHATS_LIST": { + "TEXT_ARCHIVED_CHATS": "アーカイブ済みチャット", + "TEXT_NO_CHATS": "アーカイブ済みチャットはありません。", + "CHAT_ITEM": { + "TEXT_DELETE_CHAT": "チャットを削除しますか?", + "TEXT_THIS_WILL_DELETE": "{{name}} が削除されます", + "TEXT_RESTORE": "復元", + "TEXT_EXPORT": "エクスポート", + "TEXT_DELETE": "削除", + "TEXT_KEEP": "保持" + }, + "ARCHIVED_CHATS_ACTIONS_SHEET": { + "TEXT_UNARCHIVE_CHATS": "すべてのチャットのアーカイブを解除しますか?", + "TEXT_ARE_YOU_SURE": "アーカイブ済みのすべてのチャットのアーカイブを解除してもよろしいですか?", + "BUTTON_RESTORE_ALL_CHATS": "すべてのチャットを復元", + "BUTTON_EXPORT_ALL_CHATS": "すべてのチャットをエクスポート" + } + }, + "USER_MESSAGE_ACTIONS": { + "TEXT_EDIT": "編集", + "TEXT_COPY": "コピー" + }, + "AI_MESSAGE_ACTIONS": { + "TEXT_EDIT": "編集", + "TEXT_COPY": "コピー", + "TEXT_CONTINUE_RESPONSE": "回答を続ける", + "TEXT_REGENERATE": "再生成", + "REGENERATE_MESSAGE_ACTION_SHEET": { + "TEXT_SUGGEST_A_CHANGE": "変更を提案", + "TEXT_TRY_AGAIN": "もう一度試す", + "TEXT_ADD_DETAILS": "詳細を追加", + "TEXT_MORE_CONCISE": "より簡潔に" + } + }, + "EDIT_MESSAGE_INPUT": { + "TEXT_EDIT_MESSAGE": "メッセージを編集", + "BUTTON_SAVE": "保存", + "BUTTON_SAVE_AS_COPY": "コピーとして保存", + "BUTTON_SEND": "送信", + "BUTTON_CANCEL": "キャンセル" + }, + "SUGGEST_CHANGE_INPUT": { + "TEXT_SUGGEST_A_CHANGE": "変更を提案", + "BUTTON_CANCEL": "キャンセル" + }, + "ARCHIVED_CHATS_FILTERS_SHEET": { + "USE_SEARCH_FILTERS": { + "TEXT_MOST_RECENT": "最新順", + "TEXT_OLDEST": "古い順", + "TEXT_A-Z": "A-Z", + "TEXT_Z-A": "Z-A" + } + }, + "VOICE_MODE_MODAL": { + "TEXT_LISTENING": "聞いています...", + "TEXT_THINKING": "考えています...", + "TEXT_TALKING": "話しています..." + }, + "MESSAGE_FOLLOW_UPS": { + "TEXT_FOLLOW_UP": "フォローアップ" + }, + "AI_MESSAGE": { + "TOOL_OUTPUT_SHEET": { + "TEXT_VIEW_RESULT_PREFIX": "次の結果を表示", + "TEXT_INPUT": "入力", + "TEXT_OUTPUT": "出力" + } + } + } +} diff --git a/i18n/mobile/chat/pt.json b/i18n/mobile/chat/pt.json new file mode 100644 index 00000000..0379e46b --- /dev/null +++ b/i18n/mobile/chat/pt.json @@ -0,0 +1,168 @@ +{ + "CHAT": { + "CHAT_SCREEN": { + "TEXT_LOADING": "Carregando...", + "TEXT_SELECT_A_MODEL": "Selecionar um modelo" + }, + "CHAT": { + "TEXT_INPUT_PLACEHOLDER": "Enviar uma mensagem", + "TEXT_MODEL_NOT_SELECTED": "Modelo não selecionado" + }, + "CHAT_MENU_LIST": { + "PINNED_CHAT_LIST": { + "TEXT_PINNED": "Fixados" + }, + "TEXT_NEW_CHAT": "Novo chat", + "TEXT_SEARCH": "Pesquisar", + "TEXT_THERE_ARE_NO_CHATS": "Não há chats" + }, + "SEARCH_CHATS_LIST": { + "TEXT_THERE_ARE_NO_CHATS": "Não há chats" + }, + "FORM_CHAT_INPUT": { + "TEXT_MODEL_NOT_SELECTED": "Modelo não selecionado", + "ATTACHMENTS_ACTIONS_POPUP": { + "TEXT_CAPTURE": "Capturar", + "TEXT_CHOOSE_FROM_GALLERY": "Escolher da galeria", + "TEXT_UPLOAD_FILES": "Enviar arquivos", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Não é possível enviar um arquivo vazio." + } + }, + "SHARE_CHAT_MODAL": { + "TEXT_SHARE_CHAT": "Compartilhar chat", + "TEXT_DESCRIPTION_NOT_SHARED": "As mensagens enviadas após a criação do link não serão compartilhadas. Os usuários com o URL poderão ver o chat compartilhado.", + "TEXT_DESCRIPTION_SHARED_1": "Você compartilhou este chat", + "TEXT_BEFORE_LINK": "antes", + "TEXT_DESCRIPTION_SHARED_2": "Clique aqui para", + "TEXT_DELETE_LINK": "excluir este link", + "TEXT_DESCRIPTION_SHARED_3": "e criar um novo link compartilhado.", + "BUTTON_COPY_LINK": "Copiar link", + "BUTTON_UPDATE_AND_COPY_LINK": "Atualizar e copiar link", + "TEXT_LINK_COPIED": "Link copiado para a área de transferência" + }, + "CREATE_CHAT": { + "TEXT_NEW_CHAT": "Novo chat", + "TEXT_PLACEHOLDER": "Como posso ajudar você hoje?", + "TEXT_MODEL_NOT_SELECTED": "Modelo não selecionado", + "TEXT_SELECT_A_MODEL": "Selecionar um modelo", + "SEARCH_MODEL_VIEW": { + "TEXT_SELECT_A_MODEL": "Selecionar um modelo", + "TEXT_SEARCH_MODEL": "Pesquisar modelo" + }, + "SEARCH_FOLDER_VIEW": { + "TEXT_SEARCH_FOLDER": "Pesquisar pasta", + "TEXT_NO_FOLDER": "Nenhuma pasta", + "TEXT_CREATE_NEW_FOLDER": "Criar nova pasta" + }, + "SUGGESTIONS_LIST": { + "TEXT_SUGGESTED": "Sugestões", + "TEXT_SUGGESTION_TITLE_1": "Ajude-me a estudar", + "TEXT_SUGGESTION_SUBTITLE_1": "vocabulário para um vestibular", + "TEXT_SUGGESTION_CONTENT_1": "Ajude-me a estudar vocabulário: escreva uma frase com um espaço em branco para eu tentar escolher a opção correta.", + "TEXT_SUGGESTION_TITLE_2": "Me dê ideias", + "TEXT_SUGGESTION_SUBTITLE_2": "sobre o que fazer com a arte dos meus filhos", + "TEXT_SUGGESTION_CONTENT_2": "Quais são 5 coisas criativas que eu poderia fazer com a arte dos meus filhos? Não quero jogá-las fora, mas também ocupam muito espaço.", + "TEXT_SUGGESTION_TITLE_3": "Conte-me um fato divertido", + "TEXT_SUGGESTION_SUBTITLE_3": "sobre o Império Romano", + "TEXT_SUGGESTION_CONTENT_3": "Conte-me um fato divertido aleatório sobre o Império Romano", + "TEXT_SUGGESTION_TITLE_4": "Mostre-me um trecho de código", + "TEXT_SUGGESTION_SUBTITLE_4": "de um cabeçalho fixo de site", + "TEXT_SUGGESTION_CONTENT_4": "Mostre-me um trecho de código de um cabeçalho fixo de site em CSS e JavaScript.", + "TEXT_SUGGESTION_TITLE_5": "Explique o trading de opções", + "TEXT_SUGGESTION_SUBTITLE_5": "se eu já sei comprar e vender ações", + "TEXT_SUGGESTION_CONTENT_5": "Explique o trading de opções em termos simples se eu já estiver familiarizado com a compra e venda de ações.", + "TEXT_SUGGESTION_TITLE_6": "Superar a procrastinação", + "TEXT_SUGGESTION_SUBTITLE_6": "me dê dicas", + "TEXT_SUGGESTION_CONTENT_6": "Você poderia começar perguntando sobre as situações em que mais procrastino e depois me dar algumas sugestões para superar isso?" + } + }, + "ATTACHED_FILE_ITEM": { + "TEXT_FILE": "Arquivo", + "TEXT_DOCUMENT": "Documento", + "TEXT_COLLECTION": "Coleção", + "FILE_INFO_MODAL": { + "TEXT_FORMATTING_DISCLAIMER": "A formatação pode ser inconsistente em relação à origem.", + "TEXT_NO_PREVIEW_AVAILABLE": "Pré-visualização indisponível", + "TEXT_EXTRACTED_LINES": { + "one": "{{count}} linha extraída", + "other": "{{count}} linhas extraídas" + } + } + }, + "SOURCE_CITATION_MODAL": { + "TEXT_CITATION": "Citação", + "TEXT_SOURCE": "Fonte", + "TEXT_RELEVANCE": "Relevância", + "TEXT_CONTENT": "Conteúdo", + "TEXT_NO_PREVIEW_AVAILABLE": "Pré-visualização indisponível" + }, + "ARCHIVED_CHATS_LIST": { + "TEXT_ARCHIVED_CHATS": "Chats arquivados", + "TEXT_NO_CHATS": "Não há chats arquivados.", + "CHAT_ITEM": { + "TEXT_DELETE_CHAT": "Excluir chat?", + "TEXT_THIS_WILL_DELETE": "Isso excluirá {{name}}", + "TEXT_RESTORE": "Restaurar", + "TEXT_EXPORT": "Exportar", + "TEXT_DELETE": "Excluir", + "TEXT_KEEP": "Manter" + }, + "ARCHIVED_CHATS_ACTIONS_SHEET": { + "TEXT_UNARCHIVE_CHATS": "Desarquivar todos os chats?", + "TEXT_ARE_YOU_SURE": "Tem certeza de que deseja desarquivar todos os chats arquivados?", + "BUTTON_RESTORE_ALL_CHATS": "Restaurar todos os chats", + "BUTTON_EXPORT_ALL_CHATS": "Exportar todos os chats" + } + }, + "USER_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Editar", + "TEXT_COPY": "Copiar" + }, + "AI_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Editar", + "TEXT_COPY": "Copiar", + "TEXT_CONTINUE_RESPONSE": "Continuar resposta", + "TEXT_REGENERATE": "Regenerar", + "REGENERATE_MESSAGE_ACTION_SHEET": { + "TEXT_SUGGEST_A_CHANGE": "Sugerir uma alteração", + "TEXT_TRY_AGAIN": "Tentar novamente", + "TEXT_ADD_DETAILS": "Adicionar detalhes", + "TEXT_MORE_CONCISE": "Mais conciso" + } + }, + "EDIT_MESSAGE_INPUT": { + "TEXT_EDIT_MESSAGE": "Editar mensagem", + "BUTTON_SAVE": "Salvar", + "BUTTON_SAVE_AS_COPY": "Salvar como cópia", + "BUTTON_SEND": "Enviar", + "BUTTON_CANCEL": "Cancelar" + }, + "SUGGEST_CHANGE_INPUT": { + "TEXT_SUGGEST_A_CHANGE": "Sugerir uma alteração", + "BUTTON_CANCEL": "Cancelar" + }, + "ARCHIVED_CHATS_FILTERS_SHEET": { + "USE_SEARCH_FILTERS": { + "TEXT_MOST_RECENT": "Mais recentes", + "TEXT_OLDEST": "Mais antigos", + "TEXT_A-Z": "A-Z", + "TEXT_Z-A": "Z-A" + } + }, + "VOICE_MODE_MODAL": { + "TEXT_LISTENING": "Ouvindo...", + "TEXT_THINKING": "Pensando...", + "TEXT_TALKING": "Falando..." + }, + "MESSAGE_FOLLOW_UPS": { + "TEXT_FOLLOW_UP": "Continuação" + }, + "AI_MESSAGE": { + "TOOL_OUTPUT_SHEET": { + "TEXT_VIEW_RESULT_PREFIX": "Ver resultado de", + "TEXT_INPUT": "Entrada", + "TEXT_OUTPUT": "Saída" + } + } + } +} diff --git a/i18n/mobile/chat/ru.json b/i18n/mobile/chat/ru.json new file mode 100644 index 00000000..02a69f81 --- /dev/null +++ b/i18n/mobile/chat/ru.json @@ -0,0 +1,169 @@ +{ + "CHAT": { + "CHAT_SCREEN": { + "TEXT_LOADING": "Загрузка...", + "TEXT_SELECT_A_MODEL": "Выберите модель" + }, + "CHAT": { + "TEXT_INPUT_PLACEHOLDER": "Отправить сообщение", + "TEXT_MODEL_NOT_SELECTED": "Модель не выбрана" + }, + "CHAT_MENU_LIST": { + "PINNED_CHAT_LIST": { + "TEXT_PINNED": "Закреплённые" + }, + "TEXT_NEW_CHAT": "Новый чат", + "TEXT_SEARCH": "Поиск", + "TEXT_THERE_ARE_NO_CHATS": "Чатов нет" + }, + "SEARCH_CHATS_LIST": { + "TEXT_THERE_ARE_NO_CHATS": "Чатов нет" + }, + "FORM_CHAT_INPUT": { + "TEXT_MODEL_NOT_SELECTED": "Модель не выбрана", + "ATTACHMENTS_ACTIONS_POPUP": { + "TEXT_CAPTURE": "Сделать снимок", + "TEXT_CHOOSE_FROM_GALLERY": "Выбрать из галереи", + "TEXT_UPLOAD_FILES": "Загрузить файлы", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Нельзя загрузить пустой файл." + } + }, + "SHARE_CHAT_MODAL": { + "TEXT_SHARE_CHAT": "Поделиться чатом", + "TEXT_DESCRIPTION_NOT_SHARED": "Сообщения, отправленные после создания ссылки, не будут доступны. Пользователи с URL смогут просматривать общий чат.", + "TEXT_DESCRIPTION_SHARED_1": "Вы поделились этим чатом", + "TEXT_BEFORE_LINK": "ранее", + "TEXT_DESCRIPTION_SHARED_2": "Нажмите здесь, чтобы", + "TEXT_DELETE_LINK": "удалить эту ссылку", + "TEXT_DESCRIPTION_SHARED_3": "и создать новую общую ссылку.", + "BUTTON_COPY_LINK": "Скопировать ссылку", + "BUTTON_UPDATE_AND_COPY_LINK": "Обновить и скопировать ссылку", + "TEXT_LINK_COPIED": "Ссылка скопирована в буфер обмена" + }, + "CREATE_CHAT": { + "TEXT_NEW_CHAT": "Новый чат", + "TEXT_PLACEHOLDER": "Чем я могу помочь сегодня?", + "TEXT_MODEL_NOT_SELECTED": "Модель не выбрана", + "TEXT_SELECT_A_MODEL": "Выберите модель", + "SEARCH_MODEL_VIEW": { + "TEXT_SELECT_A_MODEL": "Выберите модель", + "TEXT_SEARCH_MODEL": "Поиск модели" + }, + "SEARCH_FOLDER_VIEW": { + "TEXT_SEARCH_FOLDER": "Поиск папки", + "TEXT_NO_FOLDER": "Нет папки", + "TEXT_CREATE_NEW_FOLDER": "Создать новую папку" + }, + "SUGGESTIONS_LIST": { + "TEXT_SUGGESTED": "Рекомендации", + "TEXT_SUGGESTION_TITLE_1": "Помоги мне учиться", + "TEXT_SUGGESTION_SUBTITLE_1": "словарный запас для вступительного экзамена в колледж", + "TEXT_SUGGESTION_CONTENT_1": "Помоги мне учить слова: напиши предложение с пропуском, а я попробую выбрать правильный вариант.", + "TEXT_SUGGESTION_TITLE_2": "Дай идеи", + "TEXT_SUGGESTION_SUBTITLE_2": "что делать с детскими рисунками", + "TEXT_SUGGESTION_CONTENT_2": "Какие 5 творческих идей можно сделать с детскими рисунками? Не хочу их выбрасывать, но они занимают слишком много места.", + "TEXT_SUGGESTION_TITLE_3": "Расскажи интересный факт", + "TEXT_SUGGESTION_SUBTITLE_3": "о Римской империи", + "TEXT_SUGGESTION_CONTENT_3": "Расскажи случайный интересный факт о Римской империи", + "TEXT_SUGGESTION_TITLE_4": "Покажи фрагмент кода", + "TEXT_SUGGESTION_SUBTITLE_4": "липкого заголовка сайта", + "TEXT_SUGGESTION_CONTENT_4": "Покажи фрагмент кода липкого заголовка сайта на CSS и JavaScript.", + "TEXT_SUGGESTION_TITLE_5": "Объясни торговлю опционами", + "TEXT_SUGGESTION_SUBTITLE_5": "если я знаком с покупкой и продажей акций", + "TEXT_SUGGESTION_CONTENT_5": "Объясни торговлю опционами простыми словами, если я знаком с покупкой и продажей акций.", + "TEXT_SUGGESTION_TITLE_6": "Преодолеть прокрастинацию", + "TEXT_SUGGESTION_SUBTITLE_6": "дай советы", + "TEXT_SUGGESTION_CONTENT_6": "Можешь сначала спросить меня о ситуациях, когда я чаще всего откладываю дела, а затем дать несколько советов, как это преодолеть?" + } + }, + "ATTACHED_FILE_ITEM": { + "TEXT_FILE": "Файл", + "TEXT_DOCUMENT": "Документ", + "TEXT_COLLECTION": "Коллекция", + "FILE_INFO_MODAL": { + "TEXT_FORMATTING_DISCLAIMER": "Форматирование может отличаться от исходного.", + "TEXT_NO_PREVIEW_AVAILABLE": "Предпросмотр недоступен", + "TEXT_EXTRACTED_LINES": { + "one": "{{count}} извлечённая строка", + "few": "{{count}} извлечённые строки", + "many": "{{count}} извлечённых строк" + } + } + }, + "SOURCE_CITATION_MODAL": { + "TEXT_CITATION": "Цитата", + "TEXT_SOURCE": "Источник", + "TEXT_RELEVANCE": "Релевантность", + "TEXT_CONTENT": "Содержание", + "TEXT_NO_PREVIEW_AVAILABLE": "Предпросмотр недоступен" + }, + "ARCHIVED_CHATS_LIST": { + "TEXT_ARCHIVED_CHATS": "Архивные чаты", + "TEXT_NO_CHATS": "Архивных чатов нет.", + "CHAT_ITEM": { + "TEXT_DELETE_CHAT": "Удалить чат?", + "TEXT_THIS_WILL_DELETE": "Будет удалён {{name}}", + "TEXT_RESTORE": "Восстановить", + "TEXT_EXPORT": "Экспорт", + "TEXT_DELETE": "Удалить", + "TEXT_KEEP": "Оставить" + }, + "ARCHIVED_CHATS_ACTIONS_SHEET": { + "TEXT_UNARCHIVE_CHATS": "Разархивировать все чаты?", + "TEXT_ARE_YOU_SURE": "Вы уверены, что хотите разархивировать все архивные чаты?", + "BUTTON_RESTORE_ALL_CHATS": "Восстановить все чаты", + "BUTTON_EXPORT_ALL_CHATS": "Экспортировать все чаты" + } + }, + "USER_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Изменить", + "TEXT_COPY": "Копировать" + }, + "AI_MESSAGE_ACTIONS": { + "TEXT_EDIT": "Изменить", + "TEXT_COPY": "Копировать", + "TEXT_CONTINUE_RESPONSE": "Продолжить ответ", + "TEXT_REGENERATE": "Перегенерировать", + "REGENERATE_MESSAGE_ACTION_SHEET": { + "TEXT_SUGGEST_A_CHANGE": "Предложить изменение", + "TEXT_TRY_AGAIN": "Попробовать снова", + "TEXT_ADD_DETAILS": "Добавить детали", + "TEXT_MORE_CONCISE": "Более кратко" + } + }, + "EDIT_MESSAGE_INPUT": { + "TEXT_EDIT_MESSAGE": "Редактировать сообщение", + "BUTTON_SAVE": "Сохранить", + "BUTTON_SAVE_AS_COPY": "Сохранить как копию", + "BUTTON_SEND": "Отправить", + "BUTTON_CANCEL": "Отмена" + }, + "SUGGEST_CHANGE_INPUT": { + "TEXT_SUGGEST_A_CHANGE": "Предложить изменение", + "BUTTON_CANCEL": "Отмена" + }, + "ARCHIVED_CHATS_FILTERS_SHEET": { + "USE_SEARCH_FILTERS": { + "TEXT_MOST_RECENT": "Сначала новые", + "TEXT_OLDEST": "Сначала старые", + "TEXT_A-Z": "A-Z", + "TEXT_Z-A": "Z-A" + } + }, + "VOICE_MODE_MODAL": { + "TEXT_LISTENING": "Слушаю...", + "TEXT_THINKING": "Думаю...", + "TEXT_TALKING": "Говорю..." + }, + "MESSAGE_FOLLOW_UPS": { + "TEXT_FOLLOW_UP": "Уточнение" + }, + "AI_MESSAGE": { + "TOOL_OUTPUT_SHEET": { + "TEXT_VIEW_RESULT_PREFIX": "Посмотреть результат от", + "TEXT_INPUT": "Ввод", + "TEXT_OUTPUT": "Вывод" + } + } + } +} diff --git a/i18n/mobile/chat/zh.json b/i18n/mobile/chat/zh.json new file mode 100644 index 00000000..8a05814d --- /dev/null +++ b/i18n/mobile/chat/zh.json @@ -0,0 +1,167 @@ +{ + "CHAT": { + "CHAT_SCREEN": { + "TEXT_LOADING": "加载中...", + "TEXT_SELECT_A_MODEL": "选择模型" + }, + "CHAT": { + "TEXT_INPUT_PLACEHOLDER": "发送消息", + "TEXT_MODEL_NOT_SELECTED": "未选择模型" + }, + "CHAT_MENU_LIST": { + "PINNED_CHAT_LIST": { + "TEXT_PINNED": "已置顶" + }, + "TEXT_NEW_CHAT": "新对话", + "TEXT_SEARCH": "搜索", + "TEXT_THERE_ARE_NO_CHATS": "暂无对话" + }, + "SEARCH_CHATS_LIST": { + "TEXT_THERE_ARE_NO_CHATS": "暂无对话" + }, + "FORM_CHAT_INPUT": { + "TEXT_MODEL_NOT_SELECTED": "未选择模型", + "ATTACHMENTS_ACTIONS_POPUP": { + "TEXT_CAPTURE": "拍摄", + "TEXT_CHOOSE_FROM_GALLERY": "从相册选择", + "TEXT_UPLOAD_FILES": "上传文件", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "无法上传空文件。" + } + }, + "SHARE_CHAT_MODAL": { + "TEXT_SHARE_CHAT": "分享对话", + "TEXT_DESCRIPTION_NOT_SHARED": "创建链接后发送的消息不会被分享。拥有该 URL 的用户可以查看已分享的对话。", + "TEXT_DESCRIPTION_SHARED_1": "您已分享此对话", + "TEXT_BEFORE_LINK": "之前", + "TEXT_DESCRIPTION_SHARED_2": "点击此处", + "TEXT_DELETE_LINK": "删除此链接", + "TEXT_DESCRIPTION_SHARED_3": "并创建新的分享链接。", + "BUTTON_COPY_LINK": "复制链接", + "BUTTON_UPDATE_AND_COPY_LINK": "更新并复制链接", + "TEXT_LINK_COPIED": "链接已复制到剪贴板" + }, + "CREATE_CHAT": { + "TEXT_NEW_CHAT": "新对话", + "TEXT_PLACEHOLDER": "今天我能为您做什么?", + "TEXT_MODEL_NOT_SELECTED": "未选择模型", + "TEXT_SELECT_A_MODEL": "选择模型", + "SEARCH_MODEL_VIEW": { + "TEXT_SELECT_A_MODEL": "选择模型", + "TEXT_SEARCH_MODEL": "搜索模型" + }, + "SEARCH_FOLDER_VIEW": { + "TEXT_SEARCH_FOLDER": "搜索文件夹", + "TEXT_NO_FOLDER": "无文件夹", + "TEXT_CREATE_NEW_FOLDER": "创建新文件夹" + }, + "SUGGESTIONS_LIST": { + "TEXT_SUGGESTED": "建议", + "TEXT_SUGGESTION_TITLE_1": "帮我学习", + "TEXT_SUGGESTION_SUBTITLE_1": "大学入学考试的词汇", + "TEXT_SUGGESTION_CONTENT_1": "帮我学习词汇:写一个填空句子,我来试着选择正确的选项。", + "TEXT_SUGGESTION_TITLE_2": "给我一些想法", + "TEXT_SUGGESTION_SUBTITLE_2": "如何处理孩子们的画作", + "TEXT_SUGGESTION_CONTENT_2": "对于孩子们的画作,我能做哪 5 件有创意的事?我不想扔掉它们,但它们也太占地方了。", + "TEXT_SUGGESTION_TITLE_3": "告诉我一个有趣的事实", + "TEXT_SUGGESTION_SUBTITLE_3": "关于罗马帝国", + "TEXT_SUGGESTION_CONTENT_3": "告诉我一个关于罗马帝国的随机有趣事实", + "TEXT_SUGGESTION_TITLE_4": "给我看一段代码", + "TEXT_SUGGESTION_SUBTITLE_4": "网站粘性页眉的", + "TEXT_SUGGESTION_CONTENT_4": "给我看一段网站粘性页眉的 CSS 和 JavaScript 代码片段。", + "TEXT_SUGGESTION_TITLE_5": "解释期权交易", + "TEXT_SUGGESTION_SUBTITLE_5": "如果我熟悉买卖股票", + "TEXT_SUGGESTION_CONTENT_5": "用简单的话解释期权交易,假设我已经熟悉买卖股票。", + "TEXT_SUGGESTION_TITLE_6": "克服拖延", + "TEXT_SUGGESTION_SUBTITLE_6": "给我一些建议", + "TEXT_SUGGESTION_CONTENT_6": "你能先问问我最容易拖延的情况,然后再给我一些克服拖延的建议吗?" + } + }, + "ATTACHED_FILE_ITEM": { + "TEXT_FILE": "文件", + "TEXT_DOCUMENT": "文档", + "TEXT_COLLECTION": "集合", + "FILE_INFO_MODAL": { + "TEXT_FORMATTING_DISCLAIMER": "格式可能与源文件不一致。", + "TEXT_NO_PREVIEW_AVAILABLE": "暂无预览", + "TEXT_EXTRACTED_LINES": { + "other": "{{count}} 行已提取" + } + } + }, + "SOURCE_CITATION_MODAL": { + "TEXT_CITATION": "引用", + "TEXT_SOURCE": "来源", + "TEXT_RELEVANCE": "相关度", + "TEXT_CONTENT": "内容", + "TEXT_NO_PREVIEW_AVAILABLE": "暂无预览" + }, + "ARCHIVED_CHATS_LIST": { + "TEXT_ARCHIVED_CHATS": "已归档对话", + "TEXT_NO_CHATS": "暂无已归档对话。", + "CHAT_ITEM": { + "TEXT_DELETE_CHAT": "删除对话?", + "TEXT_THIS_WILL_DELETE": "这将删除 {{name}}", + "TEXT_RESTORE": "恢复", + "TEXT_EXPORT": "导出", + "TEXT_DELETE": "删除", + "TEXT_KEEP": "保留" + }, + "ARCHIVED_CHATS_ACTIONS_SHEET": { + "TEXT_UNARCHIVE_CHATS": "取消归档所有对话?", + "TEXT_ARE_YOU_SURE": "确定要取消归档所有已归档对话吗?", + "BUTTON_RESTORE_ALL_CHATS": "恢复所有对话", + "BUTTON_EXPORT_ALL_CHATS": "导出所有对话" + } + }, + "USER_MESSAGE_ACTIONS": { + "TEXT_EDIT": "编辑", + "TEXT_COPY": "复制" + }, + "AI_MESSAGE_ACTIONS": { + "TEXT_EDIT": "编辑", + "TEXT_COPY": "复制", + "TEXT_CONTINUE_RESPONSE": "继续回复", + "TEXT_REGENERATE": "重新生成", + "REGENERATE_MESSAGE_ACTION_SHEET": { + "TEXT_SUGGEST_A_CHANGE": "建议修改", + "TEXT_TRY_AGAIN": "再试一次", + "TEXT_ADD_DETAILS": "添加细节", + "TEXT_MORE_CONCISE": "更简洁" + } + }, + "EDIT_MESSAGE_INPUT": { + "TEXT_EDIT_MESSAGE": "编辑消息", + "BUTTON_SAVE": "保存", + "BUTTON_SAVE_AS_COPY": "另存为副本", + "BUTTON_SEND": "发送", + "BUTTON_CANCEL": "取消" + }, + "SUGGEST_CHANGE_INPUT": { + "TEXT_SUGGEST_A_CHANGE": "建议修改", + "BUTTON_CANCEL": "取消" + }, + "ARCHIVED_CHATS_FILTERS_SHEET": { + "USE_SEARCH_FILTERS": { + "TEXT_MOST_RECENT": "最新", + "TEXT_OLDEST": "最早", + "TEXT_A-Z": "A-Z", + "TEXT_Z-A": "Z-A" + } + }, + "VOICE_MODE_MODAL": { + "TEXT_LISTENING": "正在聆听...", + "TEXT_THINKING": "正在思考...", + "TEXT_TALKING": "正在说话..." + }, + "MESSAGE_FOLLOW_UPS": { + "TEXT_FOLLOW_UP": "追问" + }, + "AI_MESSAGE": { + "TOOL_OUTPUT_SHEET": { + "TEXT_VIEW_RESULT_PREFIX": "查看来自以下工具的结果", + "TEXT_INPUT": "输入", + "TEXT_OUTPUT": "输出" + } + } + } +} diff --git a/i18n/mobile/folder/de.json b/i18n/mobile/folder/de.json new file mode 100644 index 00000000..fb011ed7 --- /dev/null +++ b/i18n/mobile/folder/de.json @@ -0,0 +1,36 @@ +{ + "FOLDER": { + "CHATS_LIST": { + "TEXT_NO_CHATS": "In diesem Ordner gibt es keine Chats." + }, + "FOLDER_ACTIONS_SHEET": { + "TEXT_EDIT": "Bearbeiten", + "TEXT_EXPORT": "Exportieren", + "TEXT_DELETE": "Löschen", + "TEXT_KEEP": "Behalten", + "TEXT_DELETE_FOLDER": "Ordner löschen?", + "TEXT_THIS_WILL_DELETE": "Dadurch wird {{name}} gelöscht" + }, + "UPSERT_FOLDER_SHEET": { + "TEXT_NEW_FOLDER": "Neuer Ordner", + "TEXT_EDIT_FOLDER": "Ordner bearbeiten", + "TEXT_FOLDER_NAME": "Ordnername", + "TEXT_DOCUMENT": "Dokument", + "TEXT_FILE": "Datei", + "TEXT_COLLECTION": "Sammlung", + "TEXT_FOLDER_NAME_PLACEHOLDER": "z. B. Mein Ordner", + "TEXT_SYSTEM_PROMPT": "Systemprompt", + "TEXT_KNOWLEDGE": "Wissen", + "BUTTON_SELECT_KNOWLEDGE": "Wissen auswählen", + "BUTTON_UPLOAD_FILES": "Dateien hochladen", + "TEXT_CREATE": "Erstellen", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Sie können keine leere Datei hochladen.", + "TEXT_UNSUPPORTED_TYPE": "Nicht unterstützter Typ." + }, + "SELECT_KNOWLEDGE_SHEET": { + "TEXT_SEARCH_KNOWLEDGE": "Wissen suchen", + "TEXT_SELECT_KNOWLEDGE": "Wissen auswählen", + "TEXT_NO_KNOWLEDGE": "Es ist kein Wissen vorhanden." + } + } +} diff --git a/i18n/mobile/folder/es.json b/i18n/mobile/folder/es.json new file mode 100644 index 00000000..8e1b348d --- /dev/null +++ b/i18n/mobile/folder/es.json @@ -0,0 +1,36 @@ +{ + "FOLDER": { + "CHATS_LIST": { + "TEXT_NO_CHATS": "No hay chats en esta carpeta." + }, + "FOLDER_ACTIONS_SHEET": { + "TEXT_EDIT": "Editar", + "TEXT_EXPORT": "Exportar", + "TEXT_DELETE": "Eliminar", + "TEXT_KEEP": "Conservar", + "TEXT_DELETE_FOLDER": "¿Eliminar carpeta?", + "TEXT_THIS_WILL_DELETE": "Se eliminará {{name}}" + }, + "UPSERT_FOLDER_SHEET": { + "TEXT_NEW_FOLDER": "Nueva carpeta", + "TEXT_EDIT_FOLDER": "Editar carpeta", + "TEXT_FOLDER_NAME": "Nombre de la carpeta", + "TEXT_DOCUMENT": "Documento", + "TEXT_FILE": "Archivo", + "TEXT_COLLECTION": "Colección", + "TEXT_FOLDER_NAME_PLACEHOLDER": "p. ej. Mi carpeta", + "TEXT_SYSTEM_PROMPT": "Prompt del sistema", + "TEXT_KNOWLEDGE": "Conocimiento", + "BUTTON_SELECT_KNOWLEDGE": "Seleccionar conocimiento", + "BUTTON_UPLOAD_FILES": "Subir archivos", + "TEXT_CREATE": "Crear", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "No puedes subir un archivo vacío.", + "TEXT_UNSUPPORTED_TYPE": "Tipo no compatible." + }, + "SELECT_KNOWLEDGE_SHEET": { + "TEXT_SEARCH_KNOWLEDGE": "Buscar conocimiento", + "TEXT_SELECT_KNOWLEDGE": "Seleccionar conocimiento", + "TEXT_NO_KNOWLEDGE": "No hay conocimiento." + } + } +} diff --git a/i18n/mobile/folder/fr.json b/i18n/mobile/folder/fr.json new file mode 100644 index 00000000..447033e2 --- /dev/null +++ b/i18n/mobile/folder/fr.json @@ -0,0 +1,36 @@ +{ + "FOLDER": { + "CHATS_LIST": { + "TEXT_NO_CHATS": "Il n’y a aucune discussion dans ce dossier." + }, + "FOLDER_ACTIONS_SHEET": { + "TEXT_EDIT": "Modifier", + "TEXT_EXPORT": "Exporter", + "TEXT_DELETE": "Supprimer", + "TEXT_KEEP": "Conserver", + "TEXT_DELETE_FOLDER": "Supprimer le dossier ?", + "TEXT_THIS_WILL_DELETE": "Cela supprimera {{name}}" + }, + "UPSERT_FOLDER_SHEET": { + "TEXT_NEW_FOLDER": "Nouveau dossier", + "TEXT_EDIT_FOLDER": "Modifier le dossier", + "TEXT_FOLDER_NAME": "Nom du dossier", + "TEXT_DOCUMENT": "Document", + "TEXT_FILE": "Fichier", + "TEXT_COLLECTION": "Collection", + "TEXT_FOLDER_NAME_PLACEHOLDER": "ex. Mon dossier", + "TEXT_SYSTEM_PROMPT": "Invite système", + "TEXT_KNOWLEDGE": "Connaissances", + "BUTTON_SELECT_KNOWLEDGE": "Sélectionner des connaissances", + "BUTTON_UPLOAD_FILES": "Téléverser des fichiers", + "TEXT_CREATE": "Créer", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Vous ne pouvez pas téléverser un fichier vide.", + "TEXT_UNSUPPORTED_TYPE": "Type non pris en charge." + }, + "SELECT_KNOWLEDGE_SHEET": { + "TEXT_SEARCH_KNOWLEDGE": "Rechercher des connaissances", + "TEXT_SELECT_KNOWLEDGE": "Sélectionner des connaissances", + "TEXT_NO_KNOWLEDGE": "Aucune connaissance." + } + } +} diff --git a/i18n/mobile/folder/ja.json b/i18n/mobile/folder/ja.json new file mode 100644 index 00000000..07f8b0cc --- /dev/null +++ b/i18n/mobile/folder/ja.json @@ -0,0 +1,36 @@ +{ + "FOLDER": { + "CHATS_LIST": { + "TEXT_NO_CHATS": "このフォルダにはチャットがありません。" + }, + "FOLDER_ACTIONS_SHEET": { + "TEXT_EDIT": "編集", + "TEXT_EXPORT": "エクスポート", + "TEXT_DELETE": "削除", + "TEXT_KEEP": "保持", + "TEXT_DELETE_FOLDER": "フォルダを削除しますか?", + "TEXT_THIS_WILL_DELETE": "{{name}} が削除されます" + }, + "UPSERT_FOLDER_SHEET": { + "TEXT_NEW_FOLDER": "新しいフォルダ", + "TEXT_EDIT_FOLDER": "フォルダを編集", + "TEXT_FOLDER_NAME": "フォルダ名", + "TEXT_DOCUMENT": "ドキュメント", + "TEXT_FILE": "ファイル", + "TEXT_COLLECTION": "コレクション", + "TEXT_FOLDER_NAME_PLACEHOLDER": "例:マイフォルダ", + "TEXT_SYSTEM_PROMPT": "システムプロンプト", + "TEXT_KNOWLEDGE": "ナレッジ", + "BUTTON_SELECT_KNOWLEDGE": "ナレッジを選択", + "BUTTON_UPLOAD_FILES": "ファイルをアップロード", + "TEXT_CREATE": "作成", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "空のファイルはアップロードできません。", + "TEXT_UNSUPPORTED_TYPE": "サポートされていない種類です。" + }, + "SELECT_KNOWLEDGE_SHEET": { + "TEXT_SEARCH_KNOWLEDGE": "ナレッジを検索", + "TEXT_SELECT_KNOWLEDGE": "ナレッジを選択", + "TEXT_NO_KNOWLEDGE": "ナレッジがありません。" + } + } +} diff --git a/i18n/mobile/folder/pt.json b/i18n/mobile/folder/pt.json new file mode 100644 index 00000000..a2fe50aa --- /dev/null +++ b/i18n/mobile/folder/pt.json @@ -0,0 +1,36 @@ +{ + "FOLDER": { + "CHATS_LIST": { + "TEXT_NO_CHATS": "Não há chats nesta pasta." + }, + "FOLDER_ACTIONS_SHEET": { + "TEXT_EDIT": "Editar", + "TEXT_EXPORT": "Exportar", + "TEXT_DELETE": "Excluir", + "TEXT_KEEP": "Manter", + "TEXT_DELETE_FOLDER": "Excluir pasta?", + "TEXT_THIS_WILL_DELETE": "Isso excluirá {{name}}" + }, + "UPSERT_FOLDER_SHEET": { + "TEXT_NEW_FOLDER": "Nova pasta", + "TEXT_EDIT_FOLDER": "Editar pasta", + "TEXT_FOLDER_NAME": "Nome da pasta", + "TEXT_DOCUMENT": "Documento", + "TEXT_FILE": "Arquivo", + "TEXT_COLLECTION": "Coleção", + "TEXT_FOLDER_NAME_PLACEHOLDER": "ex.: Minha pasta", + "TEXT_SYSTEM_PROMPT": "Prompt do sistema", + "TEXT_KNOWLEDGE": "Conhecimento", + "BUTTON_SELECT_KNOWLEDGE": "Selecionar conhecimento", + "BUTTON_UPLOAD_FILES": "Enviar arquivos", + "TEXT_CREATE": "Criar", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Você não pode enviar um arquivo vazio.", + "TEXT_UNSUPPORTED_TYPE": "Tipo não suportado." + }, + "SELECT_KNOWLEDGE_SHEET": { + "TEXT_SEARCH_KNOWLEDGE": "Pesquisar conhecimento", + "TEXT_SELECT_KNOWLEDGE": "Selecionar conhecimento", + "TEXT_NO_KNOWLEDGE": "Não há conhecimento." + } + } +} diff --git a/i18n/mobile/folder/ru.json b/i18n/mobile/folder/ru.json new file mode 100644 index 00000000..68207671 --- /dev/null +++ b/i18n/mobile/folder/ru.json @@ -0,0 +1,36 @@ +{ + "FOLDER": { + "CHATS_LIST": { + "TEXT_NO_CHATS": "В этой папке нет чатов." + }, + "FOLDER_ACTIONS_SHEET": { + "TEXT_EDIT": "Изменить", + "TEXT_EXPORT": "Экспорт", + "TEXT_DELETE": "Удалить", + "TEXT_KEEP": "Оставить", + "TEXT_DELETE_FOLDER": "Удалить папку?", + "TEXT_THIS_WILL_DELETE": "Будет удалено: {{name}}" + }, + "UPSERT_FOLDER_SHEET": { + "TEXT_NEW_FOLDER": "Новая папка", + "TEXT_EDIT_FOLDER": "Изменить папку", + "TEXT_FOLDER_NAME": "Название папки", + "TEXT_DOCUMENT": "Документ", + "TEXT_FILE": "Файл", + "TEXT_COLLECTION": "Коллекция", + "TEXT_FOLDER_NAME_PLACEHOLDER": "напр. Моя папка", + "TEXT_SYSTEM_PROMPT": "Системный промпт", + "TEXT_KNOWLEDGE": "База знаний", + "BUTTON_SELECT_KNOWLEDGE": "Выбрать базу знаний", + "BUTTON_UPLOAD_FILES": "Загрузить файлы", + "TEXT_CREATE": "Создать", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "Нельзя загрузить пустой файл.", + "TEXT_UNSUPPORTED_TYPE": "Неподдерживаемый тип." + }, + "SELECT_KNOWLEDGE_SHEET": { + "TEXT_SEARCH_KNOWLEDGE": "Поиск по базе знаний", + "TEXT_SELECT_KNOWLEDGE": "Выбрать базу знаний", + "TEXT_NO_KNOWLEDGE": "База знаний пуста." + } + } +} diff --git a/i18n/mobile/folder/zh.json b/i18n/mobile/folder/zh.json new file mode 100644 index 00000000..4469b49a --- /dev/null +++ b/i18n/mobile/folder/zh.json @@ -0,0 +1,36 @@ +{ + "FOLDER": { + "CHATS_LIST": { + "TEXT_NO_CHATS": "此文件夹中没有聊天。" + }, + "FOLDER_ACTIONS_SHEET": { + "TEXT_EDIT": "编辑", + "TEXT_EXPORT": "导出", + "TEXT_DELETE": "删除", + "TEXT_KEEP": "保留", + "TEXT_DELETE_FOLDER": "删除文件夹?", + "TEXT_THIS_WILL_DELETE": "这将删除 {{name}}" + }, + "UPSERT_FOLDER_SHEET": { + "TEXT_NEW_FOLDER": "新建文件夹", + "TEXT_EDIT_FOLDER": "编辑文件夹", + "TEXT_FOLDER_NAME": "文件夹名称", + "TEXT_DOCUMENT": "文档", + "TEXT_FILE": "文件", + "TEXT_COLLECTION": "集合", + "TEXT_FOLDER_NAME_PLACEHOLDER": "例如:我的文件夹", + "TEXT_SYSTEM_PROMPT": "系统提示词", + "TEXT_KNOWLEDGE": "知识库", + "BUTTON_SELECT_KNOWLEDGE": "选择知识库", + "BUTTON_UPLOAD_FILES": "上传文件", + "TEXT_CREATE": "创建", + "TEXT_YOU_CANNOT_UPLOAD_EMPTY_FILE": "无法上传空文件。", + "TEXT_UNSUPPORTED_TYPE": "不支持的类型。" + }, + "SELECT_KNOWLEDGE_SHEET": { + "TEXT_SEARCH_KNOWLEDGE": "搜索知识库", + "TEXT_SELECT_KNOWLEDGE": "选择知识库", + "TEXT_NO_KNOWLEDGE": "暂无知识库。" + } + } +} diff --git a/i18n/mobile/profile/de.json b/i18n/mobile/profile/de.json new file mode 100644 index 00000000..01d16ac4 --- /dev/null +++ b/i18n/mobile/profile/de.json @@ -0,0 +1,15 @@ +{ + "PROFILE": { + "PROFILE_MENU_SHEET": { + "TEXT_LOGOUT": "Abmelden", + "TEXT_ARCHIVED_CHATS": "Archivierte Chats", + "TEXT_SETTINGS": "Einstellungen", + "TEXT_DELETE_ACCOUNT": "Konto löschen", + "TEXT_DELETE_ACCOUNT_TITLE": "Möchten Sie Ihr Konto wirklich löschen?", + "TEXT_DELETE_ACCOUNT_MESSAGE": "Diese Aktion führt zu einem dauerhaften Datenverlust, wenn wir in den nächsten 30 Tagen nichts von Ihnen hören.", + "BUTTON_DELETE_ACCOUNT": "Ja, mein Konto löschen", + "BUTTON_DONT_DELETE": "Nicht löschen", + "TEXT_ACCOUNT_DELETION_REQUEST": "Ihre Anfrage zur Kontolöschung wurde übermittelt." + } + } +} diff --git a/i18n/mobile/profile/es.json b/i18n/mobile/profile/es.json new file mode 100644 index 00000000..a1068eca --- /dev/null +++ b/i18n/mobile/profile/es.json @@ -0,0 +1,15 @@ +{ + "PROFILE": { + "PROFILE_MENU_SHEET": { + "TEXT_LOGOUT": "Cerrar sesión", + "TEXT_ARCHIVED_CHATS": "Chats archivados", + "TEXT_SETTINGS": "Ajustes", + "TEXT_DELETE_ACCOUNT": "Eliminar cuenta", + "TEXT_DELETE_ACCOUNT_TITLE": "¿Seguro que quieres eliminar tu cuenta?", + "TEXT_DELETE_ACCOUNT_MESSAGE": "Esta acción provocará la pérdida permanente de datos si no tenemos noticias tuyas en los próximos 30 días.", + "BUTTON_DELETE_ACCOUNT": "Sí, eliminar mi cuenta", + "BUTTON_DONT_DELETE": "No eliminar", + "TEXT_ACCOUNT_DELETION_REQUEST": "Se ha enviado la solicitud de eliminación de cuenta." + } + } +} diff --git a/i18n/mobile/profile/fr.json b/i18n/mobile/profile/fr.json new file mode 100644 index 00000000..bdd02d7b --- /dev/null +++ b/i18n/mobile/profile/fr.json @@ -0,0 +1,15 @@ +{ + "PROFILE": { + "PROFILE_MENU_SHEET": { + "TEXT_LOGOUT": "Déconnexion", + "TEXT_ARCHIVED_CHATS": "Discussions archivées", + "TEXT_SETTINGS": "Paramètres", + "TEXT_DELETE_ACCOUNT": "Supprimer le compte", + "TEXT_DELETE_ACCOUNT_TITLE": "Voulez-vous vraiment supprimer votre compte ?", + "TEXT_DELETE_ACCOUNT_MESSAGE": "Cette action entraînera une perte permanente de données si nous n’avons pas de nouvelles de votre part dans les 30 prochains jours.", + "BUTTON_DELETE_ACCOUNT": "Oui, supprimer mon compte", + "BUTTON_DONT_DELETE": "Ne pas supprimer", + "TEXT_ACCOUNT_DELETION_REQUEST": "Votre demande de suppression de compte a été envoyée." + } + } +} diff --git a/i18n/mobile/profile/ja.json b/i18n/mobile/profile/ja.json new file mode 100644 index 00000000..88114505 --- /dev/null +++ b/i18n/mobile/profile/ja.json @@ -0,0 +1,15 @@ +{ + "PROFILE": { + "PROFILE_MENU_SHEET": { + "TEXT_LOGOUT": "ログアウト", + "TEXT_ARCHIVED_CHATS": "アーカイブ済みチャット", + "TEXT_SETTINGS": "設定", + "TEXT_DELETE_ACCOUNT": "アカウントを削除", + "TEXT_DELETE_ACCOUNT_TITLE": "アカウントを削除してもよろしいですか?", + "TEXT_DELETE_ACCOUNT_MESSAGE": "今後30日以内にご連絡がない場合、この操作によりデータが永久に失われます。", + "BUTTON_DELETE_ACCOUNT": "はい、アカウントを削除します", + "BUTTON_DONT_DELETE": "削除しない", + "TEXT_ACCOUNT_DELETION_REQUEST": "アカウント削除のリクエストが送信されました。" + } + } +} diff --git a/i18n/mobile/profile/pt.json b/i18n/mobile/profile/pt.json new file mode 100644 index 00000000..2a657b9f --- /dev/null +++ b/i18n/mobile/profile/pt.json @@ -0,0 +1,15 @@ +{ + "PROFILE": { + "PROFILE_MENU_SHEET": { + "TEXT_LOGOUT": "Sair", + "TEXT_ARCHIVED_CHATS": "Chats arquivados", + "TEXT_SETTINGS": "Configurações", + "TEXT_DELETE_ACCOUNT": "Excluir conta", + "TEXT_DELETE_ACCOUNT_TITLE": "Tem certeza de que deseja excluir sua conta?", + "TEXT_DELETE_ACCOUNT_MESSAGE": "Esta ação resultará na perda permanente de dados se não tivermos notícias suas nos próximos 30 dias.", + "BUTTON_DELETE_ACCOUNT": "Sim, excluir minha conta", + "BUTTON_DONT_DELETE": "Não excluir", + "TEXT_ACCOUNT_DELETION_REQUEST": "Sua solicitação de exclusão de conta foi enviada." + } + } +} diff --git a/i18n/mobile/profile/ru.json b/i18n/mobile/profile/ru.json new file mode 100644 index 00000000..b0feda44 --- /dev/null +++ b/i18n/mobile/profile/ru.json @@ -0,0 +1,15 @@ +{ + "PROFILE": { + "PROFILE_MENU_SHEET": { + "TEXT_LOGOUT": "Выйти", + "TEXT_ARCHIVED_CHATS": "Архивные чаты", + "TEXT_SETTINGS": "Настройки", + "TEXT_DELETE_ACCOUNT": "Удалить аккаунт", + "TEXT_DELETE_ACCOUNT_TITLE": "Вы уверены, что хотите удалить аккаунт?", + "TEXT_DELETE_ACCOUNT_MESSAGE": "Это действие приведёт к безвозвратной потере данных, если мы не получим от вас ответа в течение следующих 30 дней.", + "BUTTON_DELETE_ACCOUNT": "Да, удалить мой аккаунт", + "BUTTON_DONT_DELETE": "Не удалять", + "TEXT_ACCOUNT_DELETION_REQUEST": "Запрос на удаление аккаунта отправлен." + } + } +} diff --git a/i18n/mobile/profile/zh.json b/i18n/mobile/profile/zh.json new file mode 100644 index 00000000..94c73d09 --- /dev/null +++ b/i18n/mobile/profile/zh.json @@ -0,0 +1,15 @@ +{ + "PROFILE": { + "PROFILE_MENU_SHEET": { + "TEXT_LOGOUT": "退出登录", + "TEXT_ARCHIVED_CHATS": "已归档聊天", + "TEXT_SETTINGS": "设置", + "TEXT_DELETE_ACCOUNT": "删除账户", + "TEXT_DELETE_ACCOUNT_TITLE": "确定要删除您的账户吗?", + "TEXT_DELETE_ACCOUNT_MESSAGE": "如果在接下来的 30 天内未收到您的回复,此操作将导致数据永久丢失。", + "BUTTON_DELETE_ACCOUNT": "是的,删除我的账户", + "BUTTON_DONT_DELETE": "不删除", + "TEXT_ACCOUNT_DELETION_REQUEST": "您的账户删除请求已提交。" + } + } +} diff --git a/i18n/mobile/shared/de.json b/i18n/mobile/shared/de.json new file mode 100644 index 00000000..0fab70cd --- /dev/null +++ b/i18n/mobile/shared/de.json @@ -0,0 +1,108 @@ +{ + "SHARED": { + "VALIDATION": { + "TEXT_INVALID_EMAIL": "Bitte geben Sie eine gültige E-Mail-Adresse ein", + "TEXT_REQUIRED_EMAIL": "Bitte geben Sie Ihre E-Mail-Adresse ein", + "TEXT_REQUIRED_PASSWORD": "Bitte geben Sie Ihr Passwort ein", + "TEXT_INVALID_URL": "Bitte geben Sie eine gültige Server-URL ein, z. B. https://your.domain oder http://192.168.1.10:3000", + "TEXT_REQUIRED_FOLDER_NAME": "Bitte geben Sie einen Ordnernamen ein" + }, + "COMMON": { + "TEXT_FEATURE_NOT_IMPLEMENTED_YET": "Funktion ist noch nicht implementiert.", + "TEXT_NEW_CHAT": "Neuer Chat", + "BUTTON_CANCEL": "Abbrechen", + "BUTTON_CONFIRM": "Bestätigen", + "BUTTON_OPEN_SETTINGS": "Einstellungen öffnen", + "TEXT_UNABLE_TO_OPEN_SETTINGS": "Einstellungen können nicht geöffnet werden", + "TEXT_SETTINGS": "Einstellungen", + "TEXT_DISABLED_IN_OFFLINE_MODE": "Funktionen sind im Offline-Modus deaktiviert", + "ACTIONS_BOTTOM_SHEET": { + "BUTTON_CANCEL": "Abbrechen" + }, + "TEXT_COPIED_TO_CLIPBOARD": "In die Zwischenablage kopiert" + }, + "API_ERRORS": { + "TEXT_SOMETHING_WENT_WRONG": "Etwas ist schiefgelaufen", + "TEXT_YOUR_SESSION_HAS_EXPIRED": "Ihre Sitzung ist abgelaufen. Bitte melden Sie sich erneut an", + "TEXT_FORBIDDEN_ERROR": "Sie haben keinen Zugriff auf diese Aktion", + "TEXT_INTERNAL_SERVER_ERROR": "Fehler beim Laden der Daten", + "TEXT_NOT_FOUND_ERROR": "Daten nicht gefunden" + }, + "DATES": { + "TEXT_TODAY": "Heute", + "TEXT_YESTERDAY": "Gestern", + "TEXT_LAST_DAYS": "Letzte {{days}} Tage", + "TEXT_AT_TIME": "um {{time}}", + "TEXT_TODAY_TIME": "Heute {{time}}", + "TEXT_YESTERDAY_TIME": "Gestern {{time}}" + }, + "CODE_BLOCK": { + "TEXT_COPIED_TO_CLIPBOARD": "In die Zwischenablage kopiert", + "TEXT_COPY": "Kopieren" + }, + "SOCKET_SERVICE": { + "TEXT_CONNECTION_ERROR": "Verbindungsfehler" + }, + "IMAGE_PICKER_SERVICE": { + "TEXT_ACCESS_DENIED": "Zugriff verweigert" + }, + "ACTION_BUTTONS_MODAL": { + "BUTTON_CONFIRM": "Bestätigen", + "BUTTON_CANCEL": "Abbrechen", + "TEXT_TITLE_CAN_NOT_BE_EMPTY": "Titel darf nicht leer sein" + }, + "MEDIA_LIBRARY_SERVICE": { + "TEXT_SUCCESSFULLY_SAVED": "Bild erfolgreich gespeichert", + "TEXT_ERROR_DURING_SAVING": "Beim Speichern des Bildes ist ein Fehler aufgetreten", + "TEXT_SETTINGS": "Einstellungen", + "TEXT_SETTINGS_MESSAGE": "Erlauben Sie den Kamerazugriff in den Einstellungen. Settings > Open Web UI > Photos > All Photos" + }, + "FILE_SYSTEM_SERVICE": { + "TEXT_SHARE": "{{fileName}} teilen", + "TEXT_SHARING_IS_NOT_AVAILABLE": "Teilen ist auf diesem Gerät nicht verfügbar" + }, + "USE_AUDIO_RECORDER": { + "TEXT_NO_ACCESS": "Kein Zugriff", + "TEXT_APP_NEEDS_ACCESS": "Die App benötigt Zugriff auf das Mikrofon Ihres Geräts" + }, + "NO_CONNECTION_BANNER": { + "TEXT_YOU_ARE_OFFLINE": "Sie sind offline!" + }, + "PRESSABLE_SEARCH_INPUT": { + "TEXT_SEARCH_CHATS": "Chats suchen" + }, + "CHAT_ACTIONS_MENU_SHEET": { + "TEXT_PIN": "Anheften", + "TEXT_UNPIN": "Lösen", + "TEXT_RENAME": "Umbenennen", + "TEXT_CLONE": "Klonen", + "TEXT_ARCHIVE": "Archivieren", + "TEXT_RESTORE": "Wiederherstellen", + "TEXT_SHARE": "Teilen", + "TEXT_DOWNLOAD": "Herunterladen", + "TEXT_DELETE": "Löschen", + "TEXT_KEEP": "Behalten", + "TEXT_RENAME_CHAT": "Chat umbenennen", + "TEXT_DELETE_CHAT": "Chat löschen?", + "TEXT_THIS_WILL_DELETE": "Dadurch wird {{name}} gelöscht", + "TEXT_CLONE_OF": "Klon von {{title}}", + "TEXT_CHAT_ACTIONS": "Chat-Aktionen", + "TEXT_MOVE_TO_FOLDER": "In Ordner verschieben", + "DOWNLOAD_CHAT_OPTIONS_SHEET": { + "TEXT_EXPORT_CHAT_JSON": "Chat exportieren (.json)", + "TEXT_PLAIN_TEXT": "Nur Text (.txt)", + "TEXT_PDF_DOCUMENT": "PDF-Dokument (.pdf)" + }, + "MOVE_CHAT_TO_FOLDER_MODAL": { + "TEXT_SEARCH_FOLDER": "Ordner suchen", + "TEXT_NO_FOLDERS": "Keine Ordner vorhanden", + "TEXT_CREATE_NEW_FOLDER": "Ordner erstellen", + "TEXT_NO_FOLDER": "Kein Ordner" + } + }, + "SEARCH_INPUT": { + "BUTTON_CANCEL": "Abbrechen", + "TEXT_SEARCH_CHATS": "Chats suchen" + } + } +} diff --git a/i18n/mobile/shared/es.json b/i18n/mobile/shared/es.json new file mode 100644 index 00000000..6bda66bb --- /dev/null +++ b/i18n/mobile/shared/es.json @@ -0,0 +1,108 @@ +{ + "SHARED": { + "VALIDATION": { + "TEXT_INVALID_EMAIL": "Introduce una dirección de correo válida", + "TEXT_REQUIRED_EMAIL": "Introduce tu correo electrónico", + "TEXT_REQUIRED_PASSWORD": "Introduce tu contraseña", + "TEXT_INVALID_URL": "Introduce una URL de servidor válida, p. ej. https://your.domain o http://192.168.1.10:3000", + "TEXT_REQUIRED_FOLDER_NAME": "Introduce un nombre de carpeta" + }, + "COMMON": { + "TEXT_FEATURE_NOT_IMPLEMENTED_YET": "La función aún no está implementada.", + "TEXT_NEW_CHAT": "Nuevo chat", + "BUTTON_CANCEL": "Cancelar", + "BUTTON_CONFIRM": "Confirmar", + "BUTTON_OPEN_SETTINGS": "Abrir ajustes", + "TEXT_UNABLE_TO_OPEN_SETTINGS": "No se pueden abrir los ajustes", + "TEXT_SETTINGS": "Ajustes", + "TEXT_DISABLED_IN_OFFLINE_MODE": "Las funciones están desactivadas en modo sin conexión", + "ACTIONS_BOTTOM_SHEET": { + "BUTTON_CANCEL": "Cancelar" + }, + "TEXT_COPIED_TO_CLIPBOARD": "Copiado al portapapeles" + }, + "API_ERRORS": { + "TEXT_SOMETHING_WENT_WRONG": "Algo salió mal", + "TEXT_YOUR_SESSION_HAS_EXPIRED": "Tu sesión ha caducado. Inicia sesión de nuevo", + "TEXT_FORBIDDEN_ERROR": "No tienes acceso a esta acción", + "TEXT_INTERNAL_SERVER_ERROR": "Error al cargar los datos", + "TEXT_NOT_FOUND_ERROR": "Datos no encontrados" + }, + "DATES": { + "TEXT_TODAY": "Hoy", + "TEXT_YESTERDAY": "Ayer", + "TEXT_LAST_DAYS": "Últimos {{days}} días", + "TEXT_AT_TIME": "a las {{time}}", + "TEXT_TODAY_TIME": "Hoy {{time}}", + "TEXT_YESTERDAY_TIME": "Ayer {{time}}" + }, + "CODE_BLOCK": { + "TEXT_COPIED_TO_CLIPBOARD": "Copiado al portapapeles", + "TEXT_COPY": "Copiar" + }, + "SOCKET_SERVICE": { + "TEXT_CONNECTION_ERROR": "Error de conexión" + }, + "IMAGE_PICKER_SERVICE": { + "TEXT_ACCESS_DENIED": "Acceso denegado" + }, + "ACTION_BUTTONS_MODAL": { + "BUTTON_CONFIRM": "Confirmar", + "BUTTON_CANCEL": "Cancelar", + "TEXT_TITLE_CAN_NOT_BE_EMPTY": "El título no puede estar vacío" + }, + "MEDIA_LIBRARY_SERVICE": { + "TEXT_SUCCESSFULLY_SAVED": "Imagen guardada correctamente", + "TEXT_ERROR_DURING_SAVING": "Se produjo un error al guardar la imagen", + "TEXT_SETTINGS": "Ajustes", + "TEXT_SETTINGS_MESSAGE": "Permite el acceso a la cámara desde ajustes. Settings > Open Web UI > Photos > All Photos" + }, + "FILE_SYSTEM_SERVICE": { + "TEXT_SHARE": "Compartir {{fileName}}", + "TEXT_SHARING_IS_NOT_AVAILABLE": "Compartir no está disponible en este dispositivo" + }, + "USE_AUDIO_RECORDER": { + "TEXT_NO_ACCESS": "Sin acceso", + "TEXT_APP_NEEDS_ACCESS": "La app necesita acceso al micrófono del dispositivo" + }, + "NO_CONNECTION_BANNER": { + "TEXT_YOU_ARE_OFFLINE": "¡Estás sin conexión!" + }, + "PRESSABLE_SEARCH_INPUT": { + "TEXT_SEARCH_CHATS": "Buscar chats" + }, + "CHAT_ACTIONS_MENU_SHEET": { + "TEXT_PIN": "Fijar", + "TEXT_UNPIN": "Desfijar", + "TEXT_RENAME": "Renombrar", + "TEXT_CLONE": "Clonar", + "TEXT_ARCHIVE": "Archivar", + "TEXT_RESTORE": "Restaurar", + "TEXT_SHARE": "Compartir", + "TEXT_DOWNLOAD": "Descargar", + "TEXT_DELETE": "Eliminar", + "TEXT_KEEP": "Conservar", + "TEXT_RENAME_CHAT": "Renombrar chat", + "TEXT_DELETE_CHAT": "¿Eliminar chat?", + "TEXT_THIS_WILL_DELETE": "Se eliminará {{name}}", + "TEXT_CLONE_OF": "Copia de {{title}}", + "TEXT_CHAT_ACTIONS": "Acciones del chat", + "TEXT_MOVE_TO_FOLDER": "Mover a carpeta", + "DOWNLOAD_CHAT_OPTIONS_SHEET": { + "TEXT_EXPORT_CHAT_JSON": "Exportar chat (.json)", + "TEXT_PLAIN_TEXT": "Texto plano (.txt)", + "TEXT_PDF_DOCUMENT": "Documento PDF (.pdf)" + }, + "MOVE_CHAT_TO_FOLDER_MODAL": { + "TEXT_SEARCH_FOLDER": "Buscar carpeta", + "TEXT_NO_FOLDERS": "No hay carpetas", + "TEXT_CREATE_NEW_FOLDER": "Crear carpeta", + "TEXT_NO_FOLDER": "Sin carpeta" + } + }, + "SEARCH_INPUT": { + "BUTTON_CANCEL": "Cancelar", + "TEXT_SEARCH_CHATS": "Buscar chats" + } + } +} diff --git a/i18n/mobile/shared/fr.json b/i18n/mobile/shared/fr.json new file mode 100644 index 00000000..93892f61 --- /dev/null +++ b/i18n/mobile/shared/fr.json @@ -0,0 +1,108 @@ +{ + "SHARED": { + "VALIDATION": { + "TEXT_INVALID_EMAIL": "Veuillez saisir une adresse e-mail valide", + "TEXT_REQUIRED_EMAIL": "Veuillez saisir votre e-mail", + "TEXT_REQUIRED_PASSWORD": "Veuillez saisir votre mot de passe", + "TEXT_INVALID_URL": "Veuillez saisir une URL de serveur valide, ex. https://your.domain ou http://192.168.1.10:3000", + "TEXT_REQUIRED_FOLDER_NAME": "Veuillez saisir un nom de dossier" + }, + "COMMON": { + "TEXT_FEATURE_NOT_IMPLEMENTED_YET": "Cette fonctionnalité n’est pas encore implémentée.", + "TEXT_NEW_CHAT": "Nouvelle discussion", + "BUTTON_CANCEL": "Annuler", + "BUTTON_CONFIRM": "Confirmer", + "BUTTON_OPEN_SETTINGS": "Ouvrir les paramètres", + "TEXT_UNABLE_TO_OPEN_SETTINGS": "Impossible d’ouvrir les paramètres", + "TEXT_SETTINGS": "Paramètres", + "TEXT_DISABLED_IN_OFFLINE_MODE": "Les fonctionnalités sont désactivées en mode hors ligne", + "ACTIONS_BOTTOM_SHEET": { + "BUTTON_CANCEL": "Annuler" + }, + "TEXT_COPIED_TO_CLIPBOARD": "Copié dans le presse-papiers" + }, + "API_ERRORS": { + "TEXT_SOMETHING_WENT_WRONG": "Une erreur s’est produite", + "TEXT_YOUR_SESSION_HAS_EXPIRED": "Votre session a expiré. Veuillez vous reconnecter", + "TEXT_FORBIDDEN_ERROR": "Vous n’avez pas accès à cette action", + "TEXT_INTERNAL_SERVER_ERROR": "Erreur de chargement des données", + "TEXT_NOT_FOUND_ERROR": "Données introuvables" + }, + "DATES": { + "TEXT_TODAY": "Aujourd’hui", + "TEXT_YESTERDAY": "Hier", + "TEXT_LAST_DAYS": "{{days}} derniers jours", + "TEXT_AT_TIME": "à {{time}}", + "TEXT_TODAY_TIME": "Aujourd’hui {{time}}", + "TEXT_YESTERDAY_TIME": "Hier {{time}}" + }, + "CODE_BLOCK": { + "TEXT_COPIED_TO_CLIPBOARD": "Copié dans le presse-papiers", + "TEXT_COPY": "Copier" + }, + "SOCKET_SERVICE": { + "TEXT_CONNECTION_ERROR": "Erreur de connexion" + }, + "IMAGE_PICKER_SERVICE": { + "TEXT_ACCESS_DENIED": "Accès refusé" + }, + "ACTION_BUTTONS_MODAL": { + "BUTTON_CONFIRM": "Confirmer", + "BUTTON_CANCEL": "Annuler", + "TEXT_TITLE_CAN_NOT_BE_EMPTY": "Le titre ne peut pas être vide" + }, + "MEDIA_LIBRARY_SERVICE": { + "TEXT_SUCCESSFULLY_SAVED": "Image enregistrée avec succès", + "TEXT_ERROR_DURING_SAVING": "Une erreur s’est produite lors de l’enregistrement de l’image", + "TEXT_SETTINGS": "Paramètres", + "TEXT_SETTINGS_MESSAGE": "Autorisez l’accès à la caméra dans les paramètres. Settings > Open Web UI > Photos > All Photos" + }, + "FILE_SYSTEM_SERVICE": { + "TEXT_SHARE": "Partager {{fileName}}", + "TEXT_SHARING_IS_NOT_AVAILABLE": "Le partage n’est pas disponible sur cet appareil" + }, + "USE_AUDIO_RECORDER": { + "TEXT_NO_ACCESS": "Aucun accès", + "TEXT_APP_NEEDS_ACCESS": "L’application a besoin d’accéder au microphone de votre appareil" + }, + "NO_CONNECTION_BANNER": { + "TEXT_YOU_ARE_OFFLINE": "Vous êtes hors ligne !" + }, + "PRESSABLE_SEARCH_INPUT": { + "TEXT_SEARCH_CHATS": "Rechercher des discussions" + }, + "CHAT_ACTIONS_MENU_SHEET": { + "TEXT_PIN": "Épingler", + "TEXT_UNPIN": "Désépingler", + "TEXT_RENAME": "Renommer", + "TEXT_CLONE": "Cloner", + "TEXT_ARCHIVE": "Archiver", + "TEXT_RESTORE": "Restaurer", + "TEXT_SHARE": "Partager", + "TEXT_DOWNLOAD": "Télécharger", + "TEXT_DELETE": "Supprimer", + "TEXT_KEEP": "Conserver", + "TEXT_RENAME_CHAT": "Renommer la discussion", + "TEXT_DELETE_CHAT": "Supprimer la discussion ?", + "TEXT_THIS_WILL_DELETE": "Cela supprimera {{name}}", + "TEXT_CLONE_OF": "Clone de {{title}}", + "TEXT_CHAT_ACTIONS": "Actions de la discussion", + "TEXT_MOVE_TO_FOLDER": "Déplacer vers un dossier", + "DOWNLOAD_CHAT_OPTIONS_SHEET": { + "TEXT_EXPORT_CHAT_JSON": "Exporter la discussion (.json)", + "TEXT_PLAIN_TEXT": "Texte brut (.txt)", + "TEXT_PDF_DOCUMENT": "Document PDF (.pdf)" + }, + "MOVE_CHAT_TO_FOLDER_MODAL": { + "TEXT_SEARCH_FOLDER": "Rechercher un dossier", + "TEXT_NO_FOLDERS": "Aucun dossier", + "TEXT_CREATE_NEW_FOLDER": "Créer un dossier", + "TEXT_NO_FOLDER": "Aucun dossier" + } + }, + "SEARCH_INPUT": { + "BUTTON_CANCEL": "Annuler", + "TEXT_SEARCH_CHATS": "Rechercher des discussions" + } + } +} diff --git a/i18n/mobile/shared/ja.json b/i18n/mobile/shared/ja.json new file mode 100644 index 00000000..ddfa3e3e --- /dev/null +++ b/i18n/mobile/shared/ja.json @@ -0,0 +1,108 @@ +{ + "SHARED": { + "VALIDATION": { + "TEXT_INVALID_EMAIL": "有効なメールアドレスを入力してください", + "TEXT_REQUIRED_EMAIL": "メールアドレスを入力してください", + "TEXT_REQUIRED_PASSWORD": "パスワードを入力してください", + "TEXT_INVALID_URL": "有効なサーバー URL を入力してください(例: https://your.domain または http://192.168.1.10:3000)", + "TEXT_REQUIRED_FOLDER_NAME": "フォルダ名を入力してください" + }, + "COMMON": { + "TEXT_FEATURE_NOT_IMPLEMENTED_YET": "この機能はまだ実装されていません。", + "TEXT_NEW_CHAT": "新しいチャット", + "BUTTON_CANCEL": "キャンセル", + "BUTTON_CONFIRM": "確認", + "BUTTON_OPEN_SETTINGS": "設定を開く", + "TEXT_UNABLE_TO_OPEN_SETTINGS": "設定を開けません", + "TEXT_SETTINGS": "設定", + "TEXT_DISABLED_IN_OFFLINE_MODE": "オフラインモードでは機能が無効です", + "ACTIONS_BOTTOM_SHEET": { + "BUTTON_CANCEL": "キャンセル" + }, + "TEXT_COPIED_TO_CLIPBOARD": "クリップボードにコピーしました" + }, + "API_ERRORS": { + "TEXT_SOMETHING_WENT_WRONG": "問題が発生しました", + "TEXT_YOUR_SESSION_HAS_EXPIRED": "セッションの有効期限が切れました。再度サインインしてください", + "TEXT_FORBIDDEN_ERROR": "この操作へのアクセス権がありません", + "TEXT_INTERNAL_SERVER_ERROR": "データの読み込みエラー", + "TEXT_NOT_FOUND_ERROR": "データが見つかりません" + }, + "DATES": { + "TEXT_TODAY": "今日", + "TEXT_YESTERDAY": "昨日", + "TEXT_LAST_DAYS": "過去 {{days}} 日", + "TEXT_AT_TIME": "{{time}}", + "TEXT_TODAY_TIME": "今日 {{time}}", + "TEXT_YESTERDAY_TIME": "昨日 {{time}}" + }, + "CODE_BLOCK": { + "TEXT_COPIED_TO_CLIPBOARD": "クリップボードにコピーしました", + "TEXT_COPY": "コピー" + }, + "SOCKET_SERVICE": { + "TEXT_CONNECTION_ERROR": "接続エラー" + }, + "IMAGE_PICKER_SERVICE": { + "TEXT_ACCESS_DENIED": "アクセスが拒否されました" + }, + "ACTION_BUTTONS_MODAL": { + "BUTTON_CONFIRM": "確認", + "BUTTON_CANCEL": "キャンセル", + "TEXT_TITLE_CAN_NOT_BE_EMPTY": "タイトルは空にできません" + }, + "MEDIA_LIBRARY_SERVICE": { + "TEXT_SUCCESSFULLY_SAVED": "画像を保存しました", + "TEXT_ERROR_DURING_SAVING": "画像の保存中にエラーが発生しました", + "TEXT_SETTINGS": "設定", + "TEXT_SETTINGS_MESSAGE": "設定からカメラへのアクセスを許可してください。Settings > Open Web UI > Photos > All Photos" + }, + "FILE_SYSTEM_SERVICE": { + "TEXT_SHARE": "{{fileName}} を共有", + "TEXT_SHARING_IS_NOT_AVAILABLE": "このデバイスでは共有できません" + }, + "USE_AUDIO_RECORDER": { + "TEXT_NO_ACCESS": "アクセスなし", + "TEXT_APP_NEEDS_ACCESS": "アプリはデバイスのマイクへのアクセスが必要です" + }, + "NO_CONNECTION_BANNER": { + "TEXT_YOU_ARE_OFFLINE": "オフラインです!" + }, + "PRESSABLE_SEARCH_INPUT": { + "TEXT_SEARCH_CHATS": "チャットを検索" + }, + "CHAT_ACTIONS_MENU_SHEET": { + "TEXT_PIN": "ピン留め", + "TEXT_UNPIN": "ピン留め解除", + "TEXT_RENAME": "名前を変更", + "TEXT_CLONE": "複製", + "TEXT_ARCHIVE": "アーカイブ", + "TEXT_RESTORE": "復元", + "TEXT_SHARE": "共有", + "TEXT_DOWNLOAD": "ダウンロード", + "TEXT_DELETE": "削除", + "TEXT_KEEP": "保持", + "TEXT_RENAME_CHAT": "チャット名を変更", + "TEXT_DELETE_CHAT": "チャットを削除しますか?", + "TEXT_THIS_WILL_DELETE": "{{name}} が削除されます", + "TEXT_CLONE_OF": "{{title}} の複製", + "TEXT_CHAT_ACTIONS": "チャット操作", + "TEXT_MOVE_TO_FOLDER": "フォルダに移動", + "DOWNLOAD_CHAT_OPTIONS_SHEET": { + "TEXT_EXPORT_CHAT_JSON": "チャットをエクスポート (.json)", + "TEXT_PLAIN_TEXT": "プレーンテキスト (.txt)", + "TEXT_PDF_DOCUMENT": "PDF ドキュメント (.pdf)" + }, + "MOVE_CHAT_TO_FOLDER_MODAL": { + "TEXT_SEARCH_FOLDER": "フォルダを検索", + "TEXT_NO_FOLDERS": "フォルダがありません", + "TEXT_CREATE_NEW_FOLDER": "フォルダを作成", + "TEXT_NO_FOLDER": "フォルダなし" + } + }, + "SEARCH_INPUT": { + "BUTTON_CANCEL": "キャンセル", + "TEXT_SEARCH_CHATS": "チャットを検索" + } + } +} diff --git a/i18n/mobile/shared/pt.json b/i18n/mobile/shared/pt.json new file mode 100644 index 00000000..d1197027 --- /dev/null +++ b/i18n/mobile/shared/pt.json @@ -0,0 +1,108 @@ +{ + "SHARED": { + "VALIDATION": { + "TEXT_INVALID_EMAIL": "Digite um endereço de e-mail válido", + "TEXT_REQUIRED_EMAIL": "Digite seu e-mail", + "TEXT_REQUIRED_PASSWORD": "Digite sua senha", + "TEXT_INVALID_URL": "Digite uma URL de servidor válida, ex.: https://your.domain ou http://192.168.1.10:3000", + "TEXT_REQUIRED_FOLDER_NAME": "Digite um nome de pasta" + }, + "COMMON": { + "TEXT_FEATURE_NOT_IMPLEMENTED_YET": "O recurso ainda não foi implementado.", + "TEXT_NEW_CHAT": "Novo chat", + "BUTTON_CANCEL": "Cancelar", + "BUTTON_CONFIRM": "Confirmar", + "BUTTON_OPEN_SETTINGS": "Abrir configurações", + "TEXT_UNABLE_TO_OPEN_SETTINGS": "Não foi possível abrir as configurações", + "TEXT_SETTINGS": "Configurações", + "TEXT_DISABLED_IN_OFFLINE_MODE": "Os recursos estão desativados no modo offline", + "ACTIONS_BOTTOM_SHEET": { + "BUTTON_CANCEL": "Cancelar" + }, + "TEXT_COPIED_TO_CLIPBOARD": "Copiado para a área de transferência" + }, + "API_ERRORS": { + "TEXT_SOMETHING_WENT_WRONG": "Algo deu errado", + "TEXT_YOUR_SESSION_HAS_EXPIRED": "Sua sessão expirou. Entre novamente", + "TEXT_FORBIDDEN_ERROR": "Você não tem acesso a esta ação", + "TEXT_INTERNAL_SERVER_ERROR": "Erro ao carregar dados", + "TEXT_NOT_FOUND_ERROR": "Dados não encontrados" + }, + "DATES": { + "TEXT_TODAY": "Hoje", + "TEXT_YESTERDAY": "Ontem", + "TEXT_LAST_DAYS": "Últimos {{days}} dias", + "TEXT_AT_TIME": "às {{time}}", + "TEXT_TODAY_TIME": "Hoje {{time}}", + "TEXT_YESTERDAY_TIME": "Ontem {{time}}" + }, + "CODE_BLOCK": { + "TEXT_COPIED_TO_CLIPBOARD": "Copiado para a área de transferência", + "TEXT_COPY": "Copiar" + }, + "SOCKET_SERVICE": { + "TEXT_CONNECTION_ERROR": "Erro de conexão" + }, + "IMAGE_PICKER_SERVICE": { + "TEXT_ACCESS_DENIED": "Acesso negado" + }, + "ACTION_BUTTONS_MODAL": { + "BUTTON_CONFIRM": "Confirmar", + "BUTTON_CANCEL": "Cancelar", + "TEXT_TITLE_CAN_NOT_BE_EMPTY": "O título não pode ficar vazio" + }, + "MEDIA_LIBRARY_SERVICE": { + "TEXT_SUCCESSFULLY_SAVED": "Imagem salva com sucesso", + "TEXT_ERROR_DURING_SAVING": "Ocorreu um erro ao salvar a imagem", + "TEXT_SETTINGS": "Configurações", + "TEXT_SETTINGS_MESSAGE": "Permita o acesso à câmera nas configurações. Settings > Open Web UI > Photos > All Photos" + }, + "FILE_SYSTEM_SERVICE": { + "TEXT_SHARE": "Compartilhar {{fileName}}", + "TEXT_SHARING_IS_NOT_AVAILABLE": "O compartilhamento não está disponível neste dispositivo" + }, + "USE_AUDIO_RECORDER": { + "TEXT_NO_ACCESS": "Sem acesso", + "TEXT_APP_NEEDS_ACCESS": "O app precisa de acesso ao microfone do dispositivo" + }, + "NO_CONNECTION_BANNER": { + "TEXT_YOU_ARE_OFFLINE": "Você está offline!" + }, + "PRESSABLE_SEARCH_INPUT": { + "TEXT_SEARCH_CHATS": "Pesquisar chats" + }, + "CHAT_ACTIONS_MENU_SHEET": { + "TEXT_PIN": "Fixar", + "TEXT_UNPIN": "Desafixar", + "TEXT_RENAME": "Renomear", + "TEXT_CLONE": "Clonar", + "TEXT_ARCHIVE": "Arquivar", + "TEXT_RESTORE": "Restaurar", + "TEXT_SHARE": "Compartilhar", + "TEXT_DOWNLOAD": "Baixar", + "TEXT_DELETE": "Excluir", + "TEXT_KEEP": "Manter", + "TEXT_RENAME_CHAT": "Renomear chat", + "TEXT_DELETE_CHAT": "Excluir chat?", + "TEXT_THIS_WILL_DELETE": "Isso excluirá {{name}}", + "TEXT_CLONE_OF": "Clone de {{title}}", + "TEXT_CHAT_ACTIONS": "Ações do chat", + "TEXT_MOVE_TO_FOLDER": "Mover para pasta", + "DOWNLOAD_CHAT_OPTIONS_SHEET": { + "TEXT_EXPORT_CHAT_JSON": "Exportar chat (.json)", + "TEXT_PLAIN_TEXT": "Texto simples (.txt)", + "TEXT_PDF_DOCUMENT": "Documento PDF (.pdf)" + }, + "MOVE_CHAT_TO_FOLDER_MODAL": { + "TEXT_SEARCH_FOLDER": "Pesquisar pasta", + "TEXT_NO_FOLDERS": "Não há pastas", + "TEXT_CREATE_NEW_FOLDER": "Criar pasta", + "TEXT_NO_FOLDER": "Sem pasta" + } + }, + "SEARCH_INPUT": { + "BUTTON_CANCEL": "Cancelar", + "TEXT_SEARCH_CHATS": "Pesquisar chats" + } + } +} diff --git a/i18n/mobile/shared/ru.json b/i18n/mobile/shared/ru.json new file mode 100644 index 00000000..6ef43296 --- /dev/null +++ b/i18n/mobile/shared/ru.json @@ -0,0 +1,108 @@ +{ + "SHARED": { + "VALIDATION": { + "TEXT_INVALID_EMAIL": "Введите корректный адрес электронной почты", + "TEXT_REQUIRED_EMAIL": "Введите адрес электронной почты", + "TEXT_REQUIRED_PASSWORD": "Введите пароль", + "TEXT_INVALID_URL": "Введите корректный URL сервера, напр. https://your.domain или http://192.168.1.10:3000", + "TEXT_REQUIRED_FOLDER_NAME": "Введите название папки" + }, + "COMMON": { + "TEXT_FEATURE_NOT_IMPLEMENTED_YET": "Функция пока не реализована.", + "TEXT_NEW_CHAT": "Новый чат", + "BUTTON_CANCEL": "Отмена", + "BUTTON_CONFIRM": "Подтвердить", + "BUTTON_OPEN_SETTINGS": "Открыть настройки", + "TEXT_UNABLE_TO_OPEN_SETTINGS": "Не удалось открыть настройки", + "TEXT_SETTINGS": "Настройки", + "TEXT_DISABLED_IN_OFFLINE_MODE": "Функции недоступны в офлайн-режиме", + "ACTIONS_BOTTOM_SHEET": { + "BUTTON_CANCEL": "Отмена" + }, + "TEXT_COPIED_TO_CLIPBOARD": "Скопировано в буфер обмена" + }, + "API_ERRORS": { + "TEXT_SOMETHING_WENT_WRONG": "Что-то пошло не так", + "TEXT_YOUR_SESSION_HAS_EXPIRED": "Сеанс истёк. Войдите снова", + "TEXT_FORBIDDEN_ERROR": "У вас нет доступа к этому действию", + "TEXT_INTERNAL_SERVER_ERROR": "Ошибка загрузки данных", + "TEXT_NOT_FOUND_ERROR": "Данные не найдены" + }, + "DATES": { + "TEXT_TODAY": "Сегодня", + "TEXT_YESTERDAY": "Вчера", + "TEXT_LAST_DAYS": "Последние {{days}} дн.", + "TEXT_AT_TIME": "в {{time}}", + "TEXT_TODAY_TIME": "Сегодня {{time}}", + "TEXT_YESTERDAY_TIME": "Вчера {{time}}" + }, + "CODE_BLOCK": { + "TEXT_COPIED_TO_CLIPBOARD": "Скопировано в буфер обмена", + "TEXT_COPY": "Копировать" + }, + "SOCKET_SERVICE": { + "TEXT_CONNECTION_ERROR": "Ошибка соединения" + }, + "IMAGE_PICKER_SERVICE": { + "TEXT_ACCESS_DENIED": "Доступ запрещён" + }, + "ACTION_BUTTONS_MODAL": { + "BUTTON_CONFIRM": "Подтвердить", + "BUTTON_CANCEL": "Отмена", + "TEXT_TITLE_CAN_NOT_BE_EMPTY": "Название не может быть пустым" + }, + "MEDIA_LIBRARY_SERVICE": { + "TEXT_SUCCESSFULLY_SAVED": "Изображение успешно сохранено", + "TEXT_ERROR_DURING_SAVING": "Произошла ошибка при сохранении изображения", + "TEXT_SETTINGS": "Настройки", + "TEXT_SETTINGS_MESSAGE": "Разрешите доступ к камере в настройках. Settings > Open Web UI > Photos > All Photos" + }, + "FILE_SYSTEM_SERVICE": { + "TEXT_SHARE": "Поделиться {{fileName}}", + "TEXT_SHARING_IS_NOT_AVAILABLE": "Обмен недоступен на этом устройстве" + }, + "USE_AUDIO_RECORDER": { + "TEXT_NO_ACCESS": "Нет доступа", + "TEXT_APP_NEEDS_ACCESS": "Приложению нужен доступ к микрофону устройства" + }, + "NO_CONNECTION_BANNER": { + "TEXT_YOU_ARE_OFFLINE": "Вы офлайн!" + }, + "PRESSABLE_SEARCH_INPUT": { + "TEXT_SEARCH_CHATS": "Поиск чатов" + }, + "CHAT_ACTIONS_MENU_SHEET": { + "TEXT_PIN": "Закрепить", + "TEXT_UNPIN": "Открепить", + "TEXT_RENAME": "Переименовать", + "TEXT_CLONE": "Клонировать", + "TEXT_ARCHIVE": "В архив", + "TEXT_RESTORE": "Восстановить", + "TEXT_SHARE": "Поделиться", + "TEXT_DOWNLOAD": "Скачать", + "TEXT_DELETE": "Удалить", + "TEXT_KEEP": "Оставить", + "TEXT_RENAME_CHAT": "Переименовать чат", + "TEXT_DELETE_CHAT": "Удалить чат?", + "TEXT_THIS_WILL_DELETE": "Будет удалено: {{name}}", + "TEXT_CLONE_OF": "Копия {{title}}", + "TEXT_CHAT_ACTIONS": "Действия с чатом", + "TEXT_MOVE_TO_FOLDER": "Переместить в папку", + "DOWNLOAD_CHAT_OPTIONS_SHEET": { + "TEXT_EXPORT_CHAT_JSON": "Экспорт чата (.json)", + "TEXT_PLAIN_TEXT": "Обычный текст (.txt)", + "TEXT_PDF_DOCUMENT": "PDF-документ (.pdf)" + }, + "MOVE_CHAT_TO_FOLDER_MODAL": { + "TEXT_SEARCH_FOLDER": "Поиск папки", + "TEXT_NO_FOLDERS": "Папок нет", + "TEXT_CREATE_NEW_FOLDER": "Создать папку", + "TEXT_NO_FOLDER": "Без папки" + } + }, + "SEARCH_INPUT": { + "BUTTON_CANCEL": "Отмена", + "TEXT_SEARCH_CHATS": "Поиск чатов" + } + } +} diff --git a/i18n/mobile/shared/zh.json b/i18n/mobile/shared/zh.json new file mode 100644 index 00000000..55b6297d --- /dev/null +++ b/i18n/mobile/shared/zh.json @@ -0,0 +1,108 @@ +{ + "SHARED": { + "VALIDATION": { + "TEXT_INVALID_EMAIL": "请输入有效的电子邮箱地址", + "TEXT_REQUIRED_EMAIL": "请输入您的电子邮箱", + "TEXT_REQUIRED_PASSWORD": "请输入您的密码", + "TEXT_INVALID_URL": "请输入有效的服务器 URL,例如 https://your.domain 或 http://192.168.1.10:3000", + "TEXT_REQUIRED_FOLDER_NAME": "请输入文件夹名称" + }, + "COMMON": { + "TEXT_FEATURE_NOT_IMPLEMENTED_YET": "功能尚未实现。", + "TEXT_NEW_CHAT": "新聊天", + "BUTTON_CANCEL": "取消", + "BUTTON_CONFIRM": "确认", + "BUTTON_OPEN_SETTINGS": "打开设置", + "TEXT_UNABLE_TO_OPEN_SETTINGS": "无法打开设置", + "TEXT_SETTINGS": "设置", + "TEXT_DISABLED_IN_OFFLINE_MODE": "离线模式下功能已禁用", + "ACTIONS_BOTTOM_SHEET": { + "BUTTON_CANCEL": "取消" + }, + "TEXT_COPIED_TO_CLIPBOARD": "已复制到剪贴板" + }, + "API_ERRORS": { + "TEXT_SOMETHING_WENT_WRONG": "出了点问题", + "TEXT_YOUR_SESSION_HAS_EXPIRED": "会话已过期。请重新登录", + "TEXT_FORBIDDEN_ERROR": "您无权执行此操作", + "TEXT_INTERNAL_SERVER_ERROR": "加载数据出错", + "TEXT_NOT_FOUND_ERROR": "未找到数据" + }, + "DATES": { + "TEXT_TODAY": "今天", + "TEXT_YESTERDAY": "昨天", + "TEXT_LAST_DAYS": "最近 {{days}} 天", + "TEXT_AT_TIME": "{{time}}", + "TEXT_TODAY_TIME": "今天 {{time}}", + "TEXT_YESTERDAY_TIME": "昨天 {{time}}" + }, + "CODE_BLOCK": { + "TEXT_COPIED_TO_CLIPBOARD": "已复制到剪贴板", + "TEXT_COPY": "复制" + }, + "SOCKET_SERVICE": { + "TEXT_CONNECTION_ERROR": "连接错误" + }, + "IMAGE_PICKER_SERVICE": { + "TEXT_ACCESS_DENIED": "访问被拒绝" + }, + "ACTION_BUTTONS_MODAL": { + "BUTTON_CONFIRM": "确认", + "BUTTON_CANCEL": "取消", + "TEXT_TITLE_CAN_NOT_BE_EMPTY": "标题不能为空" + }, + "MEDIA_LIBRARY_SERVICE": { + "TEXT_SUCCESSFULLY_SAVED": "图片保存成功", + "TEXT_ERROR_DURING_SAVING": "保存图片时出错", + "TEXT_SETTINGS": "设置", + "TEXT_SETTINGS_MESSAGE": "请在设置中允许相机访问。Settings > Open Web UI > Photos > All Photos" + }, + "FILE_SYSTEM_SERVICE": { + "TEXT_SHARE": "分享 {{fileName}}", + "TEXT_SHARING_IS_NOT_AVAILABLE": "此设备不支持分享" + }, + "USE_AUDIO_RECORDER": { + "TEXT_NO_ACCESS": "无访问权限", + "TEXT_APP_NEEDS_ACCESS": "应用需要访问设备麦克风" + }, + "NO_CONNECTION_BANNER": { + "TEXT_YOU_ARE_OFFLINE": "您处于离线状态!" + }, + "PRESSABLE_SEARCH_INPUT": { + "TEXT_SEARCH_CHATS": "搜索聊天" + }, + "CHAT_ACTIONS_MENU_SHEET": { + "TEXT_PIN": "置顶", + "TEXT_UNPIN": "取消置顶", + "TEXT_RENAME": "重命名", + "TEXT_CLONE": "克隆", + "TEXT_ARCHIVE": "归档", + "TEXT_RESTORE": "恢复", + "TEXT_SHARE": "分享", + "TEXT_DOWNLOAD": "下载", + "TEXT_DELETE": "删除", + "TEXT_KEEP": "保留", + "TEXT_RENAME_CHAT": "重命名聊天", + "TEXT_DELETE_CHAT": "删除聊天?", + "TEXT_THIS_WILL_DELETE": "这将删除 {{name}}", + "TEXT_CLONE_OF": "{{title}} 的副本", + "TEXT_CHAT_ACTIONS": "聊天操作", + "TEXT_MOVE_TO_FOLDER": "移动到文件夹", + "DOWNLOAD_CHAT_OPTIONS_SHEET": { + "TEXT_EXPORT_CHAT_JSON": "导出聊天 (.json)", + "TEXT_PLAIN_TEXT": "纯文本 (.txt)", + "TEXT_PDF_DOCUMENT": "PDF 文档 (.pdf)" + }, + "MOVE_CHAT_TO_FOLDER_MODAL": { + "TEXT_SEARCH_FOLDER": "搜索文件夹", + "TEXT_NO_FOLDERS": "没有文件夹", + "TEXT_CREATE_NEW_FOLDER": "创建文件夹", + "TEXT_NO_FOLDER": "无文件夹" + } + }, + "SEARCH_INPUT": { + "BUTTON_CANCEL": "取消", + "TEXT_SEARCH_CHATS": "搜索聊天" + } + } +} diff --git a/libs/shared/data-access/app-state/src/state.ts b/libs/shared/data-access/app-state/src/state.ts index ed3db746..e78f262b 100644 --- a/libs/shared/data-access/app-state/src/state.ts +++ b/libs/shared/data-access/app-state/src/state.ts @@ -1,15 +1,23 @@ import { observable, Observable } from '@legendapp/state'; +import { getLocales } from 'expo-localization'; import { authState$ } from '@open-webui-react-native/shared/data-access/auth'; import { cookieService } from '@open-webui-react-native/shared/data-access/cookie'; import { appStorageService } from '@open-webui-react-native/shared/data-access/storage'; import { constants, LanguageCode } from '@open-webui-react-native/shared/utils/config'; +const isSupportedLocale = (locale?: string | null): locale is LanguageCode => + Object.values(LanguageCode).includes(locale as LanguageCode); + const getInitialLocale = (): LanguageCode => { const storedLocale = appStorageService.locale.get(); - return Object.values(LanguageCode).includes(storedLocale as LanguageCode) - ? (storedLocale as LanguageCode) - : constants.defaultLocale; + if (isSupportedLocale(storedLocale)) { + return storedLocale; + } + + const deviceLanguageCode = getLocales()[0]?.languageCode; + + return isSupportedLocale(deviceLanguageCode) ? deviceLanguageCode : constants.defaultLocale; }; interface AppState { diff --git a/libs/shared/utils/config/src/constants.ts b/libs/shared/utils/config/src/constants.ts index 83a19217..a6439bf9 100644 --- a/libs/shared/utils/config/src/constants.ts +++ b/libs/shared/utils/config/src/constants.ts @@ -4,4 +4,13 @@ export const constants = { defaultLocale: LanguageCode.ENGLISH, }; -export const availableLanguages = [{ code: LanguageCode.ENGLISH, label: 'English' }] as const; +export const availableLanguages = [ + { code: LanguageCode.ENGLISH, label: 'English' }, + { code: LanguageCode.RUSSIAN, label: 'Русский' }, + { code: LanguageCode.SPANISH, label: 'Español' }, + { code: LanguageCode.PORTUGUESE, label: 'Português' }, + { code: LanguageCode.FRENCH, label: 'Français' }, + { code: LanguageCode.GERMAN, label: 'Deutsch' }, + { code: LanguageCode.CHINESE, label: '中文' }, + { code: LanguageCode.JAPANESE, label: '日本語' }, +] as const; diff --git a/libs/shared/utils/config/src/enums/language-code.ts b/libs/shared/utils/config/src/enums/language-code.ts index 4cbf7efd..91a0f032 100644 --- a/libs/shared/utils/config/src/enums/language-code.ts +++ b/libs/shared/utils/config/src/enums/language-code.ts @@ -1,3 +1,10 @@ export enum LanguageCode { ENGLISH = 'en', + RUSSIAN = 'ru', + SPANISH = 'es', + PORTUGUESE = 'pt', + FRENCH = 'fr', + GERMAN = 'de', + CHINESE = 'zh', + JAPANESE = 'ja', } diff --git a/nativewind-env.d.ts b/nativewind-env.d.ts index 533ae610..e1b556fa 100644 --- a/nativewind-env.d.ts +++ b/nativewind-env.d.ts @@ -1,4 +1,4 @@ /// // NOTE: This file should not be edited and should be committed with your source code. It is generated by NativeWind. -declare module '*.css' {} +declare module '*.css'; diff --git a/package-lock.json b/package-lock.json index c094c0cb..c2c649f8 100644 --- a/package-lock.json +++ b/package-lock.json @@ -69,6 +69,7 @@ "immer": "^10.1.1", "lodash-es": "^4.17.21", "luxon": "^3.6.1", + "make-plural": "^7.5.0", "markdown-it-math": "^5.2.1", "nativewind": "^4.1.23", "patch-package": "^8.0.0", diff --git a/package.json b/package.json index 4bf58fc7..674471f9 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "immer": "^10.1.1", "lodash-es": "^4.17.21", "luxon": "^3.6.1", + "make-plural": "^7.5.0", "markdown-it-math": "^5.2.1", "nativewind": "^4.1.23", "patch-package": "^8.0.0",