@umituz/react-native-localization 1.7.7 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/package.json +3 -3
- package/src/infrastructure/config/i18n.ts +31 -124
- package/src/infrastructure/config/languages.ts +80 -144
- package/src/infrastructure/config/languagesData.ts +0 -28
- package/src/infrastructure/locales/en-US/alerts.json +107 -0
- package/src/infrastructure/locales/en-US/clipboard.json +9 -0
- package/src/infrastructure/locales/en-US/device.json +14 -0
- package/src/infrastructure/locales/en-US/editor.json +64 -0
- package/src/infrastructure/locales/en-US/haptics.json +6 -0
- package/src/infrastructure/locales/en-US/home.json +58 -16
- package/src/infrastructure/locales/en-US/index.ts +1 -1
- package/src/infrastructure/locales/en-US/navigation.json +3 -20
- package/src/infrastructure/locales/en-US/projects.json +34 -0
- package/src/infrastructure/locales/en-US/sharing.json +8 -0
- package/src/infrastructure/locales/en-US/templates.json +28 -0
package/README.md
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
# @umituz/react-native-localization
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
English-only localization system for React Native apps with i18n support. Built with Domain-Driven Design principles and TypeScript.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
7
|
-
- **
|
|
8
|
-
- **Automatic Device Locale Detection**:
|
|
7
|
+
- **English-Only Support**: Optimized for English (en-US) language only
|
|
8
|
+
- **Automatic Device Locale Detection**: Maps all device locales to English (en-US)
|
|
9
9
|
- **Persistent Language Preferences**: Saves user's language choice using AsyncStorage
|
|
10
|
-
- **Translation Management
|
|
10
|
+
- **Simple Translation Management**: Easy-to-use translation files for English content
|
|
11
11
|
- **Type-Safe**: Full TypeScript support with type definitions
|
|
12
12
|
- **Zero Configuration**: Works out of the box with sensible defaults
|
|
13
13
|
- **Production Ready**: Battle-tested in production apps
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@umituz/react-native-localization",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "1.8.1",
|
|
4
|
+
"description": "English-only localization system for React Native apps with i18n support",
|
|
5
5
|
"main": "./src/index.ts",
|
|
6
6
|
"types": "./src/index.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
"peerDependencies": {
|
|
46
46
|
"react": ">=18.2.0",
|
|
47
47
|
"react-native": ">=0.74.0",
|
|
48
|
-
"@react-navigation/native": "
|
|
48
|
+
"@react-navigation/native": ">=6.0.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependenciesMeta": {
|
|
51
51
|
"@react-navigation/native": {
|
|
@@ -1,133 +1,58 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* i18next Configuration
|
|
3
|
-
*
|
|
2
|
+
* i18next Configuration for English-only
|
|
3
|
+
* Simple translation structure - only en-US supported
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* - No manual imports needed - all languages loaded automatically
|
|
5
|
+
* SINGLE LANGUAGE LOADING:
|
|
6
|
+
* - Only loads en-US translations
|
|
8
7
|
* - Project translations merged with package defaults
|
|
9
8
|
*/
|
|
10
9
|
|
|
11
10
|
import i18n from 'i18next';
|
|
12
11
|
import { initReactI18next } from 'react-i18next';
|
|
13
|
-
import {
|
|
12
|
+
import { DEFAULT_LANGUAGE } from './languages';
|
|
14
13
|
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* Uses Metro bundler's require.context to automatically discover and load
|
|
19
|
-
* all language directories. No manual imports needed!
|
|
20
|
-
*
|
|
21
|
-
* Structure:
|
|
22
|
-
* locales/
|
|
23
|
-
* ar-SA/index.ts
|
|
24
|
-
* bg-BG/index.ts
|
|
25
|
-
* en-US/index.ts
|
|
26
|
-
* ... (all languages auto-discovered)
|
|
27
|
-
*/
|
|
28
|
-
|
|
29
|
-
// Auto-load all package locale directories using require.context
|
|
30
|
-
// This automatically discovers all language folders (ar-SA, bg-BG, en-US, etc.)
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
32
|
-
const packageLocalesContext = (require as any).context('../locales', true, /\/index\.ts$/);
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Load all package translations automatically
|
|
36
|
-
* Extracts language code from path (e.g., './ar-SA/index.ts' -> 'ar-SA')
|
|
15
|
+
* Load en-US package translations
|
|
37
16
|
*/
|
|
38
17
|
const loadPackageTranslations = (): Record<string, any> => {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
packageTranslations[languageCode] = translations.default || translations;
|
|
49
|
-
} catch (error) {
|
|
50
|
-
// Ignore individual language loading errors
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
return packageTranslations;
|
|
18
|
+
try {
|
|
19
|
+
// Load only en-US translations
|
|
20
|
+
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
21
|
+
const translations = require('../locales/en-US');
|
|
22
|
+
return { 'en-US': translations.default || translations };
|
|
23
|
+
} catch (error) {
|
|
24
|
+
// Fallback to empty translations
|
|
25
|
+
return { 'en-US': {} };
|
|
26
|
+
}
|
|
56
27
|
};
|
|
57
28
|
|
|
58
29
|
const packageTranslations = loadPackageTranslations();
|
|
59
30
|
|
|
60
31
|
/**
|
|
61
|
-
* Try to load project-specific translations
|
|
32
|
+
* Try to load project-specific en-US translations
|
|
62
33
|
* Metro bundler will resolve these at build time if they exist
|
|
63
34
|
* If they don't exist, the require will fail gracefully
|
|
64
35
|
*/
|
|
65
36
|
let projectTranslations: Record<string, any> = {};
|
|
66
37
|
|
|
67
38
|
// Try to load project translations from common paths
|
|
68
|
-
// Metro bundler will include these if they exist at build time
|
|
69
39
|
try {
|
|
70
|
-
// Try DDD structure path
|
|
40
|
+
// Try DDD structure path
|
|
71
41
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
projectLocalesContext.keys().forEach((key: string) => {
|
|
75
|
-
const match = key.match(/\.\/([^/]+)\/index\.ts$/);
|
|
76
|
-
if (match) {
|
|
77
|
-
const languageCode = match[1];
|
|
78
|
-
try {
|
|
79
|
-
const translations = projectLocalesContext(key);
|
|
80
|
-
if (!projectTranslations[languageCode]) {
|
|
81
|
-
projectTranslations[languageCode] = {};
|
|
82
|
-
}
|
|
83
|
-
projectTranslations[languageCode] = translations.default || translations;
|
|
84
|
-
} catch (error) {
|
|
85
|
-
// Ignore individual language loading errors
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
});
|
|
42
|
+
const translations = require('../../../../../../src/domains/localization/infrastructure/locales/en-US');
|
|
43
|
+
projectTranslations['en-US'] = translations.default || translations;
|
|
89
44
|
} catch (e1) {
|
|
90
45
|
try {
|
|
91
46
|
// Try alternative DDD structure path
|
|
92
47
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
93
|
-
const
|
|
94
|
-
|
|
95
|
-
projectLocalesContext.keys().forEach((key: string) => {
|
|
96
|
-
const match = key.match(/\.\/([^/]+)\/index\.ts$/);
|
|
97
|
-
if (match) {
|
|
98
|
-
const languageCode = match[1];
|
|
99
|
-
try {
|
|
100
|
-
const translations = projectLocalesContext(key);
|
|
101
|
-
if (!projectTranslations[languageCode]) {
|
|
102
|
-
projectTranslations[languageCode] = {};
|
|
103
|
-
}
|
|
104
|
-
projectTranslations[languageCode] = translations.default || translations;
|
|
105
|
-
} catch (error) {
|
|
106
|
-
// Ignore individual language errors
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
});
|
|
48
|
+
const translations = require('../../../../../../domains/localization/infrastructure/locales/en-US');
|
|
49
|
+
projectTranslations['en-US'] = translations.default || translations;
|
|
110
50
|
} catch (e2) {
|
|
111
51
|
try {
|
|
112
52
|
// Try simple structure path
|
|
113
53
|
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
|
114
|
-
const
|
|
115
|
-
|
|
116
|
-
projectLocalesContext.keys().forEach((key: string) => {
|
|
117
|
-
const match = key.match(/\.\/([^/]+)\/index\.ts$/);
|
|
118
|
-
if (match) {
|
|
119
|
-
const languageCode = match[1];
|
|
120
|
-
try {
|
|
121
|
-
const translations = projectLocalesContext(key);
|
|
122
|
-
if (!projectTranslations[languageCode]) {
|
|
123
|
-
projectTranslations[languageCode] = {};
|
|
124
|
-
}
|
|
125
|
-
projectTranslations[languageCode] = translations.default || translations;
|
|
126
|
-
} catch (error) {
|
|
127
|
-
// Ignore individual language errors
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
});
|
|
54
|
+
const translations = require('../../../../../../src/locales/en-US');
|
|
55
|
+
projectTranslations['en-US'] = translations.default || translations;
|
|
131
56
|
} catch (e3) {
|
|
132
57
|
// No project translations found - this is OK, use package defaults only
|
|
133
58
|
}
|
|
@@ -170,45 +95,28 @@ const mergeTranslations = (packageTranslations: any, projectTranslations: any):
|
|
|
170
95
|
};
|
|
171
96
|
|
|
172
97
|
/**
|
|
173
|
-
* Build resources object for
|
|
174
|
-
* Automatically includes all package languages + project languages
|
|
98
|
+
* Build resources object for en-US only
|
|
175
99
|
*/
|
|
176
100
|
const buildResources = (): Record<string, { translation: any }> => {
|
|
177
|
-
const
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
...Object.keys(projectTranslations),
|
|
183
|
-
]);
|
|
184
|
-
|
|
185
|
-
// Build resources for each language
|
|
186
|
-
allLanguageCodes.forEach((languageCode) => {
|
|
187
|
-
const packageTranslation = packageTranslations[languageCode] || {};
|
|
188
|
-
const projectTranslation = projectTranslations[languageCode] || {};
|
|
189
|
-
|
|
190
|
-
resources[languageCode] = {
|
|
101
|
+
const packageTranslation = packageTranslations['en-US'] || {};
|
|
102
|
+
const projectTranslation = projectTranslations['en-US'] || {};
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
'en-US': {
|
|
191
106
|
translation: mergeTranslations(packageTranslation, projectTranslation),
|
|
192
|
-
}
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
return resources;
|
|
107
|
+
},
|
|
108
|
+
};
|
|
196
109
|
};
|
|
197
110
|
|
|
198
111
|
const resources = buildResources();
|
|
199
112
|
|
|
200
113
|
// Debug: Log loaded resources in development (only once to prevent spam)
|
|
201
|
-
// Use global flag to prevent multiple logs when module is imported multiple times
|
|
202
114
|
if (typeof globalThis !== 'undefined' && !(globalThis as any).__i18n_resources_logged) {
|
|
203
115
|
/* eslint-disable-next-line no-console */
|
|
204
116
|
if (typeof __DEV__ !== 'undefined' && __DEV__) {
|
|
205
117
|
console.log('🌍 i18n Resources loaded:', {
|
|
206
118
|
languages: Object.keys(resources),
|
|
207
119
|
enUSKeys: resources['en-US']?.translation ? Object.keys(resources['en-US'].translation) : [],
|
|
208
|
-
hasGoals: !!resources['en-US']?.translation?.goals,
|
|
209
|
-
navigationKeys: resources['en-US']?.translation?.navigation ? Object.keys(resources['en-US'].translation.navigation) : [],
|
|
210
|
-
hasMilestones: !!resources['en-US']?.translation?.navigation?.milestones,
|
|
211
|
-
hasStatistics: !!resources['en-US']?.translation?.navigation?.statistics,
|
|
212
120
|
});
|
|
213
121
|
(globalThis as any).__i18n_resources_logged = true;
|
|
214
122
|
}
|
|
@@ -267,7 +175,6 @@ const initializeI18n = () => {
|
|
|
267
175
|
console.log('✅ i18n initialized:', {
|
|
268
176
|
language: i18n.language,
|
|
269
177
|
hasResource: !!i18n.getResourceBundle(i18n.language, 'translation'),
|
|
270
|
-
goalsTitle: i18n.t('goals.list.title', { defaultValue: 'NOT_FOUND' }),
|
|
271
178
|
});
|
|
272
179
|
}
|
|
273
180
|
} catch (error) {
|
|
@@ -27,42 +27,13 @@ export const DEFAULT_LANGUAGE = 'en-US';
|
|
|
27
27
|
|
|
28
28
|
/**
|
|
29
29
|
* Locale mapping for device locales to supported app locales
|
|
30
|
-
* Maps short codes
|
|
30
|
+
* Maps short codes and regional variants to en-US
|
|
31
31
|
*
|
|
32
|
-
*
|
|
33
|
-
* -
|
|
34
|
-
* - iOS regional variants → Our standard locales
|
|
35
|
-
* - All 29 supported languages included
|
|
32
|
+
* SIMPLE MAPPING:
|
|
33
|
+
* - All variants map to en-US (only supported language)
|
|
36
34
|
*/
|
|
37
35
|
const LOCALE_MAPPING: Record<string, string> = {
|
|
38
|
-
//
|
|
39
|
-
'ar': 'ar-SA',
|
|
40
|
-
'ar-SA': 'ar-SA',
|
|
41
|
-
'ar-AE': 'ar-SA',
|
|
42
|
-
'ar-EG': 'ar-SA',
|
|
43
|
-
|
|
44
|
-
// Bulgarian
|
|
45
|
-
'bg': 'bg-BG',
|
|
46
|
-
'bg-BG': 'bg-BG',
|
|
47
|
-
|
|
48
|
-
// Czech
|
|
49
|
-
'cs': 'cs-CZ',
|
|
50
|
-
'cs-CZ': 'cs-CZ',
|
|
51
|
-
|
|
52
|
-
// Danish
|
|
53
|
-
'da': 'da-DK',
|
|
54
|
-
'da-DK': 'da-DK',
|
|
55
|
-
|
|
56
|
-
// German
|
|
57
|
-
'de': 'de-DE',
|
|
58
|
-
'de-DE': 'de-DE',
|
|
59
|
-
'de-AT': 'de-DE',
|
|
60
|
-
'de-CH': 'de-DE',
|
|
61
|
-
|
|
62
|
-
// Greek (iOS has el, we map to en-US fallback since we don't support Greek)
|
|
63
|
-
'el': 'en-US',
|
|
64
|
-
|
|
65
|
-
// English variants
|
|
36
|
+
// All English variants map to en-US
|
|
66
37
|
'en': 'en-US',
|
|
67
38
|
'en-US': 'en-US',
|
|
68
39
|
'en-GB': 'en-US',
|
|
@@ -72,119 +43,84 @@ const LOCALE_MAPPING: Record<string, string> = {
|
|
|
72
43
|
'en-IE': 'en-US',
|
|
73
44
|
'en-ZA': 'en-US',
|
|
74
45
|
|
|
75
|
-
//
|
|
76
|
-
'
|
|
77
|
-
'
|
|
78
|
-
'
|
|
79
|
-
'
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
'
|
|
83
|
-
'
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
'
|
|
87
|
-
'
|
|
88
|
-
'
|
|
89
|
-
'
|
|
90
|
-
'
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
'
|
|
94
|
-
'
|
|
95
|
-
|
|
96
|
-
|
|
46
|
+
// All other languages map to en-US (fallback)
|
|
47
|
+
'ar': 'en-US',
|
|
48
|
+
'ar-SA': 'en-US',
|
|
49
|
+
'ar-AE': 'en-US',
|
|
50
|
+
'ar-EG': 'en-US',
|
|
51
|
+
'bg': 'en-US',
|
|
52
|
+
'bg-BG': 'en-US',
|
|
53
|
+
'cs': 'en-US',
|
|
54
|
+
'cs-CZ': 'en-US',
|
|
55
|
+
'da': 'en-US',
|
|
56
|
+
'da-DK': 'en-US',
|
|
57
|
+
'de': 'en-US',
|
|
58
|
+
'de-DE': 'en-US',
|
|
59
|
+
'de-AT': 'en-US',
|
|
60
|
+
'de-CH': 'en-US',
|
|
61
|
+
'el': 'en-US',
|
|
62
|
+
'es': 'en-US',
|
|
63
|
+
'es-ES': 'en-US',
|
|
64
|
+
'es-MX': 'en-US',
|
|
65
|
+
'es-AR': 'en-US',
|
|
66
|
+
'fi': 'en-US',
|
|
67
|
+
'fi-FI': 'en-US',
|
|
68
|
+
'fr': 'en-US',
|
|
69
|
+
'fr-FR': 'en-US',
|
|
70
|
+
'fr-CA': 'en-US',
|
|
71
|
+
'fr-BE': 'en-US',
|
|
72
|
+
'fr-CH': 'en-US',
|
|
73
|
+
'hi': 'en-US',
|
|
74
|
+
'hi-IN': 'en-US',
|
|
97
75
|
'hr': 'en-US',
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
'
|
|
101
|
-
'
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
'
|
|
105
|
-
'
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
'
|
|
109
|
-
'
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
'
|
|
113
|
-
'
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
'
|
|
117
|
-
'
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
'
|
|
121
|
-
'
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
'
|
|
125
|
-
'no': 'no-NO',
|
|
126
|
-
'no-NO': 'no-NO',
|
|
127
|
-
|
|
128
|
-
// Dutch
|
|
129
|
-
'nl': 'nl-NL',
|
|
130
|
-
'nl-NL': 'nl-NL',
|
|
131
|
-
'nl-BE': 'nl-NL',
|
|
132
|
-
|
|
133
|
-
// Polish
|
|
134
|
-
'pl': 'pl-PL',
|
|
135
|
-
'pl-PL': 'pl-PL',
|
|
136
|
-
|
|
137
|
-
// Portuguese
|
|
138
|
-
'pt': 'pt-PT',
|
|
139
|
-
'pt-PT': 'pt-PT',
|
|
140
|
-
'pt-BR': 'pt-PT',
|
|
141
|
-
|
|
142
|
-
// Romanian
|
|
143
|
-
'ro': 'ro-RO',
|
|
144
|
-
'ro-RO': 'ro-RO',
|
|
145
|
-
|
|
146
|
-
// Russian
|
|
147
|
-
'ru': 'ru-RU',
|
|
148
|
-
'ru-RU': 'ru-RU',
|
|
149
|
-
|
|
150
|
-
// Slovak (iOS has sk, we map to en-US fallback since we don't support Slovak)
|
|
76
|
+
'hu': 'en-US',
|
|
77
|
+
'hu-HU': 'en-US',
|
|
78
|
+
'id': 'en-US',
|
|
79
|
+
'id-ID': 'en-US',
|
|
80
|
+
'it': 'en-US',
|
|
81
|
+
'it-IT': 'en-US',
|
|
82
|
+
'ja': 'en-US',
|
|
83
|
+
'ja-JP': 'en-US',
|
|
84
|
+
'ko': 'en-US',
|
|
85
|
+
'ko-KR': 'en-US',
|
|
86
|
+
'ms': 'en-US',
|
|
87
|
+
'ms-MY': 'en-US',
|
|
88
|
+
'nb': 'en-US',
|
|
89
|
+
'no': 'en-US',
|
|
90
|
+
'no-NO': 'en-US',
|
|
91
|
+
'nl': 'en-US',
|
|
92
|
+
'nl-NL': 'en-US',
|
|
93
|
+
'nl-BE': 'en-US',
|
|
94
|
+
'pl': 'en-US',
|
|
95
|
+
'pl-PL': 'en-US',
|
|
96
|
+
'pt': 'en-US',
|
|
97
|
+
'pt-PT': 'en-US',
|
|
98
|
+
'pt-BR': 'en-US',
|
|
99
|
+
'ro': 'en-US',
|
|
100
|
+
'ro-RO': 'en-US',
|
|
101
|
+
'ru': 'en-US',
|
|
102
|
+
'ru-RU': 'en-US',
|
|
151
103
|
'sk': 'en-US',
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
'
|
|
155
|
-
'
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
'
|
|
159
|
-
'
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
'
|
|
163
|
-
'
|
|
164
|
-
'
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
'
|
|
168
|
-
'
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
'
|
|
172
|
-
'uk-UA': 'uk-UA',
|
|
173
|
-
|
|
174
|
-
// Vietnamese
|
|
175
|
-
'vi': 'vi-VN',
|
|
176
|
-
'vi-VN': 'vi-VN',
|
|
177
|
-
|
|
178
|
-
// Chinese Simplified (iOS uses zh-Hans)
|
|
179
|
-
'zh': 'zh-CN',
|
|
180
|
-
'zh-CN': 'zh-CN',
|
|
181
|
-
'zh-Hans': 'zh-CN',
|
|
182
|
-
'zh-Hans-CN': 'zh-CN',
|
|
183
|
-
|
|
184
|
-
// Chinese Traditional (iOS uses zh-Hant, we map to zh-CN since we only support Simplified)
|
|
185
|
-
'zh-Hant': 'zh-CN',
|
|
186
|
-
'zh-TW': 'zh-CN',
|
|
187
|
-
'zh-HK': 'zh-CN',
|
|
104
|
+
'sv': 'en-US',
|
|
105
|
+
'sv-SE': 'en-US',
|
|
106
|
+
'th': 'en-US',
|
|
107
|
+
'th-TH': 'en-US',
|
|
108
|
+
'tl': 'en-US',
|
|
109
|
+
'tl-PH': 'en-US',
|
|
110
|
+
'fil': 'en-US',
|
|
111
|
+
'tr': 'en-US',
|
|
112
|
+
'tr-TR': 'en-US',
|
|
113
|
+
'uk': 'en-US',
|
|
114
|
+
'uk-UA': 'en-US',
|
|
115
|
+
'vi': 'en-US',
|
|
116
|
+
'vi-VN': 'en-US',
|
|
117
|
+
'zh': 'en-US',
|
|
118
|
+
'zh-CN': 'en-US',
|
|
119
|
+
'zh-Hans': 'en-US',
|
|
120
|
+
'zh-Hans-CN': 'en-US',
|
|
121
|
+
'zh-Hant': 'en-US',
|
|
122
|
+
'zh-TW': 'en-US',
|
|
123
|
+
'zh-HK': 'en-US',
|
|
188
124
|
};
|
|
189
125
|
|
|
190
126
|
export const getLanguageByCode = (code: string): Language | undefined => {
|
|
@@ -13,35 +13,7 @@ export interface Language {
|
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
export const LANGUAGES: Language[] = [
|
|
16
|
-
{ code: 'ar-SA', name: 'Arabic', nativeName: 'العربية', flag: '🇸🇦' },
|
|
17
|
-
{ code: 'bg-BG', name: 'Bulgarian', nativeName: 'Български', flag: '🇧🇬' },
|
|
18
|
-
{ code: 'cs-CZ', name: 'Czech', nativeName: 'Čeština', flag: '🇨🇿' },
|
|
19
|
-
{ code: 'da-DK', name: 'Danish', nativeName: 'Dansk', flag: '🇩🇰' },
|
|
20
|
-
{ code: 'de-DE', name: 'German', nativeName: 'Deutsch', flag: '🇩🇪' },
|
|
21
16
|
{ code: 'en-US', name: 'English', nativeName: 'English', flag: '🇺🇸' },
|
|
22
|
-
{ code: 'es-ES', name: 'Spanish', nativeName: 'Español', flag: '🇪🇸' },
|
|
23
|
-
{ code: 'fi-FI', name: 'Finnish', nativeName: 'Suomi', flag: '🇫🇮' },
|
|
24
|
-
{ code: 'fr-FR', name: 'French', nativeName: 'Français', flag: '🇫🇷' },
|
|
25
|
-
{ code: 'hi-IN', name: 'Hindi', nativeName: 'हिन्दी', flag: '🇮🇳' },
|
|
26
|
-
{ code: 'hu-HU', name: 'Hungarian', nativeName: 'Magyar', flag: '🇭🇺' },
|
|
27
|
-
{ code: 'id-ID', name: 'Indonesian', nativeName: 'Bahasa Indonesia', flag: '🇮🇩' },
|
|
28
|
-
{ code: 'it-IT', name: 'Italian', nativeName: 'Italiano', flag: '🇮🇹' },
|
|
29
|
-
{ code: 'ja-JP', name: 'Japanese', nativeName: '日本語', flag: '🇯🇵' },
|
|
30
|
-
{ code: 'ko-KR', name: 'Korean', nativeName: '한국어', flag: '🇰🇷' },
|
|
31
|
-
{ code: 'ms-MY', name: 'Malay', nativeName: 'Bahasa Melayu', flag: '🇲🇾' },
|
|
32
|
-
{ code: 'nl-NL', name: 'Dutch', nativeName: 'Nederlands', flag: '🇳🇱' },
|
|
33
|
-
{ code: 'no-NO', name: 'Norwegian', nativeName: 'Norsk', flag: '🇳🇴' },
|
|
34
|
-
{ code: 'pl-PL', name: 'Polish', nativeName: 'Polski', flag: '🇵🇱' },
|
|
35
|
-
{ code: 'pt-PT', name: 'Portuguese', nativeName: 'Português', flag: '🇵🇹' },
|
|
36
|
-
{ code: 'ro-RO', name: 'Romanian', nativeName: 'Română', flag: '🇷🇴' },
|
|
37
|
-
{ code: 'ru-RU', name: 'Russian', nativeName: 'Русский', flag: '🇷🇺' },
|
|
38
|
-
{ code: 'sv-SE', name: 'Swedish', nativeName: 'Svenska', flag: '🇸🇪' },
|
|
39
|
-
{ code: 'th-TH', name: 'Thai', nativeName: 'ไทย', flag: '🇹🇭' },
|
|
40
|
-
{ code: 'tl-PH', name: 'Filipino', nativeName: 'Filipino', flag: '🇵🇭' },
|
|
41
|
-
{ code: 'tr-TR', name: 'Turkish', nativeName: 'Türkçe', flag: '🇹🇷' },
|
|
42
|
-
{ code: 'uk-UA', name: 'Ukrainian', nativeName: 'Українська', flag: '🇺🇦' },
|
|
43
|
-
{ code: 'vi-VN', name: 'Vietnamese', nativeName: 'Tiếng Việt', flag: '🇻🇳' },
|
|
44
|
-
{ code: 'zh-CN', name: 'Chinese (Simplified)', nativeName: '简体中文', flag: '🇨🇳' },
|
|
45
17
|
];
|
|
46
18
|
|
|
47
19
|
/**
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
{
|
|
2
|
+
"error": {
|
|
3
|
+
"title": "Error",
|
|
4
|
+
"generic": "An error occurred",
|
|
5
|
+
"failed_to_select_video": "Failed to select video",
|
|
6
|
+
"failed_to_select_images": "Failed to select images",
|
|
7
|
+
"failed_to_select_audio": "Failed to select audio file",
|
|
8
|
+
"failed_to_generate_video": "Failed to generate video",
|
|
9
|
+
"failed_to_transform_video": "Failed to transform video",
|
|
10
|
+
"failed_to_generate_script": "Failed to generate script",
|
|
11
|
+
"failed_to_export": "Export failed",
|
|
12
|
+
"failed_to_pick_image": "Failed to pick image. Please try again.",
|
|
13
|
+
"failed_to_take_photo": "Failed to take photo. Please try again.",
|
|
14
|
+
"project_not_found": "Project not found",
|
|
15
|
+
"cannot_delete_last_scene": "Cannot delete the last scene",
|
|
16
|
+
"configuration_error": "Firebase is not configured. Please check your environment settings.",
|
|
17
|
+
"sign_in_failed": "Failed to sign in. Please try again.",
|
|
18
|
+
"sign_up_failed": "Failed to create account. Please try again.",
|
|
19
|
+
"sign_in_google_failed": "Failed to sign in with Google.",
|
|
20
|
+
"sign_up_google_failed": "Failed to sign up with Google."
|
|
21
|
+
},
|
|
22
|
+
"success": {
|
|
23
|
+
"title": "Success",
|
|
24
|
+
"project_saved": "Project saved successfully!",
|
|
25
|
+
"text_layer_added": "Text layer added!",
|
|
26
|
+
"text_layer_updated": "Text layer updated!",
|
|
27
|
+
"layer_deleted": "Layer deleted",
|
|
28
|
+
"layer_duplicated": "Layer duplicated!",
|
|
29
|
+
"scene_added": "New scene added!",
|
|
30
|
+
"scene_duplicated": "Scene duplicated!",
|
|
31
|
+
"scene_deleted": "Scene deleted",
|
|
32
|
+
"image_layer_added": "Image layer added!",
|
|
33
|
+
"image_layer_updated": "Image layer updated!",
|
|
34
|
+
"shape_layer_added": "Shape layer added!",
|
|
35
|
+
"audio_added": "Audio added to scene!",
|
|
36
|
+
"audio_removed": "Audio removed from scene",
|
|
37
|
+
"animation_applied": "Animation applied to layer!",
|
|
38
|
+
"animation_removed": "Animation removed from layer",
|
|
39
|
+
"custom_audio_selected": "Custom audio selected!",
|
|
40
|
+
"video_created": "Video Created! 🎬",
|
|
41
|
+
"video_generated": "Video Generated! 🎉",
|
|
42
|
+
"script_copied": "Copied!",
|
|
43
|
+
"password_reset_sent": "Password reset link sent to your email.",
|
|
44
|
+
"account_created": "Your account has been created successfully.",
|
|
45
|
+
"project_deleted": "{{title}} deleted successfully",
|
|
46
|
+
"project_duplicated": "Project duplicated: {{title}}"
|
|
47
|
+
},
|
|
48
|
+
"validation": {
|
|
49
|
+
"missing_prompt": "Missing Prompt",
|
|
50
|
+
"missing_prompt_message": "Please enter a description for your video",
|
|
51
|
+
"missing_topic": "Missing Topic",
|
|
52
|
+
"missing_topic_message": "Please enter a topic for your video",
|
|
53
|
+
"missing_email": "Enter Email",
|
|
54
|
+
"missing_email_message": "Please enter your email address first.",
|
|
55
|
+
"enter_name": "Please enter your name",
|
|
56
|
+
"enter_email": "Please enter your email",
|
|
57
|
+
"enter_valid_email": "Please enter a valid email address",
|
|
58
|
+
"enter_password": "Please enter a password",
|
|
59
|
+
"enter_email_password": "Please enter email and password",
|
|
60
|
+
"password_min_length": "Password must be at least 6 characters",
|
|
61
|
+
"passwords_not_match": "Passwords do not match",
|
|
62
|
+
"no_video_selected": "No Video",
|
|
63
|
+
"no_video_selected_message": "Please select a video first",
|
|
64
|
+
"no_image_selected": "No Image",
|
|
65
|
+
"no_image_selected_message": "Please select an image first.",
|
|
66
|
+
"no_audio_selected": "Please select an audio file"
|
|
67
|
+
},
|
|
68
|
+
"video": {
|
|
69
|
+
"generation_failed": "Generation Failed",
|
|
70
|
+
"generation_failed_message": "Unable to generate video",
|
|
71
|
+
"transformation_failed": "Transformation Failed",
|
|
72
|
+
"transformation_failed_message": "Unable to transform video",
|
|
73
|
+
"video_ready": "Your AI-generated video is ready!",
|
|
74
|
+
"video_created_message": "Created {{count}} animated scenes with {{style}} effect"
|
|
75
|
+
},
|
|
76
|
+
"script": {
|
|
77
|
+
"generation_failed": "Generation Failed",
|
|
78
|
+
"generation_failed_message": "Unable to generate script"
|
|
79
|
+
},
|
|
80
|
+
"export": {
|
|
81
|
+
"title": "Export Complete",
|
|
82
|
+
"message": "Your video has been exported successfully!\n\nLocation: {{uri}}",
|
|
83
|
+
"failed_title": "Export Failed",
|
|
84
|
+
"failed_message": "An error occurred during export"
|
|
85
|
+
},
|
|
86
|
+
"delete": {
|
|
87
|
+
"layer_title": "Delete Layer",
|
|
88
|
+
"layer_message": "Are you sure you want to delete this layer?",
|
|
89
|
+
"scene_title": "Delete Scene",
|
|
90
|
+
"scene_message": "Are you sure you want to delete this scene?"
|
|
91
|
+
},
|
|
92
|
+
"actions": {
|
|
93
|
+
"undo": "Undo",
|
|
94
|
+
"undo_message": "Action undone",
|
|
95
|
+
"redo": "Redo",
|
|
96
|
+
"redo_message": "Action done",
|
|
97
|
+
"coming_soon": "Coming soon!",
|
|
98
|
+
"export_coming_soon": "Export feature coming soon!",
|
|
99
|
+
"share_coming_soon": "Share feature coming soon!",
|
|
100
|
+
"effects_coming_soon": "Effects feature coming soon!"
|
|
101
|
+
},
|
|
102
|
+
"premium": {
|
|
103
|
+
"upgrade_successful": "🎉 Upgrade Successful!",
|
|
104
|
+
"upgrade_message": "Welcome to Premium! You now have unlimited access to all features.",
|
|
105
|
+
"start_creating": "Start Creating"
|
|
106
|
+
}
|
|
107
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"device": {
|
|
3
|
+
"deviceInfo": "Device Information",
|
|
4
|
+
"appInfo": "App Information",
|
|
5
|
+
"model": "Model",
|
|
6
|
+
"os": "Operating System",
|
|
7
|
+
"version": "Version",
|
|
8
|
+
"build": "Build",
|
|
9
|
+
"memory": "Memory",
|
|
10
|
+
"installed": "Installed",
|
|
11
|
+
"updated": "Last Updated",
|
|
12
|
+
"unknown": "Unknown"
|
|
13
|
+
}
|
|
14
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
{
|
|
2
|
+
"screen": {
|
|
3
|
+
"title": "Video Editor",
|
|
4
|
+
"untitled_project": "Untitled Project"
|
|
5
|
+
},
|
|
6
|
+
"preview": {
|
|
7
|
+
"play": "Play",
|
|
8
|
+
"pause": "Pause",
|
|
9
|
+
"reset": "Reset"
|
|
10
|
+
},
|
|
11
|
+
"tools": {
|
|
12
|
+
"title": "Tools",
|
|
13
|
+
"text": "Text",
|
|
14
|
+
"image": "Image",
|
|
15
|
+
"shape": "Shape",
|
|
16
|
+
"audio": "Audio",
|
|
17
|
+
"effects": "Effects"
|
|
18
|
+
},
|
|
19
|
+
"timeline": {
|
|
20
|
+
"title": "Timeline",
|
|
21
|
+
"add_scene": "Add Scene",
|
|
22
|
+
"duration": "Duration: {{duration}}s",
|
|
23
|
+
"scene": "Scene {{number}}"
|
|
24
|
+
},
|
|
25
|
+
"layers": {
|
|
26
|
+
"title": "Layers",
|
|
27
|
+
"add_layer": "Add Layer",
|
|
28
|
+
"no_layers": "No layers yet",
|
|
29
|
+
"text_layer": "Text Layer",
|
|
30
|
+
"image_layer": "Image Layer",
|
|
31
|
+
"video_layer": "Video Layer",
|
|
32
|
+
"shape_layer": "Shape Layer"
|
|
33
|
+
},
|
|
34
|
+
"properties": {
|
|
35
|
+
"title": "Properties",
|
|
36
|
+
"position": "Position",
|
|
37
|
+
"size": "Size",
|
|
38
|
+
"rotation": "Rotation",
|
|
39
|
+
"opacity": "Opacity",
|
|
40
|
+
"text": "Text",
|
|
41
|
+
"font_size": "Font Size",
|
|
42
|
+
"font_family": "Font Family",
|
|
43
|
+
"color": "Color",
|
|
44
|
+
"text_align": "Text Align",
|
|
45
|
+
"animation": "Animation"
|
|
46
|
+
},
|
|
47
|
+
"export": {
|
|
48
|
+
"title": "Export Video",
|
|
49
|
+
"resolution": "Resolution",
|
|
50
|
+
"quality": "Quality",
|
|
51
|
+
"format": "Format",
|
|
52
|
+
"exporting": "Exporting...",
|
|
53
|
+
"success": "Video exported successfully!",
|
|
54
|
+
"error": "Failed to export video"
|
|
55
|
+
},
|
|
56
|
+
"actions": {
|
|
57
|
+
"save": "Save",
|
|
58
|
+
"export": "Export",
|
|
59
|
+
"undo": "Undo",
|
|
60
|
+
"redo": "Redo",
|
|
61
|
+
"delete": "Delete",
|
|
62
|
+
"duplicate": "Duplicate"
|
|
63
|
+
}
|
|
64
|
+
}
|
|
@@ -1,20 +1,62 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"subtitle": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"error": "Test Error Alert",
|
|
7
|
-
"warning": "Test Warning Alert",
|
|
8
|
-
"info": "Test Info Alert"
|
|
2
|
+
"greeting": "Create Amazing Videos",
|
|
3
|
+
"subtitle": "Choose a template and start creating",
|
|
4
|
+
"categories": {
|
|
5
|
+
"title": "Browse by Category"
|
|
9
6
|
},
|
|
10
|
-
"
|
|
11
|
-
"
|
|
12
|
-
"
|
|
13
|
-
"
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
7
|
+
"recent_projects": {
|
|
8
|
+
"title": "Recent Projects",
|
|
9
|
+
"view_all": "View All",
|
|
10
|
+
"empty": "No recent projects"
|
|
11
|
+
},
|
|
12
|
+
"quick_actions": {
|
|
13
|
+
"title": "Quick Actions",
|
|
14
|
+
"browse_templates": "Browse Templates",
|
|
15
|
+
"my_projects": "My Projects",
|
|
16
|
+
"create_blank": "Create Blank"
|
|
17
|
+
},
|
|
18
|
+
"featured": {
|
|
19
|
+
"title": "Featured Templates",
|
|
20
|
+
"view_all": "View All"
|
|
21
|
+
},
|
|
22
|
+
"ai_hero": {
|
|
23
|
+
"title": "🎬 AI Video Studio",
|
|
24
|
+
"subtitle": "Create professional videos with AI-powered tools",
|
|
25
|
+
"start_button": "Start Creating"
|
|
26
|
+
},
|
|
27
|
+
"ai_features": {
|
|
28
|
+
"title": "🤖 AI Features",
|
|
29
|
+
"text_to_video": {
|
|
30
|
+
"title": "Text to Video",
|
|
31
|
+
"description": "Generate videos from prompts"
|
|
32
|
+
},
|
|
33
|
+
"image_to_video": {
|
|
34
|
+
"title": "Image to Video",
|
|
35
|
+
"description": "Animate your photos"
|
|
36
|
+
},
|
|
37
|
+
"style_transfer": {
|
|
38
|
+
"title": "Style Transfer",
|
|
39
|
+
"description": "Transform video styles"
|
|
40
|
+
},
|
|
41
|
+
"script_generator": {
|
|
42
|
+
"title": "Script Generator",
|
|
43
|
+
"description": "AI-powered scripts"
|
|
44
|
+
},
|
|
45
|
+
"voice_over": {
|
|
46
|
+
"title": "AI Voice-over",
|
|
47
|
+
"description": "Text-to-speech"
|
|
48
|
+
},
|
|
49
|
+
"auto_captions": {
|
|
50
|
+
"title": "Auto Captions",
|
|
51
|
+
"description": "AI subtitles"
|
|
52
|
+
},
|
|
53
|
+
"ai_music": {
|
|
54
|
+
"title": "AI Music",
|
|
55
|
+
"description": "Generate soundtracks"
|
|
56
|
+
},
|
|
57
|
+
"ai_prompt": {
|
|
58
|
+
"title": "AI Prompt",
|
|
59
|
+
"description": "Scene generator"
|
|
60
|
+
}
|
|
19
61
|
}
|
|
20
62
|
}
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* This file is automatically generated by setup-languages.js or createLocaleLoaders.js
|
|
21
21
|
* but can be manually edited if needed.
|
|
22
22
|
*
|
|
23
|
-
* Generated: 2025-11-
|
|
23
|
+
* Generated: 2025-11-16T18:53:58.972Z
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
// Metro bundler require.context - auto-discover all .json files
|
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"home": "Home",
|
|
3
|
-
"
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
"activity": "Activity",
|
|
7
|
-
"discover": "Discover",
|
|
8
|
-
"library": "Library",
|
|
9
|
-
"stats": "Stats",
|
|
10
|
-
"progress": "Progress",
|
|
11
|
-
"dashboard": "Dashboard",
|
|
12
|
-
"calendar": "Calendar",
|
|
13
|
-
"categories": "Categories",
|
|
14
|
-
"saved": "Saved",
|
|
15
|
-
"history": "History",
|
|
16
|
-
"statistics": "Statistics",
|
|
17
|
-
"reminders": "Reminders",
|
|
18
|
-
"profile": "Profile",
|
|
19
|
-
"account": "Account",
|
|
20
|
-
"settings": "Settings",
|
|
21
|
-
"about": "About",
|
|
22
|
-
"today": "Today"
|
|
3
|
+
"templates": "Templates",
|
|
4
|
+
"projects": "Projects",
|
|
5
|
+
"settings": "Settings"
|
|
23
6
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"screen": {
|
|
3
|
+
"title": "My Projects",
|
|
4
|
+
"search_placeholder": "Search projects...",
|
|
5
|
+
"empty_title": "No projects yet",
|
|
6
|
+
"empty_description": "Create your first video from a template",
|
|
7
|
+
"create_button": "Browse Templates"
|
|
8
|
+
},
|
|
9
|
+
"card": {
|
|
10
|
+
"created": "Created {{date}}",
|
|
11
|
+
"updated": "Updated {{date}}",
|
|
12
|
+
"duration": "{{duration}}s"
|
|
13
|
+
},
|
|
14
|
+
"actions": {
|
|
15
|
+
"edit": "Edit",
|
|
16
|
+
"duplicate": "Duplicate",
|
|
17
|
+
"delete": "Delete",
|
|
18
|
+
"export": "Export",
|
|
19
|
+
"share": "Share"
|
|
20
|
+
},
|
|
21
|
+
"delete": {
|
|
22
|
+
"title": "Delete Project",
|
|
23
|
+
"message": "Are you sure you want to delete this project? This action cannot be undone.",
|
|
24
|
+
"confirm": "Delete",
|
|
25
|
+
"cancel": "Cancel"
|
|
26
|
+
},
|
|
27
|
+
"sort": {
|
|
28
|
+
"title": "Sort by",
|
|
29
|
+
"recent": "Most Recent",
|
|
30
|
+
"oldest": "Oldest",
|
|
31
|
+
"name": "Name (A-Z)",
|
|
32
|
+
"duration": "Duration"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"categories": {
|
|
3
|
+
"all": "All Templates",
|
|
4
|
+
"social_media": "Social Media",
|
|
5
|
+
"business": "Business",
|
|
6
|
+
"education": "Education",
|
|
7
|
+
"marketing": "Marketing",
|
|
8
|
+
"event": "Events",
|
|
9
|
+
"intro_outro": "Intro/Outro"
|
|
10
|
+
},
|
|
11
|
+
"screen": {
|
|
12
|
+
"title": "Templates",
|
|
13
|
+
"search_placeholder": "Search templates...",
|
|
14
|
+
"no_results": "No templates found",
|
|
15
|
+
"no_results_description": "Try adjusting your search or browse by category"
|
|
16
|
+
},
|
|
17
|
+
"card": {
|
|
18
|
+
"duration": "{{duration}}s",
|
|
19
|
+
"premium": "Premium",
|
|
20
|
+
"use_template": "Use Template"
|
|
21
|
+
},
|
|
22
|
+
"filters": {
|
|
23
|
+
"all": "All",
|
|
24
|
+
"favorites": "Favorites",
|
|
25
|
+
"free": "Free",
|
|
26
|
+
"premium": "Premium"
|
|
27
|
+
}
|
|
28
|
+
}
|