@umituz/react-native-localization 1.7.6 → 1.8.0

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 CHANGED
@@ -1,13 +1,13 @@
1
1
  # @umituz/react-native-localization
2
2
 
3
- Universal localization system for React Native apps with i18n support. Built with Domain-Driven Design principles and TypeScript.
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
- - **29+ Language Support**: Pre-configured support for 29 languages including RTL languages (Arabic)
8
- - **Automatic Device Locale Detection**: Automatically detects and applies device language on first launch
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 Scripts**: Built-in scripts for setup, translation, and validation
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.7.6",
4
- "description": "Universal localization system for React Native apps with i18n support",
3
+ "version": "1.8.0",
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": {
@@ -1,133 +1,58 @@
1
1
  /**
2
- * i18next Configuration
3
- * Nested translation structure - common translations spread, domain translations nested
2
+ * i18next Configuration for English-only
3
+ * Simple translation structure - only en-US supported
4
4
  *
5
- * AUTOMATIC LANGUAGE LOADING:
6
- * - Uses require.context to auto-discover all language directories
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 { SUPPORTED_LANGUAGES, DEFAULT_LANGUAGE } from './languages';
12
+ import { DEFAULT_LANGUAGE } from './languages';
14
13
 
15
14
  /**
16
- * AUTOMATIC LANGUAGE LOADING
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
- const packageTranslations: Record<string, any> = {};
40
-
41
- packageLocalesContext.keys().forEach((key: string) => {
42
- // Extract language code from path: './ar-SA/index.ts' -> 'ar-SA'
43
- const match = key.match(/\.\/([^/]+)\/index\.ts$/);
44
- if (match) {
45
- const languageCode = match[1];
46
- try {
47
- const translations = packageLocalesContext(key);
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 with require.context for automatic discovery
40
+ // Try DDD structure path
71
41
  // eslint-disable-next-line @typescript-eslint/no-require-imports
72
- const projectLocalesContext = (require as any).context('../../../../../../src/domains/localization/infrastructure/locales', true, /\/index\.ts$/);
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 projectLocalesContext = (require as any).context('../../../../../../domains/localization/infrastructure/locales', true, /\/index\.ts$/);
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 projectLocalesContext = (require as any).context('../../../../../../src/locales', true, /\/index\.ts$/);
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 all languages
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 resources: Record<string, { translation: any }> = {};
178
-
179
- // Get all unique language codes from both package and project translations
180
- const allLanguageCodes = new Set([
181
- ...Object.keys(packageTranslations),
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 (e.g., "en") and iOS variants (e.g., "en-GB", "zh-Hans") to our supported locales
30
+ * Maps short codes and regional variants to en-US
31
31
  *
32
- * COMPREHENSIVE MAPPING:
33
- * - Short codes (ar, bg, cs, da, de, etc.) → Full locale codes (ar-SA, bg-BG, etc.)
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
- // Arabic
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
- // Spanish
76
- 'es': 'es-ES',
77
- 'es-ES': 'es-ES',
78
- 'es-MX': 'es-ES',
79
- 'es-AR': 'es-ES',
80
-
81
- // Finnish
82
- 'fi': 'fi-FI',
83
- 'fi-FI': 'fi-FI',
84
-
85
- // French
86
- 'fr': 'fr-FR',
87
- 'fr-FR': 'fr-FR',
88
- 'fr-CA': 'fr-FR',
89
- 'fr-BE': 'fr-FR',
90
- 'fr-CH': 'fr-FR',
91
-
92
- // Hindi
93
- 'hi': 'hi-IN',
94
- 'hi-IN': 'hi-IN',
95
-
96
- // Croatian (iOS has hr, we map to en-US fallback since we don't support Croatian)
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
- // Hungarian
100
- 'hu': 'hu-HU',
101
- 'hu-HU': 'hu-HU',
102
-
103
- // Indonesian
104
- 'id': 'id-ID',
105
- 'id-ID': 'id-ID',
106
-
107
- // Italian
108
- 'it': 'it-IT',
109
- 'it-IT': 'it-IT',
110
-
111
- // Japanese
112
- 'ja': 'ja-JP',
113
- 'ja-JP': 'ja-JP',
114
-
115
- // Korean
116
- 'ko': 'ko-KR',
117
- 'ko-KR': 'ko-KR',
118
-
119
- // Malay
120
- 'ms': 'ms-MY',
121
- 'ms-MY': 'ms-MY',
122
-
123
- // Norwegian (iOS uses nb for Norwegian Bokmål)
124
- 'nb': 'no-NO',
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
- // Swedish
154
- 'sv': 'sv-SE',
155
- 'sv-SE': 'sv-SE',
156
-
157
- // Thai
158
- 'th': 'th-TH',
159
- 'th-TH': 'th-TH',
160
-
161
- // Filipino/Tagalog
162
- 'tl': 'tl-PH',
163
- 'tl-PH': 'tl-PH',
164
- 'fil': 'tl-PH',
165
-
166
- // Turkish
167
- 'tr': 'tr-TR',
168
- 'tr-TR': 'tr-TR',
169
-
170
- // Ukrainian
171
- 'uk': 'uk-UA',
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
+ }
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "appName": "App Name",
3
3
  "tagline": "Welcome",
4
+ "poweredBy": "Powered by",
4
5
  "splash": {
5
6
  "loading": "Loading..."
6
7
  }
@@ -0,0 +1,9 @@
1
+ {
2
+ "clipboard": {
3
+ "copied": "Copied",
4
+ "copyFailed": "Failed to copy",
5
+ "pasteFailed": "Failed to paste",
6
+ "cleared": "Clipboard cleared",
7
+ "empty": "Clipboard is empty"
8
+ }
9
+ }
@@ -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
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "haptics": {
3
+ "notSupported": "Haptics not supported on this device",
4
+ "disabled": "Haptic feedback disabled"
5
+ }
6
+ }
@@ -1,20 +1,62 @@
1
1
  {
2
- "title": "AI Video Generator",
3
- "subtitle": "Create stunning videos with AI - from text to video, images to video, and templates",
4
- "testAlerts": {
5
- "success": "Test Success Alert",
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
- "alertMessages": {
11
- "successTitle": "Test Success",
12
- "successMessage": "This is a success alert!",
13
- "errorTitle": "Test Error",
14
- "errorMessage": "This is an error alert!",
15
- "warningTitle": "Test Warning",
16
- "warningMessage": "This is a warning alert!",
17
- "infoTitle": "Test Info",
18
- "infoMessage": "This is an info alert!"
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-16T15:04:51.100Z
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
- "explore": "Explore",
4
- "search": "Search",
5
- "favorites": "Favorites",
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,8 @@
1
+ {
2
+ "sharing": {
3
+ "share": "Share",
4
+ "shareWith": "Share with",
5
+ "shareFailed": "Failed to share",
6
+ "notAvailable": "Sharing not available on this device"
7
+ }
8
+ }
@@ -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
+ }