feat(i18n): migrate settings literals
This commit is contained in:
@@ -33,9 +33,9 @@ class PantallaAjustes extends StatelessWidget {
|
||||
title: l10n.settingsTitle,
|
||||
subtitle: l10n.settingsSubtitle,
|
||||
glyph: PluriIconGlyph.settings,
|
||||
trailing: const PluriStatusPill(
|
||||
trailing: PluriStatusPill(
|
||||
icon: Icons.security_rounded,
|
||||
label: 'Seguro',
|
||||
label: l10n.settingsSafeStatus,
|
||||
),
|
||||
),
|
||||
const Padding(
|
||||
@@ -80,8 +80,9 @@ class _SeccionGrabaciones extends StatelessWidget {
|
||||
Future<void> _seleccionarRuta(BuildContext context) async {
|
||||
final estado = context.read<EstadoRadio>();
|
||||
final messenger = ScaffoldMessenger.of(context);
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final ruta = await FilePicker.platform.getDirectoryPath(
|
||||
dialogTitle: 'Selecciona la carpeta de grabaciones',
|
||||
dialogTitle: l10n.recordingsFolderDialogTitle,
|
||||
);
|
||||
if (ruta == null) return;
|
||||
try {
|
||||
@@ -91,7 +92,7 @@ class _SeccionGrabaciones extends StatelessWidget {
|
||||
);
|
||||
} catch (e) {
|
||||
messenger.showSnackBar(
|
||||
SnackBar(content: Text('No se pudo guardar la ruta: $e')),
|
||||
SnackBar(content: Text(l10n.recordingsPathSaveError(e.toString()))),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -118,7 +119,7 @@ class _SeccionGrabaciones extends StatelessWidget {
|
||||
const Icon(Icons.radio_button_checked),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'Grabaciones',
|
||||
AppLocalizations.of(context).recordingsSectionTitle,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
@@ -131,7 +132,7 @@ class _SeccionGrabaciones extends StatelessWidget {
|
||||
leading: const Icon(Icons.folder_outlined),
|
||||
title: const Text('Carpeta de grabación'),
|
||||
subtitle: Text(
|
||||
snap.data ?? 'Calculando ruta...',
|
||||
snap.data ?? AppLocalizations.of(context).recordingsPathCalculating,
|
||||
maxLines: 2,
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
@@ -143,13 +144,13 @@ class _SeccionGrabaciones extends StatelessWidget {
|
||||
Expanded(
|
||||
child: OutlinedButton.icon(
|
||||
icon: const Icon(Icons.folder_open_rounded),
|
||||
label: const Text('Cambiar ruta'),
|
||||
label: Text(AppLocalizations.of(context).recordingsChangePath),
|
||||
onPressed: () => _seleccionarRuta(context),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
IconButton.filledTonal(
|
||||
tooltip: 'Usar ruta por defecto',
|
||||
tooltip: AppLocalizations.of(context).recordingsUseDefaultPath,
|
||||
icon: const Icon(Icons.restore_rounded),
|
||||
onPressed: () => _restaurarRuta(context),
|
||||
),
|
||||
@@ -157,7 +158,7 @@ class _SeccionGrabaciones extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
Text(
|
||||
'La radio se guarda desde el stream original, sin recomprimir.',
|
||||
AppLocalizations.of(context).recordingsOriginalStreamHint,
|
||||
style: Theme.of(context).textTheme.bodySmall,
|
||||
),
|
||||
],
|
||||
@@ -456,13 +457,13 @@ class _SeccionEcualizador extends StatelessWidget {
|
||||
const Icon(Icons.equalizer),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'Ecualizador',
|
||||
AppLocalizations.of(ctx).equalizerTitle,
|
||||
style: Theme.of(ctx).textTheme.titleMedium,
|
||||
),
|
||||
const Spacer(),
|
||||
Chip(
|
||||
label: Text(
|
||||
estado.ecualizadorActivo ? 'Activo' : 'Desactivado',
|
||||
estado.ecualizadorActivo ? AppLocalizations.of(ctx).equalizerActive : AppLocalizations.of(ctx).equalizerDisabled,
|
||||
),
|
||||
visualDensity: VisualDensity.compact,
|
||||
),
|
||||
@@ -471,7 +472,7 @@ class _SeccionEcualizador extends StatelessWidget {
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: const Text('Activar ecualizador'),
|
||||
title: Text(AppLocalizations.of(ctx).equalizerEnable),
|
||||
subtitle: Text(
|
||||
disponible
|
||||
? 'Los cambios se aplican en tiempo real a la emisora actual.'
|
||||
@@ -484,11 +485,11 @@ class _SeccionEcualizador extends StatelessWidget {
|
||||
const SizedBox(height: 8),
|
||||
SwitchListTile.adaptive(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
title: const Text('Usar EQ propio para esta favorita'),
|
||||
title: Text(AppLocalizations.of(ctx).equalizerPerStationTitle),
|
||||
subtitle: Text(
|
||||
usandoEqPropio
|
||||
? 'Activo para ${emisoraActual.nombre}'
|
||||
: 'Usando EQ principal para ${emisoraActual.nombre}',
|
||||
? AppLocalizations.of(ctx).equalizerPerStationActive(emisoraActual.nombre)
|
||||
: AppLocalizations.of(ctx).equalizerPerStationMain(emisoraActual.nombre),
|
||||
),
|
||||
value: usandoEqPropio,
|
||||
onChanged:
|
||||
@@ -535,7 +536,7 @@ class _SeccionEmisoraPreferida extends StatelessWidget {
|
||||
const Icon(Icons.radio_rounded),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'Emisora preferida',
|
||||
AppLocalizations.of(context).preferredStationTitle,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
@@ -593,7 +594,7 @@ class _SeccionEmisoraPreferida extends StatelessWidget {
|
||||
alignment: Alignment.centerLeft,
|
||||
child: FilledButton.tonalIcon(
|
||||
icon: const Icon(Icons.play_arrow_rounded),
|
||||
label: const Text('Reproducir preferida'),
|
||||
label: Text(AppLocalizations.of(context).preferredStationPlay),
|
||||
onPressed:
|
||||
() => context.read<EstadoRadio>().reproducirEmisoraPreferida(),
|
||||
),
|
||||
@@ -634,7 +635,7 @@ class _SeccionEmisoras extends StatelessWidget {
|
||||
const Icon(Icons.add_circle_outline),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'Emisoras personalizadas',
|
||||
AppLocalizations.of(context).customStationsTitle,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
const Spacer(),
|
||||
@@ -646,11 +647,11 @@ class _SeccionEmisoras extends StatelessWidget {
|
||||
],
|
||||
),
|
||||
if (custom.isEmpty)
|
||||
const Padding(
|
||||
padding: EdgeInsets.only(top: 8),
|
||||
Padding(
|
||||
padding: const EdgeInsets.only(top: 8),
|
||||
child: Text(
|
||||
'No hay emisoras personalizadas.',
|
||||
style: TextStyle(color: Colors.grey),
|
||||
AppLocalizations.of(context).customStationsEmpty,
|
||||
style: const TextStyle(color: Colors.grey),
|
||||
),
|
||||
)
|
||||
else
|
||||
@@ -669,13 +670,13 @@ class _SeccionEmisoras extends StatelessWidget {
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.play_arrow),
|
||||
tooltip: 'Reproducir',
|
||||
tooltip: AppLocalizations.of(context).playAction,
|
||||
onPressed:
|
||||
() => context.read<EstadoRadio>().reproducir(emisora),
|
||||
),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.delete_outline),
|
||||
tooltip: 'Eliminar',
|
||||
tooltip: AppLocalizations.of(context).deleteAction,
|
||||
onPressed:
|
||||
() => context
|
||||
.read<EstadoRadio>()
|
||||
@@ -753,27 +754,27 @@ class _FormularioEmisoraState extends State<_FormularioEmisora> {
|
||||
const SizedBox(height: 16),
|
||||
TextFormField(
|
||||
controller: _nombreCtrl,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'Nombre *',
|
||||
border: OutlineInputBorder(),
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).stationNameLabel,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
validator:
|
||||
(v) =>
|
||||
v == null || v.trim().isEmpty
|
||||
? 'Campo obligatorio'
|
||||
? AppLocalizations.of(context).requiredField
|
||||
: null,
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
TextFormField(
|
||||
controller: _urlCtrl,
|
||||
decoration: const InputDecoration(
|
||||
labelText: 'URL del stream *',
|
||||
decoration: InputDecoration(
|
||||
labelText: AppLocalizations.of(context).streamUrlLabel,
|
||||
hintText: 'http://stream.ejemplo.com:8000/radio',
|
||||
border: OutlineInputBorder(),
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
keyboardType: TextInputType.url,
|
||||
validator: (v) {
|
||||
if (v == null || v.trim().isEmpty) return 'Campo obligatorio';
|
||||
if (v == null || v.trim().isEmpty) return AppLocalizations.of(context).requiredField;
|
||||
final uri = Uri.tryParse(v.trim());
|
||||
if (uri == null || !uri.hasScheme) return 'URL no válida';
|
||||
return null;
|
||||
@@ -797,7 +798,7 @@ class _FormularioEmisoraState extends State<_FormularioEmisora> {
|
||||
width: 20,
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
)
|
||||
: const Text('Guardar emisora'),
|
||||
: Text(AppLocalizations.of(context).saveStation),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -829,7 +830,7 @@ class _SeccionBackup extends StatelessWidget {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('Error al exportar: $e')));
|
||||
).showSnackBar(SnackBar(content: Text(AppLocalizations.of(context).backupExportError(e.toString()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -858,11 +859,11 @@ class _SeccionBackup extends StatelessWidget {
|
||||
actions: [
|
||||
TextButton(
|
||||
onPressed: () => Navigator.pop(ctx, false),
|
||||
child: const Text('Cancelar'),
|
||||
child: Text(AppLocalizations.of(ctx).cancelAction),
|
||||
),
|
||||
FilledButton(
|
||||
onPressed: () => Navigator.pop(ctx, true),
|
||||
child: const Text('Importar'),
|
||||
child: Text(AppLocalizations.of(ctx).backupImportTitle),
|
||||
),
|
||||
],
|
||||
),
|
||||
@@ -883,7 +884,7 @@ class _SeccionBackup extends StatelessWidget {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(SnackBar(content: Text('Error al importar: $e')));
|
||||
).showSnackBar(SnackBar(content: Text(AppLocalizations.of(context).backupImportError(e.toString()))));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -899,7 +900,7 @@ class _SeccionBackup extends StatelessWidget {
|
||||
const Icon(Icons.backup_outlined),
|
||||
const SizedBox(width: 12),
|
||||
Text(
|
||||
'Copia de seguridad',
|
||||
AppLocalizations.of(context).backupSectionTitle,
|
||||
style: Theme.of(context).textTheme.titleMedium,
|
||||
),
|
||||
],
|
||||
@@ -908,16 +909,14 @@ class _SeccionBackup extends StatelessWidget {
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.upload_outlined),
|
||||
title: const Text('Exportar configuración'),
|
||||
subtitle: const Text('Favoritos, emisoras custom y presets de EQ'),
|
||||
subtitle: Text(AppLocalizations.of(context).backupExportSubtitle),
|
||||
onTap: () => _exportar(context),
|
||||
),
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.download_outlined),
|
||||
title: const Text('Importar configuración'),
|
||||
subtitle: const Text(
|
||||
'Restaurar desde un fichero de copia de seguridad',
|
||||
),
|
||||
subtitle: Text(AppLocalizations.of(context).backupImportSubtitle),
|
||||
onTap: () => _importar(context),
|
||||
),
|
||||
],
|
||||
@@ -950,7 +949,7 @@ class _SeccionInfo extends StatelessWidget {
|
||||
variant: PluriIconVariant.filled,
|
||||
),
|
||||
title: const Text('PluriWave'),
|
||||
subtitle: Text('$version - Radio mundial'),
|
||||
subtitle: Text(AppLocalizations.of(ctx).appVersionSubtitle(version)),
|
||||
);
|
||||
},
|
||||
),
|
||||
@@ -960,19 +959,19 @@ class _SeccionInfo extends StatelessWidget {
|
||||
(ctx, snap) => ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: const Icon(Icons.favorite_outline),
|
||||
title: const Text('Favoritos guardados'),
|
||||
title: Text(AppLocalizations.of(ctx).savedFavoritesTitle),
|
||||
trailing: Text(
|
||||
snap.data?.toString() ?? '—',
|
||||
style: Theme.of(ctx).textTheme.bodyLarge,
|
||||
),
|
||||
),
|
||||
),
|
||||
const ListTile(
|
||||
ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
leading: Icon(Icons.verified_outlined),
|
||||
title: Text('Filtro de emisoras'),
|
||||
subtitle: Text('Solo emisoras verificadas como activas'),
|
||||
trailing: Icon(Icons.check_circle, color: Colors.green),
|
||||
leading: const Icon(Icons.verified_outlined),
|
||||
title: Text(AppLocalizations.of(ctx).stationFilterTitle),
|
||||
subtitle: Text(AppLocalizations.of(ctx).stationFilterSubtitle),
|
||||
trailing: const Icon(Icons.check_circle, color: Colors.green),
|
||||
),
|
||||
const ListTile(
|
||||
contentPadding: EdgeInsets.zero,
|
||||
|
||||
Reference in New Issue
Block a user