Files
farolero/lib/servicios/servicio_idioma.dart
ShanaiaBot 1bca50af1d v0.2.0: i18n 18 idiomas + pantalla ajustes + bancos multiidioma
Internacionalización completa:
- 18 ficheros .arb: es, en, fr, pt, de, it, ru, ja, ko, zh, zh_TW, ar, hi, tr, pl, nl, ca, eu
- Todos los strings extraídos de todas las pantallas
- Detección automática de idioma del sistema
- Selector manual en pantalla de ajustes

Pantalla de ajustes nueva:
- Selector de idioma con banderas emoji
- Vibración ON/OFF
- Acerca de (versión, desarrollador)

Bancos de palabras multiidioma:
- palabras.json (castellano, 1000 palabras)
- palabras_en.json (inglés, 1000 palabras)
- palabras_fr.json (francés, 1000 palabras)
- Fallback a castellano si no hay banco del idioma

13138 líneas Dart, 39 ficheros, 0 issues en flutter analyze
2026-04-04 01:18:09 +02:00

84 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// Servicio para gestionar el idioma de la app
class ServicioIdioma extends ChangeNotifier {
static const _claveIdioma = 'idioma_app';
Locale? _locale;
Locale? get locale => _locale;
/// Idiomas soportados con su bandera y nombre nativo
static const idiomasSoportados = <String, ({String bandera, String nombre})>{
'es': (bandera: '🇪🇸', nombre: 'Español'),
'en': (bandera: '🇬🇧', nombre: 'English'),
'fr': (bandera: '🇫🇷', nombre: 'Français'),
'pt': (bandera: '🇧🇷', nombre: 'Português'),
'de': (bandera: '🇩🇪', nombre: 'Deutsch'),
'it': (bandera: '🇮🇹', nombre: 'Italiano'),
'ru': (bandera: '🇷🇺', nombre: 'Русский'),
'ja': (bandera: '🇯🇵', nombre: '日本語'),
'ko': (bandera: '🇰🇷', nombre: '한국어'),
'zh': (bandera: '🇨🇳', nombre: '简体中文'),
'zh_TW': (bandera: '🇹🇼', nombre: '繁體中文'),
'ar': (bandera: '🇸🇦', nombre: 'العربية'),
'hi': (bandera: '🇮🇳', nombre: 'हिन्दी'),
'tr': (bandera: '🇹🇷', nombre: 'Türkçe'),
'pl': (bandera: '🇵🇱', nombre: 'Polski'),
'nl': (bandera: '🇳🇱', nombre: 'Nederlands'),
'ca': (bandera: '🏴', nombre: 'Català'),
'eu': (bandera: '🏴', nombre: 'Euskara'),
};
static List<Locale> get localesSoportados => idiomasSoportados.keys.map((k) {
if (k.contains('_')) {
final partes = k.split('_');
return Locale(partes[0], partes[1]);
}
return Locale(k);
}).toList();
/// Carga el idioma guardado en preferencias
Future<void> cargar() async {
final prefs = await SharedPreferences.getInstance();
final codigo = prefs.getString(_claveIdioma);
if (codigo != null) {
if (codigo.contains('_')) {
final partes = codigo.split('_');
_locale = Locale(partes[0], partes[1]);
} else {
_locale = Locale(codigo);
}
}
// Si no hay preferencia guardada, _locale queda null → se usa el del sistema
notifyListeners();
}
/// Cambia el idioma y lo persiste
Future<void> cambiarIdioma(String codigoIdioma) async {
final prefs = await SharedPreferences.getInstance();
if (codigoIdioma == 'sistema') {
await prefs.remove(_claveIdioma);
_locale = null;
} else {
await prefs.setString(_claveIdioma, codigoIdioma);
if (codigoIdioma.contains('_')) {
final partes = codigoIdioma.split('_');
_locale = Locale(partes[0], partes[1]);
} else {
_locale = Locale(codigoIdioma);
}
}
notifyListeners();
}
/// Devuelve el código de idioma actual (o 'sistema' si usa el del dispositivo)
String get codigoActual {
if (_locale == null) return 'sistema';
if (_locale!.countryCode != null && _locale!.countryCode!.isNotEmpty) {
return '${_locale!.languageCode}_${_locale!.countryCode}';
}
return _locale!.languageCode;
}
}