@umituz/react-native-settings 5.4.22 → 5.4.24
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/package.json +1 -1
- package/src/domains/feedback/presentation/components/FeedbackForm.styles.ts +8 -2
- package/src/domains/gamification/components/AchievementItem.tsx +3 -2
- package/src/domains/gamification/components/GamificationScreen/GamificationScreen.tsx +2 -1
- package/src/domains/gamification/components/GamificationScreen/styles.ts +43 -37
- package/src/domains/gamification/components/styles/achievementItemStyles.ts +75 -68
- package/src/domains/localization/infrastructure/components/LanguageSwitcher.styles.ts +28 -25
- package/src/domains/localization/infrastructure/components/LanguageSwitcher.tsx +6 -6
- package/src/domains/localization/presentation/components/LanguageItem.styles.ts +47 -33
- package/src/domains/localization/presentation/components/LanguageItem.tsx +9 -29
- package/src/domains/localization/scripts/prepublish.js +0 -36
- package/src/domains/localization/scripts/setup-languages.js +0 -85
- package/src/domains/localization/scripts/sync-translations.js +0 -124
- package/src/domains/localization/scripts/translate-missing.js +0 -211
- package/src/domains/localization/scripts/utils/file-parser.js +0 -104
- package/src/domains/localization/scripts/utils/key-detector.js +0 -45
- package/src/domains/localization/scripts/utils/key-extractor.js +0 -105
- package/src/domains/localization/scripts/utils/object-helper.js +0 -29
- package/src/domains/localization/scripts/utils/sync-helper.js +0 -49
- package/src/domains/localization/scripts/utils/translation-config.js +0 -116
- package/src/domains/localization/scripts/utils/translator.js +0 -91
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Object Helper
|
|
3
|
-
* Utilities for deep object manipulation
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Set a value in a nested object, creating intermediate objects if necessary
|
|
8
|
-
* Returns true if the key was newly added, false if it already existed
|
|
9
|
-
*/
|
|
10
|
-
export function setDeep(obj, path, value) {
|
|
11
|
-
const keys = path.split('.');
|
|
12
|
-
let current = obj;
|
|
13
|
-
|
|
14
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
15
|
-
const key = keys[i];
|
|
16
|
-
if (!current[key] || typeof current[key] !== 'object' || Array.isArray(current[key])) {
|
|
17
|
-
current[key] = {};
|
|
18
|
-
}
|
|
19
|
-
current = current[key];
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
const lastKey = keys[keys.length - 1];
|
|
23
|
-
if (current[lastKey] === undefined) {
|
|
24
|
-
current[lastKey] = value;
|
|
25
|
-
return true;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
return false;
|
|
29
|
-
}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Sync Helper
|
|
3
|
-
* Helper functions for synchronizing translation keys
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export function addMissingKeys(sourceObj, targetObj, stats = { added: 0, newKeys: [] }) {
|
|
7
|
-
for (const key in sourceObj) {
|
|
8
|
-
const sourceValue = sourceObj[key];
|
|
9
|
-
const isNewKey = !Object.prototype.hasOwnProperty.call(targetObj, key);
|
|
10
|
-
|
|
11
|
-
if (isNewKey) {
|
|
12
|
-
targetObj[key] = sourceValue;
|
|
13
|
-
stats.added++;
|
|
14
|
-
stats.newKeys.push(key);
|
|
15
|
-
} else if (
|
|
16
|
-
typeof sourceValue === 'object' &&
|
|
17
|
-
sourceValue !== null &&
|
|
18
|
-
!Array.isArray(sourceValue)
|
|
19
|
-
) {
|
|
20
|
-
if (!targetObj[key] || typeof targetObj[key] !== 'object') {
|
|
21
|
-
targetObj[key] = {};
|
|
22
|
-
}
|
|
23
|
-
addMissingKeys(sourceValue, targetObj[key], stats);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return stats;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
export function removeExtraKeys(sourceObj, targetObj, stats = { removed: 0, removedKeys: [] }) {
|
|
30
|
-
for (const key in targetObj) {
|
|
31
|
-
const isExtraKey = !Object.prototype.hasOwnProperty.call(sourceObj, key);
|
|
32
|
-
|
|
33
|
-
if (isExtraKey) {
|
|
34
|
-
delete targetObj[key];
|
|
35
|
-
stats.removed++;
|
|
36
|
-
stats.removedKeys.push(key);
|
|
37
|
-
} else if (
|
|
38
|
-
typeof sourceObj[key] === 'object' &&
|
|
39
|
-
sourceObj[key] !== null &&
|
|
40
|
-
!Array.isArray(sourceObj[key]) &&
|
|
41
|
-
typeof targetObj[key] === 'object' &&
|
|
42
|
-
targetObj[key] !== null &&
|
|
43
|
-
!Array.isArray(targetObj[key])
|
|
44
|
-
) {
|
|
45
|
-
removeExtraKeys(sourceObj[key], targetObj[key], stats);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return stats;
|
|
49
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Translation Configuration
|
|
3
|
-
* Language mappings and constants for translation system
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
export const LANGUAGE_MAP = {
|
|
7
|
-
'ar-SA': 'ar',
|
|
8
|
-
'bg-BG': 'bg',
|
|
9
|
-
'cs-CZ': 'cs',
|
|
10
|
-
'da-DK': 'da',
|
|
11
|
-
'de-DE': 'de',
|
|
12
|
-
'el-GR': 'el',
|
|
13
|
-
'en-AU': 'en',
|
|
14
|
-
'en-CA': 'en',
|
|
15
|
-
'en-GB': 'en',
|
|
16
|
-
'es-ES': 'es',
|
|
17
|
-
'es-MX': 'es',
|
|
18
|
-
'fi-FI': 'fi',
|
|
19
|
-
'fr-CA': 'fr',
|
|
20
|
-
'fr-FR': 'fr',
|
|
21
|
-
'hi-IN': 'hi',
|
|
22
|
-
'hr-HR': 'hr',
|
|
23
|
-
'hu-HU': 'hu',
|
|
24
|
-
'id-ID': 'id',
|
|
25
|
-
'it-IT': 'it',
|
|
26
|
-
'ja-JP': 'ja',
|
|
27
|
-
'ko-KR': 'ko',
|
|
28
|
-
'ms-MY': 'ms',
|
|
29
|
-
'nl-NL': 'nl',
|
|
30
|
-
'no-NO': 'no',
|
|
31
|
-
'pl-PL': 'pl',
|
|
32
|
-
'pt-BR': 'pt',
|
|
33
|
-
'pt-PT': 'pt',
|
|
34
|
-
'ro-RO': 'ro',
|
|
35
|
-
'ru-RU': 'ru',
|
|
36
|
-
'sk-SK': 'sk',
|
|
37
|
-
'sl-SI': 'sl',
|
|
38
|
-
'sv-SE': 'sv',
|
|
39
|
-
'th-TH': 'th',
|
|
40
|
-
'tl-PH': 'tl',
|
|
41
|
-
'tr-TR': 'tr',
|
|
42
|
-
'uk-UA': 'uk',
|
|
43
|
-
'vi-VN': 'vi',
|
|
44
|
-
'zh-CN': 'zh-CN',
|
|
45
|
-
'zh-TW': 'zh-TW',
|
|
46
|
-
};
|
|
47
|
-
|
|
48
|
-
export const SKIP_WORDS = new Set([
|
|
49
|
-
'Google',
|
|
50
|
-
'Apple',
|
|
51
|
-
'Facebook',
|
|
52
|
-
'Instagram',
|
|
53
|
-
'Twitter',
|
|
54
|
-
'YouTube',
|
|
55
|
-
'WhatsApp',
|
|
56
|
-
]);
|
|
57
|
-
|
|
58
|
-
export const LANGUAGE_NAMES = {
|
|
59
|
-
'ar-SA': 'Arabic (Saudi Arabia)',
|
|
60
|
-
'bg-BG': 'Bulgarian',
|
|
61
|
-
'cs-CZ': 'Czech',
|
|
62
|
-
'da-DK': 'Danish',
|
|
63
|
-
'de-DE': 'German',
|
|
64
|
-
'el-GR': 'Greek',
|
|
65
|
-
'en-AU': 'English (Australia)',
|
|
66
|
-
'en-CA': 'English (Canada)',
|
|
67
|
-
'en-GB': 'English (UK)',
|
|
68
|
-
'en-US': 'English (US)',
|
|
69
|
-
'es-ES': 'Spanish (Spain)',
|
|
70
|
-
'es-MX': 'Spanish (Mexico)',
|
|
71
|
-
'fi-FI': 'Finnish',
|
|
72
|
-
'fr-CA': 'French (Canada)',
|
|
73
|
-
'fr-FR': 'French (France)',
|
|
74
|
-
'hi-IN': 'Hindi',
|
|
75
|
-
'hr-HR': 'Croatian',
|
|
76
|
-
'hu-HU': 'Hungarian',
|
|
77
|
-
'id-ID': 'Indonesian',
|
|
78
|
-
'it-IT': 'Italian',
|
|
79
|
-
'ja-JP': 'Japanese',
|
|
80
|
-
'ko-KR': 'Korean',
|
|
81
|
-
'ms-MY': 'Malay',
|
|
82
|
-
'nl-NL': 'Dutch',
|
|
83
|
-
'no-NO': 'Norwegian',
|
|
84
|
-
'pl-PL': 'Polish',
|
|
85
|
-
'pt-BR': 'Portuguese (Brazil)',
|
|
86
|
-
'pt-PT': 'Portuguese (Portugal)',
|
|
87
|
-
'ro-RO': 'Romanian',
|
|
88
|
-
'ru-RU': 'Russian',
|
|
89
|
-
'sk-SK': 'Slovak',
|
|
90
|
-
'sl-SI': 'Slovenian',
|
|
91
|
-
'sv-SE': 'Swedish',
|
|
92
|
-
'th-TH': 'Thai',
|
|
93
|
-
'tl-PH': 'Tagalog',
|
|
94
|
-
'tr-TR': 'Turkish',
|
|
95
|
-
'uk-UA': 'Ukrainian',
|
|
96
|
-
'vi-VN': 'Vietnamese',
|
|
97
|
-
'zh-CN': 'Chinese (Simplified)',
|
|
98
|
-
'zh-TW': 'Chinese (Traditional)',
|
|
99
|
-
};
|
|
100
|
-
|
|
101
|
-
export function getLangDisplayName(code) {
|
|
102
|
-
return LANGUAGE_NAMES[code] || code;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export function getTargetLanguage(langCode) {
|
|
106
|
-
return LANGUAGE_MAP[langCode];
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
export function shouldSkipWord(word) {
|
|
110
|
-
return SKIP_WORDS.has(word);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export function isEnglishVariant(langCode) {
|
|
114
|
-
const targetLang = LANGUAGE_MAP[langCode];
|
|
115
|
-
return targetLang === 'en';
|
|
116
|
-
}
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Translation Utilities
|
|
3
|
-
* Handles call to translation APIs
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { getTargetLanguage, shouldSkipWord } from './translation-config.js';
|
|
7
|
-
|
|
8
|
-
let lastCallTime = 0;
|
|
9
|
-
const MIN_DELAY = 100; // ms
|
|
10
|
-
|
|
11
|
-
async function translateText(text, targetLang) {
|
|
12
|
-
if (!text || typeof text !== 'string') return text;
|
|
13
|
-
if (shouldSkipWord(text)) return text;
|
|
14
|
-
|
|
15
|
-
// Rate limiting
|
|
16
|
-
const now = Date.now();
|
|
17
|
-
const waitTime = Math.max(0, MIN_DELAY - (now - lastCallTime));
|
|
18
|
-
if (waitTime > 0) await new Promise(resolve => setTimeout(resolve, waitTime));
|
|
19
|
-
lastCallTime = Date.now();
|
|
20
|
-
|
|
21
|
-
try {
|
|
22
|
-
const encodedText = encodeURIComponent(text);
|
|
23
|
-
const url = `https://translate.googleapis.com/translate_a/single?client=gtx&sl=en&tl=${targetLang}&dt=t&q=${encodedText}`;
|
|
24
|
-
|
|
25
|
-
const response = await fetch(url);
|
|
26
|
-
if (!response.ok) return text;
|
|
27
|
-
|
|
28
|
-
const data = await response.json();
|
|
29
|
-
return data && data[0] && data[0][0] && data[0][0][0] ? data[0][0][0] : text;
|
|
30
|
-
} catch (error) {
|
|
31
|
-
return text;
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function needsTranslation(value, enValue) {
|
|
36
|
-
if (typeof enValue !== 'string' || !enValue.trim()) return false;
|
|
37
|
-
if (shouldSkipWord(enValue)) return false;
|
|
38
|
-
|
|
39
|
-
// CRITICAL OPTIMIZATION: If enValue is a technical key (e.g. "scenario.xxx.title"),
|
|
40
|
-
// skip translating it to other languages. We only translate REAL English content.
|
|
41
|
-
const isTechnicalKey = enValue.includes('.') && !enValue.includes(' ');
|
|
42
|
-
if (isTechnicalKey) return false;
|
|
43
|
-
|
|
44
|
-
// If value is missing or same as English, it needs translation
|
|
45
|
-
if (!value || typeof value !== 'string') return true;
|
|
46
|
-
|
|
47
|
-
if (value === enValue) {
|
|
48
|
-
const isSingleWord = !enValue.includes(' ') && enValue.length < 20;
|
|
49
|
-
return !isSingleWord;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
// Detect outdated template patterns (e.g., {{appName}}, {{variable}})
|
|
53
|
-
if (value && typeof value === 'string') {
|
|
54
|
-
const hasTemplatePattern = value.includes('{{') && value.includes('}}');
|
|
55
|
-
if (hasTemplatePattern && !enValue.includes('{{')) {
|
|
56
|
-
return true;
|
|
57
|
-
}
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
return false;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export async function translateObject(enObj, targetObj, targetLang, path = '', stats = { count: 0, checked: 0, translatedKeys: [] }) {
|
|
64
|
-
const keys = Object.keys(enObj);
|
|
65
|
-
|
|
66
|
-
if (!stats.translatedKeys) stats.translatedKeys = [];
|
|
67
|
-
|
|
68
|
-
for (const key of keys) {
|
|
69
|
-
const enValue = enObj[key];
|
|
70
|
-
const targetValue = targetObj[key];
|
|
71
|
-
const currentPath = path ? `${path}.${key}` : key;
|
|
72
|
-
|
|
73
|
-
if (typeof enValue === 'object' && enValue !== null) {
|
|
74
|
-
if (!targetObj[key] || typeof targetObj[key] !== 'object') targetObj[key] = {};
|
|
75
|
-
await translateObject(enValue, targetObj[key], targetLang, currentPath, stats);
|
|
76
|
-
} else if (typeof enValue === 'string') {
|
|
77
|
-
stats.checked++;
|
|
78
|
-
if (needsTranslation(targetValue, enValue)) {
|
|
79
|
-
// Show progress for translations
|
|
80
|
-
process.stdout.write(` \r Progress: ${stats.checked} keys checked, ${stats.count} translated...`);
|
|
81
|
-
|
|
82
|
-
const translated = await translateText(enValue, targetLang);
|
|
83
|
-
if (translated !== enValue) {
|
|
84
|
-
targetObj[key] = translated;
|
|
85
|
-
stats.count++;
|
|
86
|
-
stats.translatedKeys.push({ key: currentPath, from: enValue, to: translated });
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
}
|