fix(i18n): normalize translations and fallbacks
Build & Deploy PluriWave / Análisis de código (push) Successful in 38s
Build & Deploy PluriWave / Build APK + AAB release (push) Successful in 2m34s

This commit is contained in:
2026-06-03 21:20:08 +02:00
parent a5475ce118
commit 089b8b4227
46 changed files with 17720 additions and 4869 deletions
+25 -6
View File
@@ -4,6 +4,7 @@ import 'package:provider/provider.dart';
import 'estado/estado_radio.dart'; import 'estado/estado_radio.dart';
import 'estado/estado_alarmas.dart'; import 'estado/estado_alarmas.dart';
import 'estado/estado_idioma.dart'; import 'estado/estado_idioma.dart';
import 'l10n/display_names.dart';
import 'l10n/gen/app_localizations.dart'; import 'l10n/gen/app_localizations.dart';
import 'modelos/alarma_musical.dart'; import 'modelos/alarma_musical.dart';
import 'pantallas/pantalla_alarmas.dart'; import 'pantallas/pantalla_alarmas.dart';
@@ -236,7 +237,9 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
content: Text( content: Text(
AppLocalizations.of( AppLocalizations.of(
context, context,
).skipCurrentAlarmExecution(alarma.nombre), ).skipCurrentAlarmExecution(
localizedAlarmName(AppLocalizations.of(context), alarma.nombre),
),
), ),
), ),
); );
@@ -355,7 +358,10 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
Text( Text(
_formatearDuracionTimer(restante), _formatearDuracionTimer(
AppLocalizations.of(ctx),
restante,
),
style: style:
Theme.of(ctx).textTheme.headlineMedium, Theme.of(ctx).textTheme.headlineMedium,
), ),
@@ -385,6 +391,7 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
ActionChip( ActionChip(
label: Text( label: Text(
_formatearDuracionTimer( _formatearDuracionTimer(
AppLocalizations.of(ctx),
Duration(seconds: segundos), Duration(seconds: segundos),
), ),
), ),
@@ -431,17 +438,29 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal> {
} }
} }
String _formatearDuracionTimer(Duration duracion) { String _formatearDuracionTimer(
AppLocalizations l10n,
Duration duracion,
) {
final horas = duracion.inHours; final horas = duracion.inHours;
final minutos = duracion.inMinutes.remainder(60); final minutos = duracion.inMinutes.remainder(60);
final segundos = duracion.inSeconds.remainder(60); final segundos = duracion.inSeconds.remainder(60);
if (horas > 0) { if (horas > 0) {
return '${horas}h ${minutos.toString().padLeft(2, '0')}m ${segundos.toString().padLeft(2, '0')}s'; return l10n.durationHoursMinutesSeconds(
horas,
minutos.toString().padLeft(2, '0'),
segundos.toString().padLeft(2, '0'),
);
} }
if (minutos > 0) { if (minutos > 0) {
return segundos == 0 ? '$minutos min' : '${minutos}m ${segundos}s'; return segundos == 0
? l10n.durationMinutesOnly(minutos)
: l10n.durationMinutesSeconds(
minutos,
segundos.toString().padLeft(2, '0'),
);
} }
return '$segundos s'; return l10n.durationSecondsOnly(segundos);
} }
class _TimerPersonalizadoSheet extends StatefulWidget { class _TimerPersonalizadoSheet extends StatefulWidget {
+30 -11
View File
@@ -4,15 +4,19 @@ import 'dart:io';
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart' show Locale;
import 'package:geocoding/geocoding.dart'; import 'package:geocoding/geocoding.dart';
import 'package:geolocator/geolocator.dart'; import 'package:geolocator/geolocator.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart'; import '../modelos/emisora.dart';
import '../modelos/grupo_favoritos.dart'; import '../modelos/grupo_favoritos.dart';
import '../modelos/preset_ecualizador.dart'; import '../modelos/preset_ecualizador.dart';
import '../servicios/servicio_alarmas_android.dart';
import '../servicios/servicio_audio.dart'; import '../servicios/servicio_audio.dart';
import '../servicios/servicio_ecualizador.dart'; import '../servicios/servicio_ecualizador.dart';
import '../servicios/servicio_favoritos.dart'; import '../servicios/servicio_favoritos.dart';
@@ -57,6 +61,19 @@ class EstadoRadio extends ChangeNotifier {
final ServicioGrabacionRadio grabacion; final ServicioGrabacionRadio grabacion;
final Future<File> Function()? _resolverArchivoCustom; final Future<File> Function()? _resolverArchivoCustom;
AppLocalizations get _textos {
final actual = _l10n;
if (actual != null) return actual;
return lookupAppLocalizations(const Locale('es'));
}
void configurarLocalizaciones(AppLocalizations l10n) {
_l10n = l10n;
audio.configurarLocalizaciones(l10n);
grabacion.configurarLocalizaciones(l10n);
ServicioAlarmasAndroid.configurarLocalizaciones(l10n);
}
late final ServicioTimer timer; late final ServicioTimer timer;
StreamSubscription<EstadoReproduccion>? _suscripcionEstadoAudio; StreamSubscription<EstadoReproduccion>? _suscripcionEstadoAudio;
StreamSubscription<EstadoGrabacionRadio>? _suscripcionGrabacion; StreamSubscription<EstadoGrabacionRadio>? _suscripcionGrabacion;
@@ -64,6 +81,7 @@ class EstadoRadio extends ChangeNotifier {
int _revisionReproduccion = 0; int _revisionReproduccion = 0;
Emisora? _emisoraSeleccionada; Emisora? _emisoraSeleccionada;
String? _emisoraPreferidaUuid; String? _emisoraPreferidaUuid;
AppLocalizations? _l10n;
// Errores de reproducción → SnackBar. // Errores de reproducción → SnackBar.
final _errorController = StreamController<String>.broadcast(); final _errorController = StreamController<String>.broadcast();
@@ -237,7 +255,7 @@ class EstadoRadio extends ChangeNotifier {
_suscripcionGrabacion = grabacion.estadoStream.listen((estado) { _suscripcionGrabacion = grabacion.estadoStream.listen((estado) {
if (estado.tipo == EstadoGrabacionRadioTipo.error && if (estado.tipo == EstadoGrabacionRadioTipo.error &&
estado.error != null) { estado.error != null) {
_errorController.add('Error al grabar la radio: ${estado.error}'); _errorController.add(_textos.radioRecordingError(estado.error!));
} }
notifyListeners(); notifyListeners();
}); });
@@ -274,7 +292,7 @@ class EstadoRadio extends ChangeNotifier {
_populares = results[0]; _populares = results[0];
_tendencias = results[1]; _tendencias = results[1];
} catch (_) { } catch (_) {
_errorCarga = 'Sin conexión a la API de radio'; _errorCarga = _textos.radioApiConnectionError;
} finally { } finally {
_cargandoPopulares = false; _cargandoPopulares = false;
notifyListeners(); notifyListeners();
@@ -433,7 +451,7 @@ class EstadoRadio extends ChangeNotifier {
); );
_resultadosBusqueda = pagina; _resultadosBusqueda = pagina;
} catch (_) { } catch (_) {
_errorController.add('Error en la busqueda. Comprueba tu conexion.'); _errorController.add(_textos.radioSearchError);
} finally { } finally {
_cargandoBusqueda = false; _cargandoBusqueda = false;
notifyListeners(); notifyListeners();
@@ -468,7 +486,7 @@ class EstadoRadio extends ChangeNotifier {
// _buscarPaginaFiltrada actualiza offset/hayMas usando páginas crudas. // _buscarPaginaFiltrada actualiza offset/hayMas usando páginas crudas.
_hayMasBusqueda = _hayMasBusqueda && pagina.isNotEmpty; _hayMasBusqueda = _hayMasBusqueda && pagina.isNotEmpty;
} catch (_) { } catch (_) {
_errorController.add('No se pudieron cargar mas emisoras.'); _errorController.add(_textos.radioLoadMoreStationsError);
} finally { } finally {
_cargandoMasBusqueda = false; _cargandoMasBusqueda = false;
notifyListeners(); notifyListeners();
@@ -554,7 +572,7 @@ class EstadoRadio extends ChangeNotifier {
} }
if (pais == null || pais.isEmpty) { if (pais == null || pais.isEmpty) {
throw Exception('No se pudo detectar tu region'); throw StateError('nearby-region-not-detected');
} }
_paisCercanoDetectado = pais; _paisCercanoDetectado = pais;
_emisorasCercanas = _filtrarMinBitrate( _emisorasCercanas = _filtrarMinBitrate(
@@ -562,8 +580,7 @@ class EstadoRadio extends ChangeNotifier {
_ultimoMinBitrateBusqueda, _ultimoMinBitrateBusqueda,
); );
} catch (_) { } catch (_) {
_errorCercanas = _errorCercanas = _textos.radioNearbyStationsError;
'No pudimos detectar emisoras cercanas. Usa filtros por pais.';
_emisorasCercanas = []; _emisorasCercanas = [];
} finally { } finally {
_cargandoCercanas = false; _cargandoCercanas = false;
@@ -595,7 +612,9 @@ class EstadoRadio extends ChangeNotifier {
_errorController.add( _errorController.add(
mensajeError.isNotEmpty && mensajeError != 'Exception' mensajeError.isNotEmpty && mensajeError != 'Exception'
? mensajeError ? mensajeError
: 'No se puede reproducir "${emisora.nombre}"', : _textos.radioCannotPlayStation(
localizedStationName(_textos, emisora.nombre),
),
); );
notifyListeners(); notifyListeners();
} }
@@ -604,13 +623,13 @@ class EstadoRadio extends ChangeNotifier {
Future<void> iniciarGrabacion({Duration? duracion}) async { Future<void> iniciarGrabacion({Duration? duracion}) async {
final actual = emisoraActual; final actual = emisoraActual;
if (actual == null) { if (actual == null) {
_errorController.add('Primero selecciona una emisora para grabar.'); _errorController.add(_textos.recordingSelectStationFirst);
return; return;
} }
try { try {
await grabacion.iniciar(actual, duracion: duracion); await grabacion.iniciar(actual, duracion: duracion);
} catch (e) { } catch (e) {
_errorController.add('No se pudo iniciar la grabación: $e'); _errorController.add(_textos.recordingStartError(e.toString()));
} }
} }
@@ -898,7 +917,7 @@ class EstadoRadio extends ChangeNotifier {
/// Importa configuración desde un JSON exportado previamente. /// Importa configuración desde un JSON exportado previamente.
Future<void> importarConfig(Map<String, dynamic> data) async { Future<void> importarConfig(Map<String, dynamic> data) async {
final version = data['version'] as int? ?? 1; final version = data['version'] as int? ?? 1;
if (version != 1) throw Exception('Versión de configuración no compatible'); if (version != 1) throw Exception(_textos.unsupportedConfigVersion);
final favRaw = data['favoritos'] as List? ?? []; final favRaw = data['favoritos'] as List? ?? [];
for (final raw in favRaw) { for (final raw in favRaw) {
+397 -223
View File
@@ -1,107 +1,135 @@
{ {
"@@locale": "ar", "@@locale": "ar",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "الرئيسية",
"navSearch": "Search", "navSearch": "بحث",
"navFavorites": "Favorites", "navFavorites": "المفضلة",
"navAlarms": "Alarms", "navAlarms": "المنبهات",
"navSettings": "Settings", "navSettings": "الإعدادات",
"actionOk": "OK", "actionOk": "حسنًا",
"sleepTimer": "Sleep timer", "sleepTimer": "مؤقّت النوم",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "إيقاف الراديو بسلاسة مع عدّ تنازلي دقيق.",
"cancelTimer": "Cancel timer", "cancelTimer": "إلغاء المؤقّت",
"optionOther": "Other", "optionOther": "أخرى",
"customDurationTitle": "Custom duration", "customDurationTitle": "مدة مخصّصة",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "اختر مدة أكبر من الصفر.",
"hoursLabel": "Hours", "hoursLabel": "ساعات",
"minutesLabel": "Minutes", "minutesLabel": "دقائق",
"secondsLabel": "Seconds", "secondsLabel": "ثوانٍ",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} ? {minutes} ? {seconds} ?",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} ? {seconds} ?",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} ?",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} ?",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "حفظ كاختصار سريع",
"startTimer": "بدء المؤقّت",
"skipCurrentAlarmExecution": "تم تخطي هذا التشغيل من {alarmName}.",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "الإعدادات",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "تحكم دقيق في الصوت والنسخ الاحتياطية والمحطات المخصصة.",
"languageSectionTitle": "Language", "languageSectionTitle": "اللغة",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "اختر كيفية عرض لغة التطبيق.",
"languageSystemDefault": "System", "languageSystemDefault": "النظام",
"languageSpanish": "Spanish", "languageSpanish": "الإسبانية",
"languageEnglish": "English", "languageEnglish": "الإنجليزية",
"languageUpdated": "Language updated: {languageName}", "languageUpdated": "تم تحديث اللغة: {languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
"languageName": {} "languageName": {}
} }
}, },
"languageUpdatedSystem": "Language updated: System", "languageUpdatedSystem": "تم تحديث اللغة: النظام",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "مؤقّت النوم",
"timerSectionAdd": "Add", "timerSectionAdd": "إضافة",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "خصّص الاختصارات السريعة التي تظهر عند إيقاف الراديو تلقائيًا.",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "استعادة الأوقات الموصى بها",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "اختصار سريع جديد",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "حفظ الاختصار السريع",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "آمن",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "التسجيلات",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "اختر مجلد التسجيلات",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "تم تحديث مسار التسجيل",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "تعذّر حفظ المسار: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "سيتم استخدام المجلد الداخلي الافتراضي",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "مجلد التسجيل",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "جارٍ حساب المسار...",
"recordingsChangePath": "Change path", "recordingsChangePath": "تغيير المسار",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "استخدام المسار الافتراضي",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "يتم حفظ الراديو من البث الأصلي، دون إعادة ضغط.",
"equalizerActive": "Active", "equalizerActive": "نشط",
"equalizerDisabled": "Disabled", "equalizerDisabled": "معطّل",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "تفعيل المعادل",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "تُطبّق التغييرات فورًا على المحطة الحالية.",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "تُحفظ التغييرات وستُطبّق عندما يفعّل Android التأثير.",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "استخدام معادل خاص لهذه المفضلة",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "نشط لـ {stationName}",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "استخدام المعادل الرئيسي لـ {stationName}",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "المحطة المفضلة",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "يتم اختيارها مسبقًا عند إنشاء المنبهات ويمكن تشغيلها سريعًا.",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "لا توجد محطات متاحة بعد",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "احفظ المفضلات أو حمّل محطات لاختيار محطة مفضلة.",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "بديل تلقائي",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "المفضلة الافتراضية",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "المفضلة الحالية: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "لا توجد مفضلات: يتم استخدام {stationName} تلقائيًا",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "تشغيل المفضلة",
"customStationsTitle": "Custom stations", "customStationsTitle": "محطات مخصصة",
"customStationsAdd": "Add", "customStationsAdd": "إضافة",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "لا توجد محطات مخصصة.",
"playAction": "Play", "playAction": "تشغيل",
"deleteAction": "Delete", "deleteAction": "حذف",
"addStationTitle": "Add station", "addStationTitle": "إضافة محطة",
"stationNameLabel": "Name *", "stationNameLabel": "الاسم *",
"requiredField": "Required field", "unnamedStation": "محطة بدون اسم",
"streamUrlLabel": "Stream URL *", "requiredField": "حقل مطلوب",
"invalidUrl": "Invalid URL", "streamUrlLabel": "رابط البث *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "رابط غير صالح",
"saveStation": "Save station", "countryOptionalLabel": "البلد (اختياري)",
"backupSectionTitle": "Backup", "saveStation": "حفظ المحطة",
"backupExportTitle": "Export configuration", "backupSectionTitle": "النسخ الاحتياطي",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "تصدير الإعدادات",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "المفضلات والمحطات المخصصة وإعدادات المعادل المسبقة",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "استيراد الإعدادات",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "استعادة من ملف نسخة احتياطية",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — نسخة احتياطية",
"backupExportError": "Export error: {error}", "backupShareText": "إعدادات PluriWave المصدّرة في {date}",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "خطأ أثناء التصدير: {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "سيضيف هذا المفضلات والمحطات وإعدادات المعادل من الملف. هل تريد المتابعة؟",
"backupImportError": "Import error: {error}", "backupImportSuccess": "تم استيراد الإعدادات بنجاح",
"appVersionLoading": "Loading version...", "backupImportError": "خطأ أثناء الاستيراد: {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "جارٍ تحميل الإصدار...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - راديو عالمي",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "المفضلات المحفوظة",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "فلتر المحطات",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "المحطات المؤكدة كنشطة فقط",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "الصوت في الخلفية",
"backgroundAudioSubtitle": "يستمر عند إطفاء الشاشة",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -148,15 +176,15 @@
"version": {} "version": {}
} }
}, },
"cancelAction": "Cancel", "cancelAction": "إلغاء",
"equalizerTitle": "Equalizer", "equalizerTitle": "المعادل",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "فتح المجلد",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "تعذّر فتح المجلد: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "الحد الأقصى لحجم التسجيل",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "الحد الحالي: {size} ميغابايت",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "الحد الأقصى للحجم لكل تسجيل",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "الحد الأقصى بالميغابايت",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "تم تحديث حد التسجيل إلى {size} ميغابايت",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "ترتيب المحطات",
"stationOrderByName": "By name", "stationOrderByName": "حسب الاسم",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "حسب الجودة",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "ينطبق على المفضلات وعمليات البحث والمحطات القريبة والقوائم السريعة.",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "قوائم المفضلة",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "أنشئ قوائم قصيرة لتنظيم محطاتك المحفوظة.",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "إضافة قائمة",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "تعديل القائمة",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "حذف القائمة",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "اسم القائمة",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "الحد الأقصى 28 حرفًا.",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "غير معيّنة",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "القائمة الافتراضية: لا يمكن تعديلها أو حذفها.",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "تم إنشاء القائمة",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "تم تحديث القائمة",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "تم حذف القائمة؛ عادت محطاتها إلى غير معيّنة.",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "نقل إلى قائمة",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "القائمة الحالية: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "تم نقل {stationName} إلى {groupName}",
"favoritesTitle": "Favorites", "favoritesTitle": "المفضلة",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "لا توجد مفضلات بعد",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "اضغط على القلب في أي محطة لحفظها في مجموعتك.",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "نظّم مجموعتك في قوائم وأبقِ المحطات المهمة قريبة.",
"favoritesCollection": "Collection", "favoritesCollection": "المجموعة",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} محفوظة",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "إزالة من المفضلة",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "تمت إزالة {stationName} من المفضلة",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,9 +254,9 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "تم تأجيل المنبه لهذا التشغيل.",
"searchScreenTitle": "ابحث عن المحطات", "searchScreenTitle": "البحث عن إشارة",
"searchScreenSubtitle": "اعثر على المحطات بالاسم أو البلد أو اللغة باستخدام فلاتر سريعة وتباين عالٍ.", "searchScreenSubtitle": "اعثر على إذاعات حسب الاسم أو البلد أو اللغة باستخدام فلاتر سريعة وتباين عالٍ.",
"searchFiltersLabel": "الفلاتر", "searchFiltersLabel": "الفلاتر",
"searchHint": "راديو هورايزن، جاز، أخبار...", "searchHint": "راديو هورايزن، جاز، أخبار...",
"searchCountryFilterLabel": "البلد", "searchCountryFilterLabel": "البلد",
@@ -236,8 +264,8 @@
"searchMinQualityFilterLabel": "الحد الأدنى للجودة", "searchMinQualityFilterLabel": "الحد الأدنى للجودة",
"searchEmptyTitle": "ابحث عن محطة", "searchEmptyTitle": "ابحث عن محطة",
"searchNoResultsTitle": "لا توجد نتائج", "searchNoResultsTitle": "لا توجد نتائج",
"searchEmptySubtitle": "استخدم الشريط العلوي أو الوسوم لاكتشاف محطات من جميع أنحاء العالم.", "searchEmptySubtitle": "استخدم الشريط العلوي أو الشرائح لاكتشاف إشارات من كل العالم.",
"searchNoResultsSubtitle": "جرّب إزالة الفلاتر أو كتابة اسم آخر للعثور على محطة نشطة.", "searchNoResultsSubtitle": "جرّب إزالة الفلاتر أو كتابة اسم آخر للعثور على إشارة نشطة.",
"countrySpain": "إسبانيا", "countrySpain": "إسبانيا",
"countryUsa": "الولايات المتحدة", "countryUsa": "الولايات المتحدة",
"countryMexico": "المكسيك", "countryMexico": "المكسيك",
@@ -257,9 +285,9 @@
"languageNameJapanese": "اليابانية", "languageNameJapanese": "اليابانية",
"languageNameArabic": "العربية", "languageNameArabic": "العربية",
"languageNameRussian": "الروسية", "languageNameRussian": "الروسية",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "راديو عالمي مباشر بإشارات نقية ومفضلات ذكية وتجربة بصرية بأسلوب المسابقات.",
"exploreStations": "Explore stations", "exploreStations": "استكشاف المحطات",
"stationsCount": "{count} stations", "stationsCount": "{count} محطة راديو",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "جودة HD",
"nearYou": "Near you", "nearYou": "بالقرب منك",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "بالقرب منك · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "اكتشاف",
"liveRadar": "Live radar", "liveRadar": "رادار مباشر",
"genresTitle": "Genres", "genresTitle": "الأنواع",
"retryAction": "Retry", "retryAction": "إعادة المحاولة",
"noStationsAvailable": "No stations available", "noStationsAvailable": "لا توجد محطات متاحة",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "جرّب التحديث أو اختيار نوع آخر لالتقاط الإشارة من جديد.",
"genrePop": "Pop", "genrePop": "بوب",
"genreRock": "Rock", "genreRock": "روك",
"genreJazz": "Jazz", "genreJazz": "جاز",
"genreClassical": "Classical", "genreClassical": "كلاسيكي",
"genreElectronic": "Electronic", "genreElectronic": "إلكترونية",
"genreNews": "News", "genreNews": "أخبار",
"genreTalk": "Talk", "genreTalk": "حوارات",
"genreHipHop": "Hip-hop", "genreHipHop": "هيب هوب",
"genreCountry": "Country", "genreCountry": "كانتري",
"genreMetal": "Metal", "genreMetal": "ميتال",
"genreReggae": "Reggae", "genreReggae": "ريغي",
"genreLatin": "Latin", "genreLatin": "لاتينية",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "الاستيقاظ الموسيقي",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "منبهات بالراديو وصوت آمن وإجازات ذكية والتنفيذ التالي ظاهر دائمًا.",
"createAlarmAction": "Create alarm", "createAlarmAction": "إنشاء منبه",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} منبهات",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "منبهات نشطة بلا تشغيل قادم",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "لا توجد منبهات نشطة",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "المنبه التالي",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "توجد {count} منبهات نشطة، لكنها لا تملك حاليًا تاريخًا مستقبليًا صالحًا. راجع التاريخ والأيام والإجازات.",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "أنشئ منبهًا وسيحسب PluriWave التشغيل التالي تلقائيًا.",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "يرن في الإجازات",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "يتوقف في الإجازات",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "تدرّج الصوت {seconds}ث",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "التشغيل التالي: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "لا يوجد تشغيل نشط قادم.",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "تم تخطي تشغيل: {date}.",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "تعديل",
"skipNextAction": "Skip next", "skipNextAction": "تخطي التالي",
"deleteTooltip": "Delete", "deleteTooltip": "حذف",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "تم تخطي المنبه. لا يوجد تشغيل قادم.",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "تم تخطي المنبه. سيعود في {date}.",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "متوقف بسبب الإجازة ({vacationName}) ولا يوجد تشغيل قادم.",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "متوقف بسبب الإجازة ({vacationName}) وسيعود في {date}.",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "مع تفعيل الإجازات، سيعود للرنين في {date}.",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "منبه موسيقي",
"newAlarmTitle": "New alarm", "newAlarmTitle": "منبه جديد",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "تعديل المنبه",
"nameField": "Name", "nameField": "الاسم",
"timeField": "Time", "timeField": "الوقت",
"dateField": "Date", "dateField": "التاريخ",
"onceOption": "Once", "onceOption": "مرة واحدة",
"dailyOption": "Daily", "dailyOption": "يومي",
"weekdaysOption": "Weekdays", "weekdaysOption": "أيام",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "الصوت ومستوى الصوت",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "تدرّج صوت المنبه",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 ث (بدون انتقال)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} ث (من 5% إلى مستوى الصوت المختار)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "صوت داخلي آمن",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "شروق دافئ",
"soundSoftBell": "Soft bell", "soundSoftBell": "جرس ناعم",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "نبضة رقمية",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "المحطة المفضلة",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "بدون محطة: استخدام الصوت الداخلي",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "احفظ محطات في المفضلة لاستخدامها كمنبه موسيقي.",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "استخدام المحطة الحالية",
"playDuringVacations": "Play during vacations", "playDuringVacations": "الرنين أثناء الإجازات",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "إذا أوقفت ذلك، سيتخطى التشغيل التالي إلى أول يوم صالح.",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "حفظ المنبه",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "اختر يومًا واحدًا على الأقل من الأسبوع.",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "مراجعة موثوقية Android",
"statusOk": "OK", "statusOk": "حسنًا",
"statusPending": "pending", "statusPending": "معلّق",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "الموثوقية: الدقيقة {exact} · الإشعارات {notifications} · الشاشة {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "نطاقات الإجازات",
"addAction": "Add", "addAction": "إضافة",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "إذا كان المنبه لديه \"توقف في الإجازات\"، فسيتم تخطي هذه النطاقات تلقائيًا.",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "لا توجد نطاقات محمّلة.",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "حذف النطاق",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "إجازات",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "نطاق إجازة جديد",
"startField": "Start", "startField": "البداية",
"endField": "End", "endField": "النهاية",
"saveRangeAction": "Save range", "saveRangeAction": "حفظ النطاق",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "لا توجد منبهات بعد.",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "أنشئ واحدًا لتصميم استيقاظك الموسيقي.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "يرن باستخدام الصوت الداخلي الآمن.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "جارٍ تجهيز الصوت الداخلي الآمن.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "إيقاف المنبه",
"pauseAction": "إيقاف مؤقت",
"miniPlayerOpenLabel": "فتح المشغل لـ {stationName}",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "المشغل",
"playbackStatusConnecting": "جارٍ الاتصال...",
"playbackStatusLive": "مباشر",
"playbackStatusPaused": "متوقف مؤقتًا",
"playbackStatusConnectionError": "خطأ في الاتصال",
"playbackStatusStopped": "متوقف",
"stationSemanticLabel": "محطة {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "إضافة إلى المفضلة",
"favoritesAddedMessage": "تمت إضافة {stationName} إلى المفضلة",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "أيقونة المحطة",
"liveNow": "مباشر الآن",
"equalizerBandLabel": "النطاق {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} ديسيبل",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "مسطح",
"equalizerPresetRock": "روك",
"equalizerPresetPop": "بوب",
"equalizerPresetBassBoost": "تعزيز الجهير",
"equalizerPresetJazz": "جاز",
"equalizerPresetVoice": "صوت",
"equalizerPresetCustom": "مخصص",
"onboardingTitle": "مرحبًا بك في PluriWave",
"onboardingNewsTitle": "المستجدات",
"onboardingStartAction": "ابدأ",
"onboardingCloseTooltip": "إغلاق",
"radioRecordingError": "خطأ أثناء تسجيل الراديو: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "لا يوجد اتصال بواجهة برمجة تطبيقات الراديو",
"radioSearchError": "خطأ في البحث. تحقق من اتصالك.",
"radioLoadMoreStationsError": "تعذر تحميل المزيد من المحطات.",
"radioNearbyStationsError": "تعذر علينا اكتشاف محطات قريبة. استخدم عوامل التصفية حسب البلد.",
"radioCannotPlayStation": "لا يمكن تشغيل \"{stationName}\"",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "اختر محطة أولًا للتسجيل.",
"recordingStartError": "تعذر بدء التسجيل: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "إصدار الإعدادات غير مدعوم",
"audioErrorGeneric": "خطأ في التشغيل",
"audioErrorNoInternet": "لا يوجد اتصال بالإنترنت",
"audioErrorInvalidUrl": "عنوان الراديو غير صالح",
"audioErrorNotFound": "الراديو غير متاح (خطأ 404)",
"audioErrorTimeout": "انتهت مهلة الاتصال",
"audioErrorCannotConnect": "لا يمكن الاتصال بالراديو",
"audioErrorUnsupportedFormat": "تنسيق البث غير مدعوم",
"audioErrorDecode": "خطأ أثناء فك ترميز بث الصوت",
"audioErrorCleartext": "تستخدم هذه المحطة HTTP غير مشفّر، وهذا غير مسموح",
"audioErrorSsl": "شهادة SSL غير صالحة في الراديو",
"audioErrorCannotPlay": "لا يمكن تشغيل هذه المحطة",
"audioErrorUnexpectedPlayback": "خطأ غير متوقع أثناء التشغيل",
"androidExactAlarmScheduleError": "تعذر على Android جدولة منبه دقيق. تحقق من إذن المنبهات الدقيقة.",
"recordingPathEmptyError": "لا يمكن أن يكون مسار التسجيل فارغًا",
"recordingMaxSizeInvalidError": "يجب أن يكون الحجم الأقصى أكبر من الصفر",
"recordingAlreadyActiveError": "يوجد تسجيل قيد التنفيذ بالفعل",
"alarmRingingFallbackActive": "يعمل الآن باستخدام الصوت الداخلي الآمن.",
"alarmRingingPreparingFallback": "جارٍ تجهيز الصوت الداخلي الآمن.",
"alarmRingingTryingStation": "جارٍ محاولة تشغيل محطتك بأعلى جودة متاحة.",
"alarmScheduleOnce": "مرة واحدة · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "الأيام: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "مراجعة موثوقية Android",
"closeAction": "إغلاق",
"customOption": "مخصص",
"endLabel": "النهاية",
"equalizerDisable": "تعطيل المعادل",
"helpTitle": "المساعدة والشرح",
"helpSubtitle": "راجع ميزات PluriWave والنصائح والمستجدات.",
"indefiniteOption": "غير محدد",
"invalidNumber": "رقم غير صالح",
"nameLabel": "الاسم",
"notPlaying": "لا يتم التشغيل",
"oneTimeOption": "مرة واحدة",
"pausePlaybackTooltip": "إيقاف مؤقت",
"qualityOriginal": "الجودة الأصلية: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "الجودة غير مذكورة",
"recordAction": "تسجيل",
"recordDurationTitle": "مدة التسجيل",
"recordRadioSubtitle": "اختر مدة التسجيل.",
"recordRadioTitle": "تسجيل الراديو",
"recordingActiveTitle": "جارٍ تسجيل الراديو",
"recordingDirectTitle": "تسجيل مباشر",
"recordingsOpenFolderPlainError": "تعذر فتح مجلد التسجيلات",
"recordingsOpenLatest": "فتح آخر تسجيل",
"recordingsOpenLatestError": "تعذر فتح آخر تسجيل",
"startLabel": "البداية",
"startPlaybackTooltip": "بدء التشغيل",
"stopAction": "إيقاف",
"stopPlaybackTooltip": "إيقاف التشغيل",
"weekdayShortMonday": "الإثنين",
"weekdayShortTuesday": "الثلاثاء",
"weekdayShortWednesday": "الأربعاء",
"weekdayShortThursday": "الخميس",
"weekdayShortFriday": "الجمعة",
"weekdayShortSaturday": "السبت",
"weekdayShortSunday": "الأحد"
} }
+398 -224
View File
@@ -1,107 +1,135 @@
{ {
"@@locale": "bn", "@@locale": "bn",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "হোম",
"navSearch": "Search", "navSearch": "অনুসন্ধান",
"navFavorites": "Favorites", "navFavorites": "প্রিয়",
"navAlarms": "Alarms", "navAlarms": "অ্যালার্ম",
"navSettings": "Settings", "navSettings": "সেটিংস",
"actionOk": "OK", "actionOk": "ঠিক আছে",
"sleepTimer": "Sleep timer", "sleepTimer": "ঘুমের টাইমার",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "নির্ভুল কাউন্টডাউন দিয়ে রেডিও মসৃণভাবে বন্ধ করা।",
"cancelTimer": "Cancel timer", "cancelTimer": "টাইমার বাতিল করুন",
"optionOther": "Other", "optionOther": "অন্যান্য",
"customDurationTitle": "Custom duration", "customDurationTitle": "নিজস্ব সময়কাল",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "শূন্যের চেয়ে বেশি একটি সময়কাল বেছে নিন।",
"hoursLabel": "Hours", "hoursLabel": "ঘণ্টা",
"minutesLabel": "Minutes", "minutesLabel": "মিনিট",
"secondsLabel": "Seconds", "secondsLabel": "সেকেন্ড",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} ? {minutes} ?? {seconds} ??",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} ?? {seconds} ??",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} ??",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} ??",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "দ্রুত অ্যাক্সেস হিসেবে সংরক্ষণ করুন",
"startTimer": "টাইমার শুরু করুন",
"skipCurrentAlarmExecution": "{alarmName}-এর এই চালনা এড়িয়ে দেওয়া হয়েছে।",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "সেটিংস",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "শব্দ, ব্যাকআপ এবং নিজস্ব স্টেশনের সূক্ষ্ম নিয়ন্ত্রণ।",
"languageSectionTitle": "Language", "languageSectionTitle": "ভাষা",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "অ্যাপের ভাষা কীভাবে দেখাবে তা বেছে নিন।",
"languageSystemDefault": "System", "languageSystemDefault": "সিস্টেম",
"languageSpanish": "Spanish", "languageSpanish": "স্প্যানিশ",
"languageEnglish": "English", "languageEnglish": "ইংরেজি",
"languageUpdated": "Language updated: {languageName}", "languageUpdated": "ভাষা আপডেট হয়েছে: {languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
"languageName": {} "languageName": {}
} }
}, },
"languageUpdatedSystem": "Language updated: System", "languageUpdatedSystem": "ভাষা আপডেট হয়েছে: সিস্টেম",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "ঘুমের টাইমার",
"timerSectionAdd": "Add", "timerSectionAdd": "যোগ করুন",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "রেডিও স্বয়ংক্রিয়ভাবে বন্ধ করার সময় দেখা যায় এমন দ্রুত প্রিসেটগুলো সাজান।",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "প্রস্তাবিত সময় ফিরিয়ে আনুন",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "নতুন দ্রুত অ্যাক্সেস",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "দ্রুত অ্যাক্সেস সংরক্ষণ করুন",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "নিরাপদ",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "রেকর্ডিং",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "রেকর্ডিং ফোল্ডার নির্বাচন করুন",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "রেকর্ডিং পথ আপডেট হয়েছে",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "পথ সংরক্ষণ করা যায়নি: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "ডিফল্ট অভ্যন্তরীণ ফোল্ডার ব্যবহার করা হবে",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "রেকর্ডিং ফোল্ডার",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "পথ গণনা করা হচ্ছে...",
"recordingsChangePath": "Change path", "recordingsChangePath": "পথ পরিবর্তন করুন",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "ডিফল্ট পথ ব্যবহার করুন",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "রেডিওটি মূল স্ট্রিম থেকে সংরক্ষিত হয়, পুনরায় কমপ্রেস করা হয় না।",
"equalizerActive": "Active", "equalizerActive": "সক্রিয়",
"equalizerDisabled": "Disabled", "equalizerDisabled": "নিষ্ক্রিয়",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "ইকুয়ালাইজার চালু করুন",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "পরিবর্তনগুলো বর্তমান স্টেশনে তাৎক্ষণিকভাবে প্রয়োগ হয়।",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "পরিবর্তনগুলো সংরক্ষিত থাকবে এবং Android প্রভাব চালু করলে প্রয়োগ হবে।",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "এই প্রিয়টির জন্য নিজস্ব ইকুয়ালাইজার ব্যবহার করুন",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "{stationName}-এর জন্য সক্রিয়",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "{stationName}-এর জন্য মূল ইকুয়ালাইজার ব্যবহার করা হচ্ছে",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "পছন্দের স্টেশন",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "নতুন অ্যালার্মে আগে থেকে বেছে নেওয়া হয় এবং দ্রুত চালানো যায়।",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "এখনও কোনো স্টেশন উপলব্ধ নেই",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "পছন্দের স্টেশন বেছে নিতে প্রিয় সংরক্ষণ করুন বা স্টেশন লোড করুন।",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "স্বয়ংক্রিয় বিকল্প",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "ডিফল্ট প্রিয়",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "বর্তমান পছন্দের: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "কোনো প্রিয় নেই: স্বয়ংক্রিয়ভাবে {stationName} ব্যবহার করা হচ্ছে",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "পছন্দেরটি চালান",
"customStationsTitle": "Custom stations", "customStationsTitle": "নিজস্ব স্টেশন",
"customStationsAdd": "Add", "customStationsAdd": "যোগ করুন",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "কোনো নিজস্ব স্টেশন নেই।",
"playAction": "Play", "playAction": "চালান",
"deleteAction": "Delete", "deleteAction": "মুছুন",
"addStationTitle": "Add station", "addStationTitle": "স্টেশন যোগ করুন",
"stationNameLabel": "Name *", "stationNameLabel": "নাম *",
"requiredField": "Required field", "unnamedStation": "নামহীন স্টেশন",
"streamUrlLabel": "Stream URL *", "requiredField": "আবশ্যক ক্ষেত্র",
"invalidUrl": "Invalid URL", "streamUrlLabel": "স্ট্রিম URL *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "অবৈধ URL",
"saveStation": "Save station", "countryOptionalLabel": "দেশ (ঐচ্ছিক)",
"backupSectionTitle": "Backup", "saveStation": "স্টেশন সংরক্ষণ করুন",
"backupExportTitle": "Export configuration", "backupSectionTitle": "ব্যাকআপ",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "সেটিংস রপ্তানি করুন",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "প্রিয়, নিজস্ব স্টেশন এবং ইকুয়ালাইজার প্রিসেট",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "সেটিংস আমদানি করুন",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "ব্যাকআপ ফাইল থেকে পুনরুদ্ধার করুন",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — ব্যাকআপ",
"backupExportError": "Export error: {error}", "backupShareText": "{date} তারিখে রপ্তানি করা PluriWave সেটিংস",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "রপ্তানির সময় ত্রুটি: {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "এটি ফাইলের প্রিয়, স্টেশন এবং প্রিসেট যোগ করবে। চালিয়ে যাবেন?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "সেটিংস সফলভাবে আমদানি হয়েছে",
"appVersionLoading": "Loading version...", "backupImportError": "আমদানির সময় ত্রুটি: {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "সংস্করণ লোড হচ্ছে...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - বিশ্ব রেডিও",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "সংরক্ষিত প্রিয়",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "স্টেশন ফিল্টার",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "শুধু সক্রিয় হিসেবে যাচাই করা স্টেশন",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "পটভূমির অডিও",
"backgroundAudioSubtitle": "স্ক্রিন বন্ধ করলেও চলতে থাকে",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -148,15 +176,15 @@
"version": {} "version": {}
} }
}, },
"cancelAction": "Cancel", "cancelAction": "বাতিল করুন",
"equalizerTitle": "Equalizer", "equalizerTitle": "ইকুয়ালাইজার",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "ফোল্ডার খুলুন",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "ফোল্ডার খোলা যায়নি: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "রেকর্ডিংয়ের সর্বোচ্চ আকার",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "বর্তমান সীমা: {size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "প্রতি রেকর্ডিংয়ের সর্বোচ্চ আকার",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "সর্বোচ্চ মেগাবাইট",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "রেকর্ডিং সীমা {size} MB-এ আপডেট হয়েছে",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "স্টেশনের ক্রম",
"stationOrderByName": "By name", "stationOrderByName": "নাম অনুযায়ী",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "গুণমান অনুযায়ী",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "প্রিয়, অনুসন্ধান, কাছাকাছি স্টেশন এবং দ্রুত তালিকায় প্রযোজ্য।",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "প্রিয় তালিকা",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "সংরক্ষিত স্টেশন সাজাতে ছোট তালিকা তৈরি করুন।",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "তালিকা যোগ করুন",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "তালিকা সম্পাদনা করুন",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "তালিকা মুছুন",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "তালিকার নাম",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "সর্বোচ্চ ২৮ অক্ষর।",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "বরাদ্দ নয়",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "ডিফল্ট তালিকা: সম্পাদনা বা মুছে ফেলা যায় না।",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "তালিকা তৈরি হয়েছে",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "তালিকা আপডেট হয়েছে",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "তালিকা মুছে ফেলা হয়েছে; এর স্টেশনগুলো বরাদ্দ নয়-এ ফিরে গেছে।",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "তালিকায় সরান",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "বর্তমান তালিকা: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} {groupName}-এ সরানো হয়েছে",
"favoritesTitle": "Favorites", "favoritesTitle": "প্রিয়",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "এখনও কোনো প্রিয় নেই",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "যেকোনো স্টেশনে হৃদয় আইকনে ট্যাপ করে সেটি আপনার সংগ্রহে সংরক্ষণ করুন।",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "আপনার সংগ্রহ তালিকা দিয়ে সাজান এবং গুরুত্বপূর্ণ রেডিওগুলো কাছে রাখুন।",
"favoritesCollection": "Collection", "favoritesCollection": "সংগ্রহ",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} সংরক্ষিত",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "প্রিয় থেকে সরান",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} প্রিয় থেকে সরানো হয়েছে",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,18 +254,18 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "এই চালনার জন্য অ্যালার্ম পিছিয়ে দেওয়া হয়েছে।",
"searchScreenTitle": "সিগন্যাল খুঁজুন", "searchScreenTitle": "সিগন্যাল খুঁজুন",
"searchScreenSubtitle": "দ্রুত ফিল্টার আর উচ্চ কনট্রাস্টে নাম, দেশ বা ভাষা দিয়ে স্টেশন খুঁজে নিন।", "searchScreenSubtitle": "নাম, দেশ বা ভাষা দিয়ে দ্রুত ফিল্টার উচ্চ কনট্রাস্টে রেডিও খুঁজন।",
"searchFiltersLabel": "ফিল্টার", "searchFiltersLabel": "ফিল্টার",
"searchHint": "রেডিও হরাইজন, জ্যাজ, খবর...", "searchHint": "রেডিও হরাইজন, জ্যাজ, সংবাদ...",
"searchCountryFilterLabel": "দেশ", "searchCountryFilterLabel": "দেশ",
"searchLanguageFilterLabel": "ভাষা", "searchLanguageFilterLabel": "ভাষা",
"searchMinQualityFilterLabel": "ন্যূনতম মান", "searchMinQualityFilterLabel": "ন্যূনতম গুণমান",
"searchEmptyTitle": "একটি স্টেশন খুঁজুন", "searchEmptyTitle": "একটি স্টেশন খুঁজুন",
"searchNoResultsTitle": "কোনো ফলাফল নেই", "searchNoResultsTitle": "কোনো ফলাফল নেই",
"searchEmptySubtitle": "উপরের বার বা চিপগুলো ব্যবহার করে সারা বিশ্বের স্টেশন খুঁজে দেখুন।", "searchEmptySubtitle": "উপরের বার বা চিপ ব্যবহার করে সারা বিশ্বের সিগন্যাল আবিষ্কার করুন।",
"searchNoResultsSubtitle": "ফিল্টার সরিয়ে বা অন্য নাম লিখে একটি সক্রিয় স্টেশন খুঁজে দেখুন।", "searchNoResultsSubtitle": "সক্রিয় সিগন্যাল পেতে ফিল্টার সরিয়ে বা অন্য নাম লিখে দেখুন।",
"countrySpain": "স্পেন", "countrySpain": "স্পেন",
"countryUsa": "যুক্তরাষ্ট্র", "countryUsa": "যুক্তরাষ্ট্র",
"countryMexico": "মেক্সিকো", "countryMexico": "মেক্সিকো",
@@ -257,9 +285,9 @@
"languageNameJapanese": "জাপানি", "languageNameJapanese": "জাপানি",
"languageNameArabic": "আরবি", "languageNameArabic": "আরবি",
"languageNameRussian": "রুশ", "languageNameRussian": "রুশ",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "পরিষ্কার সিগন্যাল, বুদ্ধিমান প্রিয় এবং গেম শো-ধাঁচের ভিজ্যুয়াল অভিজ্ঞতাসহ লাইভ বিশ্ব রেডিও।",
"exploreStations": "Explore stations", "exploreStations": "স্টেশন দেখুন",
"stationsCount": "{count} stations", "stationsCount": "{count} রেডিও",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "HD গুণমান",
"nearYou": "Near you", "nearYou": "আপনার কাছাকাছি",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "আপনার কাছাকাছি · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "সনাক্ত করুন",
"liveRadar": "Live radar", "liveRadar": "লাইভ রাডার",
"genresTitle": "Genres", "genresTitle": "ধরন",
"retryAction": "Retry", "retryAction": "আবার চেষ্টা করুন",
"noStationsAvailable": "No stations available", "noStationsAvailable": "কোনো স্টেশন উপলব্ধ নেই",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "সিগন্যাল আবার ধরতে রিফ্রেশ করুন বা অন্য ধরন বেছে নিন।",
"genrePop": "Pop", "genrePop": "পপ",
"genreRock": "Rock", "genreRock": "রক",
"genreJazz": "Jazz", "genreJazz": "জ্যাজ",
"genreClassical": "Classical", "genreClassical": "ক্লাসিক্যাল",
"genreElectronic": "Electronic", "genreElectronic": "ইলেকট্রনিক",
"genreNews": "News", "genreNews": "সংবাদ",
"genreTalk": "Talk", "genreTalk": "আলাপ",
"genreHipHop": "Hip-hop", "genreHipHop": "হিপ-হপ",
"genreCountry": "Country", "genreCountry": "কান্ট্রি",
"genreMetal": "Metal", "genreMetal": "মেটাল",
"genreReggae": "Reggae", "genreReggae": "রেগে",
"genreLatin": "Latin", "genreLatin": "লাতিন",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "সুরেলা জাগরণ",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "রেডিও অ্যালার্ম, নিরাপদ শব্দ, স্মার্ট ছুটি এবং পরবর্তী চালনা সবসময় দৃশ্যমান।",
"createAlarmAction": "Create alarm", "createAlarmAction": "অ্যালার্ম তৈরি করুন",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} অ্যালার্ম",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "পরবর্তী চালনা ছাড়া সক্রিয় অ্যালার্ম",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "কোনো সক্রিয় অ্যালার্ম নেই",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "পরবর্তী অ্যালার্ম",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "{count}টি সক্রিয় অ্যালার্ম আছে, কিন্তু এখন তাদের কোনো বৈধ ভবিষ্যৎ তারিখ নেই। তারিখ, দিন এবং ছুটি দেখুন।",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "একটি অ্যালার্ম তৈরি করুন, PluriWave স্বয়ংক্রিয়ভাবে পরবর্তী চালনা হিসাব করবে।",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "ছুটিতে বাজে",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "ছুটিতে বিরতি",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "ফেড-ইন {seconds}সে",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "পরবর্তী চালনা: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "কোনো সক্রিয় পরবর্তী চালনা নেই।",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "একটি চালনা এড়িয়ে দেওয়া হয়েছে: {date}",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "সম্পাদনা",
"skipNextAction": "Skip next", "skipNextAction": "পরবর্তীটি এড়িয়ে যান",
"deleteTooltip": "Delete", "deleteTooltip": "মুছুন",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "অ্যালার্ম এড়ানো হয়েছে। আর কোনো পরবর্তী চালনা নেই।",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "অ্যালার্ম এড়ানো হয়েছে। {date}-এ আবার ফিরবে।",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "ছুটির কারণে ({vacationName}) বিরত আছে এবং কোনো পরবর্তী চালনা নেই।",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "ছুটির কারণে ({vacationName}) বিরত আছে এবং {date}-এ ফিরবে।",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "ছুটি চালু থাকলে, {date}-এ আবার বাজবে।",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "সুরেলা অ্যালার্ম",
"newAlarmTitle": "New alarm", "newAlarmTitle": "নতুন অ্যালার্ম",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "অ্যালার্ম সম্পাদনা",
"nameField": "Name", "nameField": "নাম",
"timeField": "Time", "timeField": "সময়",
"dateField": "Date", "dateField": "তারিখ",
"onceOption": "Once", "onceOption": "একবার",
"dailyOption": "Daily", "dailyOption": "দৈনিক",
"weekdaysOption": "Weekdays", "weekdaysOption": "দিন",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "শব্দ ও ভলিউম",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "অ্যালার্ম ফেড-ইন",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "০ সে (কোনো পরিবর্তন নয়)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} সে (৫% থেকে নির্বাচিত ভলিউমে)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "নিরাপদ অভ্যন্তরীণ শব্দ",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "উষ্ণ সূর্যোদয়",
"soundSoftBell": "Soft bell", "soundSoftBell": "নরম ঘণ্টা",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "ডিজিটাল পালস",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "প্রিয় স্টেশন",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "স্টেশন নেই: অভ্যন্তরীণ শব্দ ব্যবহার করুন",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "সুরেলা অ্যালার্ম হিসেবে ব্যবহার করতে প্রিয়তে স্টেশন সংরক্ষণ করুন।",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "বর্তমান স্টেশন ব্যবহার করুন",
"playDuringVacations": "Play during vacations", "playDuringVacations": "ছুটিতে বাজান",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "এটি বন্ধ করলে পরবর্তী চালনা প্রথম বৈধ দিনে চলে যাবে।",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "অ্যালার্ম সংরক্ষণ করুন",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "সপ্তাহের অন্তত একটি দিন বেছে নিন।",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Android নির্ভরযোগ্যতা পর্যালোচনা করুন",
"statusOk": "OK", "statusOk": "ঠিক আছে",
"statusPending": "pending", "statusPending": "অপেক্ষমাণ",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "নির্ভরযোগ্যতা: নির্দিষ্ট {exact} · বিজ্ঞপ্তি {notifications} · স্ক্রিন {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "ছুটির পরিসর",
"addAction": "Add", "addAction": "যোগ করুন",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "কোনো অ্যালার্মে \"ছুটিতে বিরতি\" থাকলে এই পরিসরগুলো স্বয়ংক্রিয়ভাবে এড়িয়ে যাবে।",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "কোনো পরিসর লোড হয়নি।",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "পরিসর মুছুন",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "ছুটি",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "নতুন ছুটির পরিসর",
"startField": "Start", "startField": "শুরু",
"endField": "End", "endField": "শেষ",
"saveRangeAction": "Save range", "saveRangeAction": "পরিসর সংরক্ষণ করুন",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "এখনও কোনো অ্যালার্ম নেই।",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "আপনার সুরেলা জাগরণ সাজাতে একটি তৈরি করুন।",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "নিরাপদ অভ্যন্তরীণ শব্দ দিয়ে বাজছে।",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "নিরাপদ অভ্যন্তরীণ শব্দ প্রস্তুত হচ্ছে।",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "অ্যালার্ম বন্ধ করুন",
"pauseAction": "বিরতি দিন",
"miniPlayerOpenLabel": "{stationName}-এর প্লেয়ার খুলুন",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "প্লেয়ার",
"playbackStatusConnecting": "সংযুক্ত হচ্ছে...",
"playbackStatusLive": "লাইভ",
"playbackStatusPaused": "বিরতিতে",
"playbackStatusConnectionError": "সংযোগে ত্রুটি",
"playbackStatusStopped": "বন্ধ",
"stationSemanticLabel": "স্টেশন {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "পছন্দের তালিকায় যোগ করুন",
"favoritesAddedMessage": "{stationName} পছন্দের তালিকায় যোগ করা হয়েছে",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "স্টেশনের প্রতীক",
"liveNow": "এখন লাইভ",
"equalizerBandLabel": "ব্যান্ড {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} ডেসিবেল",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "সমতল",
"equalizerPresetRock": "রক",
"equalizerPresetPop": "পপ",
"equalizerPresetBassBoost": "বেস বাড়ানো",
"equalizerPresetJazz": "জ্যাজ",
"equalizerPresetVoice": "কণ্ঠ",
"equalizerPresetCustom": "নিজস্ব",
"onboardingTitle": "PluriWave-এ স্বাগতম",
"onboardingNewsTitle": "নতুন কী আছে",
"onboardingStartAction": "শুরু করুন",
"onboardingCloseTooltip": "বন্ধ করুন",
"radioRecordingError": "রেডিও রেকর্ড করতে ত্রুটি: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "রেডিও এপিআই-এর সঙ্গে কোনো সংযোগ নেই",
"radioSearchError": "অনুসন্ধানে ত্রুটি। আপনার সংযোগ পরীক্ষা করুন।",
"radioLoadMoreStationsError": "আরও স্টেশন আনা যায়নি।",
"radioNearbyStationsError": "কাছাকাছি স্টেশন শনাক্ত করা যায়নি। দেশ অনুযায়ী ফিল্টার ব্যবহার করুন।",
"radioCannotPlayStation": "\"{stationName}\" চালানো যাচ্ছে না",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "রেকর্ড করার আগে একটি স্টেশন নির্বাচন করুন।",
"recordingStartError": "রেকর্ডিং শুরু করা যায়নি: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "কনফিগারেশন সংস্করণ সমর্থিত নয়",
"audioErrorGeneric": "চালানোর সময় ত্রুটি",
"audioErrorNoInternet": "ইন্টারনেট সংযোগ নেই",
"audioErrorInvalidUrl": "রেডিওর ঠিকানা বৈধ নয়",
"audioErrorNotFound": "রেডিওটি উপলব্ধ নয় (404 ত্রুটি)",
"audioErrorTimeout": "সংযোগের সময়সীমা শেষ হয়েছে",
"audioErrorCannotConnect": "রেডিওর সঙ্গে সংযোগ করা যাচ্ছে না",
"audioErrorUnsupportedFormat": "স্ট্রিম ফরম্যাট সমর্থিত নয়",
"audioErrorDecode": "অডিও স্ট্রিম ডিকোড করতে ত্রুটি",
"audioErrorCleartext": "এই রেডিও এনক্রিপশন ছাড়া HTTP ব্যবহার করে, যা অনুমোদিত নয়",
"audioErrorSsl": "রেডিওর SSL সার্টিফিকেট অবৈধ",
"audioErrorCannotPlay": "এই রেডিও চালানো যাচ্ছে না",
"audioErrorUnexpectedPlayback": "চালানোর সময় অপ্রত্যাশিত ত্রুটি",
"androidExactAlarmScheduleError": "অ্যান্ড্রয়েড সুনির্দিষ্ট অ্যালার্ম নির্ধারণ করতে পারেনি। সুনির্দিষ্ট অ্যালার্মের অনুমতি পরীক্ষা করুন।",
"recordingPathEmptyError": "রেকর্ডিংয়ের পথ খালি থাকতে পারে না",
"recordingMaxSizeInvalidError": "সর্বোচ্চ আকার শূন্যের বেশি হতে হবে",
"recordingAlreadyActiveError": "ইতিমধ্যেই একটি রেকর্ডিং চলছে",
"alarmRingingFallbackActive": "অভ্যন্তরীণ নিরাপদ অডিও দিয়ে চলছে।",
"alarmRingingPreparingFallback": "অভ্যন্তরীণ নিরাপদ অডিও প্রস্তুত করা হচ্ছে।",
"alarmRingingTryingStation": "আপনার স্টেশন সর্বোচ্চ উপলভ্য মানে চালানোর চেষ্টা করা হচ্ছে।",
"alarmScheduleOnce": "একবার · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "দিন: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Android নির্ভরযোগ্যতা দেখুন",
"closeAction": "বন্ধ করুন",
"customOption": "কাস্টম",
"endLabel": "শেষ",
"equalizerDisable": "ইকুয়ালাইজার বন্ধ করুন",
"helpTitle": "সহায়তা ও টিউটোরিয়াল",
"helpSubtitle": "PluriWave-এর ফিচার, টিপস ও নতুন বিষয়গুলো দেখুন।",
"indefiniteOption": "অনির্দিষ্ট",
"invalidNumber": "অবৈধ সংখ্যা",
"nameLabel": "নাম",
"notPlaying": "চলছে না",
"oneTimeOption": "একবার",
"pausePlaybackTooltip": "প্লেব্যাক বিরতি",
"qualityOriginal": "মূল মান: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "মান জানানো নেই",
"recordAction": "রেকর্ড করুন",
"recordDurationTitle": "রেকর্ডিং সময়কাল",
"recordRadioSubtitle": "কতক্ষণ রেকর্ড করতে চান বেছে নিন।",
"recordRadioTitle": "রেডিও রেকর্ড করুন",
"recordingActiveTitle": "রেডিও রেকর্ড হচ্ছে",
"recordingDirectTitle": "সরাসরি রেকর্ডিং",
"recordingsOpenFolderPlainError": "রেকর্ডিং ফোল্ডার খোলা যায়নি",
"recordingsOpenLatest": "সর্বশেষ রেকর্ডিং খুলুন",
"recordingsOpenLatestError": "সর্বশেষ রেকর্ডিং খোলা যায়নি",
"startLabel": "শুরু",
"startPlaybackTooltip": "প্লেব্যাক শুরু করুন",
"stopAction": "থামান",
"stopPlaybackTooltip": "প্লেব্যাক থামান",
"weekdayShortMonday": "সোম",
"weekdayShortTuesday": "মঙ্গল",
"weekdayShortWednesday": "বুধ",
"weekdayShortThursday": "বৃহস্পতি",
"weekdayShortFriday": "শুক্র",
"weekdayShortSaturday": "শনি",
"weekdayShortSunday": "রবি"
} }
+363 -189
View File
@@ -8,26 +8,53 @@
"navSettings": "Einstellungen", "navSettings": "Einstellungen",
"actionOk": "OK", "actionOk": "OK",
"sleepTimer": "Sleep-Timer", "sleepTimer": "Sleep-Timer",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "Sanftes Ausschalten des Radios mit genauem Countdown.",
"cancelTimer": "Cancel timer", "cancelTimer": "Timer abbrechen",
"optionOther": "Other", "optionOther": "Andere",
"customDurationTitle": "Custom duration", "customDurationTitle": "Benutzerdefinierte Dauer",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "Wähle eine Dauer größer als null.",
"hoursLabel": "Hours", "hoursLabel": "Stunden",
"minutesLabel": "Minutes", "minutesLabel": "Minuten",
"secondsLabel": "Seconds", "secondsLabel": "Sekunden",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} Std {minutes} Min {seconds} Sek",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} Min {seconds} Sek",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} Min",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} Sek",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Als Schnellzugriff speichern",
"startTimer": "Timer starten",
"skipCurrentAlarmExecution": "Diese Ausführung von {alarmName} wurde ausgelassen.",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Einstellungen", "settingsTitle": "Einstellungen",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "Feinabstimmung von Klang, Backups und benutzerdefinierten Sendern.",
"languageSectionTitle": "Sprache", "languageSectionTitle": "Sprache",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "Wähle, wie die Sprache der App angezeigt wird.",
"languageSystemDefault": "System", "languageSystemDefault": "System",
"languageSpanish": "Spanisch", "languageSpanish": "Spanisch",
"languageEnglish": "Englisch", "languageEnglish": "Englisch",
@@ -38,70 +65,71 @@
} }
}, },
"languageUpdatedSystem": "Sprache aktualisiert: System", "languageUpdatedSystem": "Sprache aktualisiert: System",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "Sleep-Timer",
"timerSectionAdd": "Add", "timerSectionAdd": "Hinzufügen",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "Passe die Schnellzugriffe an, die beim automatischen Ausschalten des Radios angezeigt werden.",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "Empfohlene Zeiten wiederherstellen",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "Neuer Schnellzugriff",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "Schnellzugriff speichern",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "Sicher",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "Aufnahmen",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "Aufnahmeordner auswählen",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "Aufnahmepfad aktualisiert",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "Pfad konnte nicht gespeichert werden: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "Der interne Standardordner wird verwendet",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "Aufnahmeordner",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "Pfad wird berechnet...",
"recordingsChangePath": "Change path", "recordingsChangePath": "Pfad ändern",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "Standardpfad verwenden",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "Das Radio wird aus dem Originalstream gespeichert, ohne erneute Komprimierung.",
"equalizerActive": "Active", "equalizerActive": "Aktiv",
"equalizerDisabled": "Disabled", "equalizerDisabled": "Deaktiviert",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "Equalizer aktivieren",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "Änderungen werden in Echtzeit auf den aktuellen Sender angewendet.",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "Änderungen werden gespeichert und angewendet, sobald Android den Effekt aktiviert.",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "Eigenen EQ für diesen Favoriten verwenden",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "Aktiv für {stationName}",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "Haupt-EQ für {stationName} wird verwendet",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "Bevorzugter Sender",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "Wird beim Erstellen von Alarmen vorausgewählt und kann als Schnellwiedergabe gestartet werden.",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "Noch keine Sender verfügbar",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "Speichere Favoriten oder lade Sender, um einen bevorzugten auszuwählen.",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "Automatischer Fallback",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "Standardfavorit",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "Aktuell bevorzugt: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "Keine Favoriten: {stationName} wird automatisch verwendet",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "Bevorzugten Sender abspielen",
"customStationsTitle": "Custom stations", "customStationsTitle": "Benutzerdefinierte Sender",
"customStationsAdd": "Add", "customStationsAdd": "Hinzufügen",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "Keine benutzerdefinierten Sender.",
"playAction": "Play", "playAction": "Wiedergeben",
"deleteAction": "Delete", "deleteAction": "Löschen",
"addStationTitle": "Add station", "addStationTitle": "Sender hinzufügen",
"stationNameLabel": "Name *", "stationNameLabel": "Name *",
"requiredField": "Required field", "unnamedStation": "Unbenannter Sender",
"streamUrlLabel": "Stream URL *", "requiredField": "Pflichtfeld",
"invalidUrl": "Invalid URL", "streamUrlLabel": "Stream-URL *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "Ungültige URL",
"saveStation": "Save station", "countryOptionalLabel": "Land (optional)",
"backupSectionTitle": "Backup", "saveStation": "Sender speichern",
"backupExportTitle": "Export configuration", "backupSectionTitle": "Sicherung",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "Konfiguration exportieren",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "Favoriten, benutzerdefinierte Sender und EQ-Presets",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "Konfiguration importieren",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "Aus einer Sicherungsdatei wiederherstellen",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — Sicherung",
"backupExportError": "Export error: {error}", "backupShareText": "PluriWave-Konfiguration exportiert am {date}",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "Fehler beim Exportieren: {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "Dadurch werden Favoriten, Sender und Presets aus der Datei hinzugefügt. Fortfahren?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "Konfiguration erfolgreich importiert",
"appVersionLoading": "Loading version...", "backupImportError": "Fehler beim Importieren: {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "Version wird geladen...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - Weltradio",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "Gespeicherte Favoriten",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "Senderfilter",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "Nur Sender, die als aktiv überprüft wurden",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "Audio im Hintergrund",
"backgroundAudioSubtitle": "Läuft weiter, wenn der Bildschirm ausgeschaltet wird",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -150,13 +178,13 @@
}, },
"cancelAction": "Abbrechen", "cancelAction": "Abbrechen",
"equalizerTitle": "Equalizer", "equalizerTitle": "Equalizer",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "Ordner öffnen",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "Ordner konnte nicht geöffnet werden: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "Maximale Aufnahmegröße",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "Aktuelles Limit: {size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "Maximale Größe pro Aufnahme",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "Maximale Megabytes",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "Aufnahmelimit auf {size} MB aktualisiert",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "Senderreihenfolge",
"stationOrderByName": "By name", "stationOrderByName": "Nach Name",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "Nach Qualität",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "Gilt für Favoriten, Suchen, nahegelegene Sender und Schnelllisten.",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "Favoritenlisten",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "Erstelle kurze Listen, um deine gespeicherten Sender zu organisieren.",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "Liste hinzufügen",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "Liste bearbeiten",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "Liste löschen",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "Listenname",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "Maximal 28 Zeichen.",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "Nicht zugewiesen",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "Standardliste: kann nicht bearbeitet oder gelöscht werden.",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "Liste erstellt",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "Liste aktualisiert",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "Liste gelöscht; ihre Sender kehren zu Nicht zugewiesen zurück.",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "In Liste verschieben",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "Aktuelle Liste: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} nach {groupName} verschoben",
"favoritesTitle": "Favorites", "favoritesTitle": "Favoriten",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "Noch keine Favoriten",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "Tippe bei einem Sender auf das Herz, um ihn in deiner Sammlung zu speichern.",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "Organisiere deine Sammlung in Listen und halte wichtige Radios griffbereit.",
"favoritesCollection": "Collection", "favoritesCollection": "Sammlung",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} gespeichert",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "Aus Favoriten entfernen",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} aus Favoriten entfernt",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,7 +254,7 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "Alarm für diese Ausführung verschoben.",
"searchScreenTitle": "Signal suchen", "searchScreenTitle": "Signal suchen",
"searchScreenSubtitle": "Finde Sender nach Name, Land oder Sprache mit schnellen Filtern und hohem Kontrast.", "searchScreenSubtitle": "Finde Sender nach Name, Land oder Sprache mit schnellen Filtern und hohem Kontrast.",
"searchFiltersLabel": "Filter", "searchFiltersLabel": "Filter",
@@ -257,9 +285,9 @@
"languageNameJapanese": "Japanisch", "languageNameJapanese": "Japanisch",
"languageNameArabic": "Arabisch", "languageNameArabic": "Arabisch",
"languageNameRussian": "Russisch", "languageNameRussian": "Russisch",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "Live-Weltradio mit klaren Signalen, intelligenten Favoriten und einer visuellen Game-Show-Erfahrung.",
"exploreStations": "Explore stations", "exploreStations": "Sender erkunden",
"stationsCount": "{count} stations", "stationsCount": "{count} Radios",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "HD-Qualität",
"nearYou": "Near you", "nearYou": "In deiner Nähe",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "In deiner Nähe · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "Erkennen",
"liveRadar": "Live radar", "liveRadar": "Live-Radar",
"genresTitle": "Genres", "genresTitle": "Genres",
"retryAction": "Retry", "retryAction": "Erneut versuchen",
"noStationsAvailable": "No stations available", "noStationsAvailable": "Keine Sender verfügbar",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "Versuche zu aktualisieren oder ein anderes Genre auszuwählen, um wieder ein Signal zu empfangen.",
"genrePop": "Pop", "genrePop": "Pop",
"genreRock": "Rock", "genreRock": "Rock",
"genreJazz": "Jazz", "genreJazz": "Jazz",
"genreClassical": "Classical", "genreClassical": "Klassik",
"genreElectronic": "Electronic", "genreElectronic": "Elektronisch",
"genreNews": "News", "genreNews": "Nachrichten",
"genreTalk": "Talk", "genreTalk": "Talk",
"genreHipHop": "Hip-hop", "genreHipHop": "Hip-hop",
"genreCountry": "Country", "genreCountry": "Country",
"genreMetal": "Metal", "genreMetal": "Metal",
"genreReggae": "Reggae", "genreReggae": "Reggae",
"genreLatin": "Latin", "genreLatin": "Latin",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "Musikalisch aufwachen",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "Alarme mit Radio, sicherem Ton, intelligenten Ferien und stets sichtbarer nächster Ausführung.",
"createAlarmAction": "Create alarm", "createAlarmAction": "Alarm erstellen",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} Alarme",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "Aktive Alarme ohne nächste Ausführung",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "Keine aktiven Alarme",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "Nächster Alarm",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "Es gibt {count} aktive(n) Alarm(e), aber derzeit kein gültiges zukünftiges Datum. Prüfe Datum, Wochentage und Ferien.",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,9 +343,9 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "Erstelle einen Alarm und PluriWave berechnet automatisch die nächste Ausführung.",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "Läutet in den Ferien",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "In den Ferien pausiert",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "Fade-in {seconds}s",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "Nächste Ausführung: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "Keine aktive nächste Ausführung.",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "Eine Ausführung wurde ausgelassen: {date}.",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "Bearbeiten",
"skipNextAction": "Skip next", "skipNextAction": "Nächste auslassen",
"deleteTooltip": "Delete", "deleteTooltip": "Löschen",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "Alarm ausgelassen. Es bleibt keine nächste Ausführung.",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "Alarm ausgelassen. Er kehrt am {date} zurück.",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "Wegen Ferien ({vacationName}) pausiert und ohne nächste Ausführung.",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "Wegen Ferien ({vacationName}) pausiert und kehrt am {date} zurück.",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "Mit aktiven Ferien läutet er wieder am {date}.",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "Musikalischer Wecker",
"newAlarmTitle": "New alarm", "newAlarmTitle": "Neuer Alarm",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "Alarm bearbeiten",
"nameField": "Name", "nameField": "Name",
"timeField": "Time", "timeField": "Uhrzeit",
"dateField": "Date", "dateField": "Datum",
"onceOption": "Once", "onceOption": "Einmal",
"dailyOption": "Daily", "dailyOption": "Täglich",
"weekdaysOption": "Weekdays", "weekdaysOption": "Tage",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "Klang und Lautstärke",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "Alarm-Fade-in",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 s (ohne Übergang)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} s (von 5 % bis zur gewählten Lautstärke)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "Interner Sicherheitston",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "Warmer Sonnenaufgang",
"soundSoftBell": "Soft bell", "soundSoftBell": "Sanfte Glocke",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "Digitaler Puls",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "Lieblingssender",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "Kein Sender: internen Ton verwenden",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "Speichere Sender in Favoriten, um sie als musikalischen Alarm zu verwenden.",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "Aktuellen Sender verwenden",
"playDuringVacations": "Play during vacations", "playDuringVacations": "Während der Ferien läuten",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "Wenn du das ausschaltest, springt die nächste Ausführung zum ersten gültigen Tag.",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "Alarm speichern",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "Wähle mindestens einen Wochentag.",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Android-Zuverlässigkeit prüfen",
"statusOk": "OK", "statusOk": "OK",
"statusPending": "pending", "statusPending": "ausstehend",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "Zuverlässigkeit: exakt {exact} · Benachrichtigungen {notifications} · Bildschirm {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "Ferienzeiträume",
"addAction": "Add", "addAction": "Hinzufügen",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "Wenn ein Alarm „In den Ferien pausiert“ hat, werden diese Zeiträume automatisch übersprungen.",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "Keine Zeiträume geladen.",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "Zeitraum löschen",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "Ferien",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "Neuer Ferienzeitraum",
"startField": "Start", "startField": "Beginn",
"endField": "End", "endField": "Ende",
"saveRangeAction": "Save range", "saveRangeAction": "Zeitraum speichern",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "Noch keine Alarme.",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "Erstelle einen, um dein musikalisches Aufwachen zu gestalten.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "Wiedergabe mit internem Sicherheitston.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "Interner Sicherheitston wird vorbereitet.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "Alarm stoppen",
"pauseAction": "Pausieren",
"miniPlayerOpenLabel": "Wiedergabe für {stationName} öffnen",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "Wiedergabe",
"playbackStatusConnecting": "Verbindung wird hergestellt...",
"playbackStatusLive": "Live",
"playbackStatusPaused": "Pausiert",
"playbackStatusConnectionError": "Verbindungsfehler",
"playbackStatusStopped": "Gestoppt",
"stationSemanticLabel": "Sender {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "Zu Favoriten hinzufügen",
"favoritesAddedMessage": "{stationName} zu Favoriten hinzugefügt",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "Sendersymbol",
"liveNow": "Live",
"equalizerBandLabel": "Band {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} Dezibel",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "Linear",
"equalizerPresetRock": "Rock",
"equalizerPresetPop": "Pop",
"equalizerPresetBassBoost": "Bassverstärkung",
"equalizerPresetJazz": "Jazz",
"equalizerPresetVoice": "Stimme",
"equalizerPresetCustom": "Benutzerdefiniert",
"onboardingTitle": "Willkommen bei PluriWave",
"onboardingNewsTitle": "Neuigkeiten",
"onboardingStartAction": "Loslegen",
"onboardingCloseTooltip": "Schließen",
"radioRecordingError": "Fehler beim Aufnehmen des Radios: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "Keine Verbindung zur Radio-API",
"radioSearchError": "Suchfehler. Überprüfe deine Verbindung.",
"radioLoadMoreStationsError": "Weitere Sender konnten nicht geladen werden.",
"radioNearbyStationsError": "Nahegelegene Sender konnten nicht erkannt werden. Nutze Filter nach Land.",
"radioCannotPlayStation": "\"{stationName}\" kann nicht wiedergegeben werden",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "Wähle zuerst einen Sender zum Aufnehmen aus.",
"recordingStartError": "Aufnahme konnte nicht gestartet werden: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "Nicht unterstützte Konfigurationsversion",
"audioErrorGeneric": "Wiedergabefehler",
"audioErrorNoInternet": "Keine Internetverbindung",
"audioErrorInvalidUrl": "Die Radio-URL ist ungültig",
"audioErrorNotFound": "Das Radio ist nicht verfügbar (Fehler 404)",
"audioErrorTimeout": "Zeitüberschreitung beim Verbinden",
"audioErrorCannotConnect": "Es kann keine Verbindung zum Radio hergestellt werden",
"audioErrorUnsupportedFormat": "Nicht unterstütztes Stream-Format",
"audioErrorDecode": "Fehler beim Decodieren des Audiostreams",
"audioErrorCleartext": "Dieses Radio verwendet unverschlüsseltes HTTP, was nicht erlaubt ist",
"audioErrorSsl": "Ungültiges SSL-Zertifikat für das Radio",
"audioErrorCannotPlay": "Dieses Radio kann nicht wiedergegeben werden",
"audioErrorUnexpectedPlayback": "Unerwarteter Wiedergabefehler",
"androidExactAlarmScheduleError": "Android konnte keinen exakten Alarm planen. Prüfe die Berechtigung für exakte Alarme.",
"recordingPathEmptyError": "Der Aufnahmepfad darf nicht leer sein",
"recordingMaxSizeInvalidError": "Die maximale Größe muss größer als null sein",
"recordingAlreadyActiveError": "Es läuft bereits eine Aufnahme",
"alarmRingingFallbackActive": "Wiedergabe mit internem Sicherheitsaudio.",
"alarmRingingPreparingFallback": "Internes Sicherheitsaudio wird vorbereitet.",
"alarmRingingTryingStation": "Dein Sender wird mit der bestmöglichen verfügbaren Qualität gestartet.",
"alarmScheduleOnce": "Einmal · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "Tage: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Android-Zuverlässigkeit prüfen",
"closeAction": "Schließen",
"customOption": "Benutzerdefiniert",
"endLabel": "Ende",
"equalizerDisable": "Equalizer deaktivieren",
"helpTitle": "Hilfe und Tutorial",
"helpSubtitle": "Funktionen, Tipps und Neuigkeiten von PluriWave ansehen.",
"indefiniteOption": "Unbegrenzt",
"invalidNumber": "Ungültige Zahl",
"nameLabel": "Name",
"notPlaying": "Wird nicht wiedergegeben",
"oneTimeOption": "Einmal",
"pausePlaybackTooltip": "Wiedergabe pausieren",
"qualityOriginal": "Originalqualität: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "Qualität nicht angegeben",
"recordAction": "Aufnehmen",
"recordDurationTitle": "Aufnahmedauer",
"recordRadioSubtitle": "Wähle, wie lange aufgenommen werden soll.",
"recordRadioTitle": "Radio aufnehmen",
"recordingActiveTitle": "Radio wird aufgenommen",
"recordingDirectTitle": "Direktaufnahme",
"recordingsOpenFolderPlainError": "Aufnahmeordner konnte nicht geöffnet werden",
"recordingsOpenLatest": "Letzte Aufnahme öffnen",
"recordingsOpenLatestError": "Letzte Aufnahme konnte nicht geöffnet werden",
"startLabel": "Beginn",
"startPlaybackTooltip": "Wiedergabe starten",
"stopAction": "Stoppen",
"stopPlaybackTooltip": "Wiedergabe stoppen",
"weekdayShortMonday": "Mo",
"weekdayShortTuesday": "Di",
"weekdayShortWednesday": "Mi",
"weekdayShortThursday": "Do",
"weekdayShortFriday": "Fr",
"weekdayShortSaturday": "Sa",
"weekdayShortSunday": "So"
} }
+177 -3
View File
@@ -16,6 +16,33 @@
"hoursLabel": "Hours", "hoursLabel": "Hours",
"minutesLabel": "Minutes", "minutesLabel": "Minutes",
"secondsLabel": "Seconds", "secondsLabel": "Seconds",
"durationHoursMinutesSeconds": "{hours} h {minutes} min {seconds} s",
"@durationHoursMinutesSeconds": {
"placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} min {seconds} s",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} min",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} s",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Save as quick access", "saveQuickAccess": "Save as quick access",
"startTimer": "Start timer", "startTimer": "Start timer",
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.",
@@ -79,6 +106,7 @@
"deleteAction": "Delete", "deleteAction": "Delete",
"addStationTitle": "Add station", "addStationTitle": "Add station",
"stationNameLabel": "Name *", "stationNameLabel": "Name *",
"unnamedStation": "Unnamed station",
"requiredField": "Required field", "requiredField": "Required field",
"streamUrlLabel": "Stream URL *", "streamUrlLabel": "Stream URL *",
"invalidUrl": "Invalid URL", "invalidUrl": "Invalid URL",
@@ -269,7 +297,7 @@
}, },
"qualityHd": "HD quality", "qualityHd": "HD quality",
"nearYou": "Near you", "nearYou": "Near you",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "Near you · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
@@ -403,7 +431,7 @@
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Review Android reliability",
"statusOk": "OK", "statusOk": "OK",
"statusPending": "pending", "statusPending": "pending",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "Reliability: exact {exact} · notifications {notifications} · screen {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -425,5 +453,151 @@
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "Create one to design your musical wake-up.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "Playing with internal safe audio.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "Preparing internal safe audio.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "Stop alarm",
"pauseAction": "Pause",
"miniPlayerOpenLabel": "Open player for {stationName}",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "Player",
"playbackStatusConnecting": "Connecting...",
"playbackStatusLive": "Live",
"playbackStatusPaused": "Paused",
"playbackStatusConnectionError": "Connection error",
"playbackStatusStopped": "Stopped",
"stationSemanticLabel": "Station {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "Add to favorites",
"favoritesAddedMessage": "{stationName} added to favorites",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "Station icon",
"liveNow": "Live",
"equalizerBandLabel": "{band} band",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} decibels",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "Flat",
"equalizerPresetRock": "Rock",
"equalizerPresetPop": "Pop",
"equalizerPresetBassBoost": "Bass Boost",
"equalizerPresetJazz": "Jazz",
"equalizerPresetVoice": "Voice",
"equalizerPresetCustom": "Custom",
"onboardingTitle": "Welcome to PluriWave",
"onboardingNewsTitle": "What's new",
"onboardingStartAction": "Start",
"onboardingCloseTooltip": "Close",
"radioRecordingError": "Error recording the radio: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "No connection to the radio API",
"radioSearchError": "Search error. Check your connection.",
"radioLoadMoreStationsError": "Could not load more stations.",
"radioNearbyStationsError": "We could not detect nearby stations. Use country filters.",
"radioCannotPlayStation": "Cannot play \"{stationName}\"",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "Select a station before recording.",
"recordingStartError": "Could not start recording: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "Unsupported configuration version",
"audioErrorGeneric": "Playback error",
"audioErrorNoInternet": "No internet connection",
"audioErrorInvalidUrl": "The radio URL is not valid",
"audioErrorNotFound": "The radio is not available (404 error)",
"audioErrorTimeout": "Connection timed out",
"audioErrorCannotConnect": "Cannot connect to the radio",
"audioErrorUnsupportedFormat": "Unsupported stream format",
"audioErrorDecode": "Error decoding the audio stream",
"audioErrorCleartext": "This radio uses unencrypted HTTP, which is not allowed",
"audioErrorSsl": "Invalid SSL certificate on the radio",
"audioErrorCannotPlay": "This radio cannot be played",
"audioErrorUnexpectedPlayback": "Unexpected playback error",
"androidExactAlarmScheduleError": "Android could not schedule an exact alarm. Check the exact alarm permission.",
"recordingPathEmptyError": "The recording path cannot be empty",
"recordingMaxSizeInvalidError": "The maximum size must be greater than zero",
"recordingAlreadyActiveError": "A recording is already in progress",
"alarmRingingFallbackActive": "Playing with internal safe audio.",
"alarmRingingPreparingFallback": "Preparing internal safe audio.",
"alarmRingingTryingStation": "Trying to play your station at the highest available quality.",
"alarmScheduleOnce": "Once · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "Days: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Review Android reliability",
"closeAction": "Close",
"customOption": "Custom",
"endLabel": "End",
"equalizerDisable": "Disable equalizer",
"helpTitle": "Help and tutorial",
"helpSubtitle": "Review PluriWave features, tips and whats new.",
"indefiniteOption": "Indefinite",
"invalidNumber": "Invalid number",
"nameLabel": "Name",
"notPlaying": "Not playing",
"oneTimeOption": "Once",
"pausePlaybackTooltip": "Pause playback",
"qualityOriginal": "Original quality: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "Quality not reported",
"recordAction": "Record",
"recordDurationTitle": "Recording duration",
"recordRadioSubtitle": "Choose how long you want to record.",
"recordRadioTitle": "Record radio",
"recordingActiveTitle": "Recording radio",
"recordingDirectTitle": "Direct recording",
"recordingsOpenFolderPlainError": "Could not open the recordings folder",
"recordingsOpenLatest": "Open latest recording",
"recordingsOpenLatestError": "Could not open the latest recording",
"startLabel": "Start",
"startPlaybackTooltip": "Start playback",
"stopAction": "Stop",
"stopPlaybackTooltip": "Stop playback",
"weekdayShortMonday": "Mon",
"weekdayShortTuesday": "Tue",
"weekdayShortWednesday": "Wed",
"weekdayShortThursday": "Thu",
"weekdayShortFriday": "Fri",
"weekdayShortSaturday": "Sat",
"weekdayShortSunday": "Sun"
} }
+132 -1
View File
@@ -16,6 +16,33 @@
"hoursLabel": "Horas", "hoursLabel": "Horas",
"minutesLabel": "Minutos", "minutesLabel": "Minutos",
"secondsLabel": "Segundos", "secondsLabel": "Segundos",
"durationHoursMinutesSeconds": "{hours} h {minutes} min {seconds} s",
"@durationHoursMinutesSeconds": {
"placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} min {seconds} s",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} min",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} s",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Guardar como acceso rápido", "saveQuickAccess": "Guardar como acceso rápido",
"startTimer": "Iniciar timer", "startTimer": "Iniciar timer",
"skipCurrentAlarmExecution": "Omitida esta ejecución de {alarmName}.", "skipCurrentAlarmExecution": "Omitida esta ejecución de {alarmName}.",
@@ -79,6 +106,7 @@
"deleteAction": "Eliminar", "deleteAction": "Eliminar",
"addStationTitle": "Añadir emisora", "addStationTitle": "Añadir emisora",
"stationNameLabel": "Nombre *", "stationNameLabel": "Nombre *",
"unnamedStation": "Sin nombre",
"requiredField": "Campo obligatorio", "requiredField": "Campo obligatorio",
"streamUrlLabel": "URL del stream *", "streamUrlLabel": "URL del stream *",
"invalidUrl": "URL no válida", "invalidUrl": "URL no válida",
@@ -425,5 +453,108 @@
"noAlarmsYetSubtitle": "Creá una para diseñar tu despertar musical.", "noAlarmsYetSubtitle": "Creá una para diseñar tu despertar musical.",
"ringingInternalAudioActive": "Sonando con audio seguro interno.", "ringingInternalAudioActive": "Sonando con audio seguro interno.",
"ringingPreparingInternalAudio": "Preparando audio seguro interno.", "ringingPreparingInternalAudio": "Preparando audio seguro interno.",
"stopAlarmAction": "Detener alarma" "stopAlarmAction": "Detener alarma",
"pauseAction": "Pausar",
"miniPlayerOpenLabel": "Abrir reproductor de {stationName}",
"@miniPlayerOpenLabel": {"placeholders": {"stationName": {}}},
"playerIconLabel": "Reproductor",
"playbackStatusConnecting": "Conectando...",
"playbackStatusLive": "En directo",
"playbackStatusPaused": "Pausado",
"playbackStatusConnectionError": "Error de conexión",
"playbackStatusStopped": "Detenido",
"stationSemanticLabel": "Emisora {stationName}",
"@stationSemanticLabel": {"placeholders": {"stationName": {}}},
"favoritesAddTooltip": "Añadir a favoritos",
"favoritesAddedMessage": "{stationName} añadida a favoritos",
"@favoritesAddedMessage": {"placeholders": {"stationName": {}}},
"stationIconLabel": "Icono de emisora",
"liveNow": "En vivo",
"equalizerBandLabel": "Banda {band}",
"@equalizerBandLabel": {"placeholders": {"band": {}}},
"equalizerBandValue": "{value} decibelios",
"@equalizerBandValue": {"placeholders": {"value": {}}},
"equalizerPresetFlat": "Plano",
"equalizerPresetRock": "Rock",
"equalizerPresetPop": "Pop",
"equalizerPresetBassBoost": "Refuerzo de graves",
"equalizerPresetJazz": "Jazz",
"equalizerPresetVoice": "Voz",
"equalizerPresetCustom": "Personalizado",
"onboardingTitle": "Bienvenido a PluriWave",
"onboardingNewsTitle": "Novedades",
"onboardingStartAction": "Empezar",
"onboardingCloseTooltip": "Cerrar",
"radioRecordingError": "Error al grabar la radio: {error}",
"@radioRecordingError": {"placeholders": {"error": {}}},
"radioApiConnectionError": "Sin conexión a la API de radio",
"radioSearchError": "Error en la búsqueda. Comprueba tu conexión.",
"radioLoadMoreStationsError": "No se pudieron cargar más emisoras.",
"radioNearbyStationsError": "No pudimos detectar emisoras cercanas. Usa filtros por país.",
"radioCannotPlayStation": "No se puede reproducir \"{stationName}\"",
"@radioCannotPlayStation": {"placeholders": {"stationName": {}}},
"recordingSelectStationFirst": "Primero selecciona una emisora para grabar.",
"recordingStartError": "No se pudo iniciar la grabación: {error}",
"@recordingStartError": {"placeholders": {"error": {}}},
"unsupportedConfigVersion": "Versión de configuración no compatible",
"audioErrorGeneric": "Error de reproducción",
"audioErrorNoInternet": "Sin conexión a internet",
"audioErrorInvalidUrl": "La URL de la radio no es válida",
"audioErrorNotFound": "La radio no está disponible (error 404)",
"audioErrorTimeout": "Tiempo de espera agotado al conectar",
"audioErrorCannotConnect": "No se puede conectar a la radio",
"audioErrorUnsupportedFormat": "Formato de stream no compatible",
"audioErrorDecode": "Error al decodificar el stream de audio",
"audioErrorCleartext": "Esta radio usa HTTP sin cifrar, y no está permitido",
"audioErrorSsl": "Certificado SSL inválido en la radio",
"audioErrorCannotPlay": "No se puede reproducir esta radio",
"audioErrorUnexpectedPlayback": "Error inesperado al reproducir",
"androidExactAlarmScheduleError": "Android no pudo programar una alarma exacta. Revisa el permiso de alarmas exactas.",
"recordingPathEmptyError": "La ruta de grabación no puede estar vacía",
"recordingMaxSizeInvalidError": "El tamaño máximo debe ser mayor que cero",
"recordingAlreadyActiveError": "Ya hay una grabación en curso",
"alarmRingingFallbackActive": "Sonando con audio seguro interno.",
"alarmRingingPreparingFallback": "Preparando audio seguro interno.",
"alarmRingingTryingStation": "Intentando reproducir tu emisora con máxima calidad disponible.",
"alarmScheduleOnce": "Una vez · {date}",
"@alarmScheduleOnce": {"placeholders": {"date": {}}},
"alarmScheduleWeekdays": "Días: {days}",
"@alarmScheduleWeekdays": {"placeholders": {"days": {}}},
"androidReliabilityTitle": "Revisar fiabilidad Android",
"closeAction": "Cerrar",
"customOption": "Personalizada",
"endLabel": "Fin",
"equalizerDisable": "Desactivar ecualizador",
"helpTitle": "Ayuda y tutorial",
"helpSubtitle": "Repasá funciones, consejos y novedades de PluriWave.",
"indefiniteOption": "Indefinida",
"invalidNumber": "Número inválido",
"nameLabel": "Nombre",
"notPlaying": "No está reproduciendo",
"oneTimeOption": "Una vez",
"pausePlaybackTooltip": "Pausar reproducción",
"qualityOriginal": "Calidad original: {quality}",
"@qualityOriginal": {"placeholders": {"quality": {}}},
"qualityUnknown": "Calidad no informada",
"recordAction": "Grabar",
"recordDurationTitle": "Duración de grabación",
"recordRadioSubtitle": "Elegí cuánto tiempo querés grabar.",
"recordRadioTitle": "Grabar radio",
"recordingActiveTitle": "Grabando radio",
"recordingDirectTitle": "Grabación directa",
"recordingsOpenFolderPlainError": "No se pudo abrir la carpeta de grabaciones",
"recordingsOpenLatest": "Abrir última grabación",
"recordingsOpenLatestError": "No se pudo abrir la última grabación",
"startLabel": "Inicio",
"startPlaybackTooltip": "Iniciar reproducción",
"stopAction": "Parar",
"stopPlaybackTooltip": "Detener reproducción",
"weekdayShortMonday": "Lun",
"weekdayShortTuesday": "Mar",
"weekdayShortWednesday": "Mié",
"weekdayShortThursday": "Jue",
"weekdayShortFriday": "Vie",
"weekdayShortSaturday": "Sáb",
"weekdayShortSunday": "Dom"
} }
+371 -197
View File
@@ -5,103 +5,131 @@
"navSearch": "Recherche", "navSearch": "Recherche",
"navFavorites": "Favoris", "navFavorites": "Favoris",
"navAlarms": "Alarmes", "navAlarms": "Alarmes",
"navSettings": "Settings", "navSettings": "Paramètres",
"actionOk": "OK", "actionOk": "OK",
"sleepTimer": "Minuteur de sommeil", "sleepTimer": "Minuteur de sommeil",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "Arrêt progressif de la radio avec compte à rebours précis.",
"cancelTimer": "Cancel timer", "cancelTimer": "Annuler le minuteur",
"optionOther": "Other", "optionOther": "Autre",
"customDurationTitle": "Custom duration", "customDurationTitle": "Durée personnalisée",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "Choisissez une durée supérieure à zéro.",
"hoursLabel": "Hours", "hoursLabel": "Heures",
"minutesLabel": "Minutes", "minutesLabel": "Minutes",
"secondsLabel": "Seconds", "secondsLabel": "Secondes",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} h {minutes} min {seconds} s",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} min {seconds} s",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} min",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} s",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Enregistrer comme raccourci",
"startTimer": "Démarrer le minuteur",
"skipCurrentAlarmExecution": "Cette exécution de {alarmName} a été ignorée.",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "Paramètres",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "Réglage précis du son, sauvegardes et stations personnalisées.",
"languageSectionTitle": "Langue", "languageSectionTitle": "Langue",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "Choisissez le mode daffichage de la langue de lapp.",
"languageSystemDefault": "System", "languageSystemDefault": "Système",
"languageSpanish": "Espagnol", "languageSpanish": "Espagnol",
"languageEnglish": "Anglais", "languageEnglish": "Anglais",
"languageUpdated": "Language updated: {languageName}", "languageUpdated": "Langue mise à jour : {languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
"languageName": {} "languageName": {}
} }
}, },
"languageUpdatedSystem": "Language updated: System", "languageUpdatedSystem": "Langue mise à jour : Système",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "Minuteur de sommeil",
"timerSectionAdd": "Add", "timerSectionAdd": "Ajouter",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "Personnalisez les raccourcis affichés lors de larrêt automatique de la radio.",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "Restaurer les durées recommandées",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "Nouveau raccourci",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "Enregistrer le raccourci",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "Sûr",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "Enregistrements",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "Sélectionnez le dossier denregistrement",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "Chemin denregistrement mis à jour",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "Impossible denregistrer le chemin : {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "Le dossier interne par défaut sera utilisé",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "Dossier denregistrement",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "Calcul du chemin...",
"recordingsChangePath": "Change path", "recordingsChangePath": "Changer le chemin",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "Utiliser le chemin par défaut",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "La radio est enregistrée depuis le flux original, sans recompression.",
"equalizerActive": "Active", "equalizerActive": "Actif",
"equalizerDisabled": "Disabled", "equalizerDisabled": "Désactivé",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "Activer l’égaliseur",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "Les changements sappliquent en temps réel à la station actuelle.",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "Les changements sont enregistrés et sappliqueront quand Android activera leffet.",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "Utiliser un EQ propre pour ce favori",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "Actif pour {stationName}",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "EQ principal utilisé pour {stationName}",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "Station préférée",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "Présélectionnée lors de la création dalarmes et disponible en lecture rapide.",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "Aucune station disponible pour le moment",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "Enregistrez des favoris ou chargez des stations pour en choisir une préférée.",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "Repli automatique",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "Favori par défaut",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "Préférée actuelle : {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "Aucun favori : utilisation automatique de {stationName}",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "Lire la préférée",
"customStationsTitle": "Custom stations", "customStationsTitle": "Stations personnalisées",
"customStationsAdd": "Add", "customStationsAdd": "Ajouter",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "Aucune station personnalisée.",
"playAction": "Play", "playAction": "Lire",
"deleteAction": "Delete", "deleteAction": "Supprimer",
"addStationTitle": "Add station", "addStationTitle": "Ajouter une station",
"stationNameLabel": "Name *", "stationNameLabel": "Nom *",
"requiredField": "Required field", "unnamedStation": "Station sans nom",
"streamUrlLabel": "Stream URL *", "requiredField": "Champ obligatoire",
"invalidUrl": "Invalid URL", "streamUrlLabel": "URL du flux *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "URL non valide",
"saveStation": "Save station", "countryOptionalLabel": "Pays (facultatif)",
"backupSectionTitle": "Backup", "saveStation": "Enregistrer la station",
"backupExportTitle": "Export configuration", "backupSectionTitle": "Sauvegarde",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "Exporter la configuration",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "Favoris, stations personnalisées et préréglages dEQ",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "Importer la configuration",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "Restaurer depuis un fichier de sauvegarde",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — sauvegarde",
"backupExportError": "Export error: {error}", "backupShareText": "Configuration de PluriWave exportée le {date}",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "Erreur dexportation : {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "Cela ajoutera les favoris, stations et préréglages du fichier. Continuer ?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "Configuration importée avec succès",
"appVersionLoading": "Loading version...", "backupImportError": "Erreur dimportation : {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "Chargement de la version...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - Radio mondiale",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "Favoris enregistrés",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "Filtre de stations",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "Seulement les stations vérifiées comme actives",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "Audio en arrière-plan",
"backgroundAudioSubtitle": "Continue lorsque l’écran s’éteint",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -149,14 +177,14 @@
} }
}, },
"cancelAction": "Annuler", "cancelAction": "Annuler",
"equalizerTitle": "Equalizer", "equalizerTitle": "Égaliseur",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "Ouvrir le dossier",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "Impossible douvrir le dossier : {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "Taille maximale denregistrement",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "Limite actuelle : {size} Mo",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "Taille maximale par enregistrement",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "Mégaoctets maximum",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "Limite denregistrement mise à jour à {size} Mo",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "Ordre des stations",
"stationOrderByName": "By name", "stationOrderByName": "Par nom",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "Par qualité",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "Sapplique aux favoris, recherches, stations proches et listes rapides.",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "Listes de favoris",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "Créez de courtes listes pour organiser vos stations enregistrées.",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "Ajouter une liste",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "Modifier la liste",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "Supprimer la liste",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "Nom de la liste",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "Maximum 28 caractères.",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "Non assigné",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "Liste par défaut : elle ne peut être ni modifiée ni supprimée.",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "Liste créée",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "Liste mise à jour",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "Liste supprimée ; ses stations retournent à Non assigné.",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "Déplacer vers une liste",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "Liste actuelle : {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} déplacée vers {groupName}",
"favoritesTitle": "Favorites", "favoritesTitle": "Favoris",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "Aucun favori pour le moment",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "Touchez le cœur sur nimporte quelle station pour lenregistrer dans votre collection.",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "Organisez votre collection par listes et gardez les radios importantes à portée de main.",
"favoritesCollection": "Collection", "favoritesCollection": "Collection",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} enregistrés",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "Retirer des favoris",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} retirée des favoris",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,7 +254,7 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "Alarme reportée pour cette exécution.",
"searchScreenTitle": "Rechercher un signal", "searchScreenTitle": "Rechercher un signal",
"searchScreenSubtitle": "Trouvez des stations par nom, pays ou langue grâce à des filtres rapides et à un contraste élevé.", "searchScreenSubtitle": "Trouvez des stations par nom, pays ou langue grâce à des filtres rapides et à un contraste élevé.",
"searchFiltersLabel": "Filtres", "searchFiltersLabel": "Filtres",
@@ -257,9 +285,9 @@
"languageNameJapanese": "japonais", "languageNameJapanese": "japonais",
"languageNameArabic": "arabe", "languageNameArabic": "arabe",
"languageNameRussian": "russe", "languageNameRussian": "russe",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "Radio mondiale en direct avec des signaux clairs, des favoris intelligents et une expérience visuelle de jeu télévisé.",
"exploreStations": "Explore stations", "exploreStations": "Explorer les stations",
"stationsCount": "{count} stations", "stationsCount": "{count} radios",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "Qualité HD",
"nearYou": "Near you", "nearYou": "Près de vous",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "Près de vous · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "Détecter",
"liveRadar": "Live radar", "liveRadar": "Radar en direct",
"genresTitle": "Genres", "genresTitle": "Genres",
"retryAction": "Retry", "retryAction": "Réessayer",
"noStationsAvailable": "No stations available", "noStationsAvailable": "Aucune station disponible",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "Essayez dactualiser ou de choisir un autre genre pour capter à nouveau un signal.",
"genrePop": "Pop", "genrePop": "Pop",
"genreRock": "Rock", "genreRock": "Rock",
"genreJazz": "Jazz", "genreJazz": "Jazz",
"genreClassical": "Classical", "genreClassical": "Classique",
"genreElectronic": "Electronic", "genreElectronic": "Électronique",
"genreNews": "News", "genreNews": "Infos",
"genreTalk": "Talk", "genreTalk": "Débat",
"genreHipHop": "Hip-hop", "genreHipHop": "Hip-hop",
"genreCountry": "Country", "genreCountry": "Country",
"genreMetal": "Metal", "genreMetal": "Metal",
"genreReggae": "Reggae", "genreReggae": "Reggae",
"genreLatin": "Latin", "genreLatin": "Latino",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "Réveil musical",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "Alarmes avec radio, son sécurisé, vacances intelligentes et prochaine exécution toujours visible.",
"createAlarmAction": "Create alarm", "createAlarmAction": "Créer une alarme",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} alarmes",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "Alarmes actives sans prochaine exécution",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "Aucune alarme active",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "Prochaine alarme",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "Il y a {count} alarme(s) active(s), mais elles nont actuellement aucune date future valide. Vérifiez la date, les jours et les vacances.",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "Créez une alarme et PluriWave calculera automatiquement la prochaine exécution.",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "Sonne pendant les vacances",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "En pause pendant les vacances",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "Fondu dentrée {seconds} s",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "Prochaine exécution : {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "Aucune prochaine exécution active.",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "Une exécution a été ignorée : {date}.",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "Modifier",
"skipNextAction": "Skip next", "skipNextAction": "Ignorer la suivante",
"deleteTooltip": "Delete", "deleteTooltip": "Supprimer",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "Alarme ignorée. Il ne reste aucune prochaine exécution.",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "Alarme ignorée. Elle reviendra le {date}.",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "En pause pour vacances ({vacationName}) et sans prochaine exécution.",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "En pause pour vacances ({vacationName}) et revient le {date}.",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "Avec les vacances actives, elle sonnera à nouveau le {date}.",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "Réveil musical",
"newAlarmTitle": "New alarm", "newAlarmTitle": "Nouvelle alarme",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "Modifier lalarme",
"nameField": "Name", "nameField": "Nom",
"timeField": "Time", "timeField": "Heure",
"dateField": "Date", "dateField": "Date",
"onceOption": "Once", "onceOption": "Une fois",
"dailyOption": "Daily", "dailyOption": "Quotidienne",
"weekdaysOption": "Weekdays", "weekdaysOption": "Jours",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "Son et volume",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "Fondu dentrée de lalarme",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 s (sans transition)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} s (de 5 % au volume choisi)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "Son sécurisé interne",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "Lever de soleil chaleureux",
"soundSoftBell": "Soft bell", "soundSoftBell": "Cloche douce",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "Impulsion numérique",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "Station favorite",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "Aucune station : utiliser le son interne",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "Enregistrez des stations dans les Favoris pour les utiliser comme alarme musicale.",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "Utiliser la station actuelle",
"playDuringVacations": "Play during vacations", "playDuringVacations": "Sonner pendant les vacances",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "Si vous désactivez cette option, la prochaine exécution passera au premier jour valide.",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "Enregistrer lalarme",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "Choisissez au moins un jour de la semaine.",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Vérifier la fiabilité Android",
"statusOk": "OK", "statusOk": "OK",
"statusPending": "pending", "statusPending": "en attente",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "Fiabilité : exactes {exact} · notifications {notifications} · écran {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "Périodes de vacances",
"addAction": "Add", "addAction": "Ajouter",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "Si une alarme est en « pause pendant les vacances », ces périodes sont automatiquement ignorées.",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "Aucune période chargée.",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "Supprimer la période",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "Vacances",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "Nouvelle période de vacances",
"startField": "Start", "startField": "Début",
"endField": "End", "endField": "Fin",
"saveRangeAction": "Save range", "saveRangeAction": "Enregistrer la période",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "Il ny a pas encore dalarmes.",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "Créez-en une pour concevoir votre réveil musical.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "Son sécurisé interne en cours.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "Préparation du son sécurisé interne.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "Arrêter lalarme",
"pauseAction": "Pause",
"miniPlayerOpenLabel": "Ouvrir le lecteur de {stationName}",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "Lecteur",
"playbackStatusConnecting": "Connexion...",
"playbackStatusLive": "En direct",
"playbackStatusPaused": "En pause",
"playbackStatusConnectionError": "Erreur de connexion",
"playbackStatusStopped": "Arrêté",
"stationSemanticLabel": "Station {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "Ajouter aux favoris",
"favoritesAddedMessage": "{stationName} ajoutée aux favoris",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "Icône de station",
"liveNow": "En direct",
"equalizerBandLabel": "Bande {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} décibels",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "Plat",
"equalizerPresetRock": "Rock",
"equalizerPresetPop": "Pop",
"equalizerPresetBassBoost": "Renforcement des basses",
"equalizerPresetJazz": "Jazz",
"equalizerPresetVoice": "Voix",
"equalizerPresetCustom": "Personnalisé",
"onboardingTitle": "Bienvenue dans PluriWave",
"onboardingNewsTitle": "Nouveautés",
"onboardingStartAction": "Commencer",
"onboardingCloseTooltip": "Fermer",
"radioRecordingError": "Erreur lors de l'enregistrement de la radio : {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "Aucune connexion à l'API radio",
"radioSearchError": "Erreur de recherche. Vérifiez votre connexion.",
"radioLoadMoreStationsError": "Impossible de charger plus de stations.",
"radioNearbyStationsError": "Nous n'avons pas pu détecter de stations proches. Utilisez les filtres par pays.",
"radioCannotPlayStation": "Impossible de lire \"{stationName}\"",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "Sélectionnez d'abord une station à enregistrer.",
"recordingStartError": "Impossible de démarrer l'enregistrement : {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "Version de configuration non prise en charge",
"audioErrorGeneric": "Erreur de lecture",
"audioErrorNoInternet": "Aucune connexion Internet",
"audioErrorInvalidUrl": "L'URL de la radio n'est pas valide",
"audioErrorNotFound": "La radio n'est pas disponible (erreur 404)",
"audioErrorTimeout": "Délai de connexion dépassé",
"audioErrorCannotConnect": "Impossible de se connecter à la radio",
"audioErrorUnsupportedFormat": "Format de flux non pris en charge",
"audioErrorDecode": "Erreur lors du décodage du flux audio",
"audioErrorCleartext": "Cette radio utilise HTTP non chiffré, ce qui n'est pas autorisé",
"audioErrorSsl": "Certificat SSL invalide pour la radio",
"audioErrorCannotPlay": "Impossible de lire cette radio",
"audioErrorUnexpectedPlayback": "Erreur de lecture inattendue",
"androidExactAlarmScheduleError": "Android n'a pas pu programmer une alarme exacte. Vérifiez l'autorisation des alarmes exactes.",
"recordingPathEmptyError": "Le chemin d'enregistrement ne peut pas être vide",
"recordingMaxSizeInvalidError": "La taille maximale doit être supérieure à zéro",
"recordingAlreadyActiveError": "Un enregistrement est déjà en cours",
"alarmRingingFallbackActive": "Lecture avec laudio interne sécurisé.",
"alarmRingingPreparingFallback": "Préparation de laudio interne sécurisé.",
"alarmRingingTryingStation": "Tentative de lecture de votre station avec la meilleure qualité disponible.",
"alarmScheduleOnce": "Une fois · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "Jours : {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Vérifier la fiabilité Android",
"closeAction": "Fermer",
"customOption": "Personnalisée",
"endLabel": "Fin",
"equalizerDisable": "Désactiver l’égaliseur",
"helpTitle": "Aide et tutoriel",
"helpSubtitle": "Revoyez les fonctions, conseils et nouveautés de PluriWave.",
"indefiniteOption": "Indéfinie",
"invalidNumber": "Nombre invalide",
"nameLabel": "Nom",
"notPlaying": "Lecture arrêtée",
"oneTimeOption": "Une fois",
"pausePlaybackTooltip": "Mettre en pause",
"qualityOriginal": "Qualité dorigine : {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "Qualité non indiquée",
"recordAction": "Enregistrer",
"recordDurationTitle": "Durée denregistrement",
"recordRadioSubtitle": "Choisissez la durée denregistrement.",
"recordRadioTitle": "Enregistrer la radio",
"recordingActiveTitle": "Enregistrement de la radio",
"recordingDirectTitle": "Enregistrement direct",
"recordingsOpenFolderPlainError": "Impossible douvrir le dossier des enregistrements",
"recordingsOpenLatest": "Ouvrir le dernier enregistrement",
"recordingsOpenLatestError": "Impossible douvrir le dernier enregistrement",
"startLabel": "Début",
"startPlaybackTooltip": "Démarrer la lecture",
"stopAction": "Arrêter",
"stopPlaybackTooltip": "Arrêter la lecture",
"weekdayShortMonday": "Lun",
"weekdayShortTuesday": "Mar",
"weekdayShortWednesday": "Mer",
"weekdayShortThursday": "Jeu",
"weekdayShortFriday": "Ven",
"weekdayShortSaturday": "Sam",
"weekdayShortSunday": "Dim"
} }
+399 -225
View File
@@ -1,107 +1,135 @@
{ {
"@@locale": "hi", "@@locale": "hi",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "मुखपृष्ठ",
"navSearch": "Search", "navSearch": "खोज",
"navFavorites": "Favorites", "navFavorites": "पसंदीदा",
"navAlarms": "Alarms", "navAlarms": "अलार्म",
"navSettings": "Settings", "navSettings": "सेटिंग्स",
"actionOk": "OK", "actionOk": "ठीक है",
"sleepTimer": "Sleep timer", "sleepTimer": "नींद टाइमर",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "सटीक उलटी गिनती के साथ रेडियो को धीरे से बंद करना।",
"cancelTimer": "Cancel timer", "cancelTimer": "टाइमर रद्द करें",
"optionOther": "Other", "optionOther": "अन्य",
"customDurationTitle": "Custom duration", "customDurationTitle": "मनचाही अवधि",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "शून्य से अधिक अवधि चुनें।",
"hoursLabel": "Hours", "hoursLabel": "घंटे",
"minutesLabel": "Minutes", "minutesLabel": "मिनट",
"secondsLabel": "Seconds", "secondsLabel": "सेकंड",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} ?? {minutes} ?? {seconds} ??",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} ?? {seconds} ??",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} ??",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} ??",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "त्वरित पहुँच के रूप में सहेजें",
"startTimer": "टाइमर शुरू करें",
"skipCurrentAlarmExecution": "{alarmName} की यह चाल छोड़ दी गई।",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "सेटिंग्स",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "ध्वनि, बैकअप और मनचाहे स्टेशनों पर बारीक नियंत्रण।",
"languageSectionTitle": "Language", "languageSectionTitle": "भाषा",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "ऐप की भाषा कैसे दिखाई जाए, यह चुनें।",
"languageSystemDefault": "System", "languageSystemDefault": "सिस्टम",
"languageSpanish": "Spanish", "languageSpanish": "स्पैनिश",
"languageEnglish": "English", "languageEnglish": "अंग्रेज़ी",
"languageUpdated": "Language updated: {languageName}", "languageUpdated": "भाषा अपडेट हुई: {languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
"languageName": {} "languageName": {}
} }
}, },
"languageUpdatedSystem": "Language updated: System", "languageUpdatedSystem": "भाषा अपडेट हुई: सिस्टम",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "नींद टाइमर",
"timerSectionAdd": "Add", "timerSectionAdd": "जोड़ें",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "रेडियो को अपने-आप बंद करते समय दिखने वाले त्वरित प्रीसेट सजाएँ।",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "अनुशंसित समय वापस लाएँ",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "नई त्वरित पहुँच",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "त्वरित पहुँच सहेजें",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "सुरक्षित",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "रिकॉर्डिंग",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "रिकॉर्डिंग फ़ोल्डर चुनें",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "रिकॉर्डिंग पथ अपडेट हुआ",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "पथ सहेजा नहीं जा सका: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "डिफ़ॉल्ट आंतरिक फ़ोल्डर इस्तेमाल होगा",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "रिकॉर्डिंग फ़ोल्डर",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "पथ की गणना हो रही है...",
"recordingsChangePath": "Change path", "recordingsChangePath": "पथ बदलें",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "डिफ़ॉल्ट पथ इस्तेमाल करें",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "रेडियो मूल स्ट्रीम से सहेजा जाता है, बिना दोबारा संपीड़ित किए।",
"equalizerActive": "Active", "equalizerActive": "सक्रिय",
"equalizerDisabled": "Disabled", "equalizerDisabled": "निष्क्रिय",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "इक्वलाइज़र चालू करें",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "बदलाव वर्तमान स्टेशन पर तुरंत लागू होते हैं।",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "बदलाव सहेजे जाते हैं और Android प्रभाव सक्षम होने पर लागू होंगे।",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "इस पसंदीदा के लिए अपना EQ इस्तेमाल करें",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "{stationName} के लिए सक्रिय",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "{stationName} के लिए मुख्य EQ इस्तेमाल हो रहा है",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "पसंदीदा स्टेशन",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "नए अलार्म बनाते समय पहले से चुना जाता है और त्वरित प्लेबैक में चल सकता है।",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "अभी कोई स्टेशन उपलब्ध नहीं है",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "पसंदीदा स्टेशन चुनने के लिए पसंदीदा सहेजें या स्टेशन लोड करें।",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "स्वचालित विकल्प",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "डिफ़ॉल्ट पसंदीदा",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "वर्तमान पसंदीदा: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "कोई पसंदीदा नहीं: अपने-आप {stationName} इस्तेमाल हो रहा है",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "पसंदीदा चलाएँ",
"customStationsTitle": "Custom stations", "customStationsTitle": "मनचाहे स्टेशन",
"customStationsAdd": "Add", "customStationsAdd": "जोड़ें",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "कोई मनचाहा स्टेशन नहीं।",
"playAction": "Play", "playAction": "चलाएँ",
"deleteAction": "Delete", "deleteAction": "हटाएँ",
"addStationTitle": "Add station", "addStationTitle": "स्टेशन जोड़ें",
"stationNameLabel": "Name *", "stationNameLabel": "नाम *",
"requiredField": "Required field", "unnamedStation": "बिना नाम का स्टेशन",
"streamUrlLabel": "Stream URL *", "requiredField": "आवश्यक फ़ील्ड",
"invalidUrl": "Invalid URL", "streamUrlLabel": "स्ट्रीम URL *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "अमान्य URL",
"saveStation": "Save station", "countryOptionalLabel": "देश (वैकल्पिक)",
"backupSectionTitle": "Backup", "saveStation": "स्टेशन सहेजें",
"backupExportTitle": "Export configuration", "backupSectionTitle": "बैकअप",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "सेटिंग्स निर्यात करें",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "पसंदीदा, मनचाहे स्टेशन और EQ प्रीसेट",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "सेटिंग्स आयात करें",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "बैकअप फ़ाइल से पुनर्स्थापित करें",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — बैकअप",
"backupExportError": "Export error: {error}", "backupShareText": "{date} को निर्यात की गई PluriWave सेटिंग्स",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "निर्यात करते समय त्रुटि: {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "यह फ़ाइल से पसंदीदा, स्टेशन और प्रीसेट जोड़ देगा। जारी रखें?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "सेटिंग्स सफलतापूर्वक आयात हुईं",
"appVersionLoading": "Loading version...", "backupImportError": "आयात करते समय त्रुटि: {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "संस्करण लोड हो रहा है...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - विश्व रेडियो",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "सहेजे गए पसंदीदा",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "स्टेशन फ़िल्टर",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "केवल सक्रिय सत्यापित स्टेशन",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "पृष्ठभूमि ऑडियो",
"backgroundAudioSubtitle": "स्क्रीन बंद होने पर भी जारी रहता है",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -148,15 +176,15 @@
"version": {} "version": {}
} }
}, },
"cancelAction": "Cancel", "cancelAction": "रद्द करें",
"equalizerTitle": "Equalizer", "equalizerTitle": "इक्वलाइज़र",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "फ़ोल्डर खोलें",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "फ़ोल्डर नहीं खुल सका: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "रिकॉर्डिंग का अधिकतम आकार",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "वर्तमान सीमा: {size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "प्रति रिकॉर्डिंग अधिकतम आकार",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "अधिकतम मेगाबाइट",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "रिकॉर्डिंग सीमा {size} MB पर अपडेट हुई",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "स्टेशन क्रम",
"stationOrderByName": "By name", "stationOrderByName": "नाम से",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "गुणवत्ता से",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "पसंदीदा, खोज, पास के स्टेशन और त्वरित सूचियों पर लागू होता है।",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "पसंदीदा सूचियाँ",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "सहेजे गए स्टेशनों को व्यवस्थित करने के लिए छोटी सूचियाँ बनाएँ।",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "सूची जोड़ें",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "सूची संपादित करें",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "सूची हटाएँ",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "सूची का नाम",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "अधिकतम 28 वर्ण।",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "अनिर्धारित",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "डिफ़ॉल्ट सूची: संपादित या हटाई नहीं जा सकती।",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "सूची बनाई गई",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "सूची अपडेट हुई",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "सूची हटाई गई; उसके स्टेशन अनिर्धारित में लौट गए।",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "सूची में ले जाएँ",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "वर्तमान सूची: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} को {groupName} में ले जाया गया",
"favoritesTitle": "Favorites", "favoritesTitle": "पसंदीदा",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "अभी कोई पसंदीदा नहीं",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "किसी भी स्टेशन पर दिल दबाकर उसे अपने संग्रह में सहेजें।",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "अपने संग्रह को सूचियों में सजाएँ और महत्वपूर्ण रेडियो पास रखें।",
"favoritesCollection": "Collection", "favoritesCollection": "संग्रह",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} सहेजे गए",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "पसंदीदा से हटाएँ",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} पसंदीदा से हटाया गया",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,18 +254,18 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "इस चाल के लिए अलार्म स्थगित किया गया।",
"searchScreenTitle": "सिग्नल खोजें", "searchScreenTitle": "सिग्नल खोजें",
"searchScreenSubtitle": "तेज़ फ़िल्टर और उच्च कॉन्ट्रास्ट के साथ नाम, देश या भाषा से स्टेशन खोजें।", "searchScreenSubtitle": "नाम, देश या भाषा से तेज़ फ़िल्टर और उच्च कट्रास्ट के साथ रेडियो खोजें।",
"searchFiltersLabel": "फ़िल्टर", "searchFiltersLabel": "फ़िल्टर",
"searchHint": "रेडियो होराइजन, जैज़, समाचार...", "searchHint": "रेडियो होराइजन, जैज़, समाचार...",
"searchCountryFilterLabel": "देश", "searchCountryFilterLabel": "देश",
"searchLanguageFilterLabel": "भाषा", "searchLanguageFilterLabel": "भाषा",
"searchMinQualityFilterLabel": "न्यूनतम गुणवत्ता", "searchMinQualityFilterLabel": "न्यूनतम गुणवत्ता",
"searchEmptyTitle": "कोई स्टेशन खोजें", "searchEmptyTitle": "क स्टेशन खोजें",
"searchNoResultsTitle": "कोई नतीजा नहीं", "searchNoResultsTitle": "कोई परिणाम नहीं",
"searchEmptySubtitle": "दुनिया भर के स्टेशन खोजने के लिए ऊपर की बार या चिप्स का इस्तेमाल करें।", "searchEmptySubtitle": "दुनिया भर के सिग्नल खोजने के लिए ऊपर की बार या चिप्स इस्तेमाल करें।",
"searchNoResultsSubtitle": "फ़िल्टर हटाकर देखें या सक्रिय स्टेशन खोजने के लिए कोई दूसरा नाम लिखें।", "searchNoResultsSubtitle": "सक्रिय सिग्नल पाने के लिए फ़िल्टर हटाएँ या कोई दूसरा नाम लिखें।",
"countrySpain": "स्पेन", "countrySpain": "स्पेन",
"countryUsa": "अमेरिका", "countryUsa": "अमेरिका",
"countryMexico": "मेक्सिको", "countryMexico": "मेक्सिको",
@@ -257,9 +285,9 @@
"languageNameJapanese": "जापानी", "languageNameJapanese": "जापानी",
"languageNameArabic": "अरबी", "languageNameArabic": "अरबी",
"languageNameRussian": "रूसी", "languageNameRussian": "रूसी",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "साफ़ सिग्नल, समझदार पसंदीदा और गेम शो जैसी दृश्य अनुभूति के साथ लाइव वैश्विक रेडियो।",
"exploreStations": "Explore stations", "exploreStations": "स्टेशन देखें",
"stationsCount": "{count} stations", "stationsCount": "{count} रेडियो",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "HD गुणवत्ता",
"nearYou": "Near you", "nearYou": "आपके पास",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "आपके पास · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "पहचानें",
"liveRadar": "Live radar", "liveRadar": "लाइव रडार",
"genresTitle": "Genres", "genresTitle": "शैलियाँ",
"retryAction": "Retry", "retryAction": "फिर कोशिश करें",
"noStationsAvailable": "No stations available", "noStationsAvailable": "कोई स्टेशन उपलब्ध नहीं",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "सिग्नल फिर पकड़ने के लिए रीफ़्रेश करें या दूसरी शैली चुनें।",
"genrePop": "Pop", "genrePop": "पॉप",
"genreRock": "Rock", "genreRock": "रॉक",
"genreJazz": "Jazz", "genreJazz": "जैज़",
"genreClassical": "Classical", "genreClassical": "शास्त्रीय",
"genreElectronic": "Electronic", "genreElectronic": "इलेक्ट्रॉनिक",
"genreNews": "News", "genreNews": "समाचार",
"genreTalk": "Talk", "genreTalk": "वार्ता",
"genreHipHop": "Hip-hop", "genreHipHop": "हिप-हॉप",
"genreCountry": "Country", "genreCountry": "कंट्री",
"genreMetal": "Metal", "genreMetal": "मेटल",
"genreReggae": "Reggae", "genreReggae": "रेगे",
"genreLatin": "Latin", "genreLatin": "लैटिन",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "संगीतमय जागरण",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "रेडियो अलार्म, सुरक्षित ध्वनि, स्मार्ट छुट्टियाँ और अगली चाल हमेशा दिखाई देती है।",
"createAlarmAction": "Create alarm", "createAlarmAction": "अलार्म बनाएँ",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} अलार्म",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "अगली चाल के बिना सक्रिय अलार्म",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "कोई सक्रिय अलार्म नहीं",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "अगला अलार्म",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "{count} सक्रिय अलार्म हैं, लेकिन अभी उनके पास कोई वैध भविष्य तारीख नहीं है। तारीख, दिन और छुट्टियाँ जाँचें।",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "एक अलार्म बनाएँ और PluriWave अगली चाल अपने-आप गणना करेगा।",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "छुट्टियों में बजे",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "छुट्टियों में विराम",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "फेड-इन {seconds}से",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "अगली चाल: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "कोई सक्रिय अगली चाल नहीं है।",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "एक चाल छोड़ी गई: {date}",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "संपादित करें",
"skipNextAction": "Skip next", "skipNextAction": "अगला छोड़ें",
"deleteTooltip": "Delete", "deleteTooltip": "हटाएँ",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "अलार्म छोड़ा गया। कोई अगली चाल बाकी नहीं।",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "अलार्म छोड़ा गया। {date} को वापस आएगा।",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "छुट्टी ({vacationName}) के कारण विराम में है और कोई अगली चाल नहीं है।",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "छुट्टी ({vacationName}) के कारण विराम में है और {date} को लौटेगा।",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "छुट्टियाँ सक्रिय होने पर, {date} को फिर बजेगा।",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "संगीतमय अलार्म",
"newAlarmTitle": "New alarm", "newAlarmTitle": "नया अलार्म",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "अलार्म संपादित करें",
"nameField": "Name", "nameField": "नाम",
"timeField": "Time", "timeField": "समय",
"dateField": "Date", "dateField": "तारीख",
"onceOption": "Once", "onceOption": "एक बार",
"dailyOption": "Daily", "dailyOption": "दैनिक",
"weekdaysOption": "Weekdays", "weekdaysOption": "दिन",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "ध्वनि और वॉल्यूम",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "अलार्म फेड-इन",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 से (बिना बदलाव)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} से (5% से चुने हुए वॉल्यूम तक)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "सुरक्षित आंतरिक ध्वनि",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "गरम सूर्योदय",
"soundSoftBell": "Soft bell", "soundSoftBell": "मुलायम घंटी",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "डिजिटल धड़कन",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "पसंदीदा स्टेशन",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "कोई स्टेशन नहीं: आंतरिक ध्वनि इस्तेमाल करें",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "उन्हें संगीतमय अलार्म के रूप में इस्तेमाल करने के लिए स्टेशन पसंदीदा में सहेजें।",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "वर्तमान स्टेशन इस्तेमाल करें",
"playDuringVacations": "Play during vacations", "playDuringVacations": "छुट्टियों में बजाएँ",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "इसे बंद करने पर अगली चाल पहले वैध दिन पर चली जाएगी।",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "अलार्म सहेजें",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "सप्ताह का कम से कम एक दिन चुनें।",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Android विश्वसनीयता जाँचें",
"statusOk": "OK", "statusOk": "ठीक है",
"statusPending": "pending", "statusPending": "लंबित",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "विश्वसनीयता: सटीक {exact} · सूचनाएँ {notifications} · स्क्रीन {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "छुट्टी की अवधियाँ",
"addAction": "Add", "addAction": "जोड़ें",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "यदि किसी अलार्म में \"छुट्टियों में विराम\" है, तो ये अवधियाँ अपने-आप छोड़ी जाएँगी।",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "कोई अवधि लोड नहीं हुई।",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "अवधि हटाएँ",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "छुट्टियाँ",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "नई छुट्टी अवधि",
"startField": "Start", "startField": "शुरुआत",
"endField": "End", "endField": "समाप्ति",
"saveRangeAction": "Save range", "saveRangeAction": "अवधि सहेजें",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "अभी कोई अलार्म नहीं।",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "अपना संगीतमय जागरण बनाने के लिए एक बनाएँ।",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "सुरक्षित आंतरिक ध्वनि के साथ बज रहा है।",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "सुरक्षित आंतरिक ध्वनि तैयार हो रही है।",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "अलार्म रोकें",
"pauseAction": "विराम दें",
"miniPlayerOpenLabel": "{stationName} का प्लेयर खोलें",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "प्लेयर",
"playbackStatusConnecting": "कनेक्ट हो रहा है...",
"playbackStatusLive": "लाइव",
"playbackStatusPaused": "विराम पर",
"playbackStatusConnectionError": "कनेक्शन त्रुटि",
"playbackStatusStopped": "बंद",
"stationSemanticLabel": "स्टेशन {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "पसंदीदा में जोड़ें",
"favoritesAddedMessage": "{stationName} को पसंदीदा में जोड़ा गया",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "स्टेशन आइकन",
"liveNow": "अभी लाइव",
"equalizerBandLabel": "बैंड {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} डेसिबल",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "समतल",
"equalizerPresetRock": "रॉक",
"equalizerPresetPop": "पॉप",
"equalizerPresetBassBoost": "बास बढ़ाएँ",
"equalizerPresetJazz": "जैज़",
"equalizerPresetVoice": "आवाज़",
"equalizerPresetCustom": "कस्टम",
"onboardingTitle": "PluriWave में आपका स्वागत है",
"onboardingNewsTitle": "नया क्या है",
"onboardingStartAction": "शुरू करें",
"onboardingCloseTooltip": "बंद करें",
"radioRecordingError": "रेडियो रिकॉर्ड करते समय त्रुटि: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "रेडियो एपीआई से कनेक्शन नहीं है",
"radioSearchError": "खोज त्रुटि। अपना कनेक्शन जाँचें।",
"radioLoadMoreStationsError": "और स्टेशन लोड नहीं हो सके।",
"radioNearbyStationsError": "हम आस-पास के स्टेशन नहीं खोज सके। देश के फ़िल्टर इस्तेमाल करें।",
"radioCannotPlayStation": "\"{stationName}\" नहीं चलाया जा सकता",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "रिकॉर्ड करने से पहले कोई स्टेशन चुनें।",
"recordingStartError": "रिकॉर्डिंग शुरू नहीं हो सकी: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "कॉन्फ़िगरेशन संस्करण समर्थित नहीं है",
"audioErrorGeneric": "चलाने में त्रुटि",
"audioErrorNoInternet": "इंटरनेट कनेक्शन नहीं है",
"audioErrorInvalidUrl": "रेडियो का पता मान्य नहीं है",
"audioErrorNotFound": "रेडियो उपलब्ध नहीं है (404 त्रुटि)",
"audioErrorTimeout": "कनेक्शन का समय समाप्त हो गया",
"audioErrorCannotConnect": "रेडियो से कनेक्ट नहीं हो सकता",
"audioErrorUnsupportedFormat": "स्ट्रीम स्वरूप समर्थित नहीं है",
"audioErrorDecode": "ऑडियो स्ट्रीम डिकोड करने में त्रुटि",
"audioErrorCleartext": "यह रेडियो बिना एन्क्रिप्शन वाला HTTP इस्तेमाल करता है, जिसकी अनुमति नहीं है",
"audioErrorSsl": "रेडियो पर SSL प्रमाणपत्र अमान्य है",
"audioErrorCannotPlay": "यह रेडियो नहीं चलाया जा सकता",
"audioErrorUnexpectedPlayback": "चलाते समय अनपेक्षित त्रुटि",
"androidExactAlarmScheduleError": "ऐंड्रॉयड सटीक अलार्म निर्धारित नहीं कर सका। सटीक अलार्म की अनुमति जाँचें।",
"recordingPathEmptyError": "रिकॉर्डिंग पथ खाली नहीं हो सकता",
"recordingMaxSizeInvalidError": "अधिकतम आकार शून्य से बड़ा होना चाहिए",
"recordingAlreadyActiveError": "एक रिकॉर्डिंग पहले से चल रही है",
"alarmRingingFallbackActive": "आंतरिक सुरक्षित ऑडियो के साथ चल रहा है।",
"alarmRingingPreparingFallback": "आंतरिक सुरक्षित ऑडियो तैयार किया जा रहा है।",
"alarmRingingTryingStation": "आपका स्टेशन उपलब्ध सर्वोच्च गुणवत्ता में चलाने की कोशिश की जा रही है।",
"alarmScheduleOnce": "एक बार · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "दिन: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Android विश्वसनीयता जाँचें",
"closeAction": "बंद करें",
"customOption": "कस्टम",
"endLabel": "समाप्ति",
"equalizerDisable": "इक्वलाइज़र बंद करें",
"helpTitle": "मदद और ट्यूटोरियल",
"helpSubtitle": "PluriWave की सुविधाएँ, सुझाव और नया क्या है देखें।",
"indefiniteOption": "अनिश्चित",
"invalidNumber": "अमान्य संख्या",
"nameLabel": "नाम",
"notPlaying": "नहीं चल रहा",
"oneTimeOption": "एक बार",
"pausePlaybackTooltip": "प्लेबैक रोकें",
"qualityOriginal": "मूल गुणवत्ता: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "गुणवत्ता उपलब्ध नहीं",
"recordAction": "रिकॉर्ड करें",
"recordDurationTitle": "रिकॉर्डिंग अवधि",
"recordRadioSubtitle": "रिकॉर्डिंग की अवधि चुनें।",
"recordRadioTitle": "रेडियो रिकॉर्ड करें",
"recordingActiveTitle": "रेडियो रिकॉर्ड हो रहा है",
"recordingDirectTitle": "सीधी रिकॉर्डिंग",
"recordingsOpenFolderPlainError": "रिकॉर्डिंग फ़ोल्डर नहीं खुल सका",
"recordingsOpenLatest": "नई रिकॉर्डिंग खोलें",
"recordingsOpenLatestError": "नई रिकॉर्डिंग नहीं खुल सकी",
"startLabel": "शुरुआत",
"startPlaybackTooltip": "प्लेबैक शुरू करें",
"stopAction": "रोकें",
"stopPlaybackTooltip": "प्लेबैक रोकें",
"weekdayShortMonday": "सोम",
"weekdayShortTuesday": "मंगल",
"weekdayShortWednesday": "बुध",
"weekdayShortThursday": "गुरु",
"weekdayShortFriday": "शुक्र",
"weekdayShortSaturday": "शनि",
"weekdayShortSunday": "रवि"
} }
+373 -199
View File
@@ -6,28 +6,55 @@
"navFavorites": "Favorit", "navFavorites": "Favorit",
"navAlarms": "Alarm", "navAlarms": "Alarm",
"navSettings": "Pengaturan", "navSettings": "Pengaturan",
"actionOk": "OK", "actionOk": "Oke",
"sleepTimer": "Timer tidur", "sleepTimer": "Timer tidur",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "Mematikan radio secara lembut dengan hitung mundur yang tepat.",
"cancelTimer": "Cancel timer", "cancelTimer": "Batalkan timer",
"optionOther": "Other", "optionOther": "Lainnya",
"customDurationTitle": "Custom duration", "customDurationTitle": "Durasi khusus",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "Pilih durasi yang lebih besar dari nol.",
"hoursLabel": "Hours", "hoursLabel": "Jam",
"minutesLabel": "Minutes", "minutesLabel": "Menit",
"secondsLabel": "Seconds", "secondsLabel": "Detik",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} jam {minutes} mnt {seconds} dtk",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} mnt {seconds} dtk",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} mnt",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} dtk",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Simpan sebagai akses cepat",
"startTimer": "Mulai timer",
"skipCurrentAlarmExecution": "Eksekusi {alarmName} kali ini dilewati.",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Pengaturan", "settingsTitle": "Pengaturan",
"settingsSubtitle": "Kontrol suara, cadangan, dan stasiun khusus secara detail.", "settingsSubtitle": "Kontrol halus untuk suara, cadangan, dan stasiun khusus.",
"languageSectionTitle": "Bahasa", "languageSectionTitle": "Bahasa",
"languageSectionDescription": "Pilih bahasa tampilan aplikasi.", "languageSectionDescription": "Pilih bagaimana bahasa aplikasi ditampilkan.",
"languageSystemDefault": "Sistem", "languageSystemDefault": "Sistem",
"languageSpanish": "Spanyol", "languageSpanish": "Spanyol",
"languageEnglish": "Inggris", "languageEnglish": "Inggris",
@@ -38,70 +65,71 @@
} }
}, },
"languageUpdatedSystem": "Bahasa diperbarui: Sistem", "languageUpdatedSystem": "Bahasa diperbarui: Sistem",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "Timer tidur",
"timerSectionAdd": "Add", "timerSectionAdd": "Tambah",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "Sesuaikan pintasan cepat yang muncul saat radio dimatikan otomatis.",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "Pulihkan waktu yang disarankan",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "Akses cepat baru",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "Simpan akses cepat",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "Aman",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "Rekaman",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "Pilih folder rekaman",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "Jalur rekaman diperbarui",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "Tidak dapat menyimpan jalur: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "Folder internal bawaan akan digunakan",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "Folder rekaman",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "Menghitung jalur...",
"recordingsChangePath": "Change path", "recordingsChangePath": "Ubah jalur",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "Gunakan jalur bawaan",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "Radio disimpan dari stream asli, tanpa kompresi ulang.",
"equalizerActive": "Active", "equalizerActive": "Aktif",
"equalizerDisabled": "Disabled", "equalizerDisabled": "Nonaktif",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "Aktifkan equalizer",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "Perubahan diterapkan secara langsung ke stasiun saat ini.",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "Perubahan disimpan dan akan diterapkan saat Android mengaktifkan efek.",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "Gunakan EQ khusus untuk favorit ini",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "Aktif untuk {stationName}",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "Menggunakan EQ utama untuk {stationName}",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "Stasiun pilihan",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "Dipilih lebih dulu saat membuat alarm dan dapat dimulai sebagai pemutaran cepat.",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "Belum ada stasiun yang tersedia",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "Simpan favorit atau muat stasiun untuk memilih stasiun pilihan.",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "Cadangan otomatis",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "Favorit bawaan",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "Pilihan saat ini: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "Tidak ada favorit: otomatis menggunakan {stationName}",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "Putar pilihan",
"customStationsTitle": "Custom stations", "customStationsTitle": "Stasiun khusus",
"customStationsAdd": "Add", "customStationsAdd": "Tambah",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "Tidak ada stasiun khusus.",
"playAction": "Play", "playAction": "Putar",
"deleteAction": "Delete", "deleteAction": "Hapus",
"addStationTitle": "Add station", "addStationTitle": "Tambah stasiun",
"stationNameLabel": "Name *", "stationNameLabel": "Nama *",
"requiredField": "Required field", "unnamedStation": "Stasiun tanpa nama",
"streamUrlLabel": "Stream URL *", "requiredField": "Kolom wajib",
"invalidUrl": "Invalid URL", "streamUrlLabel": "URL stream *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "URL tidak valid",
"saveStation": "Save station", "countryOptionalLabel": "Negara (opsional)",
"backupSectionTitle": "Backup", "saveStation": "Simpan stasiun",
"backupExportTitle": "Export configuration", "backupSectionTitle": "Cadangan",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "Ekspor pengaturan",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "Favorit, stasiun khusus, dan preset EQ",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "Impor pengaturan",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "Pulihkan dari berkas cadangan",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — cadangan",
"backupExportError": "Export error: {error}", "backupShareText": "Pengaturan PluriWave diekspor pada {date}",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "Kesalahan saat mengekspor: {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "Ini akan menambahkan favorit, stasiun, dan preset dari berkas. Lanjutkan?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "Pengaturan berhasil diimpor",
"appVersionLoading": "Loading version...", "backupImportError": "Kesalahan saat mengimpor: {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "Memuat versi...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - Radio dunia",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "Favorit tersimpan",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "Filter stasiun",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "Hanya stasiun yang terverifikasi aktif",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "Audio latar belakang",
"backgroundAudioSubtitle": "Tetap berjalan saat layar dimatikan",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -150,13 +178,13 @@
}, },
"cancelAction": "Batal", "cancelAction": "Batal",
"equalizerTitle": "Equalizer", "equalizerTitle": "Equalizer",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "Buka folder",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "Tidak dapat membuka folder: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "Ukuran rekaman maksimum",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "Batas saat ini: {size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "Ukuran maksimum per rekaman",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "Megabyte maksimum",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "Batas rekaman diperbarui menjadi {size} MB",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "Urutan stasiun",
"stationOrderByName": "By name", "stationOrderByName": "Berdasarkan nama",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "Berdasarkan kualitas",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "Berlaku untuk favorit, pencarian, stasiun terdekat, dan daftar cepat.",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "Daftar favorit",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "Buat daftar pendek untuk mengatur stasiun tersimpan.",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "Tambah daftar",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "Edit daftar",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "Hapus daftar",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "Nama daftar",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "Maksimum 28 karakter.",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "Belum ditetapkan",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "Daftar bawaan: tidak dapat diedit atau dihapus.",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "Daftar dibuat",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "Daftar diperbarui",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "Daftar dihapus; stasiunnya kembali ke Belum ditetapkan.",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "Pindahkan ke daftar",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "Daftar saat ini: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} dipindahkan ke {groupName}",
"favoritesTitle": "Favorites", "favoritesTitle": "Favorit",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "Belum ada favorit",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "Ketuk hati di stasiun mana pun untuk menyimpannya ke koleksi Anda.",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "Atur koleksi Anda dengan daftar dan dekatkan radio penting.",
"favoritesCollection": "Collection", "favoritesCollection": "Koleksi",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} tersimpan",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "Hapus dari favorit",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} dihapus dari favorit",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,23 +254,23 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "Alarm ditunda untuk eksekusi ini.",
"searchScreenTitle": "Cari sinyal", "searchScreenTitle": "Cari sinyal",
"searchScreenSubtitle": "Temukan stasiun berdasarkan nama, negara, atau bahasa dengan filter cepat dan kontras tinggi.", "searchScreenSubtitle": "Temukan radio berdasarkan nama, negara, atau bahasa dengan filter cepat dan kontras tinggi.",
"searchFiltersLabel": "Filter", "searchFiltersLabel": "Filter",
"searchHint": "Radio Horizon, jazz, berita...", "searchHint": "Radio Horizonte, jazz, berita...",
"searchCountryFilterLabel": "Negara", "searchCountryFilterLabel": "Negara",
"searchLanguageFilterLabel": "Bahasa", "searchLanguageFilterLabel": "Bahasa",
"searchMinQualityFilterLabel": "Kualitas minimum", "searchMinQualityFilterLabel": "Kualitas minimum",
"searchEmptyTitle": "Cari stasiun", "searchEmptyTitle": "Cari stasiun",
"searchNoResultsTitle": "Tidak ada hasil", "searchNoResultsTitle": "Tidak ada hasil",
"searchEmptySubtitle": "Gunakan bilah atas atau chip untuk menemukan stasiun dari seluruh dunia.", "searchEmptySubtitle": "Gunakan bilah atas atau chip untuk menemukan sinyal dari seluruh dunia.",
"searchNoResultsSubtitle": "Coba hapus filter atau ketik nama lain untuk menemukan stasiun yang aktif.", "searchNoResultsSubtitle": "Coba hapus filter atau tulis nama lain untuk menemukan sinyal aktif.",
"countrySpain": "Spanyol", "countrySpain": "Spanyol",
"countryUsa": "Amerika Serikat", "countryUsa": "Amerika Serikat",
"countryMexico": "Meksiko", "countryMexico": "Meksiko",
"countryArgentina": "Argentina", "countryArgentina": "Argentina",
"countryUk": "Britania Raya", "countryUk": "Inggris Raya",
"countryFrance": "Prancis", "countryFrance": "Prancis",
"countryGermany": "Jerman", "countryGermany": "Jerman",
"countryItaly": "Italia", "countryItaly": "Italia",
@@ -257,9 +285,9 @@
"languageNameJapanese": "Jepang", "languageNameJapanese": "Jepang",
"languageNameArabic": "Arab", "languageNameArabic": "Arab",
"languageNameRussian": "Rusia", "languageNameRussian": "Rusia",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "Radio global langsung dengan sinyal bersih, favorit cerdas, dan pengalaman visual bergaya kuis.",
"exploreStations": "Explore stations", "exploreStations": "Jelajahi stasiun",
"stationsCount": "{count} stations", "stationsCount": "{count} radio",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "Kualitas HD",
"nearYou": "Near you", "nearYou": "Di dekat Anda",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "Di dekat Anda · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "Deteksi",
"liveRadar": "Live radar", "liveRadar": "Radar langsung",
"genresTitle": "Genres", "genresTitle": "Genre",
"retryAction": "Retry", "retryAction": "Coba lagi",
"noStationsAvailable": "No stations available", "noStationsAvailable": "Tidak ada stasiun tersedia",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "Coba segarkan atau pilih genre lain untuk menangkap sinyal kembali.",
"genrePop": "Pop", "genrePop": "Pop",
"genreRock": "Rock", "genreRock": "Rock",
"genreJazz": "Jazz", "genreJazz": "Jazz",
"genreClassical": "Classical", "genreClassical": "Klasik",
"genreElectronic": "Electronic", "genreElectronic": "Elektronik",
"genreNews": "News", "genreNews": "Berita",
"genreTalk": "Talk", "genreTalk": "Obrolan",
"genreHipHop": "Hip-hop", "genreHipHop": "Hip-hop",
"genreCountry": "Country", "genreCountry": "Country",
"genreMetal": "Metal", "genreMetal": "Metal",
"genreReggae": "Reggae", "genreReggae": "Reggae",
"genreLatin": "Latin", "genreLatin": "Latin",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "Bangun dengan musik",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "Alarm dengan radio, suara aman, liburan cerdas, dan eksekusi berikutnya selalu terlihat.",
"createAlarmAction": "Create alarm", "createAlarmAction": "Buat alarm",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} alarm",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "Alarm aktif tanpa eksekusi berikutnya",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "Tidak ada alarm aktif",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "Alarm berikutnya",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "Ada {count} alarm aktif, tetapi saat ini tidak memiliki tanggal valid di masa depan. Periksa tanggal, hari, dan liburan.",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "Buat alarm dan PluriWave akan menghitung eksekusi berikutnya secara otomatis.",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "Berbunyi saat liburan",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "Jeda saat liburan",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "Fade-in {seconds}d",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "Eksekusi berikutnya: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "Tidak memiliki eksekusi aktif berikutnya.",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "Satu eksekusi dilewati: {date}.",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "Edit",
"skipNextAction": "Skip next", "skipNextAction": "Lewati berikutnya",
"deleteTooltip": "Delete", "deleteTooltip": "Hapus",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "Alarm dilewati. Tidak ada eksekusi berikutnya.",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "Alarm dilewati. Akan kembali pada {date}.",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "Dijeda karena liburan ({vacationName}) dan tanpa eksekusi berikutnya.",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "Dijeda karena liburan ({vacationName}) dan akan kembali pada {date}.",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "Dengan liburan aktif, akan berbunyi lagi pada {date}.",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "Alarm musik",
"newAlarmTitle": "New alarm", "newAlarmTitle": "Alarm baru",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "Edit alarm",
"nameField": "Name", "nameField": "Nama",
"timeField": "Time", "timeField": "Waktu",
"dateField": "Date", "dateField": "Tanggal",
"onceOption": "Once", "onceOption": "Sekali",
"dailyOption": "Daily", "dailyOption": "Harian",
"weekdaysOption": "Weekdays", "weekdaysOption": "Hari",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "Suara dan volume",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "Fade-in alarm",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 d (tanpa transisi)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} d (dari 5% ke volume terpilih)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "Suara internal aman",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "Matahari terbit hangat",
"soundSoftBell": "Soft bell", "soundSoftBell": "Lonceng lembut",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "Denyut digital",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "Stasiun favorit",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "Tanpa stasiun: gunakan suara internal",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "Simpan stasiun ke Favorit untuk digunakan sebagai alarm musik.",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "Gunakan stasiun saat ini",
"playDuringVacations": "Play during vacations", "playDuringVacations": "Bunyi saat liburan",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "Jika dimatikan, eksekusi berikutnya akan melompat ke hari valid pertama.",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "Simpan alarm",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "Pilih setidaknya satu hari dalam seminggu.",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Tinjau keandalan Android",
"statusOk": "OK", "statusOk": "Oke",
"statusPending": "pending", "statusPending": "tertunda",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "Keandalan: tepat {exact} · notifikasi {notifications} · layar {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "Rentang liburan",
"addAction": "Add", "addAction": "Tambah",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "Jika sebuah alarm memiliki \"Jeda saat liburan\", rentang ini dilewati otomatis.",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "Tidak ada rentang dimuat.",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "Hapus rentang",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "Liburan",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "Rentang liburan baru",
"startField": "Start", "startField": "Mulai",
"endField": "End", "endField": "Akhir",
"saveRangeAction": "Save range", "saveRangeAction": "Simpan rentang",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "Belum ada alarm.",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "Buat satu untuk merancang bangun tidur musikal Anda.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "Berbunyi dengan audio internal aman.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "Menyiapkan audio internal aman.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "Hentikan alarm",
"pauseAction": "Jeda",
"miniPlayerOpenLabel": "Buka pemutar untuk {stationName}",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "Pemutar",
"playbackStatusConnecting": "Menghubungkan...",
"playbackStatusLive": "Siaran langsung",
"playbackStatusPaused": "Dijeda",
"playbackStatusConnectionError": "Kesalahan koneksi",
"playbackStatusStopped": "Dihentikan",
"stationSemanticLabel": "Stasiun {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "Tambahkan ke favorit",
"favoritesAddedMessage": "{stationName} ditambahkan ke favorit",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "Ikon stasiun",
"liveNow": "Sedang siaran langsung",
"equalizerBandLabel": "Pita {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} desibel",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "Datar",
"equalizerPresetRock": "Rock",
"equalizerPresetPop": "Pop",
"equalizerPresetBassBoost": "Penguat bass",
"equalizerPresetJazz": "Jazz",
"equalizerPresetVoice": "Suara",
"equalizerPresetCustom": "Kustom",
"onboardingTitle": "Selamat datang di PluriWave",
"onboardingNewsTitle": "Yang baru",
"onboardingStartAction": "Mulai",
"onboardingCloseTooltip": "Tutup",
"radioRecordingError": "Kesalahan saat merekam radio: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "Tidak ada koneksi ke antarmuka pemrograman aplikasi radio",
"radioSearchError": "Kesalahan pencarian. Periksa koneksi Anda.",
"radioLoadMoreStationsError": "Tidak dapat memuat lebih banyak stasiun.",
"radioNearbyStationsError": "Kami tidak dapat mendeteksi stasiun terdekat. Gunakan filter berdasarkan negara.",
"radioCannotPlayStation": "Tidak dapat memutar \"{stationName}\"",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "Pilih stasiun sebelum merekam.",
"recordingStartError": "Tidak dapat memulai rekaman: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "Versi konfigurasi tidak didukung",
"audioErrorGeneric": "Kesalahan pemutaran",
"audioErrorNoInternet": "Tidak ada koneksi internet",
"audioErrorInvalidUrl": "Alamat radio tidak valid",
"audioErrorNotFound": "Radio tidak tersedia (kesalahan 404)",
"audioErrorTimeout": "Waktu koneksi habis",
"audioErrorCannotConnect": "Tidak dapat terhubung ke radio",
"audioErrorUnsupportedFormat": "Format aliran tidak didukung",
"audioErrorDecode": "Kesalahan saat mendekode aliran audio",
"audioErrorCleartext": "Radio ini menggunakan HTTP tanpa enkripsi, dan itu tidak diizinkan",
"audioErrorSsl": "Sertifikat SSL radio tidak valid",
"audioErrorCannotPlay": "Radio ini tidak dapat diputar",
"audioErrorUnexpectedPlayback": "Kesalahan tak terduga saat memutar",
"androidExactAlarmScheduleError": "Android tidak dapat menjadwalkan alarm tepat. Periksa izin alarm tepat.",
"recordingPathEmptyError": "Jalur rekaman tidak boleh kosong",
"recordingMaxSizeInvalidError": "Ukuran maksimum harus lebih besar dari nol",
"recordingAlreadyActiveError": "Sudah ada rekaman yang sedang berlangsung",
"alarmRingingFallbackActive": "Memutar dengan audio internal yang aman.",
"alarmRingingPreparingFallback": "Menyiapkan audio internal yang aman.",
"alarmRingingTryingStation": "Mencoba memutar stasiun Anda dengan kualitas tertinggi yang tersedia.",
"alarmScheduleOnce": "Sekali · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "Hari: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Tinjau keandalan Android",
"closeAction": "Tutup",
"customOption": "Kustom",
"endLabel": "Selesai",
"equalizerDisable": "Nonaktifkan equalizer",
"helpTitle": "Bantuan dan tutorial",
"helpSubtitle": "Tinjau fitur, tips, dan hal baru di PluriWave.",
"indefiniteOption": "Tidak terbatas",
"invalidNumber": "Nomor tidak valid",
"nameLabel": "Nama",
"notPlaying": "Tidak memutar",
"oneTimeOption": "Sekali",
"pausePlaybackTooltip": "Jeda pemutaran",
"qualityOriginal": "Kualitas asli: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "Kualitas tidak dilaporkan",
"recordAction": "Rekam",
"recordDurationTitle": "Durasi rekaman",
"recordRadioSubtitle": "Pilih berapa lama ingin merekam.",
"recordRadioTitle": "Rekam radio",
"recordingActiveTitle": "Merekam radio",
"recordingDirectTitle": "Perekaman langsung",
"recordingsOpenFolderPlainError": "Tidak dapat membuka folder rekaman",
"recordingsOpenLatest": "Buka rekaman terbaru",
"recordingsOpenLatestError": "Tidak dapat membuka rekaman terbaru",
"startLabel": "Mulai",
"startPlaybackTooltip": "Mulai pemutaran",
"stopAction": "Stop",
"stopPlaybackTooltip": "Hentikan pemutaran",
"weekdayShortMonday": "Sen",
"weekdayShortTuesday": "Sel",
"weekdayShortWednesday": "Rab",
"weekdayShortThursday": "Kam",
"weekdayShortFriday": "Jum",
"weekdayShortSaturday": "Sab",
"weekdayShortSunday": "Min"
} }
+366 -192
View File
@@ -1,24 +1,51 @@
{ {
"@@locale": "it", "@@locale": "it",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "Inizio",
"navSearch": "Cerca", "navSearch": "Cerca",
"navFavorites": "Preferiti", "navFavorites": "Preferiti",
"navAlarms": "Sveglie", "navAlarms": "Sveglie",
"navSettings": "Impostazioni", "navSettings": "Impostazioni",
"actionOk": "OK", "actionOk": "OK",
"sleepTimer": "Timer sonno", "sleepTimer": "Timer sonno",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "Spegnimento graduale della radio con conto alla rovescia preciso.",
"cancelTimer": "Cancel timer", "cancelTimer": "Annulla timer",
"optionOther": "Other", "optionOther": "Altro",
"customDurationTitle": "Custom duration", "customDurationTitle": "Durata personalizzata",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "Scegli una durata maggiore di zero.",
"hoursLabel": "Hours", "hoursLabel": "Ore",
"minutesLabel": "Minutes", "minutesLabel": "Minuti",
"secondsLabel": "Seconds", "secondsLabel": "Secondi",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} h {minutes} min {seconds} s",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} min {seconds} s",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} min",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} s",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Salva come accesso rapido",
"startTimer": "Avvia timer",
"skipCurrentAlarmExecution": "Questa esecuzione di {alarmName} è stata saltata.",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
@@ -27,7 +54,7 @@
"settingsTitle": "Impostazioni", "settingsTitle": "Impostazioni",
"settingsSubtitle": "Controllo fine del suono, backup e stazioni personalizzate.", "settingsSubtitle": "Controllo fine del suono, backup e stazioni personalizzate.",
"languageSectionTitle": "Lingua", "languageSectionTitle": "Lingua",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "Scegli come visualizzare la lingua dell'app.",
"languageSystemDefault": "Sistema", "languageSystemDefault": "Sistema",
"languageSpanish": "Spagnolo", "languageSpanish": "Spagnolo",
"languageEnglish": "Inglese", "languageEnglish": "Inglese",
@@ -38,70 +65,71 @@
} }
}, },
"languageUpdatedSystem": "Lingua aggiornata: Sistema", "languageUpdatedSystem": "Lingua aggiornata: Sistema",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "Timer sonno",
"timerSectionAdd": "Add", "timerSectionAdd": "Aggiungi",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "Personalizza gli accessi rapidi mostrati quando la radio si spegne automaticamente.",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "Ripristina tempi consigliati",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "Nuovo accesso rapido",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "Salva accesso rapido",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "Sicuro",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "Registrazioni",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "Seleziona la cartella delle registrazioni",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "Percorso di registrazione aggiornato",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "Impossibile salvare il percorso: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "Verrà usata la cartella interna predefinita",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "Cartella di registrazione",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "Calcolo percorso...",
"recordingsChangePath": "Change path", "recordingsChangePath": "Cambia percorso",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "Usa percorso predefinito",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "La radio viene salvata dallo stream originale, senza ricompressione.",
"equalizerActive": "Active", "equalizerActive": "Attivo",
"equalizerDisabled": "Disabled", "equalizerDisabled": "Disattivato",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "Attiva equalizzatore",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "Le modifiche vengono applicate in tempo reale all'emittente attuale.",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "Le modifiche vengono salvate e saranno applicate quando Android abiliterà l'effetto.",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "Usa EQ proprio per questo preferito",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "Attivo per {stationName}",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "EQ principale in uso per {stationName}",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "Emittente preferita",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "Preselezionata quando crei sveglie e disponibile per la riproduzione rapida.",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "Non ci sono ancora emittenti disponibili",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "Salva preferiti o carica emittenti per sceglierne una preferita.",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "Fallback automatico",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "Preferita predefinita",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "Preferita attuale: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "Nessun preferito: uso automatico di {stationName}",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "Riproduci preferita",
"customStationsTitle": "Custom stations", "customStationsTitle": "Emittenti personalizzate",
"customStationsAdd": "Add", "customStationsAdd": "Aggiungi",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "Nessuna emittente personalizzata.",
"playAction": "Play", "playAction": "Riproduci",
"deleteAction": "Delete", "deleteAction": "Elimina",
"addStationTitle": "Add station", "addStationTitle": "Aggiungi emittente",
"stationNameLabel": "Name *", "stationNameLabel": "Nome *",
"requiredField": "Required field", "unnamedStation": "Stazione senza nome",
"streamUrlLabel": "Stream URL *", "requiredField": "Campo obbligatorio",
"invalidUrl": "Invalid URL", "streamUrlLabel": "URL dello stream *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "URL non valido",
"saveStation": "Save station", "countryOptionalLabel": "Paese (opzionale)",
"saveStation": "Salva emittente",
"backupSectionTitle": "Backup", "backupSectionTitle": "Backup",
"backupExportTitle": "Export configuration", "backupExportTitle": "Esporta configurazione",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportSubtitle": "Preferiti, emittenti personalizzate e preset EQ",
"backupImportTitle": "Import configuration", "backupImportTitle": "Importa configurazione",
"backupImportSubtitle": "Restore from a backup file", "backupImportSubtitle": "Ripristina da un file di backup",
"backupShareSubject": "PluriWave — backup", "backupShareSubject": "PluriWave — backup",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareText": "Configurazione di PluriWave esportata il {date}",
"backupExportError": "Export error: {error}", "backupExportError": "Errore durante l'esportazione: {error}",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupImportConfirmMessage": "Questo aggiungerà preferiti, emittenti e preset dal file. Continuare?",
"backupImportSuccess": "Configuration imported successfully", "backupImportSuccess": "Configurazione importata correttamente",
"backupImportError": "Import error: {error}", "backupImportError": "Errore durante l'importazione: {error}",
"appVersionLoading": "Loading version...", "appVersionLoading": "Caricamento versione...",
"appVersionSubtitle": "{version} - World radio", "appVersionSubtitle": "{version} - Radio mondiale",
"savedFavoritesTitle": "Saved favorites", "savedFavoritesTitle": "Preferiti salvati",
"stationFilterTitle": "Station filter", "stationFilterTitle": "Filtro emittenti",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterSubtitle": "Solo emittenti verificate come attive",
"backgroundAudioTitle": "Background audio", "backgroundAudioTitle": "Audio in background",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioSubtitle": "Continua quando lo schermo si spegne",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -149,14 +177,14 @@
} }
}, },
"cancelAction": "Annulla", "cancelAction": "Annulla",
"equalizerTitle": "Equalizer", "equalizerTitle": "Equalizzatore",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "Apri cartella",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "Impossibile aprire la cartella: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "Dimensione massima registrazione",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "Limite attuale: {size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "Dimensione massima per registrazione",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "Megabyte massimi",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "Limite di registrazione aggiornato a {size} MB",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "Ordine emittenti",
"stationOrderByName": "By name", "stationOrderByName": "Per nome",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "Per qualità",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "Si applica a preferiti, ricerche, emittenti vicine ed elenchi rapidi.",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "Liste preferiti",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "Crea liste brevi per organizzare le emittenti salvate.",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "Aggiungi lista",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "Modifica lista",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "Elimina lista",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "Nome della lista",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "Massimo 28 caratteri.",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "Non assegnate",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "Lista predefinita: non può essere modificata né eliminata.",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "Lista creata",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "Lista aggiornata",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "Lista eliminata; le sue emittenti tornano a Non assegnate.",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "Sposta in lista",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "Lista attuale: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} spostata in {groupName}",
"favoritesTitle": "Favorites", "favoritesTitle": "Preferiti",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "Ancora nessun preferito",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "Tocca il cuore su qualsiasi emittente per salvarla nella tua raccolta.",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "Organizza la raccolta in liste e tieni vicine le radio importanti.",
"favoritesCollection": "Collection", "favoritesCollection": "Raccolta",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} salvate",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "Rimuovi dai preferiti",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} rimossa dai preferiti",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,7 +254,7 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "Sveglia posticipata per questa esecuzione.",
"searchScreenTitle": "Cerca segnale", "searchScreenTitle": "Cerca segnale",
"searchScreenSubtitle": "Trova emittenti per nome, Paese o lingua con filtri rapidi e contrasto elevato.", "searchScreenSubtitle": "Trova emittenti per nome, Paese o lingua con filtri rapidi e contrasto elevato.",
"searchFiltersLabel": "Filtri", "searchFiltersLabel": "Filtri",
@@ -257,9 +285,9 @@
"languageNameJapanese": "giapponese", "languageNameJapanese": "giapponese",
"languageNameArabic": "arabo", "languageNameArabic": "arabo",
"languageNameRussian": "russo", "languageNameRussian": "russo",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "Radio globale in diretta con segnali puliti, preferiti intelligenti e un'esperienza visiva da quiz show.",
"exploreStations": "Explore stations", "exploreStations": "Esplora emittenti",
"stationsCount": "{count} stations", "stationsCount": "{count} radio",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "Qualità HD",
"nearYou": "Near you", "nearYou": "Vicino a te",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "Vicino a te · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "Rileva",
"liveRadar": "Live radar", "liveRadar": "Radar live",
"genresTitle": "Genres", "genresTitle": "Generi",
"retryAction": "Retry", "retryAction": "Riprova",
"noStationsAvailable": "No stations available", "noStationsAvailable": "Nessuna emittente disponibile",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "Prova ad aggiornare o a scegliere un altro genere per captare di nuovo un segnale.",
"genrePop": "Pop", "genrePop": "Pop",
"genreRock": "Rock", "genreRock": "Rock",
"genreJazz": "Jazz", "genreJazz": "Jazz",
"genreClassical": "Classical", "genreClassical": "Classica",
"genreElectronic": "Electronic", "genreElectronic": "Elettronica",
"genreNews": "News", "genreNews": "Notizie",
"genreTalk": "Talk", "genreTalk": "Talk",
"genreHipHop": "Hip-hop", "genreHipHop": "Hip-hop",
"genreCountry": "Country", "genreCountry": "Country",
"genreMetal": "Metal", "genreMetal": "Metal",
"genreReggae": "Reggae", "genreReggae": "Reggae",
"genreLatin": "Latin", "genreLatin": "Latina",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "Risveglio musicale",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "Sveglie con radio, suono sicuro, vacanze intelligenti e prossima esecuzione sempre visibile.",
"createAlarmAction": "Create alarm", "createAlarmAction": "Crea sveglia",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} sveglie",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "Sveglie attive senza prossima esecuzione",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "Nessuna sveglia attiva",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "Prossima sveglia",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "Ci sono {count} sveglia/e attive, ma al momento non hanno una data futura valida. Controlla data, giorni e vacanze.",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,9 +343,9 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "Crea una sveglia e PluriWave calcolerà automaticamente la prossima esecuzione.",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "Suona durante le vacanze",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "Pausa durante le vacanze",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "Fade-in {seconds}s",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "Prossima esecuzione: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "Non ha una prossima esecuzione attiva.",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "Un'esecuzione è stata saltata: {date}.",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "Modifica",
"skipNextAction": "Skip next", "skipNextAction": "Salta prossima",
"deleteTooltip": "Delete", "deleteTooltip": "Elimina",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "Sveglia saltata. Non resta alcuna prossima esecuzione.",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "Sveglia saltata. Tornerà il {date}.",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "In pausa per vacanze ({vacationName}) e senza prossima esecuzione.",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "In pausa per vacanze ({vacationName}) e torna il {date}.",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "Con le vacanze attive, suonerà di nuovo il {date}.",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "Sveglia musicale",
"newAlarmTitle": "New alarm", "newAlarmTitle": "Nuova sveglia",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "Modifica sveglia",
"nameField": "Name", "nameField": "Nome",
"timeField": "Time", "timeField": "Ora",
"dateField": "Date", "dateField": "Data",
"onceOption": "Once", "onceOption": "Una volta",
"dailyOption": "Daily", "dailyOption": "Giornaliera",
"weekdaysOption": "Weekdays", "weekdaysOption": "Giorni",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "Suono e volume",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "Fade-in sveglia",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 s (senza transizione)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} s (dal 5% al volume scelto)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "Suono sicuro interno",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "Alba calda",
"soundSoftBell": "Soft bell", "soundSoftBell": "Campana dolce",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "Impulso digitale",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "Emittente preferita",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "Nessuna emittente: usa suono interno",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "Salva emittenti nei Preferiti per usarle come sveglia musicale.",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "Usa emittente attuale",
"playDuringVacations": "Play during vacations", "playDuringVacations": "Suona durante le vacanze",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "Se lo disattivi, la prossima esecuzione passerà al primo giorno valido.",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "Salva sveglia",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "Scegli almeno un giorno della settimana.",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Controlla affidabilità Android",
"statusOk": "OK", "statusOk": "OK",
"statusPending": "pending", "statusPending": "in sospeso",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "Affidabilità: esatte {exact} · notifiche {notifications} · schermo {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "Periodi di vacanza",
"addAction": "Add", "addAction": "Aggiungi",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "Se una sveglia ha \"Pausa durante le vacanze\", questi periodi vengono saltati automaticamente.",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "Nessun periodo caricato.",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "Elimina periodo",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "Vacanze",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "Nuovo periodo di vacanza",
"startField": "Start", "startField": "Inizio",
"endField": "End", "endField": "Fine",
"saveRangeAction": "Save range", "saveRangeAction": "Salva periodo",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "Non ci sono ancora sveglie.",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "Creane una per progettare il tuo risveglio musicale.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "Suono sicuro interno in riproduzione.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "Preparazione del suono sicuro interno.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "Ferma sveglia",
"pauseAction": "Pausa",
"miniPlayerOpenLabel": "Apri il lettore per {stationName}",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "Lettore",
"playbackStatusConnecting": "Connessione...",
"playbackStatusLive": "In diretta",
"playbackStatusPaused": "In pausa",
"playbackStatusConnectionError": "Errore di connessione",
"playbackStatusStopped": "Interrotto",
"stationSemanticLabel": "Stazione {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "Aggiungi ai preferiti",
"favoritesAddedMessage": "{stationName} aggiunta ai preferiti",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "Icona della stazione",
"liveNow": "In diretta",
"equalizerBandLabel": "Banda {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} decibel",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "Piatto",
"equalizerPresetRock": "Rock",
"equalizerPresetPop": "Pop",
"equalizerPresetBassBoost": "Potenziamento bassi",
"equalizerPresetJazz": "Jazz",
"equalizerPresetVoice": "Voce",
"equalizerPresetCustom": "Personalizzato",
"onboardingTitle": "Benvenuto in PluriWave",
"onboardingNewsTitle": "Novità",
"onboardingStartAction": "Inizia",
"onboardingCloseTooltip": "Chiudi",
"radioRecordingError": "Errore durante la registrazione della radio: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "Nessuna connessione all'API radio",
"radioSearchError": "Errore di ricerca. Controlla la connessione.",
"radioLoadMoreStationsError": "Impossibile caricare altre stazioni.",
"radioNearbyStationsError": "Non abbiamo potuto rilevare stazioni vicine. Usa i filtri per paese.",
"radioCannotPlayStation": "Impossibile riprodurre \"{stationName}\"",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "Seleziona prima una stazione da registrare.",
"recordingStartError": "Impossibile avviare la registrazione: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "Versione di configurazione non supportata",
"audioErrorGeneric": "Errore di riproduzione",
"audioErrorNoInternet": "Nessuna connessione a Internet",
"audioErrorInvalidUrl": "L'URL della radio non è valido",
"audioErrorNotFound": "La radio non è disponibile (errore 404)",
"audioErrorTimeout": "Tempo di connessione scaduto",
"audioErrorCannotConnect": "Impossibile connettersi alla radio",
"audioErrorUnsupportedFormat": "Formato stream non supportato",
"audioErrorDecode": "Errore durante la decodifica dello stream audio",
"audioErrorCleartext": "Questa radio usa HTTP non cifrato, non consentito",
"audioErrorSsl": "Certificato SSL non valido per la radio",
"audioErrorCannotPlay": "Questa radio non può essere riprodotta",
"audioErrorUnexpectedPlayback": "Errore di riproduzione imprevisto",
"androidExactAlarmScheduleError": "Android non ha potuto programmare una sveglia esatta. Controlla l'autorizzazione per le sveglie esatte.",
"recordingPathEmptyError": "Il percorso di registrazione non può essere vuoto",
"recordingMaxSizeInvalidError": "La dimensione massima deve essere maggiore di zero",
"recordingAlreadyActiveError": "È già in corso una registrazione",
"alarmRingingFallbackActive": "Riproduzione con audio interno sicuro.",
"alarmRingingPreparingFallback": "Preparazione dellaudio interno sicuro.",
"alarmRingingTryingStation": "Tentativo di riprodurre la tua stazione con la massima qualità disponibile.",
"alarmScheduleOnce": "Una volta · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "Giorni: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Controlla affidabilità Android",
"closeAction": "Chiudi",
"customOption": "Personalizzata",
"endLabel": "Fine",
"equalizerDisable": "Disattiva equalizzatore",
"helpTitle": "Aiuto e tutorial",
"helpSubtitle": "Rivedi funzioni, consigli e novità di PluriWave.",
"indefiniteOption": "Indefinita",
"invalidNumber": "Numero non valido",
"nameLabel": "Nome",
"notPlaying": "Non in riproduzione",
"oneTimeOption": "Una volta",
"pausePlaybackTooltip": "Pausa riproduzione",
"qualityOriginal": "Qualità originale: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "Qualità non indicata",
"recordAction": "Registra",
"recordDurationTitle": "Durata registrazione",
"recordRadioSubtitle": "Scegli per quanto tempo registrare.",
"recordRadioTitle": "Registra radio",
"recordingActiveTitle": "Registrazione radio",
"recordingDirectTitle": "Registrazione diretta",
"recordingsOpenFolderPlainError": "Impossibile aprire la cartella delle registrazioni",
"recordingsOpenLatest": "Apri ultima registrazione",
"recordingsOpenLatestError": "Impossibile aprire lultima registrazione",
"startLabel": "Inizio",
"startPlaybackTooltip": "Avvia riproduzione",
"stopAction": "Ferma",
"stopPlaybackTooltip": "Ferma riproduzione",
"weekdayShortMonday": "Lun",
"weekdayShortTuesday": "Mar",
"weekdayShortWednesday": "Mer",
"weekdayShortThursday": "Gio",
"weekdayShortFriday": "Ven",
"weekdayShortSaturday": "Sab",
"weekdayShortSunday": "Dom"
} }
+402 -228
View File
@@ -1,107 +1,135 @@
{ {
"@@locale": "ja", "@@locale": "ja",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "ホーム",
"navSearch": "Search", "navSearch": "検索",
"navFavorites": "Favorites", "navFavorites": "お気に入り",
"navAlarms": "Alarms", "navAlarms": "アラーム",
"navSettings": "Settings", "navSettings": "設定",
"actionOk": "OK", "actionOk": "了解",
"sleepTimer": "Sleep timer", "sleepTimer": "スリープタイマー",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "正確なカウントダウンでラジオをなめらかに停止します。",
"cancelTimer": "Cancel timer", "cancelTimer": "タイマーをキャンセル",
"optionOther": "Other", "optionOther": "その他",
"customDurationTitle": "Custom duration", "customDurationTitle": "カスタム時間",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "0 より大きい時間を選択してください。",
"hoursLabel": "Hours", "hoursLabel": "時間",
"minutesLabel": "Minutes", "minutesLabel": "",
"secondsLabel": "Seconds", "secondsLabel": "",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours}?? {minutes}? {seconds}?",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes}? {seconds}?",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes}?",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds}?",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "クイックアクセスとして保存",
"startTimer": "タイマーを開始",
"skipCurrentAlarmExecution": "{alarmName} の今回の実行をスキップしました。",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "設定",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "音質、バックアップ、カスタム局を細かく管理します。",
"languageSectionTitle": "Language", "languageSectionTitle": "言語",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "アプリの言語表示を選択します。",
"languageSystemDefault": "System", "languageSystemDefault": "システム",
"languageSpanish": "Spanish", "languageSpanish": "スペイン語",
"languageEnglish": "English", "languageEnglish": "英語",
"languageUpdated": "Language updated: {languageName}", "languageUpdated": "言語を更新しました: {languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
"languageName": {} "languageName": {}
} }
}, },
"languageUpdatedSystem": "Language updated: System", "languageUpdatedSystem": "言語を更新しました: システム",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "スリープタイマー",
"timerSectionAdd": "Add", "timerSectionAdd": "追加",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "ラジオを自動停止するときに表示されるクイックプリセットをカスタマイズします。",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "おすすめ時間を復元",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "新しいクイックアクセス",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "クイックアクセスを保存",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "安全",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "録音",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "録音フォルダーを選択",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "録音パスを更新しました",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "パスを保存できませんでした: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "内部の既定フォルダーを使用します",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "録音フォルダー",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "パスを計算中...",
"recordingsChangePath": "Change path", "recordingsChangePath": "パスを変更",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "既定のパスを使用",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "ラジオは元のストリームから、再圧縮せずに保存されます。",
"equalizerActive": "Active", "equalizerActive": "有効",
"equalizerDisabled": "Disabled", "equalizerDisabled": "無効",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "イコライザーを有効化",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "変更は現在の局にリアルタイムで適用されます。",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "変更は保存され、Android が効果を有効化したときに適用されます。",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "このお気に入りに専用EQを使用",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "{stationName} で有効",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "{stationName} でメインEQを使用中",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "優先局",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "アラーム作成時に事前選択され、クイック再生でも開始できます。",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "まだ利用できる局がありません",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "優先局を選ぶには、お気に入りを保存するか局を読み込んでください。",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "自動フォールバック",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "既定のお気に入り",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "現在の優先局: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "お気に入りなし: {stationName} を自動使用中",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "優先局を再生",
"customStationsTitle": "Custom stations", "customStationsTitle": "カスタム局",
"customStationsAdd": "Add", "customStationsAdd": "追加",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "カスタム局はありません。",
"playAction": "Play", "playAction": "再生",
"deleteAction": "Delete", "deleteAction": "削除",
"addStationTitle": "Add station", "addStationTitle": "局を追加",
"stationNameLabel": "Name *", "stationNameLabel": "名前 *",
"requiredField": "Required field", "unnamedStation": "無名の放送局",
"streamUrlLabel": "Stream URL *", "requiredField": "必須項目",
"invalidUrl": "Invalid URL", "streamUrlLabel": "ストリームURL *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "無効なURL",
"saveStation": "Save station", "countryOptionalLabel": "国(任意)",
"backupSectionTitle": "Backup", "saveStation": "局を保存",
"backupExportTitle": "Export configuration", "backupSectionTitle": "バックアップ",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "設定をエクスポート",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "お気に入り、カスタム局、EQプリセット",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "設定をインポート",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "バックアップファイルから復元",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — バックアップ",
"backupExportError": "Export error: {error}", "backupShareText": "{date} にエクスポートされた PluriWave 設定",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "エクスポート中にエラー: {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "ファイル内のお気に入り、局、プリセットを追加します。続行しますか?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "設定を正常にインポートしました",
"appVersionLoading": "Loading version...", "backupImportError": "インポート中にエラー: {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "バージョンを読み込み中...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - 世界のラジオ",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "保存済みのお気に入り",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "局フィルター",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "有効確認済みの局のみ",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "バックグラウンド音声",
"backgroundAudioSubtitle": "画面を消しても継続します",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -148,15 +176,15 @@
"version": {} "version": {}
} }
}, },
"cancelAction": "Cancel", "cancelAction": "キャンセル",
"equalizerTitle": "Equalizer", "equalizerTitle": "イコライザー",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "フォルダーを開く",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "フォルダーを開けませんでした: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "録音の最大サイズ",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "現在の上限: {size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "録音ごとの最大サイズ",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "最大メガバイト",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "録音上限を {size} MB に更新しました",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "局の並び順",
"stationOrderByName": "By name", "stationOrderByName": "名前順",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "品質順",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "お気に入り、検索、近くの局、クイック一覧に適用されます。",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "お気に入りリスト",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "保存した局を整理する短いリストを作成します。",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "リストを追加",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "リストを編集",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "リストを削除",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "リスト名",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "最大28文字です。",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "未割り当て",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "既定のリスト: 編集または削除できません。",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "リストを作成しました",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "リストを更新しました",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "リストを削除しました。局は未割り当てに戻りました。",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "リストへ移動",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "現在のリスト: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} {groupName} に移動しました",
"favoritesTitle": "Favorites", "favoritesTitle": "お気に入り",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "まだお気に入りはありません",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "任意の局でハートをタップしてコレクションに保存します。",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "コレクションをリストで整理し、大事なラジオを近くに置きましょう。",
"favoritesCollection": "Collection", "favoritesCollection": "コレクション",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} 件保存済み",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "お気に入りから削除",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} をお気に入りから削除しました",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,23 +254,23 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "この実行のアラームを延期しました。",
"searchScreenTitle": "放送局を探す", "searchScreenTitle": "電波を探す",
"searchScreenSubtitle": "名前・国・言語から、すばやい絞り込みと高コントラスト表示で放送局を見つけましょう。", "searchScreenSubtitle": "名前、国、言語で、すばやいフィルターと高コントラスト表示からラジオを見つけま。",
"searchFiltersLabel": "絞り込み", "searchFiltersLabel": "フィルター",
"searchHint": "Radio Horizon、ジャズ、ニュース...", "searchHint": "ラジオ・オリゾンテ、ジャズ、ニュース...",
"searchCountryFilterLabel": "国", "searchCountryFilterLabel": "国",
"searchLanguageFilterLabel": "言語", "searchLanguageFilterLabel": "言語",
"searchMinQualityFilterLabel": "最低品質", "searchMinQualityFilterLabel": "最低品質",
"searchEmptyTitle": "放送局を検索", "searchEmptyTitle": "局を検索",
"searchNoResultsTitle": "結果がありません", "searchNoResultsTitle": "結果がありません",
"searchEmptySubtitle": "上部バーやチップを使って、世界中の放送局を見つけましょう。", "searchEmptySubtitle": "上部バーやチップを使って、世界中の電波を見つけましょう。",
"searchNoResultsSubtitle": "フィルターを減らすか別の名前入力して、配信中の放送局を探してみましょう。", "searchNoResultsSubtitle": "有効な電波を見つけるには、フィルターをすか別の名前入力してください。",
"countrySpain": "スペイン", "countrySpain": "スペイン",
"countryUsa": "アメリカ", "countryUsa": "米国",
"countryMexico": "メキシコ", "countryMexico": "メキシコ",
"countryArgentina": "アルゼンチン", "countryArgentina": "アルゼンチン",
"countryUk": "イギリス", "countryUk": "英国",
"countryFrance": "フランス", "countryFrance": "フランス",
"countryGermany": "ドイツ", "countryGermany": "ドイツ",
"countryItaly": "イタリア", "countryItaly": "イタリア",
@@ -257,9 +285,9 @@
"languageNameJapanese": "日本語", "languageNameJapanese": "日本語",
"languageNameArabic": "アラビア語", "languageNameArabic": "アラビア語",
"languageNameRussian": "ロシア語", "languageNameRussian": "ロシア語",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "クリアな電波、スマートなお気に入り、クイズ番組風のビジュアル体験を備えたライブ世界ラジオ。",
"exploreStations": "Explore stations", "exploreStations": "局を探す",
"stationsCount": "{count} stations", "stationsCount": "{count} ",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "HD品質",
"nearYou": "Near you", "nearYou": "近く",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "近く · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "検出",
"liveRadar": "Live radar", "liveRadar": "ライブレーダー",
"genresTitle": "Genres", "genresTitle": "ジャンル",
"retryAction": "Retry", "retryAction": "再試行",
"noStationsAvailable": "No stations available", "noStationsAvailable": "利用できる局がありません",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "再読み込みするか別のジャンルを選んで、もう一度電波をつかまえてください。",
"genrePop": "Pop", "genrePop": "ポップ",
"genreRock": "Rock", "genreRock": "ロック",
"genreJazz": "Jazz", "genreJazz": "ジャズ",
"genreClassical": "Classical", "genreClassical": "クラシック",
"genreElectronic": "Electronic", "genreElectronic": "電子音楽",
"genreNews": "News", "genreNews": "ニュース",
"genreTalk": "Talk", "genreTalk": "トーク",
"genreHipHop": "Hip-hop", "genreHipHop": "ヒップホップ",
"genreCountry": "Country", "genreCountry": "カントリー",
"genreMetal": "Metal", "genreMetal": "メタル",
"genreReggae": "Reggae", "genreReggae": "レゲエ",
"genreLatin": "Latin", "genreLatin": "ラテン",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "音楽で目覚める",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "ラジオアラーム、安全な音、スマート休暇、次回実行を常に表示します。",
"createAlarmAction": "Create alarm", "createAlarmAction": "アラームを作成",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} 件のアラーム",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "次回実行がない有効なアラーム",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "有効なアラームはありません",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "次のアラーム",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "{count} 件の有効なアラームがありますが、現在は有効な未来の日付がありません。日付、曜日、休暇を確認してください。",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "アラームを作成すると、PluriWave が次回実行を自動計算します。",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "休暇中も鳴らす",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "休暇中は一時停止",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "フェードイン {seconds}",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "次回実行: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "有効な次回実行はありません。",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "1 回の実行をスキップしました: {date}",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "編集",
"skipNextAction": "Skip next", "skipNextAction": "次回をスキップ",
"deleteTooltip": "Delete", "deleteTooltip": "削除",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "アラームをスキップしました。次回実行は残っていません。",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "アラームをスキップしました。{date} に戻ります。",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "休暇({vacationName})で一時停止中、次回実行はありません。",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "休暇({vacationName})で一時停止中、{date} に戻ります。",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "休暇が有効なため、{date} に再び鳴ります。",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "音楽アラーム",
"newAlarmTitle": "New alarm", "newAlarmTitle": "新しいアラーム",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "アラームを編集",
"nameField": "Name", "nameField": "名前",
"timeField": "Time", "timeField": "時刻",
"dateField": "Date", "dateField": "日付",
"onceOption": "Once", "onceOption": "1回",
"dailyOption": "Daily", "dailyOption": "毎日",
"weekdaysOption": "Weekdays", "weekdaysOption": "曜日",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "音と音量",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "アラームのフェードイン",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 秒(切り替えなし)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} 秒(5% から選択音量まで)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "安全な内部音",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "暖かな日の出",
"soundSoftBell": "Soft bell", "soundSoftBell": "やさしいベル",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "デジタルパルス",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "お気に入り局",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "局なし: 内部音を使用",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "音楽アラームとして使うには、局をお気に入りに保存してください。",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "現在の局を使用",
"playDuringVacations": "Play during vacations", "playDuringVacations": "休暇中も鳴らす",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "オフにすると、次回実行は最初の有効日にスキップされます。",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "アラームを保存",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "少なくとも曜日を1つ選択してください。",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Android の信頼性を確認",
"statusOk": "OK", "statusOk": "良好",
"statusPending": "pending", "statusPending": "保留中",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "信頼性: 正確 {exact} · 通知 {notifications} · 画面 {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "休暇期間",
"addAction": "Add", "addAction": "追加",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "アラームが「休暇中は一時停止」の場合、これらの期間は自動的にスキップされます。",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "読み込まれた期間はありません。",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "期間を削除",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "休暇",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "新しい休暇期間",
"startField": "Start", "startField": "開始",
"endField": "End", "endField": "終了",
"saveRangeAction": "Save range", "saveRangeAction": "期間を保存",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "まだアラームはありません。",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "音楽で目覚める体験を作るために、アラームを作成しましょう。",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "安全な内部音で鳴っています。",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "安全な内部音を準備中です。",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "アラームを停止",
"pauseAction": "一時停止",
"miniPlayerOpenLabel": "{stationName}のプレーヤーを開く",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "プレーヤー",
"playbackStatusConnecting": "接続中...",
"playbackStatusLive": "ライブ",
"playbackStatusPaused": "一時停止中",
"playbackStatusConnectionError": "接続エラー",
"playbackStatusStopped": "停止中",
"stationSemanticLabel": "ラジオ局 {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "お気に入りに追加",
"favoritesAddedMessage": "{stationName}をお気に入りに追加しました",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "ラジオ局アイコン",
"liveNow": "ライブ",
"equalizerBandLabel": "{band}バンド",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} デシベル",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "フラット",
"equalizerPresetRock": "ロック",
"equalizerPresetPop": "ポップ",
"equalizerPresetBassBoost": "低音ブースト",
"equalizerPresetJazz": "ジャズ",
"equalizerPresetVoice": "音声",
"equalizerPresetCustom": "カスタム",
"onboardingTitle": "PluriWaveへようこそ",
"onboardingNewsTitle": "新機能",
"onboardingStartAction": "始める",
"onboardingCloseTooltip": "閉じる",
"radioRecordingError": "ラジオの録音エラー: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "ラジオAPIに接続できません",
"radioSearchError": "検索エラーです。接続を確認してください。",
"radioLoadMoreStationsError": "これ以上ラジオ局を読み込めませんでした。",
"radioNearbyStationsError": "近くのラジオ局を検出できませんでした。国フィルターを使用してください。",
"radioCannotPlayStation": "\"{stationName}\"を再生できません",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "録音するにはまずラジオ局を選択してください。",
"recordingStartError": "録音を開始できませんでした: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "サポートされていない設定バージョンです",
"audioErrorGeneric": "再生エラー",
"audioErrorNoInternet": "インターネット接続がありません",
"audioErrorInvalidUrl": "ラジオのURLが無効です",
"audioErrorNotFound": "ラジオは利用できません(404エラー)",
"audioErrorTimeout": "接続がタイムアウトしました",
"audioErrorCannotConnect": "ラジオに接続できません",
"audioErrorUnsupportedFormat": "サポートされていないストリーム形式です",
"audioErrorDecode": "音声ストリームのデコード中にエラーが発生しました",
"audioErrorCleartext": "このラジオは暗号化されていないHTTPを使用しているため、許可されていません",
"audioErrorSsl": "ラジオのSSL証明書が無効です",
"audioErrorCannotPlay": "このラジオは再生できません",
"audioErrorUnexpectedPlayback": "再生中に予期しないエラーが発生しました",
"androidExactAlarmScheduleError": "Androidで正確なアラームをスケジュールできませんでした。正確なアラームの権限を確認してください。",
"recordingPathEmptyError": "録音パスを空にすることはできません",
"recordingMaxSizeInvalidError": "最大サイズは0より大きくする必要があります",
"recordingAlreadyActiveError": "すでに録音が進行中です",
"alarmRingingFallbackActive": "内部の安全な音声で再生しています。",
"alarmRingingPreparingFallback": "内部の安全な音声を準備しています。",
"alarmRingingTryingStation": "利用可能な最高音質で放送局の再生を試みています。",
"alarmScheduleOnce": "1回 · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "曜日: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Androidの信頼性を確認",
"closeAction": "閉じる",
"customOption": "カスタム",
"endLabel": "終了",
"equalizerDisable": "イコライザーを無効化",
"helpTitle": "ヘルプとチュートリアル",
"helpSubtitle": "PluriWaveの機能、ヒント、新着情報を確認できます。",
"indefiniteOption": "無期限",
"invalidNumber": "無効な数値",
"nameLabel": "名前",
"notPlaying": "再生していません",
"oneTimeOption": "1回",
"pausePlaybackTooltip": "再生を一時停止",
"qualityOriginal": "元の音質: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "音質情報なし",
"recordAction": "録音",
"recordDurationTitle": "録音時間",
"recordRadioSubtitle": "録音する時間を選んでください。",
"recordRadioTitle": "ラジオを録音",
"recordingActiveTitle": "ラジオを録音中",
"recordingDirectTitle": "ダイレクト録音",
"recordingsOpenFolderPlainError": "録音フォルダーを開けませんでした",
"recordingsOpenLatest": "最新の録音を開く",
"recordingsOpenLatestError": "最新の録音を開けませんでした",
"startLabel": "開始",
"startPlaybackTooltip": "再生を開始",
"stopAction": "停止",
"stopPlaybackTooltip": "再生を停止",
"weekdayShortMonday": "月",
"weekdayShortTuesday": "火",
"weekdayShortWednesday": "水",
"weekdayShortThursday": "木",
"weekdayShortFriday": "金",
"weekdayShortSaturday": "土",
"weekdayShortSunday": "日"
} }
File diff suppressed because it is too large Load Diff
+371 -197
View File
@@ -1,36 +1,63 @@
{ {
"@@locale": "pt", "@@locale": "pt",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "Início",
"navSearch": "Buscar", "navSearch": "Buscar",
"navFavorites": "Favoritos", "navFavorites": "Favoritos",
"navAlarms": "Alarmes", "navAlarms": "Alarmes",
"navSettings": "Settings", "navSettings": "Configurações",
"actionOk": "OK", "actionOk": "OK",
"sleepTimer": "Timer de sono", "sleepTimer": "Timer de sono",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "Desligamento suave da rádio com contagem regressiva exata.",
"cancelTimer": "Cancel timer", "cancelTimer": "Cancelar timer",
"optionOther": "Other", "optionOther": "Outro",
"customDurationTitle": "Custom duration", "customDurationTitle": "Duração personalizada",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "Escolha uma duração maior que zero.",
"hoursLabel": "Hours", "hoursLabel": "Horas",
"minutesLabel": "Minutes", "minutesLabel": "Minutos",
"secondsLabel": "Seconds", "secondsLabel": "Segundos",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} h {minutes} min {seconds} s",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} min {seconds} s",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} min",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} s",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Salvar como acesso rápido",
"startTimer": "Iniciar timer",
"skipCurrentAlarmExecution": "Esta execução de {alarmName} foi ignorada.",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "Configurações",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "Controle fino de som, backups e estações personalizadas.",
"languageSectionTitle": "Idioma", "languageSectionTitle": "Idioma",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "Escolha como o idioma do app é exibido.",
"languageSystemDefault": "Sistema", "languageSystemDefault": "Sistema",
"languageSpanish": "Espanhol", "languageSpanish": "Espanhol",
"languageEnglish": "English", "languageEnglish": "Inglês",
"languageUpdated": "Idioma atualizado: {languageName}", "languageUpdated": "Idioma atualizado: {languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
@@ -38,70 +65,71 @@
} }
}, },
"languageUpdatedSystem": "Idioma atualizado: Sistema", "languageUpdatedSystem": "Idioma atualizado: Sistema",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "Timer de sono",
"timerSectionAdd": "Add", "timerSectionAdd": "Adicionar",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "Personalize os acessos rápidos exibidos ao desligar a rádio automaticamente.",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "Restaurar tempos recomendados",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "Novo acesso rápido",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "Salvar acesso rápido",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "Seguro",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "Gravações",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "Selecione a pasta de gravações",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "Caminho de gravação atualizado",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "Não foi possível salvar o caminho: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "A pasta interna padrão será usada",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "Pasta de gravação",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "Calculando caminho...",
"recordingsChangePath": "Change path", "recordingsChangePath": "Alterar caminho",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "Usar caminho padrão",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "A rádio é salva a partir do stream original, sem recompressão.",
"equalizerActive": "Active", "equalizerActive": "Ativo",
"equalizerDisabled": "Disabled", "equalizerDisabled": "Desativado",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "Ativar equalizador",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "As alterações são aplicadas em tempo real à estação atual.",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "As alterações são salvas e serão aplicadas quando o Android habilitar o efeito.",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "Usar EQ próprio para este favorito",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "Ativo para {stationName}",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "Usando o EQ principal para {stationName}",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "Estação preferida",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "Pré-selecionada ao criar alarmes e disponível para reprodução rápida.",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "Ainda não há estações disponíveis",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "Salve favoritas ou carregue estações para escolher uma preferida.",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "Fallback automático",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "Favorita padrão",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "Preferida atual: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "Sem favoritas: usando automaticamente {stationName}",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "Reproduzir preferida",
"customStationsTitle": "Custom stations", "customStationsTitle": "Estações personalizadas",
"customStationsAdd": "Add", "customStationsAdd": "Adicionar",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "Não há estações personalizadas.",
"playAction": "Play", "playAction": "Reproduzir",
"deleteAction": "Delete", "deleteAction": "Excluir",
"addStationTitle": "Add station", "addStationTitle": "Adicionar estação",
"stationNameLabel": "Name *", "stationNameLabel": "Nome *",
"requiredField": "Required field", "unnamedStation": "Estação sem nome",
"streamUrlLabel": "Stream URL *", "requiredField": "Campo obrigatório",
"invalidUrl": "Invalid URL", "streamUrlLabel": "URL do stream *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "URL inválida",
"saveStation": "Save station", "countryOptionalLabel": "País (opcional)",
"saveStation": "Salvar estação",
"backupSectionTitle": "Backup", "backupSectionTitle": "Backup",
"backupExportTitle": "Export configuration", "backupExportTitle": "Exportar configuração",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportSubtitle": "Favoritos, estações personalizadas e presets de EQ",
"backupImportTitle": "Import configuration", "backupImportTitle": "Importar configuração",
"backupImportSubtitle": "Restore from a backup file", "backupImportSubtitle": "Restaurar a partir de um arquivo de backup",
"backupShareSubject": "PluriWave — backup", "backupShareSubject": "PluriWave — backup",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareText": "Configuração do PluriWave exportada em {date}",
"backupExportError": "Export error: {error}", "backupExportError": "Erro ao exportar: {error}",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupImportConfirmMessage": "Isso adicionará favoritos, estações e presets do arquivo. Continuar?",
"backupImportSuccess": "Configuration imported successfully", "backupImportSuccess": "Configuração importada com sucesso",
"backupImportError": "Import error: {error}", "backupImportError": "Erro ao importar: {error}",
"appVersionLoading": "Loading version...", "appVersionLoading": "Carregando versão...",
"appVersionSubtitle": "{version} - World radio", "appVersionSubtitle": "{version} - Rádio mundial",
"savedFavoritesTitle": "Saved favorites", "savedFavoritesTitle": "Favoritos salvos",
"stationFilterTitle": "Station filter", "stationFilterTitle": "Filtro de estações",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterSubtitle": "Apenas estações verificadas como ativas",
"backgroundAudioTitle": "Background audio", "backgroundAudioTitle": "Áudio em segundo plano",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioSubtitle": "Continua ao desligar a tela",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -149,14 +177,14 @@
} }
}, },
"cancelAction": "Cancelar", "cancelAction": "Cancelar",
"equalizerTitle": "Equalizer", "equalizerTitle": "Equalizador",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "Abrir pasta",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "Não foi possível abrir a pasta: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "Tamanho máximo da gravação",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "Limite atual: {size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "Tamanho máximo por gravação",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "Megabytes máximos",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "Limite de gravação atualizado para {size} MB",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "Ordem das estações",
"stationOrderByName": "By name", "stationOrderByName": "Por nome",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "Por qualidade",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "Aplica-se a favoritos, buscas, estações próximas e listas rápidas.",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "Listas de favoritos",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "Crie listas curtas para organizar suas estações salvas.",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "Adicionar lista",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "Editar lista",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "Excluir lista",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "Nome da lista",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "Máximo de 28 caracteres.",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "Sem atribuição",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "Lista padrão: não pode ser editada nem excluída.",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "Lista criada",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "Lista atualizada",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "Lista excluída; suas estações voltam para Sem atribuição.",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "Mover para lista",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "Lista atual: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} movida para {groupName}",
"favoritesTitle": "Favorites", "favoritesTitle": "Favoritos",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "Ainda sem favoritos",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "Toque no coração em qualquer estação para salvá-la na sua coleção.",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "Organize sua coleção por listas e mantenha as rádios importantes por perto.",
"favoritesCollection": "Collection", "favoritesCollection": "Coleção",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} salvas",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "Remover dos favoritos",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} removida dos favoritos",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,7 +254,7 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "Alarme adiado para esta execução.",
"searchScreenTitle": "Buscar sinal", "searchScreenTitle": "Buscar sinal",
"searchScreenSubtitle": "Encontre estações por nome, país ou idioma com filtros rápidos e contraste elevado.", "searchScreenSubtitle": "Encontre estações por nome, país ou idioma com filtros rápidos e contraste elevado.",
"searchFiltersLabel": "Filtros", "searchFiltersLabel": "Filtros",
@@ -257,9 +285,9 @@
"languageNameJapanese": "japonês", "languageNameJapanese": "japonês",
"languageNameArabic": "árabe", "languageNameArabic": "árabe",
"languageNameRussian": "russo", "languageNameRussian": "russo",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "Rádio global ao vivo com sinais limpos, favoritos inteligentes e uma experiência visual de game show.",
"exploreStations": "Explore stations", "exploreStations": "Explorar estações",
"stationsCount": "{count} stations", "stationsCount": "{count} rádios",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "Qualidade HD",
"nearYou": "Near you", "nearYou": "Perto de você",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "Perto de você · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "Detectar",
"liveRadar": "Live radar", "liveRadar": "Radar ao vivo",
"genresTitle": "Genres", "genresTitle": "Gêneros",
"retryAction": "Retry", "retryAction": "Tentar novamente",
"noStationsAvailable": "No stations available", "noStationsAvailable": "Não há estações disponíveis",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "Tente atualizar ou escolher outro gênero para captar sinal novamente.",
"genrePop": "Pop", "genrePop": "Pop",
"genreRock": "Rock", "genreRock": "Rock",
"genreJazz": "Jazz", "genreJazz": "Jazz",
"genreClassical": "Classical", "genreClassical": "Clássica",
"genreElectronic": "Electronic", "genreElectronic": "Eletrônica",
"genreNews": "News", "genreNews": "Notícias",
"genreTalk": "Talk", "genreTalk": "Conversa",
"genreHipHop": "Hip-hop", "genreHipHop": "Hip-hop",
"genreCountry": "Country", "genreCountry": "Country",
"genreMetal": "Metal", "genreMetal": "Metal",
"genreReggae": "Reggae", "genreReggae": "Reggae",
"genreLatin": "Latin", "genreLatin": "Latina",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "Despertar musical",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "Alarmes com rádio, som seguro, férias inteligentes e próxima execução sempre visível.",
"createAlarmAction": "Create alarm", "createAlarmAction": "Criar alarme",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} alarmes",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "Alarmes ativos sem próxima execução",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "Sem alarmes ativos",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "Próximo alarme",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": " {count} alarme(s) ativos, mas no momento não têm uma data futura válida. Verifique data, dias e férias.",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,9 +343,9 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "Crie um alarme e o PluriWave calculará automaticamente a próxima execução.",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "Toca durante as férias",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "Pausa nas férias",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "Fade-in {seconds}s",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "Próxima execução: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "Não há próxima execução ativa.",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "Uma execução foi ignorada: {date}.",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "Editar",
"skipNextAction": "Skip next", "skipNextAction": "Ignorar próxima",
"deleteTooltip": "Delete", "deleteTooltip": "Excluir",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "Alarme ignorado. Não resta próxima execução.",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "Alarme ignorado. Voltará em {date}.",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "Está pausado por férias ({vacationName}) e sem próxima execução.",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "Está pausado por férias ({vacationName}) e volta em {date}.",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "Com férias ativas, tocará novamente em {date}.",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "Despertador musical",
"newAlarmTitle": "New alarm", "newAlarmTitle": "Novo alarme",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "Editar alarme",
"nameField": "Name", "nameField": "Nome",
"timeField": "Time", "timeField": "Hora",
"dateField": "Date", "dateField": "Data",
"onceOption": "Once", "onceOption": "Uma vez",
"dailyOption": "Daily", "dailyOption": "Diária",
"weekdaysOption": "Weekdays", "weekdaysOption": "Dias",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "Som e volume",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "Fade-in do alarme",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 s (sem transição)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} s (de 5% ao volume escolhido)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "Som seguro interno",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "Amanhecer acolhedor",
"soundSoftBell": "Soft bell", "soundSoftBell": "Sino suave",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "Pulso digital",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "Estação favorita",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "Sem estação: usar som interno",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "Salve estações nos Favoritos para usá-las como alarme musical.",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "Usar estação atual",
"playDuringVacations": "Play during vacations", "playDuringVacations": "Tocar durante as férias",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "Se você desativar, a próxima execução saltará para o primeiro dia válido.",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "Salvar alarme",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "Escolha pelo menos um dia da semana.",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Revisar confiabilidade Android",
"statusOk": "OK", "statusOk": "OK",
"statusPending": "pending", "statusPending": "pendente",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "Confiabilidade: exatos {exact} · notificações {notifications} · tela {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "Períodos de férias",
"addAction": "Add", "addAction": "Adicionar",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "Se um alarme tiver \"Pausa nas férias\", estes períodos serão ignorados automaticamente.",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "Nenhum período carregado.",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "Excluir período",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "Férias",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "Novo período de férias",
"startField": "Start", "startField": "Início",
"endField": "End", "endField": "Fim",
"saveRangeAction": "Save range", "saveRangeAction": "Salvar período",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "Ainda não há alarmes.",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "Crie um para configurar seu despertar musical.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "Tocando com som seguro interno.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "Preparando som seguro interno.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "Parar alarme",
"pauseAction": "Pausar",
"miniPlayerOpenLabel": "Abrir reprodutor de {stationName}",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "Reprodutor",
"playbackStatusConnecting": "Conectando...",
"playbackStatusLive": "Ao vivo",
"playbackStatusPaused": "Pausado",
"playbackStatusConnectionError": "Erro de conexão",
"playbackStatusStopped": "Parado",
"stationSemanticLabel": "Estação {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "Adicionar aos favoritos",
"favoritesAddedMessage": "{stationName} adicionada aos favoritos",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "Ícone da estação",
"liveNow": "Ao vivo",
"equalizerBandLabel": "Banda {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} decibéis",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "Plano",
"equalizerPresetRock": "Rock",
"equalizerPresetPop": "Pop",
"equalizerPresetBassBoost": "Reforço de graves",
"equalizerPresetJazz": "Jazz",
"equalizerPresetVoice": "Voz",
"equalizerPresetCustom": "Personalizado",
"onboardingTitle": "Bem-vindo ao PluriWave",
"onboardingNewsTitle": "Novidades",
"onboardingStartAction": "Começar",
"onboardingCloseTooltip": "Fechar",
"radioRecordingError": "Erro ao gravar a rádio: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "Sem conexão com a API de rádio",
"radioSearchError": "Erro na busca. Verifique sua conexão.",
"radioLoadMoreStationsError": "Não foi possível carregar mais estações.",
"radioNearbyStationsError": "Não foi possível detectar estações próximas. Use filtros por país.",
"radioCannotPlayStation": "Não é possível reproduzir \"{stationName}\"",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "Primeiro selecione uma estação para gravar.",
"recordingStartError": "Não foi possível iniciar a gravação: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "Versão de configuração não compatível",
"audioErrorGeneric": "Erro de reprodução",
"audioErrorNoInternet": "Sem conexão com a internet",
"audioErrorInvalidUrl": "A URL da rádio não é válida",
"audioErrorNotFound": "A rádio não está disponível (erro 404)",
"audioErrorTimeout": "Tempo esgotado ao conectar",
"audioErrorCannotConnect": "Não é possível conectar à rádio",
"audioErrorUnsupportedFormat": "Formato de stream não compatível",
"audioErrorDecode": "Erro ao decodificar o stream de áudio",
"audioErrorCleartext": "Esta rádio usa HTTP sem criptografia, o que não é permitido",
"audioErrorSsl": "Certificado SSL inválido na rádio",
"audioErrorCannotPlay": "Não é possível reproduzir esta rádio",
"audioErrorUnexpectedPlayback": "Erro inesperado ao reproduzir",
"androidExactAlarmScheduleError": "O Android não conseguiu agendar um alarme exato. Verifique a permissão de alarmes exatos.",
"recordingPathEmptyError": "O caminho de gravação não pode estar vazio",
"recordingMaxSizeInvalidError": "O tamanho máximo deve ser maior que zero",
"recordingAlreadyActiveError": "Já há uma gravação em andamento",
"alarmRingingFallbackActive": "Tocando com áudio interno seguro.",
"alarmRingingPreparingFallback": "Preparando áudio interno seguro.",
"alarmRingingTryingStation": "Tentando reproduzir sua estação com a maior qualidade disponível.",
"alarmScheduleOnce": "Uma vez · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "Dias: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Revisar confiabilidade Android",
"closeAction": "Fechar",
"customOption": "Personalizada",
"endLabel": "Fim",
"equalizerDisable": "Desativar equalizador",
"helpTitle": "Ajuda e tutorial",
"helpSubtitle": "Revê funções, dicas e novidades do PluriWave.",
"indefiniteOption": "Indefinida",
"invalidNumber": "Número inválido",
"nameLabel": "Nome",
"notPlaying": "Não está reproduzindo",
"oneTimeOption": "Uma vez",
"pausePlaybackTooltip": "Pausar reprodução",
"qualityOriginal": "Qualidade original: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "Qualidade não informada",
"recordAction": "Gravar",
"recordDurationTitle": "Duração da gravação",
"recordRadioSubtitle": "Escolha por quanto tempo deseja gravar.",
"recordRadioTitle": "Gravar rádio",
"recordingActiveTitle": "Gravando rádio",
"recordingDirectTitle": "Gravação direta",
"recordingsOpenFolderPlainError": "Não foi possível abrir a pasta de gravações",
"recordingsOpenLatest": "Abrir última gravação",
"recordingsOpenLatestError": "Não foi possível abrir a última gravação",
"startLabel": "Início",
"startPlaybackTooltip": "Iniciar reprodução",
"stopAction": "Parar",
"stopPlaybackTooltip": "Parar reprodução",
"weekdayShortMonday": "Seg",
"weekdayShortTuesday": "Ter",
"weekdayShortWednesday": "Qua",
"weekdayShortThursday": "Qui",
"weekdayShortFriday": "Sex",
"weekdayShortSaturday": "Sáb",
"weekdayShortSunday": "Dom"
} }
+408 -234
View File
@@ -1,107 +1,135 @@
{ {
"@@locale": "ru", "@@locale": "ru",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "Главная",
"navSearch": "Search", "navSearch": "Поиск",
"navFavorites": "Favorites", "navFavorites": "Избранное",
"navAlarms": "Alarms", "navAlarms": "Будильники",
"navSettings": "Settings", "navSettings": "Настройки",
"actionOk": "OK", "actionOk": "ОК",
"sleepTimer": "Sleep timer", "sleepTimer": "Таймер сна",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "Плавное выключение радио с точным обратным отсчётом.",
"cancelTimer": "Cancel timer", "cancelTimer": "Отменить таймер",
"optionOther": "Other", "optionOther": "Другое",
"customDurationTitle": "Custom duration", "customDurationTitle": "Своя длительность",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "Выберите длительность больше нуля.",
"hoursLabel": "Hours", "hoursLabel": "Часы",
"minutesLabel": "Minutes", "minutesLabel": "Минуты",
"secondsLabel": "Seconds", "secondsLabel": "Секунды",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} ? {minutes} ??? {seconds} ?",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} ??? {seconds} ?",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} ???",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} ?",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "Сохранить как быстрый доступ",
"startTimer": "Запустить таймер",
"skipCurrentAlarmExecution": "Этот запуск {alarmName} пропущен.",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "Настройки",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "Точная настройка звука, резервных копий и пользовательских станций.",
"languageSectionTitle": "Language", "languageSectionTitle": "Язык",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "Выберите, как отображается язык приложения.",
"languageSystemDefault": "System", "languageSystemDefault": "Система",
"languageSpanish": "Spanish", "languageSpanish": "Испанский",
"languageEnglish": "English", "languageEnglish": "Английский",
"languageUpdated": "Language updated: {languageName}", "languageUpdated": "Язык обновлён: {languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
"languageName": {} "languageName": {}
} }
}, },
"languageUpdatedSystem": "Language updated: System", "languageUpdatedSystem": "Язык обновлён: система",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "Таймер сна",
"timerSectionAdd": "Add", "timerSectionAdd": "Добавить",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "Настройте быстрые пресеты, которые появляются при автоматическом выключении радио.",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "Восстановить рекомендуемое время",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "Новый быстрый доступ",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "Сохранить быстрый доступ",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "Безопасно",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "Записи",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "Выберите папку для записей",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "Путь записи обновлён",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "Не удалось сохранить путь: {error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "Будет использована внутренняя папка по умолчанию",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "Папка записей",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "Вычисление пути...",
"recordingsChangePath": "Change path", "recordingsChangePath": "Изменить путь",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "Использовать путь по умолчанию",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "Радио сохраняется из исходного потока без повторного сжатия.",
"equalizerActive": "Active", "equalizerActive": "Активно",
"equalizerDisabled": "Disabled", "equalizerDisabled": "Отключено",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "Включить эквалайзер",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "Изменения применяются к текущей станции в реальном времени.",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "Изменения сохраняются и применятся, когда Android включит эффект.",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "Использовать свой EQ для этого избранного",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "Активно для {stationName}",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "Используется основной EQ для {stationName}",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "Предпочитаемая станция",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "Предварительно выбирается при создании будильников и доступна для быстрого воспроизведения.",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "Пока нет доступных станций",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "Сохраните избранные или загрузите станции, чтобы выбрать предпочитаемую.",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "Автоматический резерв",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "Избранное по умолчанию",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "Текущая предпочитаемая: {stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "Нет избранных: автоматически используется {stationName}",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "Воспроизвести предпочитаемую",
"customStationsTitle": "Custom stations", "customStationsTitle": "Пользовательские станции",
"customStationsAdd": "Add", "customStationsAdd": "Добавить",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "Пользовательских станций нет.",
"playAction": "Play", "playAction": "Воспроизвести",
"deleteAction": "Delete", "deleteAction": "Удалить",
"addStationTitle": "Add station", "addStationTitle": "Добавить станцию",
"stationNameLabel": "Name *", "stationNameLabel": "Название *",
"requiredField": "Required field", "unnamedStation": "Станция без названия",
"streamUrlLabel": "Stream URL *", "requiredField": "Обязательное поле",
"invalidUrl": "Invalid URL", "streamUrlLabel": "URL потока *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "Недопустимый URL",
"saveStation": "Save station", "countryOptionalLabel": "Страна (необязательно)",
"backupSectionTitle": "Backup", "saveStation": "Сохранить станцию",
"backupExportTitle": "Export configuration", "backupSectionTitle": "Резервная копия",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "Экспортировать настройки",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "Избранное, пользовательские станции и пресеты EQ",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "Импортировать настройки",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "Восстановить из файла резервной копии",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — резервная копия",
"backupExportError": "Export error: {error}", "backupShareText": "Настройки PluriWave, экспортированные {date}",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "Ошибка при экспорте: {error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "Это добавит избранное, станции и пресеты из файла. Продолжить?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "Настройки успешно импортированы",
"appVersionLoading": "Loading version...", "backupImportError": "Ошибка при импорте: {error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "Загрузка версии...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} — мировое радио",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "Сохранённое избранное",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "Фильтр станций",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "Только станции, подтверждённые как активные",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "Фоновое аудио",
"backgroundAudioSubtitle": "Продолжается при выключенном экране",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -148,15 +176,15 @@
"version": {} "version": {}
} }
}, },
"cancelAction": "Cancel", "cancelAction": "Отмена",
"equalizerTitle": "Equalizer", "equalizerTitle": "Эквалайзер",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "Открыть папку",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "Не удалось открыть папку: {error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "Максимальный размер записи",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "Текущий лимит: {size} МБ",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "Максимальный размер одной записи",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "Максимум мегабайт",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "Лимит записи обновлён до {size} МБ",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "Порядок станций",
"stationOrderByName": "By name", "stationOrderByName": "По названию",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "По качеству",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "Применяется к избранному, поиску, ближайшим станциям и быстрым спискам.",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "Списки избранного",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "Создавайте короткие списки, чтобы упорядочить сохранённые станции.",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "Добавить список",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "Изменить список",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "Удалить список",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "Название списка",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "Максимум 28 символов.",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "Без списка",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "Список по умолчанию: нельзя изменить или удалить.",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "Список создан",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "Список обновлён",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "Список удалён; его станции вернулись в «Без списка».",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "Переместить в список",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "Текущий список: {groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} перемещена в {groupName}",
"favoritesTitle": "Favorites", "favoritesTitle": "Избранное",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "Избранного пока нет",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "Нажмите на сердце у любой станции, чтобы сохранить её в коллекцию.",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "Организуйте коллекцию по спискам и держите важные радио под рукой.",
"favoritesCollection": "Collection", "favoritesCollection": "Коллекция",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "{count} сохранено",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "Удалить из избранного",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} удалена из избранного",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,18 +254,18 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "Будильник отложен для этого запуска.",
"searchScreenTitle": "Поиск станций", "searchScreenTitle": "Поиск сигнала",
"searchScreenSubtitle": "Ищите станции по названию, стране или языку с быстрыми фильтрами и высоким контрастом.", "searchScreenSubtitle": "Находите радио по названию, стране или языку с быстрыми фильтрами и высокой контрастностью.",
"searchFiltersLabel": "Фильтры", "searchFiltersLabel": "Фильтры",
"searchHint": "Radio Horizon, джаз, новости...", "searchHint": "Радио Горизонт, джаз, новости...",
"searchCountryFilterLabel": "Страна", "searchCountryFilterLabel": "Страна",
"searchLanguageFilterLabel": "Язык", "searchLanguageFilterLabel": "Язык",
"searchMinQualityFilterLabel": "Минимальное качество", "searchMinQualityFilterLabel": "Минимальное качество",
"searchEmptyTitle": "Найдите станцию", "searchEmptyTitle": "Найдите станцию",
"searchNoResultsTitle": "Ничего не найдено", "searchNoResultsTitle": "Нет результатов",
"searchEmptySubtitle": "Используйте верхнюю строку и быстрые кнопки, чтобы открыть станции со всего мира.", "searchEmptySubtitle": "Используйте верхнюю строку или чипы, чтобы находить сигналы со всего мира.",
"searchNoResultsSubtitle": "Попробуйте убрать фильтры или ввести другое название, чтобы найти активную станцию.", "searchNoResultsSubtitle": "Попробуйте убрать фильтры или ввести другое название, чтобы найти активный сигнал.",
"countrySpain": "Испания", "countrySpain": "Испания",
"countryUsa": "США", "countryUsa": "США",
"countryMexico": "Мексика", "countryMexico": "Мексика",
@@ -248,18 +276,18 @@
"countryItaly": "Италия", "countryItaly": "Италия",
"countryBrazil": "Бразилия", "countryBrazil": "Бразилия",
"countryJapan": "Япония", "countryJapan": "Япония",
"languageNameSpanish": "Испанский", "languageNameSpanish": "испанский",
"languageNameEnglish": "Английский", "languageNameEnglish": "английский",
"languageNameFrench": "Французский", "languageNameFrench": "французский",
"languageNameGerman": "Немецкий", "languageNameGerman": "немецкий",
"languageNamePortuguese": "Португальский", "languageNamePortuguese": "португальский",
"languageNameItalian": "Итальянский", "languageNameItalian": "итальянский",
"languageNameJapanese": "Японский", "languageNameJapanese": "японский",
"languageNameArabic": "Арабский", "languageNameArabic": "арабский",
"languageNameRussian": "Русский", "languageNameRussian": "русский",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "Глобальное радио в прямом эфире с чистыми сигналами, умным избранным и визуальным стилем телевикторины.",
"exploreStations": "Explore stations", "exploreStations": "Изучить станции",
"stationsCount": "{count} stations", "stationsCount": "{count} радиостанций",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "HD-качество",
"nearYou": "Near you", "nearYou": "Рядом с вами",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "Рядом с вами · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "Определить",
"liveRadar": "Live radar", "liveRadar": "Радар в эфире",
"genresTitle": "Genres", "genresTitle": "Жанры",
"retryAction": "Retry", "retryAction": "Повторить",
"noStationsAvailable": "No stations available", "noStationsAvailable": "Нет доступных станций",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "Попробуйте обновить или выбрать другой жанр, чтобы снова поймать сигнал.",
"genrePop": "Pop", "genrePop": "Поп",
"genreRock": "Rock", "genreRock": "Рок",
"genreJazz": "Jazz", "genreJazz": "Джаз",
"genreClassical": "Classical", "genreClassical": "Классика",
"genreElectronic": "Electronic", "genreElectronic": "Электронная",
"genreNews": "News", "genreNews": "Новости",
"genreTalk": "Talk", "genreTalk": "Разговорные",
"genreHipHop": "Hip-hop", "genreHipHop": "Хип-хоп",
"genreCountry": "Country", "genreCountry": "Кантри",
"genreMetal": "Metal", "genreMetal": "Метал",
"genreReggae": "Reggae", "genreReggae": "Регги",
"genreLatin": "Latin", "genreLatin": "Латинская",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "Музыкальное пробуждение",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "Будильники с радио, безопасным звуком, умными отпусками и всегда видимым следующим запуском.",
"createAlarmAction": "Create alarm", "createAlarmAction": "Создать будильник",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} будильников",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "Активные будильники без следующего запуска",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "Нет активных будильников",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "Следующий будильник",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "Есть {count} активных будильников, но сейчас у них нет допустимой будущей даты. Проверьте дату, дни и отпуска.",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "Создайте будильник, и PluriWave автоматически рассчитает следующий запуск.",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "Звонит в отпуске",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "Пауза в отпуске",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "Плавное усиление {seconds}с",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "Следующий запуск: {date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "Нет активного следующего запуска.",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "Один запуск был пропущен: {date}.",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "Изменить",
"skipNextAction": "Skip next", "skipNextAction": "Пропустить следующий",
"deleteTooltip": "Delete", "deleteTooltip": "Удалить",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "Будильник пропущен. Следующего запуска нет.",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "Будильник пропущен. Вернётся {date}.",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "Приостановлен из-за отпуска ({vacationName}) и без следующего запуска.",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "Приостановлен из-за отпуска ({vacationName}) и вернётся {date}.",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "С активным отпуском снова прозвучит {date}.",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "Музыкальный будильник",
"newAlarmTitle": "New alarm", "newAlarmTitle": "Новый будильник",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "Изменить будильник",
"nameField": "Name", "nameField": "Название",
"timeField": "Time", "timeField": "Время",
"dateField": "Date", "dateField": "Дата",
"onceOption": "Once", "onceOption": "Один раз",
"dailyOption": "Daily", "dailyOption": "Ежедневно",
"weekdaysOption": "Weekdays", "weekdaysOption": "Дни",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "Звук и громкость",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "Плавное усиление будильника",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 с (без перехода)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} с (с 5% до выбранной громкости)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "Безопасный внутренний звук",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "Тёплый рассвет",
"soundSoftBell": "Soft bell", "soundSoftBell": "Мягкий колокольчик",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "Цифровой импульс",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "Избранная станция",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "Без станции: использовать внутренний звук",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "Сохраните станции в избранное, чтобы использовать их как музыкальный будильник.",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "Использовать текущую станцию",
"playDuringVacations": "Play during vacations", "playDuringVacations": "Звонить во время отпусков",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "Если выключить, следующий запуск перейдёт на первый допустимый день.",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "Сохранить будильник",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "Выберите хотя бы один день недели.",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "Проверить надёжность Android",
"statusOk": "OK", "statusOk": "ОК",
"statusPending": "pending", "statusPending": "ожидает",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "Надёжность: точные {exact} · уведомления {notifications} · экран {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "Периоды отпусков",
"addAction": "Add", "addAction": "Добавить",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "Если у будильника включена «Пауза в отпуске», эти периоды будут автоматически пропущены.",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "Периоды не загружены.",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "Удалить период",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "Отпуск",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "Новый период отпуска",
"startField": "Start", "startField": "Начало",
"endField": "End", "endField": "Конец",
"saveRangeAction": "Save range", "saveRangeAction": "Сохранить период",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "Будильников пока нет.",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "Создайте один, чтобы настроить своё музыкальное пробуждение.",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "Звонит с безопасным внутренним звуком.",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "Подготовка безопасного внутреннего звука.",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "Остановить будильник",
"pauseAction": "Пауза",
"miniPlayerOpenLabel": "Открыть плеер для {stationName}",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "Плеер",
"playbackStatusConnecting": "Подключение...",
"playbackStatusLive": "В эфире",
"playbackStatusPaused": "Приостановлено",
"playbackStatusConnectionError": "Ошибка подключения",
"playbackStatusStopped": "Остановлено",
"stationSemanticLabel": "Станция {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "Добавить в избранное",
"favoritesAddedMessage": "{stationName} добавлена в избранное",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "Значок станции",
"liveNow": "В эфире",
"equalizerBandLabel": "Полоса {band}",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} дБ",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "Плоский",
"equalizerPresetRock": "Рок",
"equalizerPresetPop": "Поп",
"equalizerPresetBassBoost": "Усиление басов",
"equalizerPresetJazz": "Джаз",
"equalizerPresetVoice": "Голос",
"equalizerPresetCustom": "Пользовательский",
"onboardingTitle": "Добро пожаловать в PluriWave",
"onboardingNewsTitle": "Что нового",
"onboardingStartAction": "Начать",
"onboardingCloseTooltip": "Закрыть",
"radioRecordingError": "Ошибка записи радио: {error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "Нет подключения к API радио",
"radioSearchError": "Ошибка поиска. Проверьте подключение.",
"radioLoadMoreStationsError": "Не удалось загрузить больше станций.",
"radioNearbyStationsError": "Не удалось обнаружить ближайшие станции. Используйте фильтры по стране.",
"radioCannotPlayStation": "Невозможно воспроизвести \"{stationName}\"",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "Сначала выберите станцию для записи.",
"recordingStartError": "Не удалось начать запись: {error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "Неподдерживаемая версия конфигурации",
"audioErrorGeneric": "Ошибка воспроизведения",
"audioErrorNoInternet": "Нет подключения к интернету",
"audioErrorInvalidUrl": "URL радио недействителен",
"audioErrorNotFound": "Радио недоступно (ошибка 404)",
"audioErrorTimeout": "Время ожидания подключения истекло",
"audioErrorCannotConnect": "Не удалось подключиться к радио",
"audioErrorUnsupportedFormat": "Неподдерживаемый формат потока",
"audioErrorDecode": "Ошибка декодирования аудиопотока",
"audioErrorCleartext": "Это радио использует незашифрованный HTTP, что не разрешено",
"audioErrorSsl": "Недействительный SSL-сертификат у радио",
"audioErrorCannotPlay": "Это радио невозможно воспроизвести",
"audioErrorUnexpectedPlayback": "Неожиданная ошибка воспроизведения",
"androidExactAlarmScheduleError": "Android не смог запланировать точный будильник. Проверьте разрешение для точных будильников.",
"recordingPathEmptyError": "Путь записи не может быть пустым",
"recordingMaxSizeInvalidError": "Максимальный размер должен быть больше нуля",
"recordingAlreadyActiveError": "Запись уже выполняется",
"alarmRingingFallbackActive": "Воспроизведение с внутренним безопасным аудио.",
"alarmRingingPreparingFallback": "Подготавливается внутреннее безопасное аудио.",
"alarmRingingTryingStation": "Пытаемся воспроизвести вашу станцию в максимально доступном качестве.",
"alarmScheduleOnce": "Один раз · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "Дни: {days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "Проверить надёжность Android",
"closeAction": "Закрыть",
"customOption": "Своя",
"endLabel": "Конец",
"equalizerDisable": "Отключить эквалайзер",
"helpTitle": "Помощь и руководство",
"helpSubtitle": "Посмотрите функции, советы и новости PluriWave.",
"indefiniteOption": "Без ограничения",
"invalidNumber": "Недопустимое число",
"nameLabel": "Название",
"notPlaying": "Не воспроизводится",
"oneTimeOption": "Один раз",
"pausePlaybackTooltip": "Пауза",
"qualityOriginal": "Исходное качество: {quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "Качество не указано",
"recordAction": "Записать",
"recordDurationTitle": "Длительность записи",
"recordRadioSubtitle": "Выберите длительность записи.",
"recordRadioTitle": "Записать радио",
"recordingActiveTitle": "Запись радио",
"recordingDirectTitle": "Прямая запись",
"recordingsOpenFolderPlainError": "Не удалось открыть папку записей",
"recordingsOpenLatest": "Открыть последнюю запись",
"recordingsOpenLatestError": "Не удалось открыть последнюю запись",
"startLabel": "Начало",
"startPlaybackTooltip": "Начать воспроизведение",
"stopAction": "Остановить",
"stopPlaybackTooltip": "Остановить воспроизведение",
"weekdayShortMonday": "Пн",
"weekdayShortTuesday": "Вт",
"weekdayShortWednesday": "Ср",
"weekdayShortThursday": "Чт",
"weekdayShortFriday": "Пт",
"weekdayShortSaturday": "Сб",
"weekdayShortSunday": "Вс"
} }
+397 -223
View File
@@ -1,107 +1,135 @@
{ {
"@@locale": "zh", "@@locale": "zh",
"appTitle": "PluriWave", "appTitle": "PluriWave",
"navHome": "Home", "navHome": "首页",
"navSearch": "Search", "navSearch": "搜索",
"navFavorites": "Favorites", "navFavorites": "收藏",
"navAlarms": "Alarms", "navAlarms": "闹钟",
"navSettings": "Settings", "navSettings": "设置",
"actionOk": "OK", "actionOk": "确定",
"sleepTimer": "Sleep timer", "sleepTimer": "睡眠定时器",
"sleepTimerDescription": "Smooth radio shutdown with an exact countdown.", "sleepTimerDescription": "通过精准倒计时平滑关闭电台。",
"cancelTimer": "Cancel timer", "cancelTimer": "取消定时器",
"optionOther": "Other", "optionOther": "其他",
"customDurationTitle": "Custom duration", "customDurationTitle": "自定义时长",
"durationGreaterThanZero": "Choose a duration greater than zero.", "durationGreaterThanZero": "请选择大于零的时长。",
"hoursLabel": "Hours", "hoursLabel": "小时",
"minutesLabel": "Minutes", "minutesLabel": "分钟",
"secondsLabel": "Seconds", "secondsLabel": "",
"saveQuickAccess": "Save as quick access", "durationHoursMinutesSeconds": "{hours} ?? {minutes} ? {seconds} ?",
"startTimer": "Start timer", "@durationHoursMinutesSeconds": {
"skipCurrentAlarmExecution": "Skipped this execution of {alarmName}.", "placeholders": {
"hours": {},
"minutes": {},
"seconds": {}
}
},
"durationMinutesSeconds": "{minutes} ? {seconds} ?",
"@durationMinutesSeconds": {
"placeholders": {
"minutes": {},
"seconds": {}
}
},
"durationMinutesOnly": "{minutes} ?",
"@durationMinutesOnly": {
"placeholders": {
"minutes": {}
}
},
"durationSecondsOnly": "{seconds} ?",
"@durationSecondsOnly": {
"placeholders": {
"seconds": {}
}
},
"saveQuickAccess": "保存为快捷入口",
"startTimer": "启动定时器",
"skipCurrentAlarmExecution": "已跳过 {alarmName} 本次执行。",
"@skipCurrentAlarmExecution": { "@skipCurrentAlarmExecution": {
"placeholders": { "placeholders": {
"alarmName": {} "alarmName": {}
} }
}, },
"settingsTitle": "Settings", "settingsTitle": "设置",
"settingsSubtitle": "Fine-grained sound control, backups, and custom stations.", "settingsSubtitle": "精细控制声音、备份和自定义电台。",
"languageSectionTitle": "Language", "languageSectionTitle": "语言",
"languageSectionDescription": "Choose how the app language is displayed.", "languageSectionDescription": "选择应用语言的显示方式。",
"languageSystemDefault": "System", "languageSystemDefault": "系统",
"languageSpanish": "Spanish", "languageSpanish": "西班牙语",
"languageEnglish": "English", "languageEnglish": "英语",
"languageUpdated": "Language updated: {languageName}", "languageUpdated": "语言已更新:{languageName}",
"@languageUpdated": { "@languageUpdated": {
"placeholders": { "placeholders": {
"languageName": {} "languageName": {}
} }
}, },
"languageUpdatedSystem": "Language updated: System", "languageUpdatedSystem": "语言已更新:系统",
"timerSectionTitle": "Sleep timer", "timerSectionTitle": "睡眠定时器",
"timerSectionAdd": "Add", "timerSectionAdd": "添加",
"timerSectionDescription": "Customize the quick presets shown when automatically stopping the radio.", "timerSectionDescription": "自定义自动关闭电台时显示的快捷预设。",
"timerSectionRestoreRecommended": "Restore recommended times", "timerSectionRestoreRecommended": "恢复推荐时长",
"newQuickAccessTitle": "New quick access", "newQuickAccessTitle": "新的快捷入口",
"saveQuickAccessButton": "Save quick access", "saveQuickAccessButton": "保存快捷入口",
"settingsSafeStatus": "Safe", "settingsSafeStatus": "安全",
"recordingsSectionTitle": "Recordings", "recordingsSectionTitle": "录音",
"recordingsFolderDialogTitle": "Select recordings folder", "recordingsFolderDialogTitle": "选择录音文件夹",
"recordingsPathUpdated": "Recording path updated", "recordingsPathUpdated": "录音路径已更新",
"recordingsPathSaveError": "Could not save the path: {error}", "recordingsPathSaveError": "无法保存路径:{error}",
"recordingsDefaultFolderRestored": "The internal default folder will be used", "recordingsDefaultFolderRestored": "将使用默认内部文件夹",
"recordingsFolderTitle": "Recordings folder", "recordingsFolderTitle": "录音文件夹",
"recordingsPathCalculating": "Calculating path...", "recordingsPathCalculating": "正在计算路径...",
"recordingsChangePath": "Change path", "recordingsChangePath": "更改路径",
"recordingsUseDefaultPath": "Use default path", "recordingsUseDefaultPath": "使用默认路径",
"recordingsOriginalStreamHint": "The radio is saved from the original stream, without recompressing.", "recordingsOriginalStreamHint": "电台将从原始音频流保存,不重新编码。",
"equalizerActive": "Active", "equalizerActive": "已启用",
"equalizerDisabled": "Disabled", "equalizerDisabled": "已停用",
"equalizerEnable": "Enable equalizer", "equalizerEnable": "启用均衡器",
"equalizerRealtimeSubtitle": "Changes are applied in real time to the current station.", "equalizerRealtimeSubtitle": "更改会实时应用到当前电台。",
"equalizerPendingSubtitle": "Changes are saved and will apply when Android enables the effect.", "equalizerPendingSubtitle": "更改已保存,并会在 Android 启用该效果后应用。",
"equalizerPerStationTitle": "Use custom EQ for this favorite", "equalizerPerStationTitle": "为此收藏使用专属均衡器",
"equalizerPerStationActive": "Active for {stationName}", "equalizerPerStationActive": "已为 {stationName} 启用",
"equalizerPerStationMain": "Using main EQ for {stationName}", "equalizerPerStationMain": "正在为 {stationName} 使用主均衡器",
"preferredStationTitle": "Preferred station", "preferredStationTitle": "首选电台",
"preferredStationDescription": "Preselected for new alarms and available for quick playback.", "preferredStationDescription": "创建闹钟时会预先选择,也可用于快速播放。",
"preferredStationNoStationsTitle": "No stations available yet", "preferredStationNoStationsTitle": "暂时没有可用电台",
"preferredStationNoStationsSubtitle": "Save favorites or load stations to choose a preferred one.", "preferredStationNoStationsSubtitle": "请先收藏或加载电台,再选择首选电台。",
"preferredStationAutomaticFallback": "Automatic fallback", "preferredStationAutomaticFallback": "自动后备",
"preferredStationDefaultFavorite": "Default favorite", "preferredStationDefaultFavorite": "默认收藏",
"preferredStationCurrent": "Current preferred: {stationName}", "preferredStationCurrent": "当前首选:{stationName}",
"preferredStationAutoUsing": "No favorites: automatically using {stationName}", "preferredStationAutoUsing": "没有收藏:自动使用 {stationName}",
"preferredStationPlay": "Play preferred", "preferredStationPlay": "播放首选电台",
"customStationsTitle": "Custom stations", "customStationsTitle": "自定义电台",
"customStationsAdd": "Add", "customStationsAdd": "添加",
"customStationsEmpty": "No custom stations.", "customStationsEmpty": "没有自定义电台。",
"playAction": "Play", "playAction": "播放",
"deleteAction": "Delete", "deleteAction": "删除",
"addStationTitle": "Add station", "addStationTitle": "添加电台",
"stationNameLabel": "Name *", "stationNameLabel": "名称 *",
"requiredField": "Required field", "unnamedStation": "未命名电台",
"streamUrlLabel": "Stream URL *", "requiredField": "必填字段",
"invalidUrl": "Invalid URL", "streamUrlLabel": "音频流 URL *",
"countryOptionalLabel": "Country (optional)", "invalidUrl": "URL 无效",
"saveStation": "Save station", "countryOptionalLabel": "国家/地区(可选)",
"backupSectionTitle": "Backup", "saveStation": "保存电台",
"backupExportTitle": "Export configuration", "backupSectionTitle": "备份",
"backupExportSubtitle": "Favorites, custom stations, and EQ presets", "backupExportTitle": "导出配置",
"backupImportTitle": "Import configuration", "backupExportSubtitle": "收藏、自定义电台和均衡器预设",
"backupImportSubtitle": "Restore from a backup file", "backupImportTitle": "导入配置",
"backupShareSubject": "PluriWave — backup", "backupImportSubtitle": "从备份文件恢复",
"backupShareText": "PluriWave configuration exported on {date}", "backupShareSubject": "PluriWave — 备份",
"backupExportError": "Export error: {error}", "backupShareText": "PluriWave 配置已于 {date} 导出",
"backupImportConfirmMessage": "This will add favorites, stations, and presets from the file. Continue?", "backupExportError": "导出错误:{error}",
"backupImportSuccess": "Configuration imported successfully", "backupImportConfirmMessage": "这会添加文件中的收藏、电台和预设。要继续吗?",
"backupImportError": "Import error: {error}", "backupImportSuccess": "配置已成功导入",
"appVersionLoading": "Loading version...", "backupImportError": "导入错误:{error}",
"appVersionSubtitle": "{version} - World radio", "appVersionLoading": "正在加载版本...",
"savedFavoritesTitle": "Saved favorites", "appVersionSubtitle": "{version} - 全球电台",
"stationFilterTitle": "Station filter", "savedFavoritesTitle": "已保存的收藏",
"stationFilterSubtitle": "Only stations verified as active", "stationFilterTitle": "电台筛选",
"backgroundAudioTitle": "Background audio", "stationFilterSubtitle": "仅显示已验证为活跃的电台",
"backgroundAudioSubtitle": "Continues when the screen turns off", "backgroundAudioTitle": "后台音频",
"backgroundAudioSubtitle": "屏幕关闭后继续播放",
"dash": "—", "dash": "—",
"@recordingsPathSaveError": { "@recordingsPathSaveError": {
"placeholders": { "placeholders": {
@@ -148,15 +176,15 @@
"version": {} "version": {}
} }
}, },
"cancelAction": "Cancel", "cancelAction": "取消",
"equalizerTitle": "Equalizer", "equalizerTitle": "均衡器",
"recordingsOpenFolder": "Open folder", "recordingsOpenFolder": "打开文件夹",
"recordingsOpenFolderError": "Could not open the folder: {error}", "recordingsOpenFolderError": "无法打开文件夹:{error}",
"recordingsMaxSizeTitle": "Maximum recording size", "recordingsMaxSizeTitle": "最大录音大小",
"recordingsMaxSizeSubtitle": "Current limit: {size} MB", "recordingsMaxSizeSubtitle": "当前限制:{size} MB",
"recordingsMaxSizeDialogTitle": "Maximum size per recording", "recordingsMaxSizeDialogTitle": "每段录音的最大大小",
"recordingsMaxSizeMbLabel": "Maximum megabytes", "recordingsMaxSizeMbLabel": "最大兆字节数",
"recordingsMaxSizeSaved": "Recording limit updated to {size} MB", "recordingsMaxSizeSaved": "录音限制已更新为 {size} MB",
"@recordingsOpenFolderError": { "@recordingsOpenFolderError": {
"placeholders": { "placeholders": {
"error": {} "error": {}
@@ -176,33 +204,33 @@
} }
} }
}, },
"stationOrderTitle": "Station order", "stationOrderTitle": "电台排序",
"stationOrderByName": "By name", "stationOrderByName": "按名称",
"stationOrderByQuality": "By quality", "stationOrderByQuality": "按质量",
"stationOrderScopeDescription": "Applies to favorites, searches, nearby stations and quick lists.", "stationOrderScopeDescription": "适用于收藏、搜索、附近电台和快捷列表。",
"favoriteGroupsTitle": "Favorite lists", "favoriteGroupsTitle": "收藏列表",
"favoriteGroupsDescription": "Create short lists to organize your saved stations.", "favoriteGroupsDescription": "创建短列表来整理已保存的电台。",
"favoriteGroupsAdd": "Add list", "favoriteGroupsAdd": "添加列表",
"favoriteGroupsEdit": "Edit list", "favoriteGroupsEdit": "编辑列表",
"favoriteGroupsDelete": "Delete list", "favoriteGroupsDelete": "删除列表",
"favoriteGroupsNameLabel": "List name", "favoriteGroupsNameLabel": "列表名称",
"favoriteGroupsNameTooLong": "Maximum 28 characters.", "favoriteGroupsNameTooLong": "最多 28 个字符。",
"favoriteGroupsUnassigned": "Unassigned", "favoriteGroupsUnassigned": "未分配",
"favoriteGroupsProtectedHint": "Default list: it cannot be edited or deleted.", "favoriteGroupsProtectedHint": "默认列表:不能编辑或删除。",
"favoriteGroupsCreated": "List created", "favoriteGroupsCreated": "列表已创建",
"favoriteGroupsUpdated": "List updated", "favoriteGroupsUpdated": "列表已更新",
"favoriteGroupsDeleted": "List deleted; its stations return to Unassigned.", "favoriteGroupsDeleted": "列表已删除;其中的电台已回到未分配。",
"favoriteGroupsAssign": "Move to list", "favoriteGroupsAssign": "移动到列表",
"favoriteGroupsAssignSubtitle": "Current list: {groupName}", "favoriteGroupsAssignSubtitle": "当前列表:{groupName}",
"favoriteGroupsAssigned": "{stationName} moved to {groupName}", "favoriteGroupsAssigned": "{stationName} 已移动到 {groupName}",
"favoritesTitle": "Favorites", "favoritesTitle": "收藏",
"favoritesEmptyTitle": "No favorites yet", "favoritesEmptyTitle": "还没有收藏",
"favoritesEmptySubtitle": "Tap the heart on any station to save it to your collection.", "favoritesEmptySubtitle": "点按任意电台上的爱心,将它保存到你的收藏。",
"favoritesHeaderSubtitle": "Organize your collection by lists and keep important radios close.", "favoritesHeaderSubtitle": "按列表整理你的收藏,把重要电台放在手边。",
"favoritesCollection": "Collection", "favoritesCollection": "收藏集",
"favoritesSavedCount": "{count} saved", "favoritesSavedCount": "已保存 {count} ",
"favoritesRemoveTooltip": "Remove from favorites", "favoritesRemoveTooltip": "从收藏中移除",
"favoritesRemovedMessage": "{stationName} removed from favorites", "favoritesRemovedMessage": "{stationName} 已从收藏中移除",
"@favoriteGroupsAssignSubtitle": { "@favoriteGroupsAssignSubtitle": {
"placeholders": { "placeholders": {
"groupName": {} "groupName": {}
@@ -226,18 +254,18 @@
"stationName": {} "stationName": {}
} }
}, },
"alarmPostponedCurrentExecution": "Alarm postponed for this occurrence.", "alarmPostponedCurrentExecution": "本次闹钟已推迟。",
"searchScreenTitle": "搜索电台", "searchScreenTitle": "搜索信号",
"searchScreenSubtitle": "按名称、国家/地区或语言查找电台,支持快速筛选和高对比度显示。", "searchScreenSubtitle": "按名称、国家/地区或语言查找电台,支持快速筛选和高对比度显示。",
"searchFiltersLabel": "筛选", "searchFiltersLabel": "筛选",
"searchHint": "Radio Horizon、爵士、新闻...", "searchHint": "地平线电台、爵士、新闻...",
"searchCountryFilterLabel": "国家/地区", "searchCountryFilterLabel": "国家/地区",
"searchLanguageFilterLabel": "语言", "searchLanguageFilterLabel": "语言",
"searchMinQualityFilterLabel": "最低质量", "searchMinQualityFilterLabel": "最低质量",
"searchEmptyTitle": "搜索电台", "searchEmptyTitle": "搜索电台",
"searchNoResultsTitle": "没有结果", "searchNoResultsTitle": "没有结果",
"searchEmptySubtitle": "使用顶部搜索栏或筛选标签,发现来自世界各地的电台。", "searchEmptySubtitle": "使用顶部搜索栏或筛选标签,发现世界各地的电台信号。",
"searchNoResultsSubtitle": "试减少筛选条件,或换个名称搜索,找到正在播出的电台。", "searchNoResultsSubtitle": "试减少筛选条件,或换个名称搜索,找到正在播出的电台。",
"countrySpain": "西班牙", "countrySpain": "西班牙",
"countryUsa": "美国", "countryUsa": "美国",
"countryMexico": "墨西哥", "countryMexico": "墨西哥",
@@ -257,9 +285,9 @@
"languageNameJapanese": "日语", "languageNameJapanese": "日语",
"languageNameArabic": "阿拉伯语", "languageNameArabic": "阿拉伯语",
"languageNameRussian": "俄语", "languageNameRussian": "俄语",
"homeScreenSubtitle": "Live global radio with clean signals, smart favorites, and a show-style visual experience.", "homeScreenSubtitle": "全球直播电台,清晰信号、智能收藏和竞赛风格的视觉体验。",
"exploreStations": "Explore stations", "exploreStations": "探索电台",
"stationsCount": "{count} stations", "stationsCount": "{count} 个电台",
"@stationsCount": { "@stationsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -267,36 +295,36 @@
} }
} }
}, },
"qualityHd": "HD quality", "qualityHd": "高清音质",
"nearYou": "Near you", "nearYou": "你附近",
"nearYouInCountry": "Near you ? {country}", "nearYouInCountry": "你附近 · {country}",
"@nearYouInCountry": { "@nearYouInCountry": {
"placeholders": { "placeholders": {
"country": {} "country": {}
} }
}, },
"detectAction": "Detect", "detectAction": "检测",
"liveRadar": "Live radar", "liveRadar": "直播雷达",
"genresTitle": "Genres", "genresTitle": "类型",
"retryAction": "Retry", "retryAction": "重试",
"noStationsAvailable": "No stations available", "noStationsAvailable": "没有可用电台",
"noStationsAvailableSubtitle": "Try refreshing or choosing another genre to capture a signal again.", "noStationsAvailableSubtitle": "尝试刷新或选择其他类型,重新捕捉信号。",
"genrePop": "Pop", "genrePop": "流行",
"genreRock": "Rock", "genreRock": "摇滚",
"genreJazz": "Jazz", "genreJazz": "爵士",
"genreClassical": "Classical", "genreClassical": "古典",
"genreElectronic": "Electronic", "genreElectronic": "电子",
"genreNews": "News", "genreNews": "新闻",
"genreTalk": "Talk", "genreTalk": "谈话",
"genreHipHop": "Hip-hop", "genreHipHop": "嘻哈",
"genreCountry": "Country", "genreCountry": "乡村",
"genreMetal": "Metal", "genreMetal": "金属",
"genreReggae": "Reggae", "genreReggae": "雷鬼",
"genreLatin": "Latin", "genreLatin": "拉丁",
"alarmScreenTitle": "Music wake-up", "alarmScreenTitle": "音乐唤醒",
"alarmScreenSubtitle": "Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.", "alarmScreenSubtitle": "带电台、安全声音、智能假期和始终可见下次执行时间的闹钟。",
"createAlarmAction": "Create alarm", "createAlarmAction": "创建闹钟",
"alarmsCount": "{count} alarms", "alarmsCount": "{count} 个闹钟",
"@alarmsCount": { "@alarmsCount": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -304,10 +332,10 @@
} }
} }
}, },
"activeAlarmsWithoutNextTitle": "Active alarms without a next occurrence", "activeAlarmsWithoutNextTitle": "没有下次执行时间的活跃闹钟",
"noActiveAlarms": "No active alarms", "noActiveAlarms": "没有活跃闹钟",
"nextAlarmTitle": "Next alarm", "nextAlarmTitle": "下一个闹钟",
"activeAlarmsWithoutNextSubtitle": "There are {count} active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.", "activeAlarmsWithoutNextSubtitle": "有 {count} 个活跃闹钟,但现在没有有效的未来日期。请检查日期、星期和假期。",
"@activeAlarmsWithoutNextSubtitle": { "@activeAlarmsWithoutNextSubtitle": {
"placeholders": { "placeholders": {
"count": { "count": {
@@ -315,10 +343,10 @@
} }
} }
}, },
"createAlarmHint": "Create an alarm and PluriWave will calculate the next occurrence automatically.", "createAlarmHint": "创建闹钟后,PluriWave 会自动计算下次执行时间。",
"alarmVacationPlay": "Plays during vacations", "alarmVacationPlay": "假期时响铃",
"alarmVacationPause": "Paused during vacations", "alarmVacationPause": "假期时暂停",
"alarmFadeInLabel": "Fade-in {seconds}s", "alarmFadeInLabel": "渐入 {seconds}s",
"@alarmFadeInLabel": { "@alarmFadeInLabel": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -326,61 +354,61 @@
} }
} }
}, },
"alarmNextExecution": "Next occurrence: {date}", "alarmNextExecution": "下次执行:{date}",
"@alarmNextExecution": { "@alarmNextExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmNoNextExecution": "It has no active next occurrence.", "alarmNoNextExecution": "没有活跃的下次执行。",
"alarmSkippedExecution": "One occurrence was skipped: {date}.", "alarmSkippedExecution": "已跳过一次执行:{date}",
"@alarmSkippedExecution": { "@alarmSkippedExecution": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"editAction": "Edit", "editAction": "编辑",
"skipNextAction": "Skip next", "skipNextAction": "跳过下一个",
"deleteTooltip": "Delete", "deleteTooltip": "删除",
"alarmSkippedNoNextSnackbar": "Alarm skipped. There is no next occurrence left.", "alarmSkippedNoNextSnackbar": "已跳过闹钟。没有剩余的下次执行。",
"alarmSkippedReturnsSnackbar": "Alarm skipped. It will return on {date}.", "alarmSkippedReturnsSnackbar": "已跳过闹钟。将于 {date} 恢复。",
"@alarmSkippedReturnsSnackbar": { "@alarmSkippedReturnsSnackbar": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"alarmVacationPausedNoNext": "It is paused for vacations ({vacationName}) and has no next occurrence.", "alarmVacationPausedNoNext": "因假期({vacationName})暂停,且没有下次执行。",
"@alarmVacationPausedNoNext": { "@alarmVacationPausedNoNext": {
"placeholders": { "placeholders": {
"vacationName": {} "vacationName": {}
} }
}, },
"alarmVacationPausedReturns": "It is paused for vacations ({vacationName}) and returns on {date}.", "alarmVacationPausedReturns": "因假期({vacationName})暂停,将于 {date} 恢复。",
"@alarmVacationPausedReturns": { "@alarmVacationPausedReturns": {
"placeholders": { "placeholders": {
"vacationName": {}, "vacationName": {},
"date": {} "date": {}
} }
}, },
"alarmVacationReturns": "With vacations enabled, it will ring again on {date}.", "alarmVacationReturns": "假期启用时,将于 {date} 再次响铃。",
"@alarmVacationReturns": { "@alarmVacationReturns": {
"placeholders": { "placeholders": {
"date": {} "date": {}
} }
}, },
"defaultAlarmName": "Music alarm", "defaultAlarmName": "音乐闹钟",
"newAlarmTitle": "New alarm", "newAlarmTitle": "新闹钟",
"editAlarmTitle": "Edit alarm", "editAlarmTitle": "编辑闹钟",
"nameField": "Name", "nameField": "名称",
"timeField": "Time", "timeField": "时间",
"dateField": "Date", "dateField": "日期",
"onceOption": "Once", "onceOption": "一次",
"dailyOption": "Daily", "dailyOption": "每天",
"weekdaysOption": "Weekdays", "weekdaysOption": "星期",
"soundAndVolumeSection": "Sound and volume", "soundAndVolumeSection": "声音和音量",
"alarmFadeInTitle": "Alarm fade-in", "alarmFadeInTitle": "闹钟渐入",
"alarmFadeInOff": "0 s (no transition)", "alarmFadeInOff": "0 s(无过渡)",
"alarmFadeInSummary": "{seconds} s (from 5% to the selected volume)", "alarmFadeInSummary": "{seconds} s(从 5% 到所选音量)",
"@alarmFadeInSummary": { "@alarmFadeInSummary": {
"placeholders": { "placeholders": {
"seconds": { "seconds": {
@@ -388,22 +416,22 @@
} }
} }
}, },
"internalSafeSoundLabel": "Internal safe sound", "internalSafeSoundLabel": "内部安全声音",
"soundWarmSunrise": "Warm sunrise", "soundWarmSunrise": "温暖日出",
"soundSoftBell": "Soft bell", "soundSoftBell": "柔和铃声",
"soundDigitalPulse": "Digital pulse", "soundDigitalPulse": "数字脉冲",
"favoriteStationLabel": "Favorite station", "favoriteStationLabel": "收藏电台",
"noStationUseInternalSound": "No station: use internal sound", "noStationUseInternalSound": "无电台:使用内部声音",
"saveFavoritesAlarmHint": "Save stations in Favorites to use them as a music alarm.", "saveFavoritesAlarmHint": "将电台保存到收藏,即可把它们用作音乐闹钟。",
"useCurrentStationAction": "Use current station", "useCurrentStationAction": "使用当前电台",
"playDuringVacations": "Play during vacations", "playDuringVacations": "假期期间响铃",
"playDuringVacationsHint": "If you turn this off, the next occurrence will jump to the first valid day.", "playDuringVacationsHint": "如果关闭,下次执行会跳到第一个有效日期。",
"saveAlarmAction": "Save alarm", "saveAlarmAction": "保存闹钟",
"chooseOneWeekdayError": "Choose at least one weekday.", "chooseOneWeekdayError": "请至少选择一周中的一天。",
"androidReliabilityReview": "Review Android reliability", "androidReliabilityReview": "检查 Android 可靠性",
"statusOk": "OK", "statusOk": "正常",
"statusPending": "pending", "statusPending": "待处理",
"androidReliabilityStatus": "Reliability: exact {exact} ? notifications {notifications} ? screen {screen}", "androidReliabilityStatus": "可靠性:精确闹钟 {exact} · 通知 {notifications} · 屏幕 {screen}",
"@androidReliabilityStatus": { "@androidReliabilityStatus": {
"placeholders": { "placeholders": {
"exact": {}, "exact": {},
@@ -411,19 +439,165 @@
"screen": {} "screen": {}
} }
}, },
"vacationRangesTitle": "Vacation ranges", "vacationRangesTitle": "假期范围",
"addAction": "Add", "addAction": "添加",
"vacationRangesHint": "If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.", "vacationRangesHint": "如果闹钟设置为“假期时暂停”,会自动跳过这些范围。",
"noVacationRangesLoaded": "No ranges loaded.", "noVacationRangesLoaded": "未加载范围。",
"deleteRangeTooltip": "Delete range", "deleteRangeTooltip": "删除范围",
"vacationsDefaultName": "Vacation", "vacationsDefaultName": "假期",
"newVacationRangeTitle": "New vacation range", "newVacationRangeTitle": "新的假期范围",
"startField": "Start", "startField": "开始",
"endField": "End", "endField": "结束",
"saveRangeAction": "Save range", "saveRangeAction": "保存范围",
"noAlarmsYetTitle": "There are no alarms yet.", "noAlarmsYetTitle": "还没有闹钟。",
"noAlarmsYetSubtitle": "Create one to design your musical wake-up.", "noAlarmsYetSubtitle": "创建一个,设计你的音乐唤醒。",
"ringingInternalAudioActive": "Playing with internal safe audio.", "ringingInternalAudioActive": "正在使用内部安全音频响铃。",
"ringingPreparingInternalAudio": "Preparing internal safe audio.", "ringingPreparingInternalAudio": "正在准备内部安全音频。",
"stopAlarmAction": "Stop alarm" "stopAlarmAction": "停止闹钟",
"pauseAction": "暂停",
"miniPlayerOpenLabel": "打开 {stationName} 的播放器",
"@miniPlayerOpenLabel": {
"placeholders": {
"stationName": {}
}
},
"playerIconLabel": "播放器",
"playbackStatusConnecting": "正在连接...",
"playbackStatusLive": "直播中",
"playbackStatusPaused": "已暂停",
"playbackStatusConnectionError": "连接错误",
"playbackStatusStopped": "已停止",
"stationSemanticLabel": "电台 {stationName}",
"@stationSemanticLabel": {
"placeholders": {
"stationName": {}
}
},
"favoritesAddTooltip": "添加到收藏",
"favoritesAddedMessage": "已将 {stationName} 添加到收藏",
"@favoritesAddedMessage": {
"placeholders": {
"stationName": {}
}
},
"stationIconLabel": "电台图标",
"liveNow": "直播中",
"equalizerBandLabel": "{band} 频段",
"@equalizerBandLabel": {
"placeholders": {
"band": {}
}
},
"equalizerBandValue": "{value} 分贝",
"@equalizerBandValue": {
"placeholders": {
"value": {}
}
},
"equalizerPresetFlat": "平直",
"equalizerPresetRock": "摇滚",
"equalizerPresetPop": "流行",
"equalizerPresetBassBoost": "低音增强",
"equalizerPresetJazz": "爵士",
"equalizerPresetVoice": "人声",
"equalizerPresetCustom": "自定义",
"onboardingTitle": "欢迎使用 PluriWave",
"onboardingNewsTitle": "新功能",
"onboardingStartAction": "开始",
"onboardingCloseTooltip": "关闭",
"radioRecordingError": "录制电台时出错:{error}",
"@radioRecordingError": {
"placeholders": {
"error": {}
}
},
"radioApiConnectionError": "无法连接到电台 API",
"radioSearchError": "搜索出错。请检查你的连接。",
"radioLoadMoreStationsError": "无法加载更多电台。",
"radioNearbyStationsError": "未能检测到附近的电台。请使用国家/地区筛选器。",
"radioCannotPlayStation": "无法播放“{stationName}”",
"@radioCannotPlayStation": {
"placeholders": {
"stationName": {}
}
},
"recordingSelectStationFirst": "请先选择一个电台再录制。",
"recordingStartError": "无法开始录制:{error}",
"@recordingStartError": {
"placeholders": {
"error": {}
}
},
"unsupportedConfigVersion": "不支持的配置版本",
"audioErrorGeneric": "播放错误",
"audioErrorNoInternet": "无互联网连接",
"audioErrorInvalidUrl": "电台 URL 无效",
"audioErrorNotFound": "该电台不可用(404 错误)",
"audioErrorTimeout": "连接超时",
"audioErrorCannotConnect": "无法连接到电台",
"audioErrorUnsupportedFormat": "不支持的音频流格式",
"audioErrorDecode": "解码音频流时出错",
"audioErrorCleartext": "此电台使用未加密的 HTTP,不被允许",
"audioErrorSsl": "电台的 SSL 证书无效",
"audioErrorCannotPlay": "无法播放此电台",
"audioErrorUnexpectedPlayback": "播放时出现意外错误",
"androidExactAlarmScheduleError": "Android 无法安排精确闹钟。请检查精确闹钟权限。",
"recordingPathEmptyError": "录制路径不能为空",
"recordingMaxSizeInvalidError": "最大大小必须大于零",
"recordingAlreadyActiveError": "已有录制正在进行",
"alarmRingingFallbackActive": "正在使用内部安全音频播放。",
"alarmRingingPreparingFallback": "正在准备内部安全音频。",
"alarmRingingTryingStation": "正在尝试以最高可用音质播放你的电台。",
"alarmScheduleOnce": "一次 · {date}",
"@alarmScheduleOnce": {
"placeholders": {
"date": {}
}
},
"alarmScheduleWeekdays": "星期:{days}",
"@alarmScheduleWeekdays": {
"placeholders": {
"days": {}
}
},
"androidReliabilityTitle": "检查 Android 可靠性",
"closeAction": "关闭",
"customOption": "自定义",
"endLabel": "结束",
"equalizerDisable": "关闭均衡器",
"helpTitle": "帮助和教程",
"helpSubtitle": "查看 PluriWave 的功能、技巧和新内容。",
"indefiniteOption": "不限时",
"invalidNumber": "数字无效",
"nameLabel": "名称",
"notPlaying": "未播放",
"oneTimeOption": "一次",
"pausePlaybackTooltip": "暂停播放",
"qualityOriginal": "原始质量:{quality}",
"@qualityOriginal": {
"placeholders": {
"quality": {}
}
},
"qualityUnknown": "未提供质量信息",
"recordAction": "录制",
"recordDurationTitle": "录制时长",
"recordRadioSubtitle": "选择要录制多长时间。",
"recordRadioTitle": "录制电台",
"recordingActiveTitle": "正在录制电台",
"recordingDirectTitle": "直接录制",
"recordingsOpenFolderPlainError": "无法打开录音文件夹",
"recordingsOpenLatest": "打开最新录音",
"recordingsOpenLatestError": "无法打开最新录音",
"startLabel": "开始",
"startPlaybackTooltip": "开始播放",
"stopAction": "停止",
"stopPlaybackTooltip": "停止播放",
"weekdayShortMonday": "周一",
"weekdayShortTuesday": "周二",
"weekdayShortWednesday": "周三",
"weekdayShortThursday": "周四",
"weekdayShortFriday": "周五",
"weekdayShortSaturday": "周六",
"weekdayShortSunday": "周日"
} }
+29
View File
@@ -0,0 +1,29 @@
import 'gen/app_localizations.dart';
const _legacyAlarmName = 'Alarma musical';
const _legacyVacationName = 'Vacaciones';
const _legacyUnnamedStation = 'Sin nombre';
String localizedAlarmName(AppLocalizations l10n, String rawName) {
final name = rawName.trim();
if (name.isEmpty || name == _legacyAlarmName) {
return l10n.defaultAlarmName;
}
return name;
}
String localizedVacationName(AppLocalizations l10n, String rawName) {
final name = rawName.trim();
if (name.isEmpty || name == _legacyVacationName) {
return l10n.vacationsDefaultName;
}
return name;
}
String localizedStationName(AppLocalizations l10n, String rawName) {
final name = rawName.trim();
if (name.isEmpty || name == _legacyUnnamedStation) {
return l10n.unnamedStation;
}
return name;
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+740
View File
@@ -57,6 +57,30 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get secondsLabel => 'Seconds'; String get secondsLabel => 'Seconds';
@override
String durationHoursMinutesSeconds(
Object hours,
Object minutes,
Object seconds,
) {
return '$hours h $minutes min $seconds s';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes min $seconds s';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes min';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds s';
}
@override @override
String get saveQuickAccess => 'Save as quick access'; String get saveQuickAccess => 'Save as quick access';
@@ -239,6 +263,9 @@ class AppLocalizationsEn extends AppLocalizations {
@override @override
String get stationNameLabel => 'Name *'; String get stationNameLabel => 'Name *';
@override
String get unnamedStation => 'Unnamed station';
@override @override
String get requiredField => 'Required field'; String get requiredField => 'Required field';
@@ -448,4 +475,717 @@ class AppLocalizationsEn extends AppLocalizations {
String favoritesRemovedMessage(Object stationName) { String favoritesRemovedMessage(Object stationName) {
return '$stationName removed from favorites'; return '$stationName removed from favorites';
} }
@override
String get alarmPostponedCurrentExecution =>
'Alarm postponed for this occurrence.';
@override
String get searchScreenTitle => 'Search signal';
@override
String get searchScreenSubtitle =>
'Find stations by name, country, or language with fast filters and high contrast.';
@override
String get searchFiltersLabel => 'Filters';
@override
String get searchHint => 'Radio Horizon, jazz, news...';
@override
String get searchCountryFilterLabel => 'Country';
@override
String get searchLanguageFilterLabel => 'Language';
@override
String get searchMinQualityFilterLabel => 'Minimum quality';
@override
String get searchEmptyTitle => 'Search for a station';
@override
String get searchNoResultsTitle => 'No results';
@override
String get searchEmptySubtitle =>
'Use the top bar or chips to discover stations from around the world.';
@override
String get searchNoResultsSubtitle =>
'Try removing filters or typing another name to find an active station.';
@override
String get countrySpain => 'Spain';
@override
String get countryUsa => 'USA';
@override
String get countryMexico => 'Mexico';
@override
String get countryArgentina => 'Argentina';
@override
String get countryUk => 'UK';
@override
String get countryFrance => 'France';
@override
String get countryGermany => 'Germany';
@override
String get countryItaly => 'Italy';
@override
String get countryBrazil => 'Brazil';
@override
String get countryJapan => 'Japan';
@override
String get languageNameSpanish => 'Spanish';
@override
String get languageNameEnglish => 'English';
@override
String get languageNameFrench => 'French';
@override
String get languageNameGerman => 'German';
@override
String get languageNamePortuguese => 'Portuguese';
@override
String get languageNameItalian => 'Italian';
@override
String get languageNameJapanese => 'Japanese';
@override
String get languageNameArabic => 'Arabic';
@override
String get languageNameRussian => 'Russian';
@override
String get homeScreenSubtitle =>
'Live global radio with clean signals, smart favorites, and a show-style visual experience.';
@override
String get exploreStations => 'Explore stations';
@override
String stationsCount(int count) {
return '$count stations';
}
@override
String get qualityHd => 'HD quality';
@override
String get nearYou => 'Near you';
@override
String nearYouInCountry(Object country) {
return 'Near you · $country';
}
@override
String get detectAction => 'Detect';
@override
String get liveRadar => 'Live radar';
@override
String get genresTitle => 'Genres';
@override
String get retryAction => 'Retry';
@override
String get noStationsAvailable => 'No stations available';
@override
String get noStationsAvailableSubtitle =>
'Try refreshing or choosing another genre to capture a signal again.';
@override
String get genrePop => 'Pop';
@override
String get genreRock => 'Rock';
@override
String get genreJazz => 'Jazz';
@override
String get genreClassical => 'Classical';
@override
String get genreElectronic => 'Electronic';
@override
String get genreNews => 'News';
@override
String get genreTalk => 'Talk';
@override
String get genreHipHop => 'Hip-hop';
@override
String get genreCountry => 'Country';
@override
String get genreMetal => 'Metal';
@override
String get genreReggae => 'Reggae';
@override
String get genreLatin => 'Latin';
@override
String get alarmScreenTitle => 'Music wake-up';
@override
String get alarmScreenSubtitle =>
'Alarms with radio, safe fallback sound, smart vacations, and the next occurrence always visible.';
@override
String get createAlarmAction => 'Create alarm';
@override
String alarmsCount(int count) {
return '$count alarms';
}
@override
String get activeAlarmsWithoutNextTitle =>
'Active alarms without a next occurrence';
@override
String get noActiveAlarms => 'No active alarms';
@override
String get nextAlarmTitle => 'Next alarm';
@override
String activeAlarmsWithoutNextSubtitle(int count) {
return 'There are $count active alarm(s), but they do not currently have a valid future date. Check date, weekdays, and vacations.';
}
@override
String get createAlarmHint =>
'Create an alarm and PluriWave will calculate the next occurrence automatically.';
@override
String get alarmVacationPlay => 'Plays during vacations';
@override
String get alarmVacationPause => 'Paused during vacations';
@override
String alarmFadeInLabel(int seconds) {
return 'Fade-in ${seconds}s';
}
@override
String alarmNextExecution(Object date) {
return 'Next occurrence: $date';
}
@override
String get alarmNoNextExecution => 'It has no active next occurrence.';
@override
String alarmSkippedExecution(Object date) {
return 'One occurrence was skipped: $date.';
}
@override
String get editAction => 'Edit';
@override
String get skipNextAction => 'Skip next';
@override
String get deleteTooltip => 'Delete';
@override
String get alarmSkippedNoNextSnackbar =>
'Alarm skipped. There is no next occurrence left.';
@override
String alarmSkippedReturnsSnackbar(Object date) {
return 'Alarm skipped. It will return on $date.';
}
@override
String alarmVacationPausedNoNext(Object vacationName) {
return 'It is paused for vacations ($vacationName) and has no next occurrence.';
}
@override
String alarmVacationPausedReturns(Object vacationName, Object date) {
return 'It is paused for vacations ($vacationName) and returns on $date.';
}
@override
String alarmVacationReturns(Object date) {
return 'With vacations enabled, it will ring again on $date.';
}
@override
String get defaultAlarmName => 'Music alarm';
@override
String get newAlarmTitle => 'New alarm';
@override
String get editAlarmTitle => 'Edit alarm';
@override
String get nameField => 'Name';
@override
String get timeField => 'Time';
@override
String get dateField => 'Date';
@override
String get onceOption => 'Once';
@override
String get dailyOption => 'Daily';
@override
String get weekdaysOption => 'Weekdays';
@override
String get soundAndVolumeSection => 'Sound and volume';
@override
String get alarmFadeInTitle => 'Alarm fade-in';
@override
String get alarmFadeInOff => '0 s (no transition)';
@override
String alarmFadeInSummary(int seconds) {
return '$seconds s (from 5% to the selected volume)';
}
@override
String get internalSafeSoundLabel => 'Internal safe sound';
@override
String get soundWarmSunrise => 'Warm sunrise';
@override
String get soundSoftBell => 'Soft bell';
@override
String get soundDigitalPulse => 'Digital pulse';
@override
String get favoriteStationLabel => 'Favorite station';
@override
String get noStationUseInternalSound => 'No station: use internal sound';
@override
String get saveFavoritesAlarmHint =>
'Save stations in Favorites to use them as a music alarm.';
@override
String get useCurrentStationAction => 'Use current station';
@override
String get playDuringVacations => 'Play during vacations';
@override
String get playDuringVacationsHint =>
'If you turn this off, the next occurrence will jump to the first valid day.';
@override
String get saveAlarmAction => 'Save alarm';
@override
String get chooseOneWeekdayError => 'Choose at least one weekday.';
@override
String get androidReliabilityReview => 'Review Android reliability';
@override
String get statusOk => 'OK';
@override
String get statusPending => 'pending';
@override
String androidReliabilityStatus(
Object exact,
Object notifications,
Object screen,
) {
return 'Reliability: exact $exact · notifications $notifications · screen $screen';
}
@override
String get vacationRangesTitle => 'Vacation ranges';
@override
String get addAction => 'Add';
@override
String get vacationRangesHint =>
'If an alarm is set to \"Paused during vacations\", it automatically skips these ranges.';
@override
String get noVacationRangesLoaded => 'No ranges loaded.';
@override
String get deleteRangeTooltip => 'Delete range';
@override
String get vacationsDefaultName => 'Vacation';
@override
String get newVacationRangeTitle => 'New vacation range';
@override
String get startField => 'Start';
@override
String get endField => 'End';
@override
String get saveRangeAction => 'Save range';
@override
String get noAlarmsYetTitle => 'There are no alarms yet.';
@override
String get noAlarmsYetSubtitle =>
'Create one to design your musical wake-up.';
@override
String get ringingInternalAudioActive => 'Playing with internal safe audio.';
@override
String get ringingPreparingInternalAudio => 'Preparing internal safe audio.';
@override
String get stopAlarmAction => 'Stop alarm';
@override
String get pauseAction => 'Pause';
@override
String miniPlayerOpenLabel(Object stationName) {
return 'Open player for $stationName';
}
@override
String get playerIconLabel => 'Player';
@override
String get playbackStatusConnecting => 'Connecting...';
@override
String get playbackStatusLive => 'Live';
@override
String get playbackStatusPaused => 'Paused';
@override
String get playbackStatusConnectionError => 'Connection error';
@override
String get playbackStatusStopped => 'Stopped';
@override
String stationSemanticLabel(Object stationName) {
return 'Station $stationName';
}
@override
String get favoritesAddTooltip => 'Add to favorites';
@override
String favoritesAddedMessage(Object stationName) {
return '$stationName added to favorites';
}
@override
String get stationIconLabel => 'Station icon';
@override
String get liveNow => 'Live';
@override
String equalizerBandLabel(Object band) {
return '$band band';
}
@override
String equalizerBandValue(Object value) {
return '$value decibels';
}
@override
String get equalizerPresetFlat => 'Flat';
@override
String get equalizerPresetRock => 'Rock';
@override
String get equalizerPresetPop => 'Pop';
@override
String get equalizerPresetBassBoost => 'Bass Boost';
@override
String get equalizerPresetJazz => 'Jazz';
@override
String get equalizerPresetVoice => 'Voice';
@override
String get equalizerPresetCustom => 'Custom';
@override
String get onboardingTitle => 'Welcome to PluriWave';
@override
String get onboardingNewsTitle => 'What\'s new';
@override
String get onboardingStartAction => 'Start';
@override
String get onboardingCloseTooltip => 'Close';
@override
String radioRecordingError(Object error) {
return 'Error recording the radio: $error';
}
@override
String get radioApiConnectionError => 'No connection to the radio API';
@override
String get radioSearchError => 'Search error. Check your connection.';
@override
String get radioLoadMoreStationsError => 'Could not load more stations.';
@override
String get radioNearbyStationsError =>
'We could not detect nearby stations. Use country filters.';
@override
String radioCannotPlayStation(Object stationName) {
return 'Cannot play \"$stationName\"';
}
@override
String get recordingSelectStationFirst =>
'Select a station before recording.';
@override
String recordingStartError(Object error) {
return 'Could not start recording: $error';
}
@override
String get unsupportedConfigVersion => 'Unsupported configuration version';
@override
String get audioErrorGeneric => 'Playback error';
@override
String get audioErrorNoInternet => 'No internet connection';
@override
String get audioErrorInvalidUrl => 'The radio URL is not valid';
@override
String get audioErrorNotFound => 'The radio is not available (404 error)';
@override
String get audioErrorTimeout => 'Connection timed out';
@override
String get audioErrorCannotConnect => 'Cannot connect to the radio';
@override
String get audioErrorUnsupportedFormat => 'Unsupported stream format';
@override
String get audioErrorDecode => 'Error decoding the audio stream';
@override
String get audioErrorCleartext =>
'This radio uses unencrypted HTTP, which is not allowed';
@override
String get audioErrorSsl => 'Invalid SSL certificate on the radio';
@override
String get audioErrorCannotPlay => 'This radio cannot be played';
@override
String get audioErrorUnexpectedPlayback => 'Unexpected playback error';
@override
String get androidExactAlarmScheduleError =>
'Android could not schedule an exact alarm. Check the exact alarm permission.';
@override
String get recordingPathEmptyError => 'The recording path cannot be empty';
@override
String get recordingMaxSizeInvalidError =>
'The maximum size must be greater than zero';
@override
String get recordingAlreadyActiveError =>
'A recording is already in progress';
@override
String get alarmRingingFallbackActive => 'Playing with internal safe audio.';
@override
String get alarmRingingPreparingFallback => 'Preparing internal safe audio.';
@override
String get alarmRingingTryingStation =>
'Trying to play your station at the highest available quality.';
@override
String alarmScheduleOnce(Object date) {
return 'Once · $date';
}
@override
String alarmScheduleWeekdays(Object days) {
return 'Days: $days';
}
@override
String get androidReliabilityTitle => 'Review Android reliability';
@override
String get closeAction => 'Close';
@override
String get customOption => 'Custom';
@override
String get endLabel => 'End';
@override
String get equalizerDisable => 'Disable equalizer';
@override
String get helpTitle => 'Help and tutorial';
@override
String get helpSubtitle => 'Review PluriWave features, tips and whats new.';
@override
String get indefiniteOption => 'Indefinite';
@override
String get invalidNumber => 'Invalid number';
@override
String get nameLabel => 'Name';
@override
String get notPlaying => 'Not playing';
@override
String get oneTimeOption => 'Once';
@override
String get pausePlaybackTooltip => 'Pause playback';
@override
String qualityOriginal(Object quality) {
return 'Original quality: $quality';
}
@override
String get qualityUnknown => 'Quality not reported';
@override
String get recordAction => 'Record';
@override
String get recordDurationTitle => 'Recording duration';
@override
String get recordRadioSubtitle => 'Choose how long you want to record.';
@override
String get recordRadioTitle => 'Record radio';
@override
String get recordingActiveTitle => 'Recording radio';
@override
String get recordingDirectTitle => 'Direct recording';
@override
String get recordingsOpenFolderPlainError =>
'Could not open the recordings folder';
@override
String get recordingsOpenLatest => 'Open latest recording';
@override
String get recordingsOpenLatestError => 'Could not open the latest recording';
@override
String get startLabel => 'Start';
@override
String get startPlaybackTooltip => 'Start playback';
@override
String get stopAction => 'Stop';
@override
String get stopPlaybackTooltip => 'Stop playback';
@override
String get weekdayShortMonday => 'Mon';
@override
String get weekdayShortTuesday => 'Tue';
@override
String get weekdayShortWednesday => 'Wed';
@override
String get weekdayShortThursday => 'Thu';
@override
String get weekdayShortFriday => 'Fri';
@override
String get weekdayShortSaturday => 'Sat';
@override
String get weekdayShortSunday => 'Sun';
} }
+746
View File
@@ -57,6 +57,30 @@ class AppLocalizationsEs extends AppLocalizations {
@override @override
String get secondsLabel => 'Segundos'; String get secondsLabel => 'Segundos';
@override
String durationHoursMinutesSeconds(
Object hours,
Object minutes,
Object seconds,
) {
return '$hours h $minutes min $seconds s';
}
@override
String durationMinutesSeconds(Object minutes, Object seconds) {
return '$minutes min $seconds s';
}
@override
String durationMinutesOnly(Object minutes) {
return '$minutes min';
}
@override
String durationSecondsOnly(Object seconds) {
return '$seconds s';
}
@override @override
String get saveQuickAccess => 'Guardar como acceso rápido'; String get saveQuickAccess => 'Guardar como acceso rápido';
@@ -241,6 +265,9 @@ class AppLocalizationsEs extends AppLocalizations {
@override @override
String get stationNameLabel => 'Nombre *'; String get stationNameLabel => 'Nombre *';
@override
String get unnamedStation => 'Sin nombre';
@override @override
String get requiredField => 'Campo obligatorio'; String get requiredField => 'Campo obligatorio';
@@ -451,4 +478,723 @@ class AppLocalizationsEs extends AppLocalizations {
String favoritesRemovedMessage(Object stationName) { String favoritesRemovedMessage(Object stationName) {
return '$stationName eliminada de favoritos'; return '$stationName eliminada de favoritos';
} }
@override
String get alarmPostponedCurrentExecution =>
'Alarma pospuesta para esta ejecución.';
@override
String get searchScreenTitle => 'Buscar señal';
@override
String get searchScreenSubtitle =>
'Encontrá radios por nombre, país o idioma con filtros rápidos y alto contraste.';
@override
String get searchFiltersLabel => 'Filtros';
@override
String get searchHint => 'Radio Horizonte, jazz, noticias...';
@override
String get searchCountryFilterLabel => 'País';
@override
String get searchLanguageFilterLabel => 'Idioma';
@override
String get searchMinQualityFilterLabel => 'Calidad mínima';
@override
String get searchEmptyTitle => 'Buscá una emisora';
@override
String get searchNoResultsTitle => 'Sin resultados';
@override
String get searchEmptySubtitle =>
'Usá la barra superior o los chips para descubrir señales de todo el mundo.';
@override
String get searchNoResultsSubtitle =>
'Probá quitar filtros o escribir otro nombre para encontrar una señal activa.';
@override
String get countrySpain => 'España';
@override
String get countryUsa => 'EE. UU.';
@override
String get countryMexico => 'México';
@override
String get countryArgentina => 'Argentina';
@override
String get countryUk => 'Reino Unido';
@override
String get countryFrance => 'Francia';
@override
String get countryGermany => 'Alemania';
@override
String get countryItaly => 'Italia';
@override
String get countryBrazil => 'Brasil';
@override
String get countryJapan => 'Japón';
@override
String get languageNameSpanish => 'Español';
@override
String get languageNameEnglish => 'Inglés';
@override
String get languageNameFrench => 'Francés';
@override
String get languageNameGerman => 'Alemán';
@override
String get languageNamePortuguese => 'Portugués';
@override
String get languageNameItalian => 'Italiano';
@override
String get languageNameJapanese => 'Japonés';
@override
String get languageNameArabic => 'Árabe';
@override
String get languageNameRussian => 'Ruso';
@override
String get homeScreenSubtitle =>
'Radio global en vivo con señales limpias, favoritos inteligentes y una experiencia visual de concurso.';
@override
String get exploreStations => 'Explorar emisoras';
@override
String stationsCount(int count) {
return '$count radios';
}
@override
String get qualityHd => 'Calidad HD';
@override
String get nearYou => 'Cerca de vos';
@override
String nearYouInCountry(Object country) {
return 'Cerca de vos · $country';
}
@override
String get detectAction => 'Detectar';
@override
String get liveRadar => 'Radar en directo';
@override
String get genresTitle => 'Géneros';
@override
String get retryAction => 'Reintentar';
@override
String get noStationsAvailable => 'No hay emisoras disponibles';
@override
String get noStationsAvailableSubtitle =>
'Probá refrescar o elegir otro género para volver a capturar señal.';
@override
String get genrePop => 'Pop';
@override
String get genreRock => 'Rock';
@override
String get genreJazz => 'Jazz';
@override
String get genreClassical => 'Clásica';
@override
String get genreElectronic => 'Electrónica';
@override
String get genreNews => 'Noticias';
@override
String get genreTalk => 'Charlas';
@override
String get genreHipHop => 'Hip-hop';
@override
String get genreCountry => 'Country';
@override
String get genreMetal => 'Metal';
@override
String get genreReggae => 'Reggae';
@override
String get genreLatin => 'Latina';
@override
String get alarmScreenTitle => 'Despertar musical';
@override
String get alarmScreenSubtitle =>
'Alarmas con radio, sonido seguro, vacaciones inteligentes y próxima ejecución siempre visible.';
@override
String get createAlarmAction => 'Crear alarma';
@override
String alarmsCount(int count) {
return '$count alarmas';
}
@override
String get activeAlarmsWithoutNextTitle =>
'Alarmas activas sin próxima ejecución';
@override
String get noActiveAlarms => 'Sin alarmas activas';
@override
String get nextAlarmTitle => 'Próxima alarma';
@override
String activeAlarmsWithoutNextSubtitle(int count) {
return 'Hay $count alarma(s) activas, pero ahora mismo no tienen una fecha futura válida. Revisá fecha, días y vacaciones.';
}
@override
String get createAlarmHint =>
'Creá una alarma y PluriWave calculará la siguiente ejecución automáticamente.';
@override
String get alarmVacationPlay => 'Suena en vacaciones';
@override
String get alarmVacationPause => 'Pausa en vacaciones';
@override
String alarmFadeInLabel(int seconds) {
return 'Fade-in ${seconds}s';
}
@override
String alarmNextExecution(Object date) {
return 'Siguiente ejecución: $date';
}
@override
String get alarmNoNextExecution => 'No tiene próxima ejecución activa.';
@override
String alarmSkippedExecution(Object date) {
return 'Una ejecución fue omitida: $date.';
}
@override
String get editAction => 'Editar';
@override
String get skipNextAction => 'Omitir siguiente';
@override
String get deleteTooltip => 'Eliminar';
@override
String get alarmSkippedNoNextSnackbar =>
'Alarma omitida. No queda próxima ejecución.';
@override
String alarmSkippedReturnsSnackbar(Object date) {
return 'Alarma omitida. Volverá el $date.';
}
@override
String alarmVacationPausedNoNext(Object vacationName) {
return 'Está pausada por vacaciones ($vacationName) y sin próxima ejecución.';
}
@override
String alarmVacationPausedReturns(Object vacationName, Object date) {
return 'Está pausada por vacaciones ($vacationName) y vuelve el $date.';
}
@override
String alarmVacationReturns(Object date) {
return 'Con vacaciones activas, volverá a sonar el $date.';
}
@override
String get defaultAlarmName => 'Despertador musical';
@override
String get newAlarmTitle => 'Nueva alarma';
@override
String get editAlarmTitle => 'Editar alarma';
@override
String get nameField => 'Nombre';
@override
String get timeField => 'Hora';
@override
String get dateField => 'Fecha';
@override
String get onceOption => 'Una vez';
@override
String get dailyOption => 'Diaria';
@override
String get weekdaysOption => 'Días';
@override
String get soundAndVolumeSection => 'Sonido y volumen';
@override
String get alarmFadeInTitle => 'Fade-in de alarma';
@override
String get alarmFadeInOff => '0 s (sin transición)';
@override
String alarmFadeInSummary(int seconds) {
return '$seconds s (de 5% al volumen elegido)';
}
@override
String get internalSafeSoundLabel => 'Sonido seguro interno';
@override
String get soundWarmSunrise => 'Amanecer cálido';
@override
String get soundSoftBell => 'Campana suave';
@override
String get soundDigitalPulse => 'Pulso digital';
@override
String get favoriteStationLabel => 'Emisora favorita';
@override
String get noStationUseInternalSound => 'Sin emisora: usar sonido interno';
@override
String get saveFavoritesAlarmHint =>
'Guardá emisoras en Favoritos para usarlas como alarma musical.';
@override
String get useCurrentStationAction => 'Usar emisora actual';
@override
String get playDuringVacations => 'Sonar durante vacaciones';
@override
String get playDuringVacationsHint =>
'Si lo apagás, la próxima ejecución saltará al primer día válido.';
@override
String get saveAlarmAction => 'Guardar alarma';
@override
String get chooseOneWeekdayError => 'Elegí al menos un día de la semana.';
@override
String get androidReliabilityReview => 'Revisar fiabilidad Android';
@override
String get statusOk => 'OK';
@override
String get statusPending => 'pendiente';
@override
String androidReliabilityStatus(
Object exact,
Object notifications,
Object screen,
) {
return 'Fiabilidad: exactas $exact · notificaciones $notifications · pantalla $screen';
}
@override
String get vacationRangesTitle => 'Rangos de vacaciones';
@override
String get addAction => 'Agregar';
@override
String get vacationRangesHint =>
'Si una alarma tiene \"Pausa en vacaciones\", se salta automáticamente estos rangos.';
@override
String get noVacationRangesLoaded => 'Sin rangos cargados.';
@override
String get deleteRangeTooltip => 'Eliminar rango';
@override
String get vacationsDefaultName => 'Vacaciones';
@override
String get newVacationRangeTitle => 'Nuevo rango de vacaciones';
@override
String get startField => 'Inicio';
@override
String get endField => 'Fin';
@override
String get saveRangeAction => 'Guardar rango';
@override
String get noAlarmsYetTitle => 'Todavía no hay alarmas.';
@override
String get noAlarmsYetSubtitle =>
'Creá una para diseñar tu despertar musical.';
@override
String get ringingInternalAudioActive => 'Sonando con audio seguro interno.';
@override
String get ringingPreparingInternalAudio =>
'Preparando audio seguro interno.';
@override
String get stopAlarmAction => 'Detener alarma';
@override
String get pauseAction => 'Pausar';
@override
String miniPlayerOpenLabel(Object stationName) {
return 'Abrir reproductor de $stationName';
}
@override
String get playerIconLabel => 'Reproductor';
@override
String get playbackStatusConnecting => 'Conectando...';
@override
String get playbackStatusLive => 'En directo';
@override
String get playbackStatusPaused => 'Pausado';
@override
String get playbackStatusConnectionError => 'Error de conexión';
@override
String get playbackStatusStopped => 'Detenido';
@override
String stationSemanticLabel(Object stationName) {
return 'Emisora $stationName';
}
@override
String get favoritesAddTooltip => 'Añadir a favoritos';
@override
String favoritesAddedMessage(Object stationName) {
return '$stationName añadida a favoritos';
}
@override
String get stationIconLabel => 'Icono de emisora';
@override
String get liveNow => 'En vivo';
@override
String equalizerBandLabel(Object band) {
return 'Banda $band';
}
@override
String equalizerBandValue(Object value) {
return '$value decibelios';
}
@override
String get equalizerPresetFlat => 'Plano';
@override
String get equalizerPresetRock => 'Rock';
@override
String get equalizerPresetPop => 'Pop';
@override
String get equalizerPresetBassBoost => 'Refuerzo de graves';
@override
String get equalizerPresetJazz => 'Jazz';
@override
String get equalizerPresetVoice => 'Voz';
@override
String get equalizerPresetCustom => 'Personalizado';
@override
String get onboardingTitle => 'Bienvenido a PluriWave';
@override
String get onboardingNewsTitle => 'Novedades';
@override
String get onboardingStartAction => 'Empezar';
@override
String get onboardingCloseTooltip => 'Cerrar';
@override
String radioRecordingError(Object error) {
return 'Error al grabar la radio: $error';
}
@override
String get radioApiConnectionError => 'Sin conexión a la API de radio';
@override
String get radioSearchError => 'Error en la búsqueda. Comprueba tu conexión.';
@override
String get radioLoadMoreStationsError =>
'No se pudieron cargar más emisoras.';
@override
String get radioNearbyStationsError =>
'No pudimos detectar emisoras cercanas. Usa filtros por país.';
@override
String radioCannotPlayStation(Object stationName) {
return 'No se puede reproducir \"$stationName\"';
}
@override
String get recordingSelectStationFirst =>
'Primero selecciona una emisora para grabar.';
@override
String recordingStartError(Object error) {
return 'No se pudo iniciar la grabación: $error';
}
@override
String get unsupportedConfigVersion =>
'Versión de configuración no compatible';
@override
String get audioErrorGeneric => 'Error de reproducción';
@override
String get audioErrorNoInternet => 'Sin conexión a internet';
@override
String get audioErrorInvalidUrl => 'La URL de la radio no es válida';
@override
String get audioErrorNotFound => 'La radio no está disponible (error 404)';
@override
String get audioErrorTimeout => 'Tiempo de espera agotado al conectar';
@override
String get audioErrorCannotConnect => 'No se puede conectar a la radio';
@override
String get audioErrorUnsupportedFormat => 'Formato de stream no compatible';
@override
String get audioErrorDecode => 'Error al decodificar el stream de audio';
@override
String get audioErrorCleartext =>
'Esta radio usa HTTP sin cifrar, y no está permitido';
@override
String get audioErrorSsl => 'Certificado SSL inválido en la radio';
@override
String get audioErrorCannotPlay => 'No se puede reproducir esta radio';
@override
String get audioErrorUnexpectedPlayback => 'Error inesperado al reproducir';
@override
String get androidExactAlarmScheduleError =>
'Android no pudo programar una alarma exacta. Revisa el permiso de alarmas exactas.';
@override
String get recordingPathEmptyError =>
'La ruta de grabación no puede estar vacía';
@override
String get recordingMaxSizeInvalidError =>
'El tamaño máximo debe ser mayor que cero';
@override
String get recordingAlreadyActiveError => 'Ya hay una grabación en curso';
@override
String get alarmRingingFallbackActive => 'Sonando con audio seguro interno.';
@override
String get alarmRingingPreparingFallback =>
'Preparando audio seguro interno.';
@override
String get alarmRingingTryingStation =>
'Intentando reproducir tu emisora con máxima calidad disponible.';
@override
String alarmScheduleOnce(Object date) {
return 'Una vez · $date';
}
@override
String alarmScheduleWeekdays(Object days) {
return 'Días: $days';
}
@override
String get androidReliabilityTitle => 'Revisar fiabilidad Android';
@override
String get closeAction => 'Cerrar';
@override
String get customOption => 'Personalizada';
@override
String get endLabel => 'Fin';
@override
String get equalizerDisable => 'Desactivar ecualizador';
@override
String get helpTitle => 'Ayuda y tutorial';
@override
String get helpSubtitle =>
'Repasá funciones, consejos y novedades de PluriWave.';
@override
String get indefiniteOption => 'Indefinida';
@override
String get invalidNumber => 'Número inválido';
@override
String get nameLabel => 'Nombre';
@override
String get notPlaying => 'No está reproduciendo';
@override
String get oneTimeOption => 'Una vez';
@override
String get pausePlaybackTooltip => 'Pausar reproducción';
@override
String qualityOriginal(Object quality) {
return 'Calidad original: $quality';
}
@override
String get qualityUnknown => 'Calidad no informada';
@override
String get recordAction => 'Grabar';
@override
String get recordDurationTitle => 'Duración de grabación';
@override
String get recordRadioSubtitle => 'Elegí cuánto tiempo querés grabar.';
@override
String get recordRadioTitle => 'Grabar radio';
@override
String get recordingActiveTitle => 'Grabando radio';
@override
String get recordingDirectTitle => 'Grabación directa';
@override
String get recordingsOpenFolderPlainError =>
'No se pudo abrir la carpeta de grabaciones';
@override
String get recordingsOpenLatest => 'Abrir última grabación';
@override
String get recordingsOpenLatestError =>
'No se pudo abrir la última grabación';
@override
String get startLabel => 'Inicio';
@override
String get startPlaybackTooltip => 'Iniciar reproducción';
@override
String get stopAction => 'Parar';
@override
String get stopPlaybackTooltip => 'Detener reproducción';
@override
String get weekdayShortMonday => 'Lun';
@override
String get weekdayShortTuesday => 'Mar';
@override
String get weekdayShortWednesday => 'Mié';
@override
String get weekdayShortThursday => 'Jue';
@override
String get weekdayShortFriday => 'Vie';
@override
String get weekdayShortSaturday => 'Sáb';
@override
String get weekdayShortSunday => 'Dom';
} }
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+40 -25
View File
@@ -11,7 +11,7 @@ import 'package:uuid/uuid.dart';
import '../estado/estado_idioma.dart'; import '../estado/estado_idioma.dart';
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/app_localizations_ext.dart'; import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart'; import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart'; import '../modelos/emisora.dart';
import '../modelos/grupo_favoritos.dart'; import '../modelos/grupo_favoritos.dart';
@@ -291,7 +291,7 @@ class _SeccionTimerSueno extends StatelessWidget {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
'${l10n.saveQuickAccessButton}: ${_formatearDuracionTimer(duracion)}', '${l10n.saveQuickAccessButton}: ${_formatearDuracionTimer(l10n, duracion)}',
), ),
), ),
); );
@@ -336,7 +336,10 @@ class _SeccionTimerSueno extends StatelessWidget {
for (final segundos in presets) for (final segundos in presets)
InputChip( InputChip(
label: Text( label: Text(
_formatearDuracionTimer(Duration(seconds: segundos)), _formatearDuracionTimer(
l10n,
Duration(seconds: segundos),
),
), ),
onDeleted: onDeleted:
presets.length <= 1 presets.length <= 1
@@ -907,7 +910,7 @@ class _SeccionEmisoraPreferida extends StatelessWidget {
DropdownMenuItem<String>( DropdownMenuItem<String>(
value: emisora.uuid, value: emisora.uuid,
child: Text( child: Text(
emisora.nombre, localizedStationName(l10n, emisora.nombre),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
), ),
@@ -923,8 +926,12 @@ class _SeccionEmisoraPreferida extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
favoritas.any((e) => e.uuid == preferida.uuid) favoritas.any((e) => e.uuid == preferida.uuid)
? l10n.preferredStationCurrent(preferida.nombre) ? l10n.preferredStationCurrent(
: l10n.preferredStationAutoUsing(preferida.nombre), localizedStationName(l10n, preferida.nombre),
)
: l10n.preferredStationAutoUsing(
localizedStationName(l10n, preferida.nombre),
),
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Align( Align(
@@ -1001,7 +1008,12 @@ class _SeccionEmisoras extends StatelessWidget {
ListTile( ListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
leading: const Icon(Icons.radio), leading: const Icon(Icons.radio),
title: Text(emisora.nombre), title: Text(
localizedStationName(
AppLocalizations.of(context),
emisora.nombre,
),
),
subtitle: Text( subtitle: Text(
emisora.url, emisora.url,
maxLines: 1, maxLines: 1,
@@ -1179,11 +1191,7 @@ class _SeccionBackup extends StatelessWidget {
} catch (e) { } catch (e) {
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(content: Text(l10n.backupExportError(e.toString()))),
content: Text(
l10n.backupExportError(e.toString()),
),
),
); );
} }
} }
@@ -1229,20 +1237,14 @@ class _SeccionBackup extends StatelessWidget {
final messenger = ScaffoldMessenger.of(context); final messenger = ScaffoldMessenger.of(context);
await estado.importarConfig(json); await estado.importarConfig(json);
messenger.showSnackBar( messenger.showSnackBar(
SnackBar( SnackBar(content: Text(l10n.backupImportSuccess)),
content: Text(l10n.backupImportSuccess),
),
); );
} }
} }
} catch (e) { } catch (e) {
if (context.mounted) { if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(content: Text(l10n.backupImportError(e.toString()))),
content: Text(
l10n.backupImportError(e.toString()),
),
),
); );
} }
} }
@@ -1324,7 +1326,8 @@ class _SeccionInfo extends StatelessWidget {
AppLocalizations.of(ctx).savedFavoritesTitle, AppLocalizations.of(ctx).savedFavoritesTitle,
), ),
trailing: Text( trailing: Text(
snap.data?.toString() ?? AppLocalizations.of(ctx).dash, snap.data?.toString() ??
AppLocalizations.of(ctx).dash,
style: Theme.of(ctx).textTheme.bodyLarge, style: Theme.of(ctx).textTheme.bodyLarge,
), ),
), ),
@@ -1362,15 +1365,27 @@ class _SeccionInfo extends StatelessWidget {
} }
} }
String _formatearDuracionTimer(Duration duracion) { String _formatearDuracionTimer(
AppLocalizations l10n,
Duration duracion,
) {
final horas = duracion.inHours; final horas = duracion.inHours;
final minutos = duracion.inMinutes.remainder(60); final minutos = duracion.inMinutes.remainder(60);
final segundos = duracion.inSeconds.remainder(60); final segundos = duracion.inSeconds.remainder(60);
if (horas > 0) { if (horas > 0) {
return '${horas}h ${minutos.toString().padLeft(2, '0')}m ${segundos.toString().padLeft(2, '0')}s'; return l10n.durationHoursMinutesSeconds(
horas,
minutos.toString().padLeft(2, '0'),
segundos.toString().padLeft(2, '0'),
);
} }
if (minutos > 0) { if (minutos > 0) {
return segundos == 0 ? '$minutos min' : '${minutos}m ${segundos}s'; return segundos == 0
? l10n.durationMinutesOnly(minutos)
: l10n.durationMinutesSeconds(
minutos,
segundos.toString().padLeft(2, '0'),
);
} }
return '$segundos s'; return l10n.durationSecondsOnly(segundos);
} }
+4 -5
View File
@@ -1,4 +1,4 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:just_audio/just_audio.dart'; import 'package:just_audio/just_audio.dart';
@@ -6,7 +6,7 @@ import 'package:provider/provider.dart';
import '../estado/estado_alarmas.dart'; import '../estado/estado_alarmas.dart';
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/app_localizations_ext.dart'; import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart'; import '../l10n/gen/app_localizations.dart';
import '../modelos/alarma_musical.dart'; import '../modelos/alarma_musical.dart';
import '../servicios/servicio_audio.dart'; import '../servicios/servicio_audio.dart';
@@ -183,7 +183,7 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
alarma.nombre, localizedAlarmName(l10n, alarma.nombre),
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: Theme.of(context).textTheme.titleLarge, style: Theme.of(context).textTheme.titleLarge,
), ),
@@ -214,8 +214,7 @@ class _PantallaAlarmaSonandoState extends State<PantallaAlarmaSonando> {
String _assetFallback(SonidoInternoAlarma sonido) => switch (sonido) { String _assetFallback(SonidoInternoAlarma sonido) => switch (sonido) {
SonidoInternoAlarma.amanecer => 'assets/audio/alarm_amanecer.wav', SonidoInternoAlarma.amanecer => 'assets/audio/alarm_amanecer.wav',
SonidoInternoAlarma.campanaSuave => SonidoInternoAlarma.campanaSuave => 'assets/audio/alarm_campana_suave.wav',
'assets/audio/alarm_campana_suave.wav',
SonidoInternoAlarma.pulsoDigital => 'assets/audio/alarm_pulso_digital.wav', SonidoInternoAlarma.pulsoDigital => 'assets/audio/alarm_pulso_digital.wav',
}; };
+70 -34
View File
@@ -3,6 +3,7 @@ import 'package:provider/provider.dart';
import '../estado/estado_alarmas.dart'; import '../estado/estado_alarmas.dart';
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/display_names.dart';
import '../l10n/app_localizations_ext.dart'; import '../l10n/app_localizations_ext.dart';
import '../l10n/gen/app_localizations.dart'; import '../l10n/gen/app_localizations.dart';
import '../modelos/alarma_musical.dart'; import '../modelos/alarma_musical.dart';
@@ -83,7 +84,8 @@ class _PanelProximaAlarma extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context); final l10n = AppLocalizations.of(context);
final proxima = estado.proximaAlarma; final proxima = estado.proximaAlarma;
final activasSinProxima = estado.alarmas final activasSinProxima =
estado.alarmas
.where((a) => a.activa && a.proximaProgramable == null) .where((a) => a.activa && a.proximaProgramable == null)
.length; .length;
final proximaProgramable = proxima?.proximaProgramable; final proximaProgramable = proxima?.proximaProgramable;
@@ -102,7 +104,7 @@ class _PanelProximaAlarma extends StatelessWidget {
proxima == null proxima == null
? activasSinProxima > 0 ? activasSinProxima > 0
? l10n.activeAlarmsWithoutNextTitle ? l10n.activeAlarmsWithoutNextTitle
: l10n.activeAlarmsNoneTitle : l10n.noActiveAlarms
: l10n.nextAlarmTitle, : l10n.nextAlarmTitle,
style: Theme.of(context).textTheme.titleMedium?.copyWith( style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
@@ -116,10 +118,7 @@ class _PanelProximaAlarma extends StatelessWidget {
activasSinProxima, activasSinProxima,
) )
: l10n.createAlarmHint : l10n.createAlarmHint
: l10n.alarmNextSummary( : '${_nombreVisibleAlarma(l10n, proxima)} · ${_fechaHora(l10n, proximaProgramable!)}',
proxima.nombre,
_fechaHora(l10n, proximaProgramable!),
),
), ),
], ],
), ),
@@ -166,7 +165,7 @@ class _TarjetaAlarma extends StatelessWidget {
letterSpacing: -1, letterSpacing: -1,
), ),
), ),
Text(alarma.nombre), Text(_nombreVisibleAlarma(l10n, alarma)),
], ],
), ),
), ),
@@ -198,7 +197,7 @@ class _TarjetaAlarma extends StatelessWidget {
), ),
_InfoChip( _InfoChip(
icon: Icons.trending_up_rounded, icon: Icons.trending_up_rounded,
label: l10n.fadeInSeconds(alarma.fadeInSegundos), label: l10n.alarmFadeInLabel(alarma.fadeInSegundos),
), ),
], ],
), ),
@@ -302,10 +301,12 @@ class _TarjetaAlarma extends StatelessWidget {
} }
if (actual != null) { if (actual != null) {
if (alarma.proximaProgramable == null) { if (alarma.proximaProgramable == null) {
return l10n.alarmVacationPausedNoNext(actual.nombre); return l10n.alarmVacationPausedNoNext(
_nombreVisibleVacaciones(l10n, actual),
);
} }
return l10n.alarmVacationPausedReturns( return l10n.alarmVacationPausedReturns(
actual.nombre, _nombreVisibleVacaciones(l10n, actual),
_fechaHora(l10n, alarma.proximaProgramable!), _fechaHora(l10n, alarma.proximaProgramable!),
); );
} }
@@ -357,7 +358,10 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
final l10n = AppLocalizations.of(context); final l10n = AppLocalizations.of(context);
final ahora = DateTime.now().add(const Duration(minutes: 5)); final ahora = DateTime.now().add(const Duration(minutes: 5));
_nombreController = TextEditingController( _nombreController = TextEditingController(
text: alarma?.nombre ?? l10n.defaultAlarmName, text:
alarma == null
? l10n.defaultAlarmName
: _nombreVisibleAlarma(l10n, alarma),
); );
_hora = TimeOfDay( _hora = TimeOfDay(
hour: alarma?.hora ?? ahora.hour, hour: alarma?.hora ?? ahora.hour,
@@ -419,7 +423,9 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
const SizedBox(width: 12), const SizedBox(width: 12),
Expanded( Expanded(
child: Text( child: Text(
widget.alarma == null ? l10n.newAlarmTitle : l10n.editAlarmTitle, widget.alarma == null
? l10n.newAlarmTitle
: l10n.editAlarmTitle,
style: Theme.of(context).textTheme.titleLarge?.copyWith( style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
), ),
@@ -442,7 +448,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
Expanded( Expanded(
child: _PickerButton( child: _PickerButton(
icon: Icons.schedule_rounded, icon: Icons.schedule_rounded,
label: l10n.timeLabel, label: l10n.timeField,
value: _hora.format(context), value: _hora.format(context),
onTap: _elegirHora, onTap: _elegirHora,
), ),
@@ -451,7 +457,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
Expanded( Expanded(
child: _PickerButton( child: _PickerButton(
icon: Icons.event_rounded, icon: Icons.event_rounded,
label: l10n.dateLabel, label: l10n.dateField,
value: _fechaCorta(_fecha), value: _fechaCorta(_fecha),
onTap: onTap:
_tipo == TipoProgramacionAlarma.unica _tipo == TipoProgramacionAlarma.unica
@@ -488,7 +494,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
children: [ children: [
for (var i = DateTime.monday; i <= DateTime.sunday; i++) for (var i = DateTime.monday; i <= DateTime.sunday; i++)
FilterChip( FilterChip(
label: Text(l10n.weekdayShort(i)), label: Text(_weekdayShort(l10n, i)),
selected: _diasSemana.contains(i), selected: _diasSemana.contains(i),
onSelected: onSelected:
(selected) => setState(() { (selected) => setState(() {
@@ -503,7 +509,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
const SizedBox(height: 14), const SizedBox(height: 14),
_SectionLabel( _SectionLabel(
icon: 'assets/icons/alarmas/fallback_sound.png', icon: 'assets/icons/alarmas/fallback_sound.png',
text: l10n.soundAndVolumeTitle, text: l10n.soundAndVolumeSection,
), ),
Slider( Slider(
value: _volumen, value: _volumen,
@@ -520,7 +526,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
subtitle: Text( subtitle: Text(
_fadeInSegundos == 0 _fadeInSegundos == 0
? l10n.alarmFadeInOff ? l10n.alarmFadeInOff
: l10n.alarmFadeInProgress(_fadeInSegundos), : l10n.alarmFadeInSummary(_fadeInSegundos),
), ),
), ),
Slider( Slider(
@@ -530,13 +536,12 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
divisions: 60, divisions: 60,
label: '${_fadeInSegundos}s', label: '${_fadeInSegundos}s',
onChanged: onChanged:
(value) => (value) => setState(() => _fadeInSegundos = value.round()),
setState(() => _fadeInSegundos = value.round()),
), ),
DropdownButtonFormField<SonidoInternoAlarma>( DropdownButtonFormField<SonidoInternoAlarma>(
initialValue: _sonidoInterno, initialValue: _sonidoInterno,
decoration: InputDecoration( decoration: InputDecoration(
labelText: l10n.soundInternalSafe, labelText: l10n.internalSafeSoundLabel,
), ),
items: [ items: [
DropdownMenuItem( DropdownMenuItem(
@@ -574,7 +579,7 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
DropdownMenuItem<String>( DropdownMenuItem<String>(
value: emisora.uuid, value: emisora.uuid,
child: Text( child: Text(
emisora.nombre, localizedStationName(l10n, emisora.nombre),
overflow: TextOverflow.ellipsis, overflow: TextOverflow.ellipsis,
), ),
), ),
@@ -608,7 +613,8 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
SwitchListTile.adaptive( SwitchListTile.adaptive(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
value: _sonarEnVacaciones, value: _sonarEnVacaciones,
onChanged: (value) => setState(() => _sonarEnVacaciones = value), onChanged:
(value) => setState(() => _sonarEnVacaciones = value),
secondary: const _AssetIcon( secondary: const _AssetIcon(
'assets/icons/alarmas/vacation_wave.png', 'assets/icons/alarmas/vacation_wave.png',
size: 42, size: 42,
@@ -648,7 +654,9 @@ class _EditorAlarmaSheetState extends State<_EditorAlarmaSheet> {
Future<void> _guardar() async { Future<void> _guardar() async {
if (_tipo == TipoProgramacionAlarma.diasSemana && _diasSemana.isEmpty) { if (_tipo == TipoProgramacionAlarma.diasSemana && _diasSemana.isEmpty) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(AppLocalizations.of(context).chooseOneWeekdayError)), SnackBar(
content: Text(AppLocalizations.of(context).chooseOneWeekdayError),
),
); );
return; return;
} }
@@ -711,9 +719,18 @@ class _AccesoDiagnostico extends StatelessWidget {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final l10n = AppLocalizations.of(context); final l10n = AppLocalizations.of(context);
final diag = estado.diagnostico; final diag = estado.diagnostico;
final exactStatus = diag?.puedeProgramarExactas == true ? l10n.statusOk : l10n.statusPending; final exactStatus =
final notificationStatus = diag?.notificacionesPermitidas == true ? l10n.statusOk : l10n.statusPending; diag?.puedeProgramarExactas == true
final screenStatus = diag?.puedeUsarPantallaCompleta == true ? l10n.statusOk : l10n.statusPending; ? l10n.statusOk
: l10n.statusPending;
final notificationStatus =
diag?.notificacionesPermitidas == true
? l10n.statusOk
: l10n.statusPending;
final screenStatus =
diag?.puedeUsarPantallaCompleta == true
? l10n.statusOk
: l10n.statusPending;
return TextButton.icon( return TextButton.icon(
icon: const _AssetIcon( icon: const _AssetIcon(
'assets/icons/alarmas/android_reliability.png', 'assets/icons/alarmas/android_reliability.png',
@@ -784,18 +801,18 @@ class _PanelVacaciones extends StatelessWidget {
const SizedBox(height: 8), const SizedBox(height: 8),
Text(l10n.vacationRangesHint), Text(l10n.vacationRangesHint),
if (vacaciones.isEmpty) if (vacaciones.isEmpty)
Text(l10n.vacationRangesEmpty) Text(l10n.noVacationRangesLoaded)
else else
for (final rango in vacaciones) for (final rango in vacaciones)
ListTile( ListTile(
contentPadding: EdgeInsets.zero, contentPadding: EdgeInsets.zero,
leading: const Icon(Icons.event_busy_rounded), leading: const Icon(Icons.event_busy_rounded),
title: Text(rango.nombre), title: Text(_nombreVisibleVacaciones(l10n, rango)),
subtitle: Text( subtitle: Text(
'${_fechaCorta(rango.inicioDia)}${_fechaCorta(rango.finDia)}', '${_fechaCorta(rango.inicioDia)}${_fechaCorta(rango.finDia)}',
), ),
trailing: IconButton( trailing: IconButton(
tooltip: l10n.deleteRangeAction, tooltip: l10n.deleteRangeTooltip,
onPressed: () => estado.eliminarRangoVacaciones(rango.id), onPressed: () => estado.eliminarRangoVacaciones(rango.id),
icon: const Icon(Icons.delete_outline_rounded), icon: const Icon(Icons.delete_outline_rounded),
), ),
@@ -1057,17 +1074,25 @@ class _EmptyAlarmas extends StatelessWidget {
} }
} }
String _nombreVisibleAlarma(AppLocalizations l10n, AlarmaMusical alarma) {
return localizedAlarmName(l10n, alarma.nombre);
}
String _nombreVisibleVacaciones(AppLocalizations l10n, RangoVacaciones rango) {
return localizedVacationName(l10n, rango.nombre);
}
String _hora(AlarmaMusical alarma) => String _hora(AlarmaMusical alarma) =>
'${alarma.hora.toString().padLeft(2, '0')}:${alarma.minuto.toString().padLeft(2, '0')}'; '${alarma.hora.toString().padLeft(2, '0')}:${alarma.minuto.toString().padLeft(2, '0')}';
String _programacion(AppLocalizations l10n, AlarmaMusical alarma) { String _programacion(AppLocalizations l10n, AlarmaMusical alarma) {
return switch (alarma.tipoProgramacion) { return switch (alarma.tipoProgramacion) {
TipoProgramacionAlarma.unica => TipoProgramacionAlarma.unica => l10n.alarmScheduleOnce(
l10n.alarmScheduleOnce(_fechaCorta(alarma.fechaUnica ?? DateTime.now())), _fechaCorta(alarma.fechaUnica ?? DateTime.now()),
),
TipoProgramacionAlarma.diaria => l10n.dailyOption, TipoProgramacionAlarma.diaria => l10n.dailyOption,
TipoProgramacionAlarma.diasSemana => TipoProgramacionAlarma.diasSemana => l10n.alarmScheduleWeekdays(
l10n.alarmScheduleWeekdays( alarma.diasSemana.map((day) => _weekdayShort(l10n, day)).join(', '),
alarma.diasSemana.map(l10n.weekdayShort).join(', '),
), ),
}; };
} }
@@ -1075,5 +1100,16 @@ String _programacion(AppLocalizations l10n, AlarmaMusical alarma) {
String _fechaHora(AppLocalizations l10n, DateTime fecha) => String _fechaHora(AppLocalizations l10n, DateTime fecha) =>
l10n.dateTimeSentence(fecha); l10n.dateTimeSentence(fecha);
String _weekdayShort(AppLocalizations l10n, int day) => switch (day) {
DateTime.monday => l10n.weekdayShortMonday,
DateTime.tuesday => l10n.weekdayShortTuesday,
DateTime.wednesday => l10n.weekdayShortWednesday,
DateTime.thursday => l10n.weekdayShortThursday,
DateTime.friday => l10n.weekdayShortFriday,
DateTime.saturday => l10n.weekdayShortSaturday,
DateTime.sunday => l10n.weekdayShortSunday,
_ => '?',
};
String _fechaCorta(DateTime fecha) => String _fechaCorta(DateTime fecha) =>
'${fecha.day.toString().padLeft(2, '0')}/${fecha.month.toString().padLeft(2, '0')}/${fecha.year}'; '${fecha.day.toString().padLeft(2, '0')}/${fecha.month.toString().padLeft(2, '0')}/${fecha.year}';
+8 -2
View File
@@ -2,6 +2,7 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart'; import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart'; import '../modelos/emisora.dart';
import '../modelos/grupo_favoritos.dart'; import '../modelos/grupo_favoritos.dart';
@@ -212,10 +213,14 @@ class _FavoritoItem extends StatelessWidget {
); );
if (!context.mounted) return; if (!context.mounted) return;
final destino = grupos.firstWhere((g) => g.id == seleccionado); final destino = grupos.firstWhere((g) => g.id == seleccionado);
final stationName = localizedStationName(l10n, emisora.nombre);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
l10n.favoriteGroupsAssigned(emisora.nombre, _nombreVisible(l10n, destino)), l10n.favoriteGroupsAssigned(
stationName,
_nombreVisible(l10n, destino),
),
), ),
), ),
); );
@@ -224,11 +229,12 @@ class _FavoritoItem extends StatelessWidget {
Future<void> _eliminar(BuildContext context) async { Future<void> _eliminar(BuildContext context) async {
final l10n = AppLocalizations.of(context); final l10n = AppLocalizations.of(context);
final estado = context.read<EstadoRadio>(); final estado = context.read<EstadoRadio>();
final stationName = localizedStationName(l10n, emisora.nombre);
await estado.favoritos.eliminar(emisora.uuid); await estado.favoritos.eliminar(emisora.uuid);
await estado.cargarFavoritos(); await estado.cargarFavoritos();
if (!context.mounted) return; if (!context.mounted) return;
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(l10n.favoritesRemovedMessage(emisora.nombre))), SnackBar(content: Text(l10n.favoritesRemovedMessage(stationName))),
); );
} }
+47 -15
View File
@@ -4,7 +4,6 @@ import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart' as shimmer; import 'package:shimmer/shimmer.dart' as shimmer;
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/app_localizations_ext.dart';
import '../l10n/gen/app_localizations.dart'; import '../l10n/gen/app_localizations.dart';
import '../widgets/pluri_glass_surface.dart'; import '../widgets/pluri_glass_surface.dart';
import '../widgets/pluri_icon.dart'; import '../widgets/pluri_icon.dart';
@@ -56,7 +55,12 @@ class _PantallaInicioState extends State<PantallaInicio> {
if (estado.error != null) if (estado.error != null)
SliverToBoxAdapter(child: _errorBanner(estado, theme, l10n)), SliverToBoxAdapter(child: _errorBanner(estado, theme, l10n)),
SliverPadding( SliverPadding(
padding: const EdgeInsets.fromLTRB(PluriLayout.horizontal, 0, PluriLayout.horizontal, PluriLayout.bottomChromeInset), padding: const EdgeInsets.fromLTRB(
PluriLayout.horizontal,
0,
PluriLayout.horizontal,
PluriLayout.bottomChromeInset,
),
sliver: _gridEmisoras(estado, l10n), sliver: _gridEmisoras(estado, l10n),
), ),
], ],
@@ -80,14 +84,11 @@ class _PantallaInicioState extends State<PantallaInicio> {
children: [ children: [
PluriStatusPill( PluriStatusPill(
icon: Icons.public_rounded, icon: Icons.public_rounded,
label: l10n.homeStationsCount(estado.emisorasInicio.length), label: l10n.stationsCount(estado.emisorasInicio.length),
accent: Theme.of(context).colorScheme.secondary, accent: Theme.of(context).colorScheme.secondary,
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
PluriStatusPill( PluriStatusPill(icon: Icons.hd_rounded, label: l10n.qualityHd),
icon: Icons.hd_rounded,
label: l10n.qualityHd,
),
], ],
), ),
); );
@@ -100,7 +101,12 @@ class _PantallaInicioState extends State<PantallaInicio> {
) { ) {
final pais = estado.paisCercanoDetectado; final pais = estado.paisCercanoDetectado;
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(PluriLayout.horizontal, 8, PluriLayout.horizontal, 0), padding: const EdgeInsets.fromLTRB(
PluriLayout.horizontal,
8,
PluriLayout.horizontal,
0,
),
child: PluriGlassSurface( child: PluriGlassSurface(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Column( child: Column(
@@ -117,10 +123,12 @@ class _PantallaInicioState extends State<PantallaInicio> {
), ),
), ),
TextButton.icon( TextButton.icon(
onPressed: estado.cargandoCercanas onPressed:
estado.cargandoCercanas
? null ? null
: estado.cargarEmisorasCercanas, : estado.cargarEmisorasCercanas,
icon: estado.cargandoCercanas icon:
estado.cargandoCercanas
? const SizedBox( ? const SizedBox(
width: 16, width: 16,
height: 16, height: 16,
@@ -172,7 +180,12 @@ class _PantallaInicioState extends State<PantallaInicio> {
AppLocalizations l10n, AppLocalizations l10n,
) { ) {
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(PluriLayout.horizontal, 8, PluriLayout.horizontal, 0), padding: const EdgeInsets.fromLTRB(
PluriLayout.horizontal,
8,
PluriLayout.horizontal,
0,
),
child: PluriGlassSurface( child: PluriGlassSurface(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Column( child: Column(
@@ -202,8 +215,7 @@ class _PantallaInicioState extends State<PantallaInicio> {
size: 18, size: 18,
), ),
label: Text(e.nombre, maxLines: 1), label: Text(e.nombre, maxLines: 1),
onPressed: onPressed: () => reproducirMinimizado(context, e),
() => reproducirMinimizado(context, e),
).animate().fadeIn(delay: (i * 50).ms); ).animate().fadeIn(delay: (i * 50).ms);
}, },
), ),
@@ -220,7 +232,12 @@ class _PantallaInicioState extends State<PantallaInicio> {
AppLocalizations l10n, AppLocalizations l10n,
) { ) {
return Padding( return Padding(
padding: const EdgeInsets.fromLTRB(PluriLayout.horizontal, 16, PluriLayout.horizontal, 8), padding: const EdgeInsets.fromLTRB(
PluriLayout.horizontal,
16,
PluriLayout.horizontal,
8,
),
child: PluriGlassSurface( child: PluriGlassSurface(
padding: const EdgeInsets.all(12), padding: const EdgeInsets.all(12),
child: Column( child: Column(
@@ -235,7 +252,7 @@ class _PantallaInicioState extends State<PantallaInicio> {
_generos.map((g) { _generos.map((g) {
final seleccionado = _generoSeleccionado == g; final seleccionado = _generoSeleccionado == g;
return FilterChip( return FilterChip(
label: Text(l10n.genreName(g)), label: Text(_genreName(l10n, g)),
selected: seleccionado, selected: seleccionado,
onSelected: (_) { onSelected: (_) {
setState(() { setState(() {
@@ -332,6 +349,21 @@ class _PantallaInicioState extends State<PantallaInicio> {
} }
} }
String _genreName(AppLocalizations l10n, String tag) => switch (tag) {
'pop' => l10n.genrePop,
'rock' => l10n.genreRock,
'jazz' => l10n.genreJazz,
'classical' => l10n.genreClassical,
'electronic' => l10n.genreElectronic,
'news' => l10n.genreNews,
'talk' => l10n.genreTalk,
'hip-hop' => l10n.genreHipHop,
'country' => l10n.genreCountry,
'metal' => l10n.genreMetal,
'reggae' => l10n.genreReggae,
'latin' => l10n.genreLatin,
_ => tag,
};
class _ChipShimmer extends StatelessWidget { class _ChipShimmer extends StatelessWidget {
final ThemeData theme; final ThemeData theme;
+55 -22
View File
@@ -5,7 +5,6 @@ import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/app_localizations_ext.dart';
import '../l10n/gen/app_localizations.dart'; import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart'; import '../modelos/emisora.dart';
import '../servicios/servicio_audio.dart'; import '../servicios/servicio_audio.dart';
@@ -115,7 +114,10 @@ class _PantallaReproductorState extends State<PantallaReproductor>
: Icons.favorite_outline_rounded, : Icons.favorite_outline_rounded,
color: esFavorito ? theme.colorScheme.error : null, color: esFavorito ? theme.colorScheme.error : null,
), ),
tooltip: esFavorito ? l10n.favoritesRemoveTooltip : l10n.favoritesAddTooltip, tooltip:
esFavorito
? l10n.favoritesRemoveTooltip
: l10n.favoritesAddTooltip,
onPressed: () async => estado.toggleFavorito(emisoraActiva), onPressed: () async => estado.toggleFavorito(emisoraActiva),
), ),
], ],
@@ -195,7 +197,7 @@ class _PantallaReproductorState extends State<PantallaReproductor>
if (e.bitrate != null && e.bitrate! > 0) parts.add('${e.bitrate} kbps'); if (e.bitrate != null && e.bitrate! > 0) parts.add('${e.bitrate} kbps');
return parts.isEmpty return parts.isEmpty
? AppLocalizations.of(context).qualityUnknown ? AppLocalizations.of(context).qualityUnknown
: AppLocalizations.of(context).qualityOriginal(parts.join(' ? ')); : AppLocalizations.of(context).qualityOriginal(parts.join(' · '));
} }
} }
@@ -385,14 +387,16 @@ class _GrabacionWidget extends StatelessWidget {
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: [ children: [
Text( Text(
activa ? l10n.recordingActiveTitle : l10n.recordingDirectTitle, activa
? l10n.recordingActiveTitle
: l10n.recordingDirectTitle,
style: theme.textTheme.titleSmall?.copyWith( style: theme.textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
), ),
Text( Text(
activa activa
? '${_formatearDuracion(grabacion.transcurrido)} · ${_formatearBytes(grabacion.bytes)}' ? '${_formatearDuracion(l10n, grabacion.transcurrido)} · ${_formatearBytes(grabacion.bytes)}'
: l10n.recordingsOriginalStreamHint, : l10n.recordingsOriginalStreamHint,
style: theme.textTheme.bodySmall?.copyWith( style: theme.textTheme.bodySmall?.copyWith(
color: theme.colorScheme.onSurface.withValues(alpha: 0.7), color: theme.colorScheme.onSurface.withValues(alpha: 0.7),
@@ -440,7 +444,9 @@ class _GrabacionWidget extends StatelessWidget {
if (!context.mounted) return; if (!context.mounted) return;
if (!abierto) { if (!abierto) {
messenger.showSnackBar( messenger.showSnackBar(
SnackBar(content: Text(AppLocalizations.of(context).recordingsOpenLatestError)), SnackBar(
content: Text(AppLocalizations.of(context).recordingsOpenLatestError),
),
); );
} }
} }
@@ -452,7 +458,9 @@ class _GrabacionWidget extends StatelessWidget {
if (!abierto) { if (!abierto) {
messenger.showSnackBar( messenger.showSnackBar(
SnackBar( SnackBar(
content: Text(AppLocalizations.of(context).recordingsOpenFolderPlainError), content: Text(
AppLocalizations.of(context).recordingsOpenFolderPlainError,
),
), ),
); );
} }
@@ -493,7 +501,15 @@ class _GrabacionWidget extends StatelessWidget {
), ),
for (final opcion in _opciones) for (final opcion in _opciones)
ActionChip( ActionChip(
label: Text(opcion.label), label: Text(
opcion.duracion.inMinutes > 0
? AppLocalizations.of(
ctx,
).durationMinutesOnly(opcion.duracion.inMinutes)
: AppLocalizations.of(
ctx,
).durationSecondsOnly(opcion.duracion.inSeconds),
),
onPressed: () { onPressed: () {
estado.iniciarGrabacion(duracion: opcion.duracion); estado.iniciarGrabacion(duracion: opcion.duracion);
Navigator.pop(ctx); Navigator.pop(ctx);
@@ -533,7 +549,9 @@ class _GrabacionWidget extends StatelessWidget {
Expanded( Expanded(
child: TextFormField( child: TextFormField(
controller: minutosCtrl, controller: minutosCtrl,
decoration: InputDecoration(labelText: AppLocalizations.of(ctx).minutesLabel), decoration: InputDecoration(
labelText: AppLocalizations.of(ctx).minutesLabel,
),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
validator: (value) => _validarNumero(ctx, value), validator: (value) => _validarNumero(ctx, value),
), ),
@@ -542,7 +560,9 @@ class _GrabacionWidget extends StatelessWidget {
Expanded( Expanded(
child: TextFormField( child: TextFormField(
controller: segundosCtrl, controller: segundosCtrl,
decoration: InputDecoration(labelText: AppLocalizations.of(ctx).secondsLabel), decoration: InputDecoration(
labelText: AppLocalizations.of(ctx).secondsLabel,
),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
validator: (value) => _validarNumero(ctx, value), validator: (value) => _validarNumero(ctx, value),
), ),
@@ -585,11 +605,14 @@ class _GrabacionWidget extends StatelessWidget {
return null; return null;
} }
String _formatearDuracion(Duration d) { String _formatearDuracion(AppLocalizations l10n, Duration d) {
final h = d.inHours; final h = d.inHours;
final m = d.inMinutes.remainder(60).toString().padLeft(2, '0'); final m = d.inMinutes.remainder(60).toString().padLeft(2, '0');
final s = d.inSeconds.remainder(60).toString().padLeft(2, '0'); final s = d.inSeconds.remainder(60).toString().padLeft(2, '0');
return h > 0 ? '${h}h ${m}m ${s}s' : '${m}m ${s}s'; if (h > 0) {
return l10n.durationHoursMinutesSeconds(h, m, s);
}
return l10n.durationMinutesSeconds(m, s);
} }
String _formatearBytes(int bytes) { String _formatearBytes(int bytes) {
@@ -600,17 +623,16 @@ class _GrabacionWidget extends StatelessWidget {
} }
class _OpcionGrabacion { class _OpcionGrabacion {
const _OpcionGrabacion(this.label, this.duracion); const _OpcionGrabacion(this.duracion);
final String label;
final Duration duracion; final Duration duracion;
} }
const _opciones = [ const _opciones = [
_OpcionGrabacion('30 s', Duration(seconds: 30)), _OpcionGrabacion(Duration(seconds: 30)),
_OpcionGrabacion('1 min', Duration(minutes: 1)), _OpcionGrabacion(Duration(minutes: 1)),
_OpcionGrabacion('5 min', Duration(minutes: 5)), _OpcionGrabacion(Duration(minutes: 5)),
_OpcionGrabacion('15 min', Duration(minutes: 15)), _OpcionGrabacion(Duration(minutes: 15)),
_OpcionGrabacion('30 min', Duration(minutes: 30)), _OpcionGrabacion(Duration(minutes: 30)),
]; ];
class _Controles extends StatelessWidget { class _Controles extends StatelessWidget {
@@ -643,7 +665,7 @@ class _Controles extends StatelessWidget {
), ),
const SizedBox(height: 8), const SizedBox(height: 8),
Text( Text(
l10n.playerPlaybackErrorTitle, l10n.audioErrorCannotPlay,
style: theme.textTheme.bodyMedium?.copyWith( style: theme.textTheme.bodyMedium?.copyWith(
color: theme.colorScheme.error, color: theme.colorScheme.error,
), ),
@@ -784,7 +806,14 @@ class _TimerWidget extends StatelessWidget {
final t = snap.data ?? Duration.zero; final t = snap.data ?? Duration.zero;
final m = t.inMinutes.remainder(60).toString().padLeft(2, '0'); final m = t.inMinutes.remainder(60).toString().padLeft(2, '0');
final s = t.inSeconds.remainder(60).toString().padLeft(2, '0'); final s = t.inSeconds.remainder(60).toString().padLeft(2, '0');
final label = t.inHours > 0 ? '${t.inHours}h ${m}m' : '${m}m ${s}s'; final label =
t.inHours > 0
? AppLocalizations.of(context).durationHoursMinutesSeconds(
t.inHours,
m,
s,
)
: AppLocalizations.of(context).durationMinutesSeconds(m, s);
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
@@ -833,7 +862,11 @@ class _TimerWidget extends StatelessWidget {
opcionesTimer opcionesTimer
.map( .map(
(min) => ActionChip( (min) => ActionChip(
label: Text('$min min'), label: Text(
AppLocalizations.of(
ctx,
).durationMinutesOnly(min),
),
onPressed: () { onPressed: () {
estado.iniciarTimer(min); estado.iniciarTimer(min);
Navigator.pop(ctx); Navigator.pop(ctx);
+20 -5
View File
@@ -1,8 +1,11 @@
import 'dart:async'; import 'dart:async';
import 'dart:ui' show Locale;
import 'package:flutter/foundation.dart'; import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart';
import '../modelos/alarma_musical.dart'; import '../modelos/alarma_musical.dart';
class EventoAlarmaAndroid { class EventoAlarmaAndroid {
@@ -114,6 +117,17 @@ class ServicioAlarmasAndroid implements PuertoAlarmasAndroid {
static final _eventosController = static final _eventosController =
StreamController<EventoAlarmaAndroid>.broadcast(); StreamController<EventoAlarmaAndroid>.broadcast();
static bool _handlerInstalado = false; static bool _handlerInstalado = false;
static AppLocalizations? _l10n;
static AppLocalizations get _textos {
final actual = _l10n;
if (actual != null) return actual;
return lookupAppLocalizations(const Locale('es'));
}
static void configurarLocalizaciones(AppLocalizations l10n) {
_l10n = l10n;
}
@override @override
Stream<EventoAlarmaAndroid> get eventosAlarma => _eventosController.stream; Stream<EventoAlarmaAndroid> get eventosAlarma => _eventosController.stream;
@@ -133,7 +147,7 @@ class ServicioAlarmasAndroid implements PuertoAlarmasAndroid {
); );
final programada = await _channel.invokeMethod<bool>('scheduleAlarm', { final programada = await _channel.invokeMethod<bool>('scheduleAlarm', {
'id': alarma.id, 'id': alarma.id,
'title': alarma.nombre, 'title': localizedAlarmName(_textos, alarma.nombre),
'triggerAtMillis': proxima.millisecondsSinceEpoch, 'triggerAtMillis': proxima.millisecondsSinceEpoch,
'preNoticeAtMillis': 'preNoticeAtMillis':
alarma.snoozeHasta == null alarma.snoozeHasta == null
@@ -150,15 +164,16 @@ class ServicioAlarmasAndroid implements PuertoAlarmasAndroid {
'lastHandledAtMillis': 'lastHandledAtMillis':
alarma.ultimaEjecucionGestionada?.millisecondsSinceEpoch, alarma.ultimaEjecucionGestionada?.millisecondsSinceEpoch,
'soundOnVacation': alarma.sonarEnVacaciones, 'soundOnVacation': alarma.sonarEnVacaciones,
'stationName': alarma.emisora?.nombre, 'stationName':
alarma.emisora == null
? null
: localizedStationName(_textos, alarma.emisora!.nombre),
'stationUrl': alarma.emisora?.url, 'stationUrl': alarma.emisora?.url,
'fallbackSound': alarma.sonidoInterno.name, 'fallbackSound': alarma.sonidoInterno.name,
'volume': alarma.volumen, 'volume': alarma.volumen,
}); });
if (programada != true) { if (programada != true) {
throw StateError( throw StateError(_textos.androidExactAlarmScheduleError);
'Android no pudo programar una alarma exacta. Revisa el permiso de alarmas exactas.',
);
} }
} }
+34 -13
View File
@@ -1,9 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer' as developer; import 'dart:developer' as developer;
import 'dart:ui' show Locale;
import 'package:audio_service/audio_service.dart'; import 'package:audio_service/audio_service.dart';
import 'package:just_audio/just_audio.dart'; import 'package:just_audio/just_audio.dart';
import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart'; import '../modelos/emisora.dart';
import '../modelos/preset_ecualizador.dart'; import '../modelos/preset_ecualizador.dart';
@@ -31,6 +34,10 @@ class ServicioAudio {
Emisora? get emisoraActual => _handler.emisoraActual; Emisora? get emisoraActual => _handler.emisoraActual;
void configurarLocalizaciones(AppLocalizations l10n) {
_handler.configurarLocalizaciones(l10n);
}
Stream<EstadoReproduccion> get estadoStream => Stream<EstadoReproduccion> get estadoStream =>
_handler.playbackState.map((s) { _handler.playbackState.map((s) {
if (s.processingState == AudioProcessingState.error) { if (s.processingState == AudioProcessingState.error) {
@@ -50,7 +57,10 @@ class ServicioAudio {
Future<void> reproducir(Emisora emisora) async { Future<void> reproducir(Emisora emisora) async {
final item = MediaItem( final item = MediaItem(
id: emisora.url, id: emisora.url,
title: emisora.nombre, title: localizedStationName(
lookupAppLocalizations(const Locale('es')),
emisora.nombre,
),
artist: emisora.pais ?? '', artist: emisora.pais ?? '',
album: 'PluriWave', album: 'PluriWave',
artUri: artUri:
@@ -118,6 +128,7 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler {
Emisora? emisoraActual; Emisora? emisoraActual;
double _volumen = 1.0; double _volumen = 1.0;
double get volumen => _volumen; double get volumen => _volumen;
AppLocalizations? _l10n;
AndroidEqualizer? get ecualizador => _eq; AndroidEqualizer? get ecualizador => _eq;
bool _eqDisponible = false; bool _eqDisponible = false;
@@ -135,6 +146,16 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler {
_conectarStreamsPlayer(); _conectarStreamsPlayer();
} }
AppLocalizations get _textos {
final actual = _l10n;
if (actual != null) return actual;
return lookupAppLocalizations(const Locale('es'));
}
void configurarLocalizaciones(AppLocalizations l10n) {
_l10n = l10n;
}
AudioPlayer _crearPlayer() { AudioPlayer _crearPlayer() {
return AudioPlayer( return AudioPlayer(
audioPipeline: AudioPipeline(androidAudioEffects: [_eq]), audioPipeline: AudioPipeline(androidAudioEffects: [_eq]),
@@ -192,7 +213,7 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler {
mensaje = _mensajeAmigable(error); mensaje = _mensajeAmigable(error);
} else { } else {
codigoLog = 'Error desconocido: $error'; codigoLog = 'Error desconocido: $error';
mensaje = 'Error de reproducción'; mensaje = _textos.audioErrorGeneric;
} }
developer.log( developer.log(
@@ -219,30 +240,30 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler {
final code = e.code; final code = e.code;
if (code >= 2000 && code < 3000) { if (code >= 2000 && code < 3000) {
if (code == 2001) return 'Sin conexión a internet'; if (code == 2001) return _textos.audioErrorNoInternet;
if (code == 2002) return 'La URL de la radio no es válida'; if (code == 2002) return _textos.audioErrorInvalidUrl;
if (code == 2003) return 'La radio no está disponible (error 404)'; if (code == 2003) return _textos.audioErrorNotFound;
if (code == 2004) return 'Tiempo de espera agotado al conectar'; if (code == 2004) return _textos.audioErrorTimeout;
return 'No se puede conectar a la radio'; return _textos.audioErrorCannotConnect;
} }
if (code >= 3000 && code < 4000) { if (code >= 3000 && code < 4000) {
return 'Formato de stream no compatible'; return _textos.audioErrorUnsupportedFormat;
} }
if (code >= 4000 && code < 5000) { if (code >= 4000 && code < 5000) {
return 'Error al decodificar el stream de audio'; return _textos.audioErrorDecode;
} }
final msg = e.message ?? ''; final msg = e.message ?? '';
if (msg.contains('Cleartext') || msg.contains('cleartext')) { if (msg.contains('Cleartext') || msg.contains('cleartext')) {
return 'Esta radio usa HTTP sin cifrar (no permitido)'; return _textos.audioErrorCleartext;
} }
if (msg.contains('CERTIFICATE') || msg.contains('HandshakeException')) { if (msg.contains('CERTIFICATE') || msg.contains('HandshakeException')) {
return 'Certificado SSL inválido en la radio'; return _textos.audioErrorSsl;
} }
return 'No se puede reproducir esta radio'; return _textos.audioErrorCannotPlay;
} }
AudioProcessingState _mapProcState(ProcessingState state) { AudioProcessingState _mapProcState(ProcessingState state) {
@@ -300,7 +321,7 @@ class PluriWaveAudioHandler extends BaseAudioHandler with SeekHandler {
playbackState.value.copyWith( playbackState.value.copyWith(
processingState: AudioProcessingState.error, processingState: AudioProcessingState.error,
playing: false, playing: false,
errorMessage: 'Error inesperado al reproducir', errorMessage: _textos.audioErrorUnexpectedPlayback,
), ),
); );
emisoraActual = null; emisoraActual = null;
+16 -3
View File
@@ -1,10 +1,12 @@
import 'dart:async'; import 'dart:async';
import 'dart:io'; import 'dart:io';
import 'dart:ui' show Locale;
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart'; import '../modelos/emisora.dart';
enum EstadoGrabacionRadioTipo { enum EstadoGrabacionRadioTipo {
@@ -92,6 +94,7 @@ class ServicioGrabacionRadio {
final Future<Directory> Function()? _resolverDirectorioBase; final Future<Directory> Function()? _resolverDirectorioBase;
final DateTime Function() _reloj; final DateTime Function() _reloj;
final _estadoController = StreamController<EstadoGrabacionRadio>.broadcast(); final _estadoController = StreamController<EstadoGrabacionRadio>.broadcast();
AppLocalizations? _l10n;
EstadoGrabacionRadio _estado = const EstadoGrabacionRadio.inactiva(); EstadoGrabacionRadio _estado = const EstadoGrabacionRadio.inactiva();
StreamSubscription<List<int>>? _subscripcionStream; StreamSubscription<List<int>>? _subscripcionStream;
@@ -108,6 +111,16 @@ class ServicioGrabacionRadio {
int get maxBytes => _maxBytes; int get maxBytes => _maxBytes;
File? get ultimoArchivo => _ultimoArchivo; File? get ultimoArchivo => _ultimoArchivo;
AppLocalizations get _textos {
final actual = _l10n;
if (actual != null) return actual;
return lookupAppLocalizations(const Locale('es'));
}
void configurarLocalizaciones(AppLocalizations l10n) {
_l10n = l10n;
}
Future<void> inicializar() async { Future<void> inicializar() async {
try { try {
final prefs = await SharedPreferences.getInstance(); final prefs = await SharedPreferences.getInstance();
@@ -134,7 +147,7 @@ class ServicioGrabacionRadio {
Future<void> guardarDirectorio(String path) async { Future<void> guardarDirectorio(String path) async {
final normalizado = path.trim(); final normalizado = path.trim();
if (normalizado.isEmpty) { if (normalizado.isEmpty) {
throw ArgumentError('La ruta de grabación no puede estar vacía'); throw ArgumentError(_textos.recordingPathEmptyError);
} }
_directorioConfigurado = normalizado; _directorioConfigurado = normalizado;
try { try {
@@ -155,7 +168,7 @@ class ServicioGrabacionRadio {
Future<void> guardarMaxBytes(int bytes) async { Future<void> guardarMaxBytes(int bytes) async {
if (bytes <= 0) { if (bytes <= 0) {
throw ArgumentError('El tamaño máximo debe ser mayor que cero'); throw ArgumentError(_textos.recordingMaxSizeInvalidError);
} }
_maxBytes = bytes; _maxBytes = bytes;
try { try {
@@ -171,7 +184,7 @@ class ServicioGrabacionRadio {
String? directorio, String? directorio,
}) async { }) async {
if (_estado.activa) { if (_estado.activa) {
throw StateError('Ya hay una grabación en curso'); throw StateError(_textos.recordingAlreadyActiveError);
} }
final inicio = _reloj(); final inicio = _reloj();
+21 -5
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../l10n/gen/app_localizations.dart';
import '../modelos/preset_ecualizador.dart'; import '../modelos/preset_ecualizador.dart';
import '../tema/pluriwave_theme.dart'; import '../tema/pluriwave_theme.dart';
import 'pluri_glass_surface.dart'; import 'pluri_glass_surface.dart';
@@ -41,6 +42,7 @@ class _EcualizadorWidgetState extends State<EcualizadorWidget> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final tokens = context.pluriTokens; final tokens = context.pluriTokens;
final l10n = AppLocalizations.of(context);
return PluriGlassSurface( return PluriGlassSurface(
borderRadius: BorderRadius.circular(tokens.radiusLg), borderRadius: BorderRadius.circular(tokens.radiusLg),
@@ -50,10 +52,10 @@ class _EcualizadorWidgetState extends State<EcualizadorWidget> {
children: [ children: [
Row( Row(
children: [ children: [
Text('Ecualizador', style: theme.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w700)), Text(l10n.equalizerTitle, style: theme.textTheme.titleMedium?.copyWith(fontWeight: FontWeight.w700)),
const Spacer(), const Spacer(),
Chip( Chip(
label: Text(widget.preset.nombre, style: theme.textTheme.labelMedium), label: Text(_nombrePreset(l10n, widget.preset.nombre), style: theme.textTheme.labelMedium),
backgroundColor: theme.colorScheme.secondaryContainer.withValues(alpha: 0.75), backgroundColor: theme.colorScheme.secondaryContainer.withValues(alpha: 0.75),
), ),
], ],
@@ -77,8 +79,8 @@ class _EcualizadorWidgetState extends State<EcualizadorWidget> {
height: 152, height: 152,
child: Semantics( child: Semantics(
slider: true, slider: true,
label: 'Banda ${_etiquetas[i]}', label: l10n.equalizerBandLabel(_etiquetas[i]),
value: '${_bandas[i].toStringAsFixed(1)} decibelios', value: l10n.equalizerBandValue(_bandas[i].toStringAsFixed(1)),
child: RotatedBox( child: RotatedBox(
quarterTurns: 3, quarterTurns: 3,
child: Slider( child: Slider(
@@ -110,6 +112,19 @@ class _EcualizadorWidgetState extends State<EcualizadorWidget> {
} }
} }
String _nombrePreset(AppLocalizations l10n, String nombre) {
return switch (nombre) {
'Flat' => l10n.equalizerPresetFlat,
'Rock' => l10n.equalizerPresetRock,
'Pop' => l10n.equalizerPresetPop,
'Bass Boost' => l10n.equalizerPresetBassBoost,
'Jazz' => l10n.equalizerPresetJazz,
'Voz' => l10n.equalizerPresetVoice,
'Personalizado' => l10n.equalizerPresetCustom,
_ => nombre,
};
}
class PresetsEcualizadorWidget extends StatelessWidget { class PresetsEcualizadorWidget extends StatelessWidget {
final PresetEcualizador presetActual; final PresetEcualizador presetActual;
final void Function(PresetEcualizador) onSeleccionar; final void Function(PresetEcualizador) onSeleccionar;
@@ -123,13 +138,14 @@ class PresetsEcualizadorWidget extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final theme = Theme.of(context); final theme = Theme.of(context);
final l10n = AppLocalizations.of(context);
return Wrap( return Wrap(
spacing: 8, spacing: 8,
runSpacing: 6, runSpacing: 6,
children: PresetEcualizador.presets.map((p) { children: PresetEcualizador.presets.map((p) {
final selected = p.nombre == presetActual.nombre; final selected = p.nombre == presetActual.nombre;
return ChoiceChip( return ChoiceChip(
label: Text(p.nombre), label: Text(_nombrePreset(l10n, p.nombre)),
selected: selected, selected: selected,
showCheckmark: false, showCheckmark: false,
selectedColor: theme.colorScheme.primaryContainer, selectedColor: theme.colorScheme.primaryContainer,
+20 -15
View File
@@ -2,6 +2,8 @@ import 'package:flutter/material.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart';
import '../pantallas/pantalla_reproductor.dart'; import '../pantallas/pantalla_reproductor.dart';
import '../servicios/servicio_audio.dart'; import '../servicios/servicio_audio.dart';
import '../tema/pluriwave_theme.dart'; import '../tema/pluriwave_theme.dart';
@@ -17,11 +19,14 @@ class MiniReproductor extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final estado = context.watch<EstadoRadio>(); final estado = context.watch<EstadoRadio>();
final l10n = AppLocalizations.of(context);
estado.configurarLocalizaciones(l10n);
final emisora = estado.emisoraActual; final emisora = estado.emisoraActual;
if (emisora == null) return const SizedBox.shrink(); if (emisora == null) return const SizedBox.shrink();
final t = context.pluriTokens; final t = context.pluriTokens;
final stationName = localizedStationName(l10n, emisora.nombre);
return SafeArea( return SafeArea(
top: false, top: false,
@@ -43,7 +48,7 @@ class MiniReproductor extends StatelessWidget {
Expanded( Expanded(
child: Semantics( child: Semantics(
button: true, button: true,
label: 'Abrir reproductor de ${emisora.nombre}', label: l10n.miniPlayerOpenLabel(stationName),
child: Material( child: Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
@@ -74,7 +79,7 @@ class MiniReproductor extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
emisora.nombre, stationName,
style: Theme.of(context) style: Theme.of(context)
.textTheme .textTheme
.titleSmall .titleSmall
@@ -91,7 +96,7 @@ class MiniReproductor extends StatelessWidget {
final activo = final activo =
s == EstadoReproduccion.reproduciendo; s == EstadoReproduccion.reproduciendo;
return Text( return Text(
_labelEstado(s), _labelEstado(l10n, s),
style: Theme.of( style: Theme.of(
context, context,
).textTheme.bodySmall?.copyWith( ).textTheme.bodySmall?.copyWith(
@@ -117,7 +122,7 @@ class MiniReproductor extends StatelessWidget {
glyph: PluriIconGlyph.player, glyph: PluriIconGlyph.player,
variant: PluriIconVariant.activeGlow, variant: PluriIconVariant.activeGlow,
size: 18, size: 18,
semanticLabel: 'Reproductor', semanticLabel: l10n.playerIconLabel,
), ),
], ],
), ),
@@ -144,7 +149,7 @@ class MiniReproductor extends StatelessWidget {
if (s == EstadoReproduccion.error) { if (s == EstadoReproduccion.error) {
final emisoraActual = estado.emisoraActual; final emisoraActual = estado.emisoraActual;
return IconButton( return IconButton(
tooltip: 'Reintentar', tooltip: l10n.retryAction,
icon: const Icon(Icons.refresh_rounded), icon: const Icon(Icons.refresh_rounded),
onPressed: onPressed:
emisoraActual != null emisoraActual != null
@@ -161,13 +166,13 @@ class MiniReproductor extends StatelessWidget {
button: true, button: true,
label: label:
s == EstadoReproduccion.reproduciendo s == EstadoReproduccion.reproduciendo
? 'Pausar' ? l10n.pauseAction
: 'Reproducir', : l10n.playAction,
child: IconButton( child: IconButton(
tooltip: tooltip:
s == EstadoReproduccion.reproduciendo s == EstadoReproduccion.reproduciendo
? 'Pausar' ? l10n.pauseAction
: 'Reproducir', : l10n.playAction,
icon: Icon( icon: Icon(
s == EstadoReproduccion.reproduciendo s == EstadoReproduccion.reproduciendo
? Icons.pause_circle_filled_rounded ? Icons.pause_circle_filled_rounded
@@ -190,13 +195,13 @@ class MiniReproductor extends StatelessWidget {
); );
} }
String _labelEstado(EstadoReproduccion estado) { String _labelEstado(AppLocalizations l10n, EstadoReproduccion estado) {
return switch (estado) { return switch (estado) {
EstadoReproduccion.cargando => 'Conectando...', EstadoReproduccion.cargando => l10n.playbackStatusConnecting,
EstadoReproduccion.reproduciendo => 'En directo', EstadoReproduccion.reproduciendo => l10n.playbackStatusLive,
EstadoReproduccion.pausado => 'Pausado', EstadoReproduccion.pausado => l10n.playbackStatusPaused,
EstadoReproduccion.error => 'Error de conexión', EstadoReproduccion.error => l10n.playbackStatusConnectionError,
EstadoReproduccion.detenido => 'Detenido', EstadoReproduccion.detenido => l10n.playbackStatusStopped,
}; };
} }
} }
+9 -8
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../l10n/gen/app_localizations.dart';
import '../tema/pluriwave_tokens.dart'; import '../tema/pluriwave_tokens.dart';
import '../tema/pluriwave_theme.dart'; import '../tema/pluriwave_theme.dart';
@@ -62,7 +63,7 @@ class PluriIcon extends StatelessWidget {
: icon; : icon;
return Semantics( return Semantics(
label: semanticLabel ?? _fallbackLabel(glyph), label: semanticLabel ?? _fallbackLabel(AppLocalizations.of(context), glyph),
image: true, image: true,
child: ExcludeSemantics(child: child), child: ExcludeSemantics(child: child),
); );
@@ -108,14 +109,14 @@ class PluriIcon extends StatelessWidget {
}; };
} }
String _fallbackLabel(PluriIconGlyph glyph) { String _fallbackLabel(AppLocalizations l10n, PluriIconGlyph glyph) {
return switch (glyph) { return switch (glyph) {
PluriIconGlyph.home => 'Inicio', PluriIconGlyph.home => l10n.navHome,
PluriIconGlyph.search => 'Buscar', PluriIconGlyph.search => l10n.navSearch,
PluriIconGlyph.favorites => 'Favoritos', PluriIconGlyph.favorites => l10n.navFavorites,
PluriIconGlyph.alarm => 'Alarmas', PluriIconGlyph.alarm => l10n.navAlarms,
PluriIconGlyph.player => 'Reproductor', PluriIconGlyph.player => l10n.playerIconLabel,
PluriIconGlyph.settings => 'Ajustes', PluriIconGlyph.settings => l10n.navSettings,
}; };
} }
} }
+6 -60
View File
@@ -1,5 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import '../l10n/gen/app_localizations.dart';
import '../servicios/servicio_contenido_app.dart'; import '../servicios/servicio_contenido_app.dart';
import 'pluri_glass_surface.dart'; import 'pluri_glass_surface.dart';
import 'pluri_markdown.dart'; import 'pluri_markdown.dart';
@@ -41,7 +42,7 @@ class _PluriOnboardingContent extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final labels = _labels(Localizations.localeOf(context).languageCode); final l10n = AppLocalizations.of(context);
final size = MediaQuery.sizeOf(context); final size = MediaQuery.sizeOf(context);
return Dialog( return Dialog(
insetPadding: const EdgeInsets.all(16), insetPadding: const EdgeInsets.all(16),
@@ -80,14 +81,14 @@ class _PluriOnboardingContent extends StatelessWidget {
const SizedBox(width: 14), const SizedBox(width: 14),
Expanded( Expanded(
child: Text( child: Text(
labels.title, l10n.onboardingTitle,
style: Theme.of(context).textTheme.titleLarge?.copyWith( style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
), ),
), ),
), ),
IconButton( IconButton(
tooltip: labels.close, tooltip: l10n.onboardingCloseTooltip,
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: const Icon(Icons.close_rounded), icon: const Icon(Icons.close_rounded),
), ),
@@ -102,7 +103,7 @@ class _PluriOnboardingContent extends StatelessWidget {
if (contenido.notas.isNotEmpty) ...[ if (contenido.notas.isNotEmpty) ...[
const SizedBox(height: 18), const SizedBox(height: 18),
Text( Text(
labels.news, l10n.onboardingNewsTitle,
style: Theme.of(context).textTheme.titleLarge?.copyWith( style: Theme.of(context).textTheme.titleLarge?.copyWith(
fontWeight: FontWeight.w900, fontWeight: FontWeight.w900,
), ),
@@ -131,7 +132,7 @@ class _PluriOnboardingContent extends StatelessWidget {
child: FilledButton.icon( child: FilledButton.icon(
onPressed: () => Navigator.of(context).pop(), onPressed: () => Navigator.of(context).pop(),
icon: const Icon(Icons.check_rounded), icon: const Icon(Icons.check_rounded),
label: Text(labels.start), label: Text(l10n.onboardingStartAction),
), ),
), ),
], ],
@@ -141,58 +142,3 @@ class _PluriOnboardingContent extends StatelessWidget {
); );
} }
} }
_OnboardingLabels _labels(String languageCode) {
return switch (languageCode) {
'es' => const _OnboardingLabels(
title: 'Bienvenido a PluriWave',
news: 'Novedades',
start: 'Empezar',
close: 'Cerrar',
),
'fr' => const _OnboardingLabels(
title: 'Bienvenue sur PluriWave',
news: 'Nouveautés',
start: 'Commencer',
close: 'Fermer',
),
'de' => const _OnboardingLabels(
title: 'Willkommen bei PluriWave',
news: 'Neuigkeiten',
start: 'Starten',
close: 'Schließen',
),
'it' => const _OnboardingLabels(
title: 'Benvenuto in PluriWave',
news: 'Novità',
start: 'Inizia',
close: 'Chiudi',
),
'pt' => const _OnboardingLabels(
title: 'Bem-vindo ao PluriWave',
news: 'Novidades',
start: 'Começar',
close: 'Fechar',
),
_ => const _OnboardingLabels(
title: 'Welcome to PluriWave',
news: 'Whats new',
start: 'Start',
close: 'Close',
),
};
}
class _OnboardingLabels {
const _OnboardingLabels({
required this.title,
required this.news,
required this.start,
required this.close,
});
final String title;
final String news;
final String start;
final String close;
}
+28 -9
View File
@@ -4,6 +4,8 @@ import 'package:provider/provider.dart';
import 'package:shimmer/shimmer.dart'; import 'package:shimmer/shimmer.dart';
import '../estado/estado_radio.dart'; import '../estado/estado_radio.dart';
import '../l10n/display_names.dart';
import '../l10n/gen/app_localizations.dart';
import '../modelos/emisora.dart'; import '../modelos/emisora.dart';
import '../tema/pluriwave_theme.dart'; import '../tema/pluriwave_theme.dart';
import 'pluri_glass_surface.dart'; import 'pluri_glass_surface.dart';
@@ -37,12 +39,14 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
final esFav = await estado.toggleFavorito(widget.emisora); final esFav = await estado.toggleFavorito(widget.emisora);
if (mounted) setState(() => _toggling = false); if (mounted) setState(() => _toggling = false);
if (mounted) { if (mounted) {
final l10n = AppLocalizations.of(context);
final stationName = localizedStationName(l10n, widget.emisora.nombre);
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
content: Text( content: Text(
esFav esFav
? '${widget.emisora.nombre} añadida a favoritos' ? l10n.favoritesAddedMessage(stationName)
: '${widget.emisora.nombre} eliminada de favoritos', : l10n.favoritesRemovedMessage(stationName),
), ),
duration: const Duration(seconds: 2), duration: const Duration(seconds: 2),
), ),
@@ -53,9 +57,11 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final t = context.pluriTokens; final t = context.pluriTokens;
final l10n = AppLocalizations.of(context);
final stationName = localizedStationName(l10n, widget.emisora.nombre);
return Semantics( return Semantics(
button: widget.onTap != null, button: widget.onTap != null,
label: 'Emisora ${widget.emisora.nombre}', label: l10n.stationSemanticLabel(stationName),
child: PluriGlassSurface( child: PluriGlassSurface(
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
borderRadius: BorderRadius.circular( borderRadius: BorderRadius.circular(
@@ -74,6 +80,10 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
Widget _buildCompleta() { Widget _buildCompleta() {
final t = context.pluriTokens; final t = context.pluriTokens;
final stationName = localizedStationName(
AppLocalizations.of(context),
widget.emisora.nombre,
);
return Stack( return Stack(
children: [ children: [
Column( Column(
@@ -116,7 +126,7 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
widget.emisora.nombre, stationName,
style: Theme.of(context).textTheme.titleSmall?.copyWith( style: Theme.of(context).textTheme.titleSmall?.copyWith(
fontWeight: FontWeight.w700, fontWeight: FontWeight.w700,
), ),
@@ -153,6 +163,10 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
Widget _buildCompacta() { Widget _buildCompacta() {
final t = context.pluriTokens; final t = context.pluriTokens;
final stationName = localizedStationName(
AppLocalizations.of(context),
widget.emisora.nombre,
);
final subtitulo = [ final subtitulo = [
widget.emisora.pais, widget.emisora.pais,
widget.emisora.idioma, widget.emisora.idioma,
@@ -192,7 +206,7 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text( Text(
widget.emisora.nombre, stationName,
style: Theme.of( style: Theme.of(
context, context,
).textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w700), ).textTheme.titleSmall?.copyWith(fontWeight: FontWeight.w700),
@@ -223,6 +237,7 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
Widget _botonFavorito({required bool mini}) { Widget _botonFavorito({required bool mini}) {
final t = context.pluriTokens; final t = context.pluriTokens;
final l10n = AppLocalizations.of(context);
final esFavorito = context.select<EstadoRadio, bool>( final esFavorito = context.select<EstadoRadio, bool>(
(estado) => (estado) =>
estado.listaFavoritos.any((e) => e.uuid == widget.emisora.uuid), estado.listaFavoritos.any((e) => e.uuid == widget.emisora.uuid),
@@ -248,13 +263,16 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
: PluriIconVariant.outline, : PluriIconVariant.outline,
size: 20, size: 20,
semanticLabel: semanticLabel:
esFavorito ? 'Quitar de favoritos' : 'Añadir a favoritos', esFavorito
? l10n.favoritesRemoveTooltip
: l10n.favoritesAddTooltip,
); );
return Semantics( return Semantics(
button: true, button: true,
toggled: esFavorito, toggled: esFavorito,
label: esFavorito ? 'Quitar de favoritos' : 'Añadir a favoritos', label:
esFavorito ? l10n.favoritesRemoveTooltip : l10n.favoritesAddTooltip,
child: Material( child: Material(
color: mini ? t.glassSurface : Colors.transparent, color: mini ? t.glassSurface : Colors.transparent,
shape: const CircleBorder(), shape: const CircleBorder(),
@@ -318,7 +336,7 @@ class _TarjetaEmisoraState extends State<TarjetaEmisora> {
glyph: PluriIconGlyph.player, glyph: PluriIconGlyph.player,
variant: PluriIconVariant.activeGlow, variant: PluriIconVariant.activeGlow,
size: size, size: size,
semanticLabel: 'Icono de emisora', semanticLabel: AppLocalizations.of(context).stationIconLabel,
), ),
), ),
], ],
@@ -345,6 +363,7 @@ class _LiveBadge extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final color = Theme.of(context).colorScheme.secondary; final color = Theme.of(context).colorScheme.secondary;
final l10n = AppLocalizations.of(context);
return Container( return Container(
padding: EdgeInsets.symmetric(horizontal: mini ? 8 : 6, vertical: mini ? 5 : 4), padding: EdgeInsets.symmetric(horizontal: mini ? 8 : 6, vertical: mini ? 5 : 4),
decoration: BoxDecoration( decoration: BoxDecoration(
@@ -358,7 +377,7 @@ class _LiveBadge extends StatelessWidget {
Icon(Icons.fiber_manual_record_rounded, size: mini ? 10 : 8, color: color), Icon(Icons.fiber_manual_record_rounded, size: mini ? 10 : 8, color: color),
if (mini) ...[ if (mini) ...[
const SizedBox(width: 5), const SizedBox(width: 5),
Text('Live', style: Theme.of(context).textTheme.labelSmall?.copyWith(fontWeight: FontWeight.w900)), Text(l10n.liveNow, style: Theme.of(context).textTheme.labelSmall?.copyWith(fontWeight: FontWeight.w900)),
], ],
], ],
), ),
+24 -2
View File
@@ -22,6 +22,7 @@ void main() {
testWidgets( testWidgets(
'PantallaInicio muestra custom, reproducir usa EstadoRadio y favorito usa flujo existente', 'PantallaInicio muestra custom, reproducir usa EstadoRadio y favorito usa flujo existente',
(tester) async { (tester) async {
_setLargeSurfaceSize(tester);
final audio = FakeServicioAudio(); final audio = FakeServicioAudio();
final favoritos = FakeServicioFavoritos(); final favoritos = FakeServicioFavoritos();
final radio = FakeServicioRadio(); final radio = FakeServicioRadio();
@@ -47,6 +48,7 @@ void main() {
); );
await _pumpStableFrame(tester); await _pumpStableFrame(tester);
await _scrollUntilText(tester, 'Custom Uno');
expect(find.text('Custom Uno'), findsOneWidget); expect(find.text('Custom Uno'), findsOneWidget);
await tester.ensureVisible(find.text('Custom Uno')); await tester.ensureVisible(find.text('Custom Uno'));
@@ -82,6 +84,7 @@ void main() {
testWidgets( testWidgets(
'PantallaInicio permite reintentar manualmente tras fallo inicial agotado', 'PantallaInicio permite reintentar manualmente tras fallo inicial agotado',
(tester) async { (tester) async {
_setLargeSurfaceSize(tester);
final radio = FakeServicioRadio( final radio = FakeServicioRadio(
erroresPopularesPorLlamada: [Exception('sin red')], erroresPopularesPorLlamada: [Exception('sin red')],
popularesPorLlamada: [ popularesPorLlamada: [
@@ -113,6 +116,7 @@ void main() {
); );
await _pumpStableFrame(tester); await _pumpStableFrame(tester);
await _scrollUntilText(tester, 'Sin conexión a la API de radio');
expect(find.text('Sin conexión a la API de radio'), findsOneWidget); expect(find.text('Sin conexión a la API de radio'), findsOneWidget);
expect(find.text('Reintentar'), findsOneWidget); expect(find.text('Reintentar'), findsOneWidget);
@@ -130,6 +134,7 @@ void main() {
testWidgets('PantallaFavoritos muestra custom favorito tras recarga', ( testWidgets('PantallaFavoritos muestra custom favorito tras recarga', (
tester, tester,
) async { ) async {
_setLargeSurfaceSize(tester);
final favoritos = FakeServicioFavoritos(); final favoritos = FakeServicioFavoritos();
final custom = emisoraDemo(uuid: 'custom-1', nombre: 'Custom Uno'); final custom = emisoraDemo(uuid: 'custom-1', nombre: 'Custom Uno');
final archivo = await _crearArchivoCustom([custom]); final archivo = await _crearArchivoCustom([custom]);
@@ -155,7 +160,7 @@ void main() {
); );
await _pumpStableFrame(tester); await _pumpStableFrame(tester);
await tester.ensureVisible(find.text('Custom Uno')); await _scrollUntilText(tester, 'Custom Uno');
await _pumpStableFrame(tester); await _pumpStableFrame(tester);
final tarjetaCustom = find.ancestor( final tarjetaCustom = find.ancestor(
of: find.text('Custom Uno'), of: find.text('Custom Uno'),
@@ -185,6 +190,7 @@ void main() {
Widget _testApp(Widget body) { Widget _testApp(Widget body) {
return MaterialApp( return MaterialApp(
locale: const Locale('es'),
localizationsDelegates: AppLocalizations.localizationsDelegates, localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales, supportedLocales: AppLocalizations.supportedLocales,
home: Scaffold(body: body), home: Scaffold(body: body),
@@ -209,7 +215,23 @@ class FakeServicioGrabacionRadio extends ServicioGrabacionRadio {
Future<void> _pumpStableFrame(WidgetTester tester) async { Future<void> _pumpStableFrame(WidgetTester tester) async {
await tester.pump(); await tester.pump();
await tester.pump(const Duration(milliseconds: 100)); await tester.pumpAndSettle(const Duration(milliseconds: 100));
}
void _setLargeSurfaceSize(WidgetTester tester) {
tester.view.physicalSize = const Size(1440, 3200);
tester.view.devicePixelRatio = 1.0;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
}
Future<void> _scrollUntilText(WidgetTester tester, String text) async {
await tester.scrollUntilVisible(
find.text(text),
300,
scrollable: find.byType(Scrollable).first,
);
await _pumpStableFrame(tester);
} }
Future<File> _crearArchivoCustom(List<dynamic> emisoras) async { Future<File> _crearArchivoCustom(List<dynamic> emisoras) async {