From a85698b009a031018afbb452e85168164dd0ce42 Mon Sep 17 00:00:00 2001 From: tapframe Date: Wed, 7 Jan 2026 12:44:42 +0530 Subject: [PATCH] added localization to themescreen. --- src/i18n/locales/ar.json | 30 +++ src/i18n/locales/en.json | 30 +++ src/i18n/locales/es.json | 30 +++ src/i18n/locales/fr.json | 30 +++ src/i18n/locales/it.json | 30 +++ src/i18n/locales/pt.json | 30 +++ src/screens/ThemeScreen.tsx | 415 +++++++++++++++++++----------------- 7 files changed, 395 insertions(+), 200 deletions(-) diff --git a/src/i18n/locales/ar.json b/src/i18n/locales/ar.json index 880bafd5..97fcf4aa 100644 --- a/src/i18n/locales/ar.json +++ b/src/i18n/locales/ar.json @@ -1193,5 +1193,35 @@ "repo_format_hint": "التنسيق: https://raw.githubusercontent.com/username/repo/refs/heads/branch", "cancel": "إلغاء", "add": "إضافة" + }, + "theme": { + "title": "سمات التطبيق", + "select_theme": "اختر السمة", + "create_custom": "إنشاء سمة مخصصة", + "options": "خيارات", + "use_dominant_color": "استخدام اللون المهيمن من العمل الفني", + "categories": { + "all": "كل السمات", + "dark": "سمات داكنة", + "colorful": "ملونة", + "custom": "سماتي" + }, + "editor": { + "theme_name_placeholder": "اسم السمة", + "save": "حفظ", + "primary": "أساسي", + "secondary": "ثانوي", + "background": "خلفية", + "invalid_name_title": "اسم غير صالح", + "invalid_name_msg": "يرجى إدخال اسم سمة صالح" + }, + "alerts": { + "delete_title": "حذف السمة", + "delete_msg": "هل أنت متأكد أنك تريد حذف \"{{name}}\"؟", + "ok": "حسناً", + "delete": "حذف", + "cancel": "إلغاء", + "back": "إعدادات" + } } } \ No newline at end of file diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 7493f969..8cb2a472 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -1193,5 +1193,35 @@ "repo_format_hint": "Format: https://raw.githubusercontent.com/username/repo/refs/heads/branch", "cancel": "Cancel", "add": "Add" + }, + "theme": { + "title": "App Themes", + "select_theme": "SELECT THEME", + "create_custom": "Create Custom Theme", + "options": "OPTIONS", + "use_dominant_color": "Use Dominant Color from Artwork", + "categories": { + "all": "All Themes", + "dark": "Dark Themes", + "colorful": "Colorful", + "custom": "My Themes" + }, + "editor": { + "theme_name_placeholder": "Theme name", + "save": "Save", + "primary": "Primary", + "secondary": "Secondary", + "background": "Background", + "invalid_name_title": "Invalid Name", + "invalid_name_msg": "Please enter a valid theme name" + }, + "alerts": { + "delete_title": "Delete Theme", + "delete_msg": "Are you sure you want to delete \"{{name}}\"?", + "ok": "OK", + "delete": "Delete", + "cancel": "Cancel", + "back": "Settings" + } } } \ No newline at end of file diff --git a/src/i18n/locales/es.json b/src/i18n/locales/es.json index 0f44c643..f0ce3bb8 100644 --- a/src/i18n/locales/es.json +++ b/src/i18n/locales/es.json @@ -1193,5 +1193,35 @@ "repo_format_hint": "Formato: https://raw.githubusercontent.com/usuario/repo/rama", "cancel": "Cancelar", "add": "Añadir" + }, + "theme": { + "title": "Temas de la App", + "select_theme": "SELECCIONAR TEMA", + "create_custom": "Crear Tema Personalizado", + "options": "OPCIONES", + "use_dominant_color": "Usar Color Dominante del Arte", + "categories": { + "all": "Todos los Temas", + "dark": "Temas Oscuros", + "colorful": "Coloridos", + "custom": "Mis Temas" + }, + "editor": { + "theme_name_placeholder": "Nombre del tema", + "save": "Guardar", + "primary": "Primario", + "secondary": "Secundario", + "background": "Fondo", + "invalid_name_title": "Nombre Inválido", + "invalid_name_msg": "Por favor ingresa un nombre válido" + }, + "alerts": { + "delete_title": "Eliminar Tema", + "delete_msg": "¿Estás seguro de que quieres eliminar \"{{name}}\"?", + "ok": "OK", + "delete": "Eliminar", + "cancel": "Cancelar", + "back": "Ajustes" + } } } \ No newline at end of file diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index 3af333bf..24e7827b 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -1193,5 +1193,35 @@ "repo_format_hint": "Format : https://raw.githubusercontent.com/utilisateur/repo/refs/heads/branche", "cancel": "Annuler", "add": "Ajouter" + }, + "theme": { + "title": "Thèmes de l'App", + "select_theme": "SÉLECTIONNER UN THÈME", + "create_custom": "Créer un Thème Personnalisé", + "options": "OPTIONS", + "use_dominant_color": "Utiliser la Couleur Dominante de l'Image", + "categories": { + "all": "Tous les Thèmes", + "dark": "Thèmes Sombres", + "colorful": "Colorés", + "custom": "Mes Thèmes" + }, + "editor": { + "theme_name_placeholder": "Nom du thème", + "save": "Enregistrer", + "primary": "Primaire", + "secondary": "Secondaire", + "background": "Arrière-plan", + "invalid_name_title": "Nom Invalide", + "invalid_name_msg": "Veuillez entrer un nom de thème valide" + }, + "alerts": { + "delete_title": "Supprimer le Thème", + "delete_msg": "Êtes-vous sûr de vouloir supprimer \"{{name}}\" ?", + "ok": "OK", + "delete": "Supprimer", + "cancel": "Annuler", + "back": "Paramètres" + } } } \ No newline at end of file diff --git a/src/i18n/locales/it.json b/src/i18n/locales/it.json index b3dc370d..40f47ea6 100644 --- a/src/i18n/locales/it.json +++ b/src/i18n/locales/it.json @@ -1193,5 +1193,35 @@ "repo_format_hint": "Formato: https://raw.githubusercontent.com/user/repo/refs/heads/branch", "cancel": "Annulla", "add": "Aggiungi" + }, + "theme": { + "title": "Temi App", + "select_theme": "SELEZIONA TEMA", + "create_custom": "Crea Tema Personalizado", + "options": "OPZIONI", + "use_dominant_color": "Usa Colore Dominante dalla Copertina", + "categories": { + "all": "Tutti i Temi", + "dark": "Temi Scuri", + "colorful": "Colorati", + "custom": "I Miei Temi" + }, + "editor": { + "theme_name_placeholder": "Nome tema", + "save": "Salva", + "primary": "Primario", + "secondary": "Secondario", + "background": "Sfondo", + "invalid_name_title": "Nome Non Valido", + "invalid_name_msg": "Inserisci un nome valido per il tema" + }, + "alerts": { + "delete_title": "Elimina Tema", + "delete_msg": "Sei sicuro di voler eliminare \"{{name}}\"?", + "ok": "OK", + "delete": "Elimina", + "cancel": "Annulla", + "back": "Impostazioni" + } } } \ No newline at end of file diff --git a/src/i18n/locales/pt.json b/src/i18n/locales/pt.json index 3d4a7575..7136dd8b 100644 --- a/src/i18n/locales/pt.json +++ b/src/i18n/locales/pt.json @@ -1159,5 +1159,35 @@ "repo_format_hint": "Formato: https://raw.githubusercontent.com/username/repo/refs/heads/branch", "cancel": "Cancelar", "add": "Adicionar" + }, + "theme": { + "title": "Temas do App", + "select_theme": "SELECIONAR TEMA", + "create_custom": "Criar Tema Personalizado", + "options": "OPÇÕES", + "use_dominant_color": "Usar Cor Dominante da Arte", + "categories": { + "all": "Todos os Temas", + "dark": "Temas Escuros", + "colorful": "Coloridos", + "custom": "Meus Temas" + }, + "editor": { + "theme_name_placeholder": "Nome do tema", + "save": "Salvar", + "primary": "Primário", + "secondary": "Secundário", + "background": "Fundo", + "invalid_name_title": "Nome Inválido", + "invalid_name_msg": "Por favor insira um nome válido" + }, + "alerts": { + "delete_title": "Excluir Tema", + "delete_msg": "Tem certeza que deseja excluir \"{{name}}\"?", + "ok": "OK", + "delete": "Excluir", + "cancel": "Cancelar", + "back": "Configurações" + } } } \ No newline at end of file diff --git a/src/screens/ThemeScreen.tsx b/src/screens/ThemeScreen.tsx index d9608d95..b68bb5c1 100644 --- a/src/screens/ThemeScreen.tsx +++ b/src/screens/ThemeScreen.tsx @@ -1,4 +1,5 @@ import React, { useState, useCallback, useEffect, useMemo } from 'react'; +import { useTranslation } from 'react-i18next'; import { View, Text, @@ -45,9 +46,9 @@ interface ThemeCardProps { onDelete?: () => void; } -const ThemeCard: React.FC = ({ - theme, - isSelected, +const ThemeCard: React.FC = ({ + theme, + isSelected, onSelect, onEdit, onDelete @@ -57,10 +58,10 @@ const ThemeCard: React.FC = ({ style={[ styles.themeCard, isSelected && styles.selectedThemeCard, - { + { borderColor: isSelected ? theme.colors.primary : 'transparent', - backgroundColor: Platform.OS === 'ios' - ? `${theme.colors.darkBackground}60` + backgroundColor: Platform.OS === 'ios' + ? `${theme.colors.darkBackground}60` : 'rgba(255, 255, 255, 0.07)' } ]} @@ -75,26 +76,26 @@ const ThemeCard: React.FC = ({ )} - + - + {theme.isEditable && ( {onEdit && ( - )} {onDelete && ( - @@ -114,11 +115,11 @@ interface FilterTabProps { primaryColor: string; } -const FilterTab: React.FC = ({ - category, - isActive, +const FilterTab: React.FC = ({ + category, + isActive, onPress, - primaryColor + primaryColor }) => ( = ({ ]} onPress={onPress} > - @@ -171,152 +172,157 @@ const ThemeColorEditor: React.FC { - const [themeName, setThemeName] = useState('Custom Theme'); - const [selectedColorKey, setSelectedColorKey] = useState('primary'); - const [themeColors, setThemeColors] = useState({ - primary: initialColors.primary, - secondary: initialColors.secondary, - darkBackground: initialColors.darkBackground, - }); - - const handleColorChange = useCallback((color: string) => { - setThemeColors(prev => ({ - ...prev, - [selectedColorKey]: color, - })); - }, [selectedColorKey]); - - const handleSave = () => { - if (!themeName.trim()) { - setAlertTitle('Invalid Name'); - setAlertMessage('Please enter a valid theme name'); - setAlertActions([{ label: 'OK', onPress: () => {} }]); - setAlertVisible(true); - return; - } - onSave({ - ...themeColors, - name: themeName + const { t } = useTranslation(); + const [themeName, setThemeName] = useState(t('theme.editor.theme_name_placeholder') || 'Custom Theme'); + const [selectedColorKey, setSelectedColorKey] = useState('primary'); + const [themeColors, setThemeColors] = useState({ + primary: initialColors.primary, + secondary: initialColors.secondary, + darkBackground: initialColors.darkBackground, }); - }; - // Compact preview component - const ThemePreview = () => ( - - - {/* App header */} - - - - - - - - - {/* Content area */} - - {/* Featured content poster */} - - - - - - + const handleColorChange = useCallback((color: string) => { + setThemeColors(prev => ({ + ...prev, + [selectedColorKey]: color, + })); + }, [selectedColorKey]); + + const handleSave = () => { + if (!themeName.trim()) { + if (!themeName.trim()) { + setAlertTitle(t('theme.editor.invalid_name_title')); + setAlertMessage(t('theme.editor.invalid_name_msg')); + setAlertActions([{ label: 'OK', onPress: () => { } }]); + setAlertVisible(true); + return; + } + setAlertVisible(true); + return; + } + onSave({ + ...themeColors, + name: themeName + }); + }; + + // Compact preview component + const ThemePreview = () => ( + + + {/* App header */} + + + + + - - {/* Content row */} - - - - - - - - - - - - ); - return ( - - - - - - - - Save - - - - - - - - - setSelectedColorKey('primary')} - > - Primary - - - setSelectedColorKey('secondary')} - > - Secondary - - - setSelectedColorKey('darkBackground')} - > - Background - + {/* Content area */} + + {/* Featured content poster */} + + + + + + + + + + {/* Content row */} + + + + + + + + - - - + ); + + return ( + + + + + + + + {t('theme.editor.save')} + + + + + + + + + setSelectedColorKey('primary')} + > + {t('theme.editor.primary')} + + + setSelectedColorKey('secondary')} + > + {t('theme.editor.secondary')} + + + setSelectedColorKey('darkBackground')} + > + {t('theme.editor.background')} + + + + + + + - - ); -}; + ); + }; const ThemeScreen: React.FC = () => { const { @@ -327,6 +333,7 @@ const ThemeScreen: React.FC = () => { updateCustomTheme, deleteCustomTheme } = useTheme(); + const { t } = useTranslation(); const navigation = useNavigation>(); const insets = useSafeAreaInsets(); const { settings, updateSetting } = useSettings(); @@ -335,7 +342,15 @@ const ThemeScreen: React.FC = () => { const headerTopPadding = Platform.OS === 'android' ? ANDROID_STATUSBAR_HEIGHT + 8 : 8; - + + // Theme categories for organization + const THEME_CATEGORIES = [ + { id: 'all', name: t('theme.categories.all') }, + { id: 'dark', name: t('theme.categories.dark') }, + { id: 'colorful', name: t('theme.categories.colorful') }, + { id: 'custom', name: t('theme.categories.custom') }, + ]; + const [isEditMode, setIsEditMode] = useState(false); const [editingTheme, setEditingTheme] = useState(null); const [activeFilter, setActiveFilter] = useState('all'); @@ -352,9 +367,9 @@ const ThemeScreen: React.FC = () => { StatusBar.setBackgroundColor('transparent'); } }; - + applyStatusBarConfig(); - + // Re-apply on focus const unsubscribe = navigation.addListener('focus', applyStatusBarConfig); return unsubscribe; @@ -365,19 +380,19 @@ const ThemeScreen: React.FC = () => { switch (activeFilter) { case 'dark': // Themes with darker colors - return availableThemes.filter(theme => - !theme.isEditable && - theme.id !== 'neon' && + return availableThemes.filter(theme => + !theme.isEditable && + theme.id !== 'neon' && theme.id !== 'retro' ); case 'colorful': // Themes with vibrant colors - return availableThemes.filter(theme => - !theme.isEditable && - (theme.id === 'neon' || - theme.id === 'retro' || - theme.id === 'sunset' || - theme.id === 'amber') + return availableThemes.filter(theme => + !theme.isEditable && + (theme.id === 'neon' || + theme.id === 'retro' || + theme.id === 'sunset' || + theme.id === 'amber') ); case 'custom': // User's custom themes @@ -398,18 +413,18 @@ const ThemeScreen: React.FC = () => { }, []); const handleDeleteTheme = useCallback((theme: Theme) => { - setAlertTitle('Delete Theme'); - setAlertMessage(`Are you sure you want to delete "${theme.name}"?`); + setAlertTitle(t('theme.alerts.delete_title')); + setAlertMessage(t('theme.alerts.delete_msg', { name: theme.name })); setAlertActions([ - { label: 'Cancel', style: { color: '#888' }, onPress: () => {} }, + { label: t('theme.alerts.cancel'), style: { color: '#888' }, onPress: () => { } }, { - label: 'Delete', + label: t('theme.alerts.delete'), style: { color: currentTheme.colors.error }, onPress: () => deleteCustomTheme(theme.id), }, ]); setAlertVisible(true); - }, [deleteCustomTheme, currentTheme.colors.error]); + }, [deleteCustomTheme, currentTheme.colors.error, t]); const handleCreateTheme = useCallback(() => { setEditingTheme(null); @@ -432,7 +447,7 @@ const ThemeScreen: React.FC = () => { } else { // Create new theme addCustomTheme({ - name: themeData.name || 'Custom Theme', + name: themeData.name || t('theme.create_custom'), colors: { ...currentTheme.colors, primary: themeData.primary, @@ -441,7 +456,7 @@ const ThemeScreen: React.FC = () => { } }); } - + setIsEditMode(false); setEditingTheme(null); }, [editingTheme, updateCustomTheme, addCustomTheme, currentTheme]); @@ -467,9 +482,9 @@ const ThemeScreen: React.FC = () => { const ThemeColorEditorWithAlert = (props: any) => { const handleSave = (themeName: string, themeColors: any, onSave: any) => { if (!themeName.trim()) { - setAlertTitle('Invalid Name'); - setAlertMessage('Please enter a valid theme name'); - setAlertActions([{ label: 'OK', onPress: () => {} }]); + setAlertTitle(t('theme.editor.invalid_name_title')); + setAlertMessage(t('theme.editor.invalid_name_msg')); + setAlertActions([{ label: 'OK', onPress: () => { } }]); setAlertVisible(true); return false; } @@ -503,7 +518,7 @@ const ThemeScreen: React.FC = () => { return ( @@ -529,31 +544,31 @@ const ThemeScreen: React.FC = () => { return ( - + - navigation.goBack()} > - Settings + {t('theme.alerts.back') || t('settings.app_settings_label').split(' ')[0] || 'Settings'} - + {/* Empty for now, but ready for future actions */} - + - App Themes + {t('theme.title')} - + {/* Category filter */} { contentContainerStyle={styles.filterList} /> - - - SELECT THEME + {t('theme.select_theme')} - + {filteredThemes.map(theme => ( { /> ))} - - - Create Custom Theme + {t('theme.create_custom')} - OPTIONS + {t('theme.options')} - Use Dominant Color from Artwork + {t('theme.use_dominant_color')} { actions={alertActions} onClose={() => setAlertVisible(false)} /> - + ); }; @@ -801,7 +816,7 @@ const styles = StyleSheet.create({ optionLabel: { fontSize: 14, }, - + // Editor styles editorContainer: { flex: 1, @@ -977,7 +992,7 @@ const styles = StyleSheet.create({ padding: 8, marginBottom: 10, }, - + // Legacy styles - keep for backward compatibility editorTitle: { fontSize: 18,