diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 2e69a75..2d559a4 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -43,5 +43,111 @@ "timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionRestoreRecommended": "Restore recommended times", "newQuickAccessTitle": "New quick access", - "saveQuickAccessButton": "Save quick access" + "saveQuickAccessButton": "Save quick access", + "settingsSafeStatus": "Safe", + "recordingsSectionTitle": "Recordings", + "recordingsFolderDialogTitle": "Select recordings folder", + "recordingsPathUpdated": "Recording path updated", + "recordingsPathSaveError": "Could not save the path: {error}", + "recordingsDefaultFolderRestored": "The internal default folder will be used", + "recordingsFolderTitle": "Recordings folder", + "recordingsPathCalculating": "Calculating path...", + "recordingsChangePath": "Change path", + "recordingsUseDefaultPath": "Use default path", + "recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", + "equalizerActive": "Active", + "equalizerDisabled": "Disabled", + "equalizerEnable": "Enable equalizer", + "equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", + "equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", + "equalizerPerStationTitle": "Use custom EQ for this favorite", + "equalizerPerStationActive": "Active for {stationName}", + "equalizerPerStationMain": "Using main EQ for {stationName}", + "preferredStationTitle": "Preferred station", + "preferredStationDescription": "Preselected for new alarms and available for quick playback.", + "preferredStationNoStationsTitle": "No stations available yet", + "preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", + "preferredStationAutomaticFallback": "Automatic fallback", + "preferredStationDefaultFavorite": "Default favorite", + "preferredStationCurrent": "Current preferred: {stationName}", + "preferredStationAutoUsing": "No favorites: automatically using {stationName}", + "preferredStationPlay": "Play preferred", + "customStationsTitle": "Custom stations", + "customStationsAdd": "Add", + "customStationsEmpty": "No custom stations.", + "playAction": "Play", + "deleteAction": "Delete", + "addStationTitle": "Add station", + "stationNameLabel": "Name *", + "requiredField": "Required field", + "streamUrlLabel": "Stream URL *", + "invalidUrl": "Invalid URL", + "countryOptionalLabel": "Country (optional)", + "saveStation": "Save station", + "backupSectionTitle": "Backup", + "backupExportTitle": "Export configuration", + "backupExportSubtitle": "Favorites, custom stations, and EQ presets", + "backupImportTitle": "Import configuration", + "backupImportSubtitle": "Restore from a backup file", + "backupShareSubject": "PluriWave ? backup", + "backupShareText": "PluriWave configuration exported on {date}", + "backupExportError": "Export error: {error}", + "backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", + "backupImportSuccess": "Configuration imported successfully", + "backupImportError": "Import error: {error}", + "appVersionLoading": "Loading version...", + "appVersionSubtitle": "{version} - World radio", + "savedFavoritesTitle": "Saved favorites", + "stationFilterTitle": "Station filter", + "stationFilterSubtitle": "Only stations verified as active", + "backgroundAudioTitle": "Background audio", + "backgroundAudioSubtitle": "Continues when the screen turns off", + "dash": "?", + "@recordingsPathSaveError": { + "placeholders": { + "error": {} + } + }, + "@equalizerPerStationActive": { + "placeholders": { + "stationName": {} + } + }, + "@equalizerPerStationMain": { + "placeholders": { + "stationName": {} + } + }, + "@preferredStationCurrent": { + "placeholders": { + "stationName": {} + } + }, + "@preferredStationAutoUsing": { + "placeholders": { + "stationName": {} + } + }, + "@backupShareText": { + "placeholders": { + "date": {} + } + }, + "@backupExportError": { + "placeholders": { + "error": {} + } + }, + "@backupImportError": { + "placeholders": { + "error": {} + } + }, + "@appVersionSubtitle": { + "placeholders": { + "version": {} + } + }, + "cancelAction": "Cancel", + "equalizerTitle": "Equalizer" } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index d476546..3c409fa 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -43,5 +43,111 @@ "timerSectionDescription": "Personalizá los accesos rápidos que aparecen al apagar la radio automáticamente.", "timerSectionRestoreRecommended": "Restaurar tiempos recomendados", "newQuickAccessTitle": "Nuevo acceso rápido", - "saveQuickAccessButton": "Guardar acceso rápido" + "saveQuickAccessButton": "Guardar acceso rápido", + "settingsSafeStatus": "Seguro", + "recordingsSectionTitle": "Grabaciones", + "recordingsFolderDialogTitle": "Selecciona la carpeta de grabaciones", + "recordingsPathUpdated": "Ruta de grabaci?n actualizada", + "recordingsPathSaveError": "No se pudo guardar la ruta: {error}", + "recordingsDefaultFolderRestored": "Se usar? la carpeta interna por defecto", + "recordingsFolderTitle": "Carpeta de grabaci?n", + "recordingsPathCalculating": "Calculando ruta...", + "recordingsChangePath": "Cambiar ruta", + "recordingsUseDefaultPath": "Usar ruta por defecto", + "recordingsOriginalStreamHint": "La radio se guarda desde el stream original, sin recomprimir.", + "equalizerActive": "Activo", + "equalizerDisabled": "Desactivado", + "equalizerEnable": "Activar ecualizador", + "equalizerRealtimeSubtitle": "Los cambios se aplican en tiempo real a la emisora actual.", + "equalizerPendingSubtitle": "Se guardan los cambios y se aplicar?n cuando Android habilite el efecto.", + "equalizerPerStationTitle": "Usar EQ propio para esta favorita", + "equalizerPerStationActive": "Activo para {stationName}", + "equalizerPerStationMain": "Usando EQ principal para {stationName}", + "preferredStationTitle": "Emisora preferida", + "preferredStationDescription": "Se preselecciona al crear alarmas y puede iniciarse como reproducci?n r?pida.", + "preferredStationNoStationsTitle": "Todav?a no hay emisoras disponibles", + "preferredStationNoStationsSubtitle": "Guard? favoritas o carg? emisoras para elegir una preferida.", + "preferredStationAutomaticFallback": "Fallback autom?tico", + "preferredStationDefaultFavorite": "Favorita por defecto", + "preferredStationCurrent": "Preferida actual: {stationName}", + "preferredStationAutoUsing": "Sin favoritas: usando autom?ticamente {stationName}", + "preferredStationPlay": "Reproducir preferida", + "customStationsTitle": "Emisoras personalizadas", + "customStationsAdd": "A?adir", + "customStationsEmpty": "No hay emisoras personalizadas.", + "playAction": "Reproducir", + "deleteAction": "Eliminar", + "addStationTitle": "A?adir emisora", + "stationNameLabel": "Nombre *", + "requiredField": "Campo obligatorio", + "streamUrlLabel": "URL del stream *", + "invalidUrl": "URL no v?lida", + "countryOptionalLabel": "Pa?s (opcional)", + "saveStation": "Guardar emisora", + "backupSectionTitle": "Copia de seguridad", + "backupExportTitle": "Exportar configuraci?n", + "backupExportSubtitle": "Favoritos, emisoras custom y presets de EQ", + "backupImportTitle": "Importar configuraci?n", + "backupImportSubtitle": "Restaurar desde un fichero de copia de seguridad", + "backupShareSubject": "PluriWave ? copia de seguridad", + "backupShareText": "Configuraci?n de PluriWave exportada el {date}", + "backupExportError": "Error al exportar: {error}", + "backupImportConfirmMessage": "Esto a?adir? los favoritos, emisoras y presets del fichero. ?Continuar?", + "backupImportSuccess": "Configuraci?n importada correctamente", + "backupImportError": "Error al importar: {error}", + "appVersionLoading": "Cargando versi?n...", + "appVersionSubtitle": "{version} - Radio mundial", + "savedFavoritesTitle": "Favoritos guardados", + "stationFilterTitle": "Filtro de emisoras", + "stationFilterSubtitle": "Solo emisoras verificadas como activas", + "backgroundAudioTitle": "Audio en background", + "backgroundAudioSubtitle": "Contin?a al apagar la pantalla", + "dash": "?", + "@recordingsPathSaveError": { + "placeholders": { + "error": {} + } + }, + "@equalizerPerStationActive": { + "placeholders": { + "stationName": {} + } + }, + "@equalizerPerStationMain": { + "placeholders": { + "stationName": {} + } + }, + "@preferredStationCurrent": { + "placeholders": { + "stationName": {} + } + }, + "@preferredStationAutoUsing": { + "placeholders": { + "stationName": {} + } + }, + "@backupShareText": { + "placeholders": { + "date": {} + } + }, + "@backupExportError": { + "placeholders": { + "error": {} + } + }, + "@backupImportError": { + "placeholders": { + "error": {} + } + }, + "@appVersionSubtitle": { + "placeholders": { + "version": {} + } + }, + "cancelAction": "Cancelar", + "equalizerTitle": "Ecualizador" } diff --git a/lib/l10n/gen/app_localizations.dart b/lib/l10n/gen/app_localizations.dart index f17d6da..8f25543 100644 --- a/lib/l10n/gen/app_localizations.dart +++ b/lib/l10n/gen/app_localizations.dart @@ -301,6 +301,372 @@ abstract class AppLocalizations { /// In es, this message translates to: /// **'Guardar acceso rápido'** String get saveQuickAccessButton; + + /// No description provided for @settingsSafeStatus. + /// + /// In es, this message translates to: + /// **'Seguro'** + String get settingsSafeStatus; + + /// No description provided for @recordingsSectionTitle. + /// + /// In es, this message translates to: + /// **'Grabaciones'** + String get recordingsSectionTitle; + + /// No description provided for @recordingsFolderDialogTitle. + /// + /// In es, this message translates to: + /// **'Selecciona la carpeta de grabaciones'** + String get recordingsFolderDialogTitle; + + /// No description provided for @recordingsPathUpdated. + /// + /// In es, this message translates to: + /// **'Ruta de grabaci?n actualizada'** + String get recordingsPathUpdated; + + /// No description provided for @recordingsPathSaveError. + /// + /// In es, this message translates to: + /// **'No se pudo guardar la ruta: {error}'** + String recordingsPathSaveError(Object error); + + /// No description provided for @recordingsDefaultFolderRestored. + /// + /// In es, this message translates to: + /// **'Se usar? la carpeta interna por defecto'** + String get recordingsDefaultFolderRestored; + + /// No description provided for @recordingsFolderTitle. + /// + /// In es, this message translates to: + /// **'Carpeta de grabaci?n'** + String get recordingsFolderTitle; + + /// No description provided for @recordingsPathCalculating. + /// + /// In es, this message translates to: + /// **'Calculando ruta...'** + String get recordingsPathCalculating; + + /// No description provided for @recordingsChangePath. + /// + /// In es, this message translates to: + /// **'Cambiar ruta'** + String get recordingsChangePath; + + /// No description provided for @recordingsUseDefaultPath. + /// + /// In es, this message translates to: + /// **'Usar ruta por defecto'** + String get recordingsUseDefaultPath; + + /// No description provided for @recordingsOriginalStreamHint. + /// + /// In es, this message translates to: + /// **'La radio se guarda desde el stream original, sin recomprimir.'** + String get recordingsOriginalStreamHint; + + /// No description provided for @equalizerActive. + /// + /// In es, this message translates to: + /// **'Activo'** + String get equalizerActive; + + /// No description provided for @equalizerDisabled. + /// + /// In es, this message translates to: + /// **'Desactivado'** + String get equalizerDisabled; + + /// No description provided for @equalizerEnable. + /// + /// In es, this message translates to: + /// **'Activar ecualizador'** + String get equalizerEnable; + + /// No description provided for @equalizerRealtimeSubtitle. + /// + /// In es, this message translates to: + /// **'Los cambios se aplican en tiempo real a la emisora actual.'** + String get equalizerRealtimeSubtitle; + + /// No description provided for @equalizerPendingSubtitle. + /// + /// In es, this message translates to: + /// **'Se guardan los cambios y se aplicar?n cuando Android habilite el efecto.'** + String get equalizerPendingSubtitle; + + /// No description provided for @equalizerPerStationTitle. + /// + /// In es, this message translates to: + /// **'Usar EQ propio para esta favorita'** + String get equalizerPerStationTitle; + + /// No description provided for @equalizerPerStationActive. + /// + /// In es, this message translates to: + /// **'Activo para {stationName}'** + String equalizerPerStationActive(Object stationName); + + /// No description provided for @equalizerPerStationMain. + /// + /// In es, this message translates to: + /// **'Usando EQ principal para {stationName}'** + String equalizerPerStationMain(Object stationName); + + /// No description provided for @preferredStationTitle. + /// + /// In es, this message translates to: + /// **'Emisora preferida'** + String get preferredStationTitle; + + /// No description provided for @preferredStationDescription. + /// + /// In es, this message translates to: + /// **'Se preselecciona al crear alarmas y puede iniciarse como reproducci?n r?pida.'** + String get preferredStationDescription; + + /// No description provided for @preferredStationNoStationsTitle. + /// + /// In es, this message translates to: + /// **'Todav?a no hay emisoras disponibles'** + String get preferredStationNoStationsTitle; + + /// No description provided for @preferredStationNoStationsSubtitle. + /// + /// In es, this message translates to: + /// **'Guard? favoritas o carg? emisoras para elegir una preferida.'** + String get preferredStationNoStationsSubtitle; + + /// No description provided for @preferredStationAutomaticFallback. + /// + /// In es, this message translates to: + /// **'Fallback autom?tico'** + String get preferredStationAutomaticFallback; + + /// No description provided for @preferredStationDefaultFavorite. + /// + /// In es, this message translates to: + /// **'Favorita por defecto'** + String get preferredStationDefaultFavorite; + + /// No description provided for @preferredStationCurrent. + /// + /// In es, this message translates to: + /// **'Preferida actual: {stationName}'** + String preferredStationCurrent(Object stationName); + + /// No description provided for @preferredStationAutoUsing. + /// + /// In es, this message translates to: + /// **'Sin favoritas: usando autom?ticamente {stationName}'** + String preferredStationAutoUsing(Object stationName); + + /// No description provided for @preferredStationPlay. + /// + /// In es, this message translates to: + /// **'Reproducir preferida'** + String get preferredStationPlay; + + /// No description provided for @customStationsTitle. + /// + /// In es, this message translates to: + /// **'Emisoras personalizadas'** + String get customStationsTitle; + + /// No description provided for @customStationsAdd. + /// + /// In es, this message translates to: + /// **'A?adir'** + String get customStationsAdd; + + /// No description provided for @customStationsEmpty. + /// + /// In es, this message translates to: + /// **'No hay emisoras personalizadas.'** + String get customStationsEmpty; + + /// No description provided for @playAction. + /// + /// In es, this message translates to: + /// **'Reproducir'** + String get playAction; + + /// No description provided for @deleteAction. + /// + /// In es, this message translates to: + /// **'Eliminar'** + String get deleteAction; + + /// No description provided for @addStationTitle. + /// + /// In es, this message translates to: + /// **'A?adir emisora'** + String get addStationTitle; + + /// No description provided for @stationNameLabel. + /// + /// In es, this message translates to: + /// **'Nombre *'** + String get stationNameLabel; + + /// No description provided for @requiredField. + /// + /// In es, this message translates to: + /// **'Campo obligatorio'** + String get requiredField; + + /// No description provided for @streamUrlLabel. + /// + /// In es, this message translates to: + /// **'URL del stream *'** + String get streamUrlLabel; + + /// No description provided for @invalidUrl. + /// + /// In es, this message translates to: + /// **'URL no v?lida'** + String get invalidUrl; + + /// No description provided for @countryOptionalLabel. + /// + /// In es, this message translates to: + /// **'Pa?s (opcional)'** + String get countryOptionalLabel; + + /// No description provided for @saveStation. + /// + /// In es, this message translates to: + /// **'Guardar emisora'** + String get saveStation; + + /// No description provided for @backupSectionTitle. + /// + /// In es, this message translates to: + /// **'Copia de seguridad'** + String get backupSectionTitle; + + /// No description provided for @backupExportTitle. + /// + /// In es, this message translates to: + /// **'Exportar configuraci?n'** + String get backupExportTitle; + + /// No description provided for @backupExportSubtitle. + /// + /// In es, this message translates to: + /// **'Favoritos, emisoras custom y presets de EQ'** + String get backupExportSubtitle; + + /// No description provided for @backupImportTitle. + /// + /// In es, this message translates to: + /// **'Importar configuraci?n'** + String get backupImportTitle; + + /// No description provided for @backupImportSubtitle. + /// + /// In es, this message translates to: + /// **'Restaurar desde un fichero de copia de seguridad'** + String get backupImportSubtitle; + + /// No description provided for @backupShareSubject. + /// + /// In es, this message translates to: + /// **'PluriWave ? copia de seguridad'** + String get backupShareSubject; + + /// No description provided for @backupShareText. + /// + /// In es, this message translates to: + /// **'Configuraci?n de PluriWave exportada el {date}'** + String backupShareText(Object date); + + /// No description provided for @backupExportError. + /// + /// In es, this message translates to: + /// **'Error al exportar: {error}'** + String backupExportError(Object error); + + /// No description provided for @backupImportConfirmMessage. + /// + /// In es, this message translates to: + /// **'Esto a?adir? los favoritos, emisoras y presets del fichero. ?Continuar?'** + String get backupImportConfirmMessage; + + /// No description provided for @backupImportSuccess. + /// + /// In es, this message translates to: + /// **'Configuraci?n importada correctamente'** + String get backupImportSuccess; + + /// No description provided for @backupImportError. + /// + /// In es, this message translates to: + /// **'Error al importar: {error}'** + String backupImportError(Object error); + + /// No description provided for @appVersionLoading. + /// + /// In es, this message translates to: + /// **'Cargando versi?n...'** + String get appVersionLoading; + + /// No description provided for @appVersionSubtitle. + /// + /// In es, this message translates to: + /// **'{version} - Radio mundial'** + String appVersionSubtitle(Object version); + + /// No description provided for @savedFavoritesTitle. + /// + /// In es, this message translates to: + /// **'Favoritos guardados'** + String get savedFavoritesTitle; + + /// No description provided for @stationFilterTitle. + /// + /// In es, this message translates to: + /// **'Filtro de emisoras'** + String get stationFilterTitle; + + /// No description provided for @stationFilterSubtitle. + /// + /// In es, this message translates to: + /// **'Solo emisoras verificadas como activas'** + String get stationFilterSubtitle; + + /// No description provided for @backgroundAudioTitle. + /// + /// In es, this message translates to: + /// **'Audio en background'** + String get backgroundAudioTitle; + + /// No description provided for @backgroundAudioSubtitle. + /// + /// In es, this message translates to: + /// **'Contin?a al apagar la pantalla'** + String get backgroundAudioSubtitle; + + /// No description provided for @dash. + /// + /// In es, this message translates to: + /// **'?'** + String get dash; + + /// No description provided for @cancelAction. + /// + /// In es, this message translates to: + /// **'Cancelar'** + String get cancelAction; + + /// No description provided for @equalizerTitle. + /// + /// In es, this message translates to: + /// **'Ecualizador'** + String get equalizerTitle; } class _AppLocalizationsDelegate diff --git a/lib/l10n/gen/app_localizations_en.dart b/lib/l10n/gen/app_localizations_en.dart index 5028c07..b778b83 100644 --- a/lib/l10n/gen/app_localizations_en.dart +++ b/lib/l10n/gen/app_localizations_en.dart @@ -117,4 +117,213 @@ class AppLocalizationsEn extends AppLocalizations { @override String get saveQuickAccessButton => 'Save quick access'; + + @override + String get settingsSafeStatus => 'Safe'; + + @override + String get recordingsSectionTitle => 'Recordings'; + + @override + String get recordingsFolderDialogTitle => 'Select recordings folder'; + + @override + String get recordingsPathUpdated => 'Recording path updated'; + + @override + String recordingsPathSaveError(Object error) { + return 'Could not save the path: $error'; + } + + @override + String get recordingsDefaultFolderRestored => + 'The internal default folder will be used'; + + @override + String get recordingsFolderTitle => 'Recordings folder'; + + @override + String get recordingsPathCalculating => 'Calculating path...'; + + @override + String get recordingsChangePath => 'Change path'; + + @override + String get recordingsUseDefaultPath => 'Use default path'; + + @override + String get recordingsOriginalStreamHint => + 'The radio is saved from the original stream, without recompressing.'; + + @override + String get equalizerActive => 'Active'; + + @override + String get equalizerDisabled => 'Disabled'; + + @override + String get equalizerEnable => 'Enable equalizer'; + + @override + String get equalizerRealtimeSubtitle => + 'Changes are applied in real time to the current station.'; + + @override + String get equalizerPendingSubtitle => + 'Changes are saved and will apply when Android enables the effect.'; + + @override + String get equalizerPerStationTitle => 'Use custom EQ for this favorite'; + + @override + String equalizerPerStationActive(Object stationName) { + return 'Active for $stationName'; + } + + @override + String equalizerPerStationMain(Object stationName) { + return 'Using main EQ for $stationName'; + } + + @override + String get preferredStationTitle => 'Preferred station'; + + @override + String get preferredStationDescription => + 'Preselected for new alarms and available for quick playback.'; + + @override + String get preferredStationNoStationsTitle => 'No stations available yet'; + + @override + String get preferredStationNoStationsSubtitle => + 'Save favorites or load stations to choose a preferred one.'; + + @override + String get preferredStationAutomaticFallback => 'Automatic fallback'; + + @override + String get preferredStationDefaultFavorite => 'Default favorite'; + + @override + String preferredStationCurrent(Object stationName) { + return 'Current preferred: $stationName'; + } + + @override + String preferredStationAutoUsing(Object stationName) { + return 'No favorites: automatically using $stationName'; + } + + @override + String get preferredStationPlay => 'Play preferred'; + + @override + String get customStationsTitle => 'Custom stations'; + + @override + String get customStationsAdd => 'Add'; + + @override + String get customStationsEmpty => 'No custom stations.'; + + @override + String get playAction => 'Play'; + + @override + String get deleteAction => 'Delete'; + + @override + String get addStationTitle => 'Add station'; + + @override + String get stationNameLabel => 'Name *'; + + @override + String get requiredField => 'Required field'; + + @override + String get streamUrlLabel => 'Stream URL *'; + + @override + String get invalidUrl => 'Invalid URL'; + + @override + String get countryOptionalLabel => 'Country (optional)'; + + @override + String get saveStation => 'Save station'; + + @override + String get backupSectionTitle => 'Backup'; + + @override + String get backupExportTitle => 'Export configuration'; + + @override + String get backupExportSubtitle => + 'Favorites, custom stations, and EQ presets'; + + @override + String get backupImportTitle => 'Import configuration'; + + @override + String get backupImportSubtitle => 'Restore from a backup file'; + + @override + String get backupShareSubject => 'PluriWave ? backup'; + + @override + String backupShareText(Object date) { + return 'PluriWave configuration exported on $date'; + } + + @override + String backupExportError(Object error) { + return 'Export error: $error'; + } + + @override + String get backupImportConfirmMessage => + 'This will add favorites, stations, and presets from the file. Continue?'; + + @override + String get backupImportSuccess => 'Configuration imported successfully'; + + @override + String backupImportError(Object error) { + return 'Import error: $error'; + } + + @override + String get appVersionLoading => 'Loading version...'; + + @override + String appVersionSubtitle(Object version) { + return '$version - World radio'; + } + + @override + String get savedFavoritesTitle => 'Saved favorites'; + + @override + String get stationFilterTitle => 'Station filter'; + + @override + String get stationFilterSubtitle => 'Only stations verified as active'; + + @override + String get backgroundAudioTitle => 'Background audio'; + + @override + String get backgroundAudioSubtitle => 'Continues when the screen turns off'; + + @override + String get dash => '?'; + + @override + String get cancelAction => 'Cancel'; + + @override + String get equalizerTitle => 'Equalizer'; } diff --git a/lib/l10n/gen/app_localizations_es.dart b/lib/l10n/gen/app_localizations_es.dart index 9c3e197..13892ff 100644 --- a/lib/l10n/gen/app_localizations_es.dart +++ b/lib/l10n/gen/app_localizations_es.dart @@ -117,4 +117,216 @@ class AppLocalizationsEs extends AppLocalizations { @override String get saveQuickAccessButton => 'Guardar acceso rápido'; + + @override + String get settingsSafeStatus => 'Seguro'; + + @override + String get recordingsSectionTitle => 'Grabaciones'; + + @override + String get recordingsFolderDialogTitle => + 'Selecciona la carpeta de grabaciones'; + + @override + String get recordingsPathUpdated => 'Ruta de grabaci?n actualizada'; + + @override + String recordingsPathSaveError(Object error) { + return 'No se pudo guardar la ruta: $error'; + } + + @override + String get recordingsDefaultFolderRestored => + 'Se usar? la carpeta interna por defecto'; + + @override + String get recordingsFolderTitle => 'Carpeta de grabaci?n'; + + @override + String get recordingsPathCalculating => 'Calculando ruta...'; + + @override + String get recordingsChangePath => 'Cambiar ruta'; + + @override + String get recordingsUseDefaultPath => 'Usar ruta por defecto'; + + @override + String get recordingsOriginalStreamHint => + 'La radio se guarda desde el stream original, sin recomprimir.'; + + @override + String get equalizerActive => 'Activo'; + + @override + String get equalizerDisabled => 'Desactivado'; + + @override + String get equalizerEnable => 'Activar ecualizador'; + + @override + String get equalizerRealtimeSubtitle => + 'Los cambios se aplican en tiempo real a la emisora actual.'; + + @override + String get equalizerPendingSubtitle => + 'Se guardan los cambios y se aplicar?n cuando Android habilite el efecto.'; + + @override + String get equalizerPerStationTitle => 'Usar EQ propio para esta favorita'; + + @override + String equalizerPerStationActive(Object stationName) { + return 'Activo para $stationName'; + } + + @override + String equalizerPerStationMain(Object stationName) { + return 'Usando EQ principal para $stationName'; + } + + @override + String get preferredStationTitle => 'Emisora preferida'; + + @override + String get preferredStationDescription => + 'Se preselecciona al crear alarmas y puede iniciarse como reproducci?n r?pida.'; + + @override + String get preferredStationNoStationsTitle => + 'Todav?a no hay emisoras disponibles'; + + @override + String get preferredStationNoStationsSubtitle => + 'Guard? favoritas o carg? emisoras para elegir una preferida.'; + + @override + String get preferredStationAutomaticFallback => 'Fallback autom?tico'; + + @override + String get preferredStationDefaultFavorite => 'Favorita por defecto'; + + @override + String preferredStationCurrent(Object stationName) { + return 'Preferida actual: $stationName'; + } + + @override + String preferredStationAutoUsing(Object stationName) { + return 'Sin favoritas: usando autom?ticamente $stationName'; + } + + @override + String get preferredStationPlay => 'Reproducir preferida'; + + @override + String get customStationsTitle => 'Emisoras personalizadas'; + + @override + String get customStationsAdd => 'A?adir'; + + @override + String get customStationsEmpty => 'No hay emisoras personalizadas.'; + + @override + String get playAction => 'Reproducir'; + + @override + String get deleteAction => 'Eliminar'; + + @override + String get addStationTitle => 'A?adir emisora'; + + @override + String get stationNameLabel => 'Nombre *'; + + @override + String get requiredField => 'Campo obligatorio'; + + @override + String get streamUrlLabel => 'URL del stream *'; + + @override + String get invalidUrl => 'URL no v?lida'; + + @override + String get countryOptionalLabel => 'Pa?s (opcional)'; + + @override + String get saveStation => 'Guardar emisora'; + + @override + String get backupSectionTitle => 'Copia de seguridad'; + + @override + String get backupExportTitle => 'Exportar configuraci?n'; + + @override + String get backupExportSubtitle => + 'Favoritos, emisoras custom y presets de EQ'; + + @override + String get backupImportTitle => 'Importar configuraci?n'; + + @override + String get backupImportSubtitle => + 'Restaurar desde un fichero de copia de seguridad'; + + @override + String get backupShareSubject => 'PluriWave ? copia de seguridad'; + + @override + String backupShareText(Object date) { + return 'Configuraci?n de PluriWave exportada el $date'; + } + + @override + String backupExportError(Object error) { + return 'Error al exportar: $error'; + } + + @override + String get backupImportConfirmMessage => + 'Esto a?adir? los favoritos, emisoras y presets del fichero. ?Continuar?'; + + @override + String get backupImportSuccess => 'Configuraci?n importada correctamente'; + + @override + String backupImportError(Object error) { + return 'Error al importar: $error'; + } + + @override + String get appVersionLoading => 'Cargando versi?n...'; + + @override + String appVersionSubtitle(Object version) { + return '$version - Radio mundial'; + } + + @override + String get savedFavoritesTitle => 'Favoritos guardados'; + + @override + String get stationFilterTitle => 'Filtro de emisoras'; + + @override + String get stationFilterSubtitle => 'Solo emisoras verificadas como activas'; + + @override + String get backgroundAudioTitle => 'Audio en background'; + + @override + String get backgroundAudioSubtitle => 'Contin?a al apagar la pantalla'; + + @override + String get dash => '?'; + + @override + String get cancelAction => 'Cancelar'; + + @override + String get equalizerTitle => 'Ecualizador'; } diff --git a/lib/pantallas/pantalla_ajustes.dart b/lib/pantallas/pantalla_ajustes.dart index 6b76739..5ebf8e7 100644 --- a/lib/pantallas/pantalla_ajustes.dart +++ b/lib/pantallas/pantalla_ajustes.dart @@ -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 _seleccionarRuta(BuildContext context) async { final estado = context.read(); 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().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().reproducir(emisora), ), IconButton( icon: const Icon(Icons.delete_outline), - tooltip: 'Eliminar', + tooltip: AppLocalizations.of(context).deleteAction, onPressed: () => context .read() @@ -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,