Compare commits
5
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ec41bb31e | ||
|
|
2959941485 | ||
|
|
f3d744aeed | ||
|
|
9b415e73b0 | ||
|
|
862197ab48 |
+21
-4
@@ -14,6 +14,7 @@ import 'l10n/gen/app_localizations.dart';
|
||||
import 'modelos/alarma_musical.dart';
|
||||
import 'pantallas/pantalla_alarmas.dart';
|
||||
import 'pantallas/pantalla_alarma_sonando.dart';
|
||||
import 'pantallas/pantalla_bienvenida.dart';
|
||||
import 'pantallas/pantalla_inicio.dart';
|
||||
import 'pantallas/pantalla_buscar.dart';
|
||||
import 'pantallas/pantalla_favoritos.dart';
|
||||
@@ -108,7 +109,10 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal>
|
||||
EstadoRadio? _estadoSuscrito;
|
||||
bool _alarmaInicialProcesada = false;
|
||||
bool _alarmaSonandoActiva = false;
|
||||
bool _onboardingInicialSolicitado = false;
|
||||
// WU17b: renamed from `_onboardingInicialSolicitado` — this single guard
|
||||
// now covers the whole first-launch sequence (welcome screen, then the
|
||||
// pre-existing what's-new dialog), not only the dialog.
|
||||
bool _flujoPrimerLanzamientoSolicitado = false;
|
||||
String? _alarmaSonandoId;
|
||||
Locale? _localeAlarmasConfigurado;
|
||||
|
||||
@@ -191,9 +195,9 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal>
|
||||
_alarmaInicialProcesada = true;
|
||||
unawaited(_procesarAlarmaInicial(alarmas));
|
||||
}
|
||||
if (!_onboardingInicialSolicitado) {
|
||||
_onboardingInicialSolicitado = true;
|
||||
unawaited(_mostrarOnboardingInicial());
|
||||
if (!_flujoPrimerLanzamientoSolicitado) {
|
||||
_flujoPrimerLanzamientoSolicitado = true;
|
||||
unawaited(_mostrarFlujoPrimerLanzamiento());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -278,6 +282,19 @@ class _PaginaPrincipalState extends State<_PaginaPrincipal>
|
||||
}
|
||||
}
|
||||
|
||||
// WU17b: runs the welcome screen's once-ever check BEFORE the recurring
|
||||
// what's-new dialog, so the two never show at the same time. The welcome
|
||||
// screen (PantallaBienvenida) is the genuine first-run surface; the
|
||||
// pre-existing PluriOnboardingDialog is an unrelated "what's new"/help
|
||||
// modal that keeps its own independent per-version due-or-not logic,
|
||||
// completely unchanged by this sequencing.
|
||||
Future<void> _mostrarFlujoPrimerLanzamiento() async {
|
||||
if (mounted) {
|
||||
await PantallaBienvenida.mostrarSiProcede(context);
|
||||
}
|
||||
await _mostrarOnboardingInicial();
|
||||
}
|
||||
|
||||
Future<void> _mostrarOnboardingInicial() async {
|
||||
await Future<void>.delayed(const Duration(milliseconds: 900));
|
||||
if (!mounted || _alarmaSonandoActiva) return;
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "ar",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "الرئيسية",
|
||||
"navHome": "استماع",
|
||||
"navSearch": "بحث",
|
||||
"navFavorites": "المفضلة",
|
||||
"navAlarms": "المنبهات",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "مجلد محدد"
|
||||
}
|
||||
"localMusicFolderGenericName": "مجلد محدد",
|
||||
"addVacationRangeCta": "إضافة فترة",
|
||||
"alarmAdvancedSectionTitle": "متقدم",
|
||||
"alarmDeleteConfirmMessage": "لا يمكن التراجع عن هذا الإجراء.",
|
||||
"alarmDeleteConfirmTitle": "هل تريد حذف المنبه؟",
|
||||
"alarmHeroSkipAction": "تخطي",
|
||||
"alarmInlineHourLabel": "الساعة",
|
||||
"alarmInlineMinuteLabel": "الدقيقة",
|
||||
"alarmVolumeRisingStatus": "رفع مستوى الصوت تدريجيًا",
|
||||
"countriesAllTitle": "كل الدول",
|
||||
"countriesScreenTitle": "الدول",
|
||||
"countriesYourLanguagesTitle": "لغاتك",
|
||||
"customStationsAddCta": "إضافة محطة مخصصة",
|
||||
"equalizerActiveOutputDefault": "مكبر صوت هذا الجهاز",
|
||||
"equalizerActiveOutputLabel": "المخرج النشط",
|
||||
"equalizerBaseExplainer": "هذا هو المعادل الأساسي: يُطبَّق على كل محطة لا تملك إعدادًا خاصًا بها. يُحدَّد معادل محطة معينة من شاشة تشغيلها الخاصة، وله الأولوية على هذا المعادل.",
|
||||
"equalizerSaveAsPresetAction": "حفظ كإعداد مسبق",
|
||||
"equalizerSavePresetConfirm": "حفظ",
|
||||
"equalizerSavePresetDialogTitle": "حفظ كإعداد مسبق",
|
||||
"equalizerSavePresetEmptyNameError": "أدخل اسمًا للإعداد المسبق.",
|
||||
"equalizerSavePresetNameLabel": "اسم الإعداد المسبق",
|
||||
"equalizerStationsWithOwnEqEmpty": "لا توجد محطة لديها معادل خاص حتى الآن.",
|
||||
"equalizerStationsWithOwnEqSubtitle": "تتجاهل هذا المعادل الأساسي",
|
||||
"equalizerStationsWithOwnEqTitle": "محطات لديها معادل خاص",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "إدارة القوائم",
|
||||
"favoritesFilterAllLabel": "الكل",
|
||||
"infoSectionTitle": "معلومات",
|
||||
"nothingPlayingSubtitle": "اختر محطة من محطاتك أو ابحث عن واحدة للبدء.",
|
||||
"nothingPlayingTitle": "لا تستمع إلى شيء بعد",
|
||||
"openFullPlayerTooltip": "فتح المشغل الكامل",
|
||||
"playerQualityChangeAction": "تغيير",
|
||||
"playerToolEqLabel": "معادل خاص",
|
||||
"radioCountriesError": "تعذّر تحميل الدول.",
|
||||
"recordingActionDelete": "حذف",
|
||||
"recordingActionRename": "إعادة تسمية",
|
||||
"recordingActionShare": "مشاركة",
|
||||
"recordingDeleteConfirmMessage": "لا يمكن التراجع عن هذا الإجراء.",
|
||||
"recordingDeleteConfirmTitle": "هل تريد حذف التسجيل؟",
|
||||
"recordingRenameDialogTitle": "إعادة تسمية التسجيل",
|
||||
"recordingRenameEmptyError": "أدخل اسمًا",
|
||||
"recordingRenameLabel": "الاسم",
|
||||
"recordingsLibraryEmptySubtitle": "التسجيلات التي تحفظها ستظهر هنا.",
|
||||
"recordingsLibraryEmptyTitle": "لا توجد تسجيلات بعد",
|
||||
"recordingsLibrarySettingsTooltip": "إعدادات التسجيل",
|
||||
"recordingsLibraryStorageCaption": "تم استخدام {usedMb} ميغابايت من أصل {totalMb} ميغابايت",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "تسجيلاتي",
|
||||
"searchClearFiltersAction": "{count, plural, one{إزالة الفلتر} two{إزالة الفلترين} few{إزالة {count} فلاتر} other{إزالة {count} فلتر}}",
|
||||
"searchResultsCount": "{count, plural, one{نتيجة واحدة} two{نتيجتان} few{{count} نتائج} other{{count} نتيجة}}",
|
||||
"seeAllAction": "عرض الكل",
|
||||
"settingsGroupApplicationTitle": "التطبيق",
|
||||
"settingsGroupAudioTitle": "الصوت",
|
||||
"settingsGroupRecordingsTitle": "التسجيلات والموسيقى",
|
||||
"settingsGroupStationsTitle": "المحطات",
|
||||
"stationOrderByPopularity": "حسب الشهرة",
|
||||
"vacationImpactContinuesLabel": "يستمر الرنين: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "إيقاف مؤقت: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "لا توجد فترة إجازة نشطة الآن.",
|
||||
"vacationPastSectionTitle": "الفترات السابقة",
|
||||
"vacationRangesCount": "{count} فترة",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "جارٍ الآن · تبقّى {days} يوم",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "الفترة التالية خلال {days} يوم",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "المجدولة",
|
||||
"welcomeBody": "53,412 محطة من 238 دولة. احفظ محطاتك المفضلة، خذها معك في السيارة، واستيقظ عليها.",
|
||||
"welcomeBullet1Subtitle": "بالإضافة إلى إعداد مسبق لكل جهاز خرج",
|
||||
"welcomeBullet1Title": "معادل لكل محطة",
|
||||
"welcomeBullet2Subtitle": "محطاتك المفضلة وموسيقاك المحلية في السيارة",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "مع رفع تدريجي للصوت ووضع الإجازة",
|
||||
"welcomeBullet3Title": "منبهات موسيقية",
|
||||
"welcomeCtaLabel": "ابدأ الاستماع",
|
||||
"welcomeHeadline": "عالمك، على الهواء مباشرة",
|
||||
"yourStationsTitle": "محطاتك"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "bn",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "হোম",
|
||||
"navHome": "শোনা",
|
||||
"navSearch": "অনুসন্ধান",
|
||||
"navFavorites": "প্রিয়",
|
||||
"navAlarms": "অ্যালার্ম",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "নির্বাচিত ফোল্ডার"
|
||||
}
|
||||
"localMusicFolderGenericName": "নির্বাচিত ফোল্ডার",
|
||||
"addVacationRangeCta": "সময়সীমা যোগ করুন",
|
||||
"alarmAdvancedSectionTitle": "উন্নত",
|
||||
"alarmDeleteConfirmMessage": "এই পদক্ষেপ ফিরিয়ে নেওয়া যাবে না।",
|
||||
"alarmDeleteConfirmTitle": "অ্যালার্ম মুছবেন?",
|
||||
"alarmHeroSkipAction": "এড়িয়ে যান",
|
||||
"alarmInlineHourLabel": "ঘণ্টা",
|
||||
"alarmInlineMinuteLabel": "মিনিট",
|
||||
"alarmVolumeRisingStatus": "ভলিউম বাড়ছে",
|
||||
"countriesAllTitle": "সব দেশ",
|
||||
"countriesScreenTitle": "দেশসমূহ",
|
||||
"countriesYourLanguagesTitle": "আপনার ভাষাসমূহ",
|
||||
"customStationsAddCta": "নিজস্ব স্টেশন যোগ করুন",
|
||||
"equalizerActiveOutputDefault": "এই ডিভাইসের স্পিকার",
|
||||
"equalizerActiveOutputLabel": "সক্রিয় আউটপুট",
|
||||
"equalizerBaseExplainer": "এটি বেস ইকুয়ালাইজার: এটি নিজস্ব সেটিং নেই এমন সব স্টেশনে প্রযোজ্য। কোনো নির্দিষ্ট স্টেশনের নিজস্ব EQ তার প্লেব্যাক স্ক্রিন থেকে ঠিক করা হয় এবং এটির চেয়ে অগ্রাধিকার পায়।",
|
||||
"equalizerSaveAsPresetAction": "প্রিসেট হিসেবে সংরক্ষণ করুন",
|
||||
"equalizerSavePresetConfirm": "সংরক্ষণ করুন",
|
||||
"equalizerSavePresetDialogTitle": "প্রিসেট হিসেবে সংরক্ষণ করুন",
|
||||
"equalizerSavePresetEmptyNameError": "প্রিসেটের জন্য একটি নাম লিখুন।",
|
||||
"equalizerSavePresetNameLabel": "প্রিসেটের নাম",
|
||||
"equalizerStationsWithOwnEqEmpty": "এখনও কোনো স্টেশনের নিজস্ব EQ নেই।",
|
||||
"equalizerStationsWithOwnEqSubtitle": "এই বেস ইকুয়ালাইজার উপেক্ষা করে",
|
||||
"equalizerStationsWithOwnEqTitle": "নিজস্ব EQ থাকা স্টেশন",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "তালিকা পরিচালনা করুন",
|
||||
"favoritesFilterAllLabel": "সব",
|
||||
"infoSectionTitle": "তথ্য",
|
||||
"nothingPlayingSubtitle": "শুরু করতে আপনার স্টেশন থেকে একটি বেছে নিন বা একটি খুঁজুন।",
|
||||
"nothingPlayingTitle": "এখনও কিছু চলছে না",
|
||||
"openFullPlayerTooltip": "সম্পূর্ণ প্লেয়ার খুলুন",
|
||||
"playerQualityChangeAction": "পরিবর্তন করুন",
|
||||
"playerToolEqLabel": "নিজস্ব EQ",
|
||||
"radioCountriesError": "দেশগুলো লোড করা যায়নি।",
|
||||
"recordingActionDelete": "মুছে ফেলুন",
|
||||
"recordingActionRename": "নাম পরিবর্তন করুন",
|
||||
"recordingActionShare": "শেয়ার করুন",
|
||||
"recordingDeleteConfirmMessage": "এই পদক্ষেপ ফিরিয়ে নেওয়া যাবে না।",
|
||||
"recordingDeleteConfirmTitle": "রেকর্ডিং মুছবেন?",
|
||||
"recordingRenameDialogTitle": "রেকর্ডিং-এর নাম পরিবর্তন করুন",
|
||||
"recordingRenameEmptyError": "একটি নাম লিখুন",
|
||||
"recordingRenameLabel": "নাম",
|
||||
"recordingsLibraryEmptySubtitle": "আপনি যেসব রেকর্ডিং সংরক্ষণ করবেন তা এখানে দেখা যাবে।",
|
||||
"recordingsLibraryEmptyTitle": "এখনও কোনো রেকর্ডিং নেই",
|
||||
"recordingsLibrarySettingsTooltip": "রেকর্ডিং সেটিংস",
|
||||
"recordingsLibraryStorageCaption": "{totalMb} MB-এর মধ্যে {usedMb} MB ব্যবহৃত",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "আমার রেকর্ডিং",
|
||||
"searchClearFiltersAction": "{count, plural, =1{ফিল্টার সরান} other{{count}টি ফিল্টার সরান}}",
|
||||
"searchResultsCount": "{count, plural, =1{১টি ফলাফল} other{{count}টি ফলাফল}}",
|
||||
"seeAllAction": "সব দেখুন",
|
||||
"settingsGroupApplicationTitle": "অ্যাপ্লিকেশন",
|
||||
"settingsGroupAudioTitle": "অডিও",
|
||||
"settingsGroupRecordingsTitle": "রেকর্ডিং ও সংগীত",
|
||||
"settingsGroupStationsTitle": "স্টেশন",
|
||||
"stationOrderByPopularity": "জনপ্রিয়তা অনুসারে",
|
||||
"vacationImpactContinuesLabel": "বাজতেই থাকবে: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "বিরতি: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "এই মুহূর্তে কোনো সক্রিয় ছুটির সময়সীমা নেই।",
|
||||
"vacationPastSectionTitle": "অতীত সময়সীমা",
|
||||
"vacationRangesCount": "{count}টি সময়সীমা",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "চলমান · আর {days} দিন বাকি",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "পরবর্তী সময়সীমা {days} দিনে",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "নির্ধারিত",
|
||||
"welcomeBody": "২৩৮টি দেশের ৫৩,৪১২টি স্টেশন। আপনার প্রিয় স্টেশন সংরক্ষণ করুন, গাড়িতে নিয়ে যান এবং সেগুলো দিয়ে ঘুম থেকে উঠুন।",
|
||||
"welcomeBullet1Subtitle": "এবং প্রতিটি আউটপুট ডিভাইসের জন্য একটি প্রিসেট",
|
||||
"welcomeBullet1Title": "স্টেশন অনুযায়ী ইকুয়ালাইজার",
|
||||
"welcomeBullet2Subtitle": "গাড়িতে আপনার প্রিয় ও স্থানীয় সংগীত",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "ধীরে ভলিউম বৃদ্ধি ও ছুটির মোড সহ",
|
||||
"welcomeBullet3Title": "সুরেলা অ্যালার্ম",
|
||||
"welcomeCtaLabel": "শোনা শুরু করুন",
|
||||
"welcomeHeadline": "আপনার বিশ্ব, সরাসরি",
|
||||
"yourStationsTitle": "আপনার স্টেশন"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "de",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "Start",
|
||||
"navHome": "Hören",
|
||||
"navSearch": "Suche",
|
||||
"navFavorites": "Favoriten",
|
||||
"navAlarms": "Alarme",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Ausgewählter Ordner"
|
||||
}
|
||||
"localMusicFolderGenericName": "Ausgewählter Ordner",
|
||||
"addVacationRangeCta": "Zeitraum hinzufügen",
|
||||
"alarmAdvancedSectionTitle": "Erweitert",
|
||||
"alarmDeleteConfirmMessage": "Dies kann nicht rückgängig gemacht werden.",
|
||||
"alarmDeleteConfirmTitle": "Alarm löschen?",
|
||||
"alarmHeroSkipAction": "Überspringen",
|
||||
"alarmInlineHourLabel": "Stunde",
|
||||
"alarmInlineMinuteLabel": "Minute",
|
||||
"alarmVolumeRisingStatus": "Lautstärke wird erhöht",
|
||||
"countriesAllTitle": "Alle Länder",
|
||||
"countriesScreenTitle": "Länder",
|
||||
"countriesYourLanguagesTitle": "Deine Sprachen",
|
||||
"customStationsAddCta": "Benutzerdefinierten Sender hinzufügen",
|
||||
"equalizerActiveOutputDefault": "Der Lautsprecher dieses Geräts",
|
||||
"equalizerActiveOutputLabel": "Aktiver Ausgang",
|
||||
"equalizerBaseExplainer": "Dies ist der Basis-Equalizer: Er gilt für alle Sender ohne eigene Einstellung. Der eigene EQ eines Senders wird auf dessen eigenem Wiedergabebildschirm festgelegt und hat Vorrang vor diesem hier.",
|
||||
"equalizerSaveAsPresetAction": "Als Preset speichern",
|
||||
"equalizerSavePresetConfirm": "Speichern",
|
||||
"equalizerSavePresetDialogTitle": "Als Preset speichern",
|
||||
"equalizerSavePresetEmptyNameError": "Gib einen Namen für das Preset ein.",
|
||||
"equalizerSavePresetNameLabel": "Preset-Name",
|
||||
"equalizerStationsWithOwnEqEmpty": "Noch kein Sender hat einen eigenen EQ.",
|
||||
"equalizerStationsWithOwnEqSubtitle": "Ignorieren diesen Basis-Equalizer",
|
||||
"equalizerStationsWithOwnEqTitle": "Sender mit eigenem EQ",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "Listen verwalten",
|
||||
"favoritesFilterAllLabel": "Alle",
|
||||
"infoSectionTitle": "Info",
|
||||
"nothingPlayingSubtitle": "Wähle einen Sender aus Deine Sender oder suche einen, um zu starten.",
|
||||
"nothingPlayingTitle": "Es läuft noch nichts",
|
||||
"openFullPlayerTooltip": "Vollständigen Player öffnen",
|
||||
"playerQualityChangeAction": "Ändern",
|
||||
"playerToolEqLabel": "Eigener EQ",
|
||||
"radioCountriesError": "Die Länder konnten nicht geladen werden.",
|
||||
"recordingActionDelete": "Löschen",
|
||||
"recordingActionRename": "Umbenennen",
|
||||
"recordingActionShare": "Teilen",
|
||||
"recordingDeleteConfirmMessage": "Dies kann nicht rückgängig gemacht werden.",
|
||||
"recordingDeleteConfirmTitle": "Aufnahme löschen?",
|
||||
"recordingRenameDialogTitle": "Aufnahme umbenennen",
|
||||
"recordingRenameEmptyError": "Gib einen Namen ein",
|
||||
"recordingRenameLabel": "Name",
|
||||
"recordingsLibraryEmptySubtitle": "Aufnahmen, die du speicherst, erscheinen hier.",
|
||||
"recordingsLibraryEmptyTitle": "Noch keine Aufnahmen",
|
||||
"recordingsLibrarySettingsTooltip": "Aufnahmeeinstellungen",
|
||||
"recordingsLibraryStorageCaption": "{usedMb} MB von {totalMb} MB belegt",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "Meine Aufnahmen",
|
||||
"searchClearFiltersAction": "{count, plural, =1{Filter entfernen} other{{count} Filter entfernen}}",
|
||||
"searchResultsCount": "{count, plural, =1{1 Ergebnis} other{{count} Ergebnisse}}",
|
||||
"seeAllAction": "Alle ansehen",
|
||||
"settingsGroupApplicationTitle": "ANWENDUNG",
|
||||
"settingsGroupAudioTitle": "AUDIO",
|
||||
"settingsGroupRecordingsTitle": "AUFNAHMEN & MUSIK",
|
||||
"settingsGroupStationsTitle": "SENDER",
|
||||
"stationOrderByPopularity": "Nach Beliebtheit",
|
||||
"vacationImpactContinuesLabel": "Klingelt weiter: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "Pausiert: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "Momentan ist kein aktiver Urlaubszeitraum vorhanden.",
|
||||
"vacationPastSectionTitle": "Vergangene Zeiträume",
|
||||
"vacationRangesCount": "{count} Zeiträume",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "Läuft gerade · noch {days} Tage",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "Nächster Zeitraum in {days} Tagen",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "GEPLANT",
|
||||
"welcomeBody": "53.412 Sender aus 238 Ländern. Speichere deine Favoriten, nimm sie mit ins Auto und wache mit ihnen auf.",
|
||||
"welcomeBullet1Subtitle": "Plus ein Preset pro Ausgabegerät",
|
||||
"welcomeBullet1Title": "Equalizer pro Sender",
|
||||
"welcomeBullet2Subtitle": "Deine Favoriten und lokale Musik im Auto",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "Mit sanftem Lautstärkeanstieg und Urlaubsmodus",
|
||||
"welcomeBullet3Title": "Musikalarme",
|
||||
"welcomeCtaLabel": "Jetzt hören",
|
||||
"welcomeHeadline": "Deine Welt, live",
|
||||
"yourStationsTitle": "Deine Sender"
|
||||
}
|
||||
|
||||
+10
-1
@@ -799,5 +799,14 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Selected folder"
|
||||
"localMusicFolderGenericName": "Selected folder",
|
||||
"welcomeHeadline": "Your world, live",
|
||||
"welcomeBody": "53,412 stations from 238 countries. Save your favorites, take them to the car, and wake up to them.",
|
||||
"welcomeBullet1Title": "Per-station equalizer",
|
||||
"welcomeBullet1Subtitle": "Plus a preset per output device",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet2Subtitle": "Your favorites and local music in the car",
|
||||
"welcomeBullet3Title": "Music alarms",
|
||||
"welcomeBullet3Subtitle": "With gradual volume rise and vacation mode",
|
||||
"welcomeCtaLabel": "Start listening"
|
||||
}
|
||||
|
||||
+10
-1
@@ -758,5 +758,14 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Carpeta seleccionada"
|
||||
"localMusicFolderGenericName": "Carpeta seleccionada",
|
||||
"welcomeHeadline": "Tu mundo, en directo",
|
||||
"welcomeBody": "53.412 emisoras de 238 países. Guardá tus favoritas, llevalas al auto y despertate con ellas.",
|
||||
"welcomeBullet1Title": "Ecualizador por emisora",
|
||||
"welcomeBullet1Subtitle": "Y un preset por dispositivo de salida",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet2Subtitle": "Tus favoritas y tu música local en el auto",
|
||||
"welcomeBullet3Title": "Alarmas musicales",
|
||||
"welcomeBullet3Subtitle": "Con subida progresiva y modo vacaciones",
|
||||
"welcomeCtaLabel": "Empezar a escuchar"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "fr",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "Accueil",
|
||||
"navHome": "Écouter",
|
||||
"navSearch": "Recherche",
|
||||
"navFavorites": "Favoris",
|
||||
"navAlarms": "Alarmes",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Dossier sélectionné"
|
||||
}
|
||||
"localMusicFolderGenericName": "Dossier sélectionné",
|
||||
"addVacationRangeCta": "Ajouter une période",
|
||||
"alarmAdvancedSectionTitle": "Avancé",
|
||||
"alarmDeleteConfirmMessage": "Cette action est irréversible.",
|
||||
"alarmDeleteConfirmTitle": "Supprimer l'alarme ?",
|
||||
"alarmHeroSkipAction": "Ignorer",
|
||||
"alarmInlineHourLabel": "Heure",
|
||||
"alarmInlineMinuteLabel": "Minute",
|
||||
"alarmVolumeRisingStatus": "Augmentation du volume",
|
||||
"countriesAllTitle": "Tous les pays",
|
||||
"countriesScreenTitle": "Pays",
|
||||
"countriesYourLanguagesTitle": "Vos langues",
|
||||
"customStationsAddCta": "Ajouter une station personnalisée",
|
||||
"equalizerActiveOutputDefault": "Le haut-parleur de cet appareil",
|
||||
"equalizerActiveOutputLabel": "Sortie active",
|
||||
"equalizerBaseExplainer": "Voici l'égaliseur de base : il s'applique à toutes les stations sans réglage propre. L'EQ propre à une station est défini depuis son propre écran de lecture et prime sur celui-ci.",
|
||||
"equalizerSaveAsPresetAction": "Enregistrer comme Preset",
|
||||
"equalizerSavePresetConfirm": "Enregistrer",
|
||||
"equalizerSavePresetDialogTitle": "Enregistrer comme Preset",
|
||||
"equalizerSavePresetEmptyNameError": "Saisissez un nom pour le Preset.",
|
||||
"equalizerSavePresetNameLabel": "Nom du Preset",
|
||||
"equalizerStationsWithOwnEqEmpty": "Aucune station n'a encore d'EQ propre.",
|
||||
"equalizerStationsWithOwnEqSubtitle": "Ignorent cet égaliseur de base",
|
||||
"equalizerStationsWithOwnEqTitle": "Stations avec un EQ propre",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "Gérer les listes",
|
||||
"favoritesFilterAllLabel": "Toutes",
|
||||
"infoSectionTitle": "Infos",
|
||||
"nothingPlayingSubtitle": "Choisissez une station dans Vos stations ou recherchez-en une pour commencer.",
|
||||
"nothingPlayingTitle": "Rien n'est en cours de lecture",
|
||||
"openFullPlayerTooltip": "Ouvrir le lecteur complet",
|
||||
"playerQualityChangeAction": "Modifier",
|
||||
"playerToolEqLabel": "EQ propre",
|
||||
"radioCountriesError": "Impossible de charger les pays.",
|
||||
"recordingActionDelete": "Supprimer",
|
||||
"recordingActionRename": "Renommer",
|
||||
"recordingActionShare": "Partager",
|
||||
"recordingDeleteConfirmMessage": "Cette action est irréversible.",
|
||||
"recordingDeleteConfirmTitle": "Supprimer l'enregistrement ?",
|
||||
"recordingRenameDialogTitle": "Renommer l'enregistrement",
|
||||
"recordingRenameEmptyError": "Saisissez un nom",
|
||||
"recordingRenameLabel": "Nom",
|
||||
"recordingsLibraryEmptySubtitle": "Les enregistrements que vous sauvegardez apparaîtront ici.",
|
||||
"recordingsLibraryEmptyTitle": "Aucun enregistrement pour l'instant",
|
||||
"recordingsLibrarySettingsTooltip": "Paramètres d'enregistrement",
|
||||
"recordingsLibraryStorageCaption": "{usedMb} Mo sur {totalMb} Mo utilisés",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "Mes enregistrements",
|
||||
"searchClearFiltersAction": "{count, plural, =1{Retirer le filtre} other{Retirer les {count} filtres}}",
|
||||
"searchResultsCount": "{count, plural, =1{1 résultat} other{{count} résultats}}",
|
||||
"seeAllAction": "Tout voir",
|
||||
"settingsGroupApplicationTitle": "APPLICATION",
|
||||
"settingsGroupAudioTitle": "AUDIO",
|
||||
"settingsGroupRecordingsTitle": "ENREGISTREMENTS ET MUSIQUE",
|
||||
"settingsGroupStationsTitle": "STATIONS",
|
||||
"stationOrderByPopularity": "Par popularité",
|
||||
"vacationImpactContinuesLabel": "Continue de sonner : {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "En pause : {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "Aucune période de vacances active pour le moment.",
|
||||
"vacationPastSectionTitle": "Périodes passées",
|
||||
"vacationRangesCount": "{count} périodes",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "En cours · encore {days} jours",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "Prochaine période dans {days} jours",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "PROGRAMMÉES",
|
||||
"welcomeBody": "53 412 stations de 238 pays. Enregistrez vos favorites, emmenez-les en voiture et réveillez-vous avec elles.",
|
||||
"welcomeBullet1Subtitle": "Plus un Preset par périphérique de sortie",
|
||||
"welcomeBullet1Title": "Égaliseur par station",
|
||||
"welcomeBullet2Subtitle": "Vos favorites et votre musique locale en voiture",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "Avec montée progressive du volume et mode vacances",
|
||||
"welcomeBullet3Title": "Alarmes musicales",
|
||||
"welcomeCtaLabel": "Commencer à écouter",
|
||||
"welcomeHeadline": "Votre monde, en direct",
|
||||
"yourStationsTitle": "Vos stations"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "hi",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "मुखपृष्ठ",
|
||||
"navHome": "सुनना",
|
||||
"navSearch": "खोज",
|
||||
"navFavorites": "पसंदीदा",
|
||||
"navAlarms": "अलार्म",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "चयनित फ़ोल्डर"
|
||||
}
|
||||
"localMusicFolderGenericName": "चयनित फ़ोल्डर",
|
||||
"addVacationRangeCta": "अवधि जोड़ें",
|
||||
"alarmAdvancedSectionTitle": "उन्नत",
|
||||
"alarmDeleteConfirmMessage": "इसे वापस नहीं लिया जा सकता।",
|
||||
"alarmDeleteConfirmTitle": "अलार्म हटाएं?",
|
||||
"alarmHeroSkipAction": "छोड़ें",
|
||||
"alarmInlineHourLabel": "घंटा",
|
||||
"alarmInlineMinuteLabel": "मिनट",
|
||||
"alarmVolumeRisingStatus": "आवाज़ बढ़ाई जा रही है",
|
||||
"countriesAllTitle": "सभी देश",
|
||||
"countriesScreenTitle": "देश",
|
||||
"countriesYourLanguagesTitle": "आपकी भाषाएं",
|
||||
"customStationsAddCta": "मनचाहा स्टेशन जोड़ें",
|
||||
"equalizerActiveOutputDefault": "इस डिवाइस का स्पीकर",
|
||||
"equalizerActiveOutputLabel": "सक्रिय आउटपुट",
|
||||
"equalizerBaseExplainer": "यह बेस इक्वलाइज़र है: यह उन सभी स्टेशन पर लागू होता है जिनकी अपनी सेटिंग नहीं है। किसी खास स्टेशन का अपना EQ उसकी प्लेबैक स्क्रीन से तय होता है और इस पर प्राथमिकता रखता है।",
|
||||
"equalizerSaveAsPresetAction": "प्रीसेट के रूप में सहेजें",
|
||||
"equalizerSavePresetConfirm": "सहेजें",
|
||||
"equalizerSavePresetDialogTitle": "प्रीसेट के रूप में सहेजें",
|
||||
"equalizerSavePresetEmptyNameError": "प्रीसेट के लिए एक नाम डालें।",
|
||||
"equalizerSavePresetNameLabel": "प्रीसेट का नाम",
|
||||
"equalizerStationsWithOwnEqEmpty": "अभी तक किसी स्टेशन का अपना EQ नहीं है।",
|
||||
"equalizerStationsWithOwnEqSubtitle": "यह बेस इक्वलाइज़र नज़रअंदाज़ करते हैं",
|
||||
"equalizerStationsWithOwnEqTitle": "अपना EQ रखने वाले स्टेशन",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "सूचियां प्रबंधित करें",
|
||||
"favoritesFilterAllLabel": "सभी",
|
||||
"infoSectionTitle": "जानकारी",
|
||||
"nothingPlayingSubtitle": "शुरू करने के लिए आपके स्टेशन में से कोई एक चुनें या खोजें।",
|
||||
"nothingPlayingTitle": "अभी तक कुछ नहीं चल रहा",
|
||||
"openFullPlayerTooltip": "पूरा प्लेयर खोलें",
|
||||
"playerQualityChangeAction": "बदलें",
|
||||
"playerToolEqLabel": "अपना EQ",
|
||||
"radioCountriesError": "देश लोड नहीं हो सके।",
|
||||
"recordingActionDelete": "हटाएं",
|
||||
"recordingActionRename": "नाम बदलें",
|
||||
"recordingActionShare": "शेयर करें",
|
||||
"recordingDeleteConfirmMessage": "इसे वापस नहीं लिया जा सकता।",
|
||||
"recordingDeleteConfirmTitle": "रिकॉर्डिंग हटाएं?",
|
||||
"recordingRenameDialogTitle": "रिकॉर्डिंग का नाम बदलें",
|
||||
"recordingRenameEmptyError": "एक नाम डालें",
|
||||
"recordingRenameLabel": "नाम",
|
||||
"recordingsLibraryEmptySubtitle": "आप जो रिकॉर्डिंग सहेजेंगे, वे यहां दिखाई देंगी।",
|
||||
"recordingsLibraryEmptyTitle": "अभी तक कोई रिकॉर्डिंग नहीं",
|
||||
"recordingsLibrarySettingsTooltip": "रिकॉर्डिंग सेटिंग्स",
|
||||
"recordingsLibraryStorageCaption": "{totalMb} MB में से {usedMb} MB इस्तेमाल हुआ",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "मेरी रिकॉर्डिंग",
|
||||
"searchClearFiltersAction": "{count, plural, =1{फ़िल्टर हटाएं} other{{count} फ़िल्टर हटाएं}}",
|
||||
"searchResultsCount": "{count, plural, =1{1 परिणाम} other{{count} परिणाम}}",
|
||||
"seeAllAction": "सभी देखें",
|
||||
"settingsGroupApplicationTitle": "ऐप्लिकेशन",
|
||||
"settingsGroupAudioTitle": "ऑडियो",
|
||||
"settingsGroupRecordingsTitle": "रिकॉर्डिंग और संगीत",
|
||||
"settingsGroupStationsTitle": "स्टेशन",
|
||||
"stationOrderByPopularity": "लोकप्रियता के अनुसार",
|
||||
"vacationImpactContinuesLabel": "बजना जारी: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "रोका गया: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "अभी कोई सक्रिय छुट्टी अवधि नहीं है।",
|
||||
"vacationPastSectionTitle": "पिछली अवधियां",
|
||||
"vacationRangesCount": "{count} अवधियां",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "जारी है · {days} दिन बाकी",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "अगली अवधि {days} दिन में",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "निर्धारित",
|
||||
"welcomeBody": "238 देशों के 53,412 स्टेशन। अपने पसंदीदा स्टेशन सहेजें, उन्हें गाड़ी में ले जाएं और उनके साथ जागें।",
|
||||
"welcomeBullet1Subtitle": "और हर आउटपुट डिवाइस के लिए एक प्रीसेट",
|
||||
"welcomeBullet1Title": "प्रति स्टेशन इक्वलाइज़र",
|
||||
"welcomeBullet2Subtitle": "गाड़ी में आपके पसंदीदा और लोकल संगीत",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "धीरे-धीरे आवाज़ बढ़ाने और छुट्टी मोड के साथ",
|
||||
"welcomeBullet3Title": "संगीत अलार्म",
|
||||
"welcomeCtaLabel": "सुनना शुरू करें",
|
||||
"welcomeHeadline": "आपकी दुनिया, लाइव",
|
||||
"yourStationsTitle": "आपके स्टेशन"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "id",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "Beranda",
|
||||
"navHome": "Dengar",
|
||||
"navSearch": "Cari",
|
||||
"navFavorites": "Favorit",
|
||||
"navAlarms": "Alarm",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Folder terpilih"
|
||||
}
|
||||
"localMusicFolderGenericName": "Folder terpilih",
|
||||
"addVacationRangeCta": "Tambahkan periode",
|
||||
"alarmAdvancedSectionTitle": "Lanjutan",
|
||||
"alarmDeleteConfirmMessage": "Tindakan ini tidak dapat dibatalkan.",
|
||||
"alarmDeleteConfirmTitle": "Hapus alarm?",
|
||||
"alarmHeroSkipAction": "Lewati",
|
||||
"alarmInlineHourLabel": "Jam",
|
||||
"alarmInlineMinuteLabel": "Menit",
|
||||
"alarmVolumeRisingStatus": "Menaikkan volume",
|
||||
"countriesAllTitle": "Semua negara",
|
||||
"countriesScreenTitle": "Negara",
|
||||
"countriesYourLanguagesTitle": "Bahasa Anda",
|
||||
"customStationsAddCta": "Tambahkan stasiun khusus",
|
||||
"equalizerActiveOutputDefault": "Speaker perangkat ini",
|
||||
"equalizerActiveOutputLabel": "Output aktif",
|
||||
"equalizerBaseExplainer": "Ini adalah equalizer dasar: berlaku untuk semua stasiun yang belum punya pengaturan sendiri. EQ khusus suatu stasiun diatur dari layar pemutarannya sendiri dan mengesampingkan yang ini.",
|
||||
"equalizerSaveAsPresetAction": "Simpan sebagai Preset",
|
||||
"equalizerSavePresetConfirm": "Simpan",
|
||||
"equalizerSavePresetDialogTitle": "Simpan sebagai Preset",
|
||||
"equalizerSavePresetEmptyNameError": "Masukkan nama untuk Preset.",
|
||||
"equalizerSavePresetNameLabel": "Nama Preset",
|
||||
"equalizerStationsWithOwnEqEmpty": "Belum ada stasiun yang punya EQ sendiri.",
|
||||
"equalizerStationsWithOwnEqSubtitle": "Mengabaikan equalizer dasar ini",
|
||||
"equalizerStationsWithOwnEqTitle": "Stasiun dengan EQ sendiri",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "Kelola daftar",
|
||||
"favoritesFilterAllLabel": "Semua",
|
||||
"infoSectionTitle": "Info",
|
||||
"nothingPlayingSubtitle": "Pilih stasiun dari Stasiun Anda atau cari salah satu untuk mulai.",
|
||||
"nothingPlayingTitle": "Belum ada yang diputar",
|
||||
"openFullPlayerTooltip": "Buka pemutar lengkap",
|
||||
"playerQualityChangeAction": "Ubah",
|
||||
"playerToolEqLabel": "EQ sendiri",
|
||||
"radioCountriesError": "Negara tidak dapat dimuat.",
|
||||
"recordingActionDelete": "Hapus",
|
||||
"recordingActionRename": "Ganti nama",
|
||||
"recordingActionShare": "Bagikan",
|
||||
"recordingDeleteConfirmMessage": "Tindakan ini tidak dapat dibatalkan.",
|
||||
"recordingDeleteConfirmTitle": "Hapus rekaman?",
|
||||
"recordingRenameDialogTitle": "Ganti nama rekaman",
|
||||
"recordingRenameEmptyError": "Masukkan nama",
|
||||
"recordingRenameLabel": "Nama",
|
||||
"recordingsLibraryEmptySubtitle": "Rekaman yang Anda simpan akan muncul di sini.",
|
||||
"recordingsLibraryEmptyTitle": "Belum ada rekaman",
|
||||
"recordingsLibrarySettingsTooltip": "Pengaturan rekaman",
|
||||
"recordingsLibraryStorageCaption": "{usedMb} MB dari {totalMb} MB terpakai",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "Rekaman saya",
|
||||
"searchClearFiltersAction": "{count, plural, =1{Hapus filter} other{Hapus {count} filter}}",
|
||||
"searchResultsCount": "{count, plural, other{{count} hasil}}",
|
||||
"seeAllAction": "Lihat semua",
|
||||
"settingsGroupApplicationTitle": "APLIKASI",
|
||||
"settingsGroupAudioTitle": "AUDIO",
|
||||
"settingsGroupRecordingsTitle": "REKAMAN & MUSIK",
|
||||
"settingsGroupStationsTitle": "STASIUN",
|
||||
"stationOrderByPopularity": "Berdasarkan popularitas",
|
||||
"vacationImpactContinuesLabel": "Tetap berbunyi: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "Dijeda: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "Tidak ada periode liburan aktif saat ini.",
|
||||
"vacationPastSectionTitle": "Periode lampau",
|
||||
"vacationRangesCount": "{count} periode",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "Sedang berlangsung · {days} hari lagi",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "Periode berikutnya dalam {days} hari",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "TERJADWAL",
|
||||
"welcomeBody": "53.412 stasiun dari 238 negara. Simpan favorit Anda, bawa ke mobil, dan bangun bersamanya.",
|
||||
"welcomeBullet1Subtitle": "Plus satu Preset per perangkat output",
|
||||
"welcomeBullet1Title": "Equalizer per stasiun",
|
||||
"welcomeBullet2Subtitle": "Favorit dan musik lokal Anda di mobil",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "Dengan kenaikan volume bertahap dan mode liburan",
|
||||
"welcomeBullet3Title": "Alarm musik",
|
||||
"welcomeCtaLabel": "Mulai mendengarkan",
|
||||
"welcomeHeadline": "Duniamu, secara langsung",
|
||||
"yourStationsTitle": "Stasiun Anda"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "it",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "Inizio",
|
||||
"navHome": "Ascolta",
|
||||
"navSearch": "Cerca",
|
||||
"navFavorites": "Preferiti",
|
||||
"navAlarms": "Sveglie",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Cartella selezionata"
|
||||
}
|
||||
"localMusicFolderGenericName": "Cartella selezionata",
|
||||
"addVacationRangeCta": "Aggiungi periodo",
|
||||
"alarmAdvancedSectionTitle": "Avanzate",
|
||||
"alarmDeleteConfirmMessage": "Questa azione non può essere annullata.",
|
||||
"alarmDeleteConfirmTitle": "Eliminare la sveglia?",
|
||||
"alarmHeroSkipAction": "Salta",
|
||||
"alarmInlineHourLabel": "Ora",
|
||||
"alarmInlineMinuteLabel": "Minuto",
|
||||
"alarmVolumeRisingStatus": "Aumento del volume",
|
||||
"countriesAllTitle": "Tutti i paesi",
|
||||
"countriesScreenTitle": "Paesi",
|
||||
"countriesYourLanguagesTitle": "Le tue lingue",
|
||||
"customStationsAddCta": "Aggiungi emittente personalizzata",
|
||||
"equalizerActiveOutputDefault": "L'altoparlante di questo dispositivo",
|
||||
"equalizerActiveOutputLabel": "Uscita attiva",
|
||||
"equalizerBaseExplainer": "Questo è l'equalizzatore di base: si applica a tutte le emittenti senza un'impostazione propria. L'EQ di un'emittente specifica si imposta dalla sua schermata di riproduzione e ha la precedenza su questo.",
|
||||
"equalizerSaveAsPresetAction": "Salva come Preset",
|
||||
"equalizerSavePresetConfirm": "Salva",
|
||||
"equalizerSavePresetDialogTitle": "Salva come Preset",
|
||||
"equalizerSavePresetEmptyNameError": "Inserisci un nome per il Preset.",
|
||||
"equalizerSavePresetNameLabel": "Nome del Preset",
|
||||
"equalizerStationsWithOwnEqEmpty": "Nessuna emittente ha ancora un EQ proprio.",
|
||||
"equalizerStationsWithOwnEqSubtitle": "Ignorano questo equalizzatore di base",
|
||||
"equalizerStationsWithOwnEqTitle": "Emittenti con EQ proprio",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "Gestisci liste",
|
||||
"favoritesFilterAllLabel": "Tutte",
|
||||
"infoSectionTitle": "Informazioni",
|
||||
"nothingPlayingSubtitle": "Scegli un'emittente da Le tue emittenti o cercane una per iniziare.",
|
||||
"nothingPlayingTitle": "Non stai ancora ascoltando nulla",
|
||||
"openFullPlayerTooltip": "Apri il player completo",
|
||||
"playerQualityChangeAction": "Cambia",
|
||||
"playerToolEqLabel": "EQ proprio",
|
||||
"radioCountriesError": "Non è stato possibile caricare i paesi.",
|
||||
"recordingActionDelete": "Elimina",
|
||||
"recordingActionRename": "Rinomina",
|
||||
"recordingActionShare": "Condividi",
|
||||
"recordingDeleteConfirmMessage": "Questa azione non può essere annullata.",
|
||||
"recordingDeleteConfirmTitle": "Eliminare la registrazione?",
|
||||
"recordingRenameDialogTitle": "Rinomina registrazione",
|
||||
"recordingRenameEmptyError": "Inserisci un nome",
|
||||
"recordingRenameLabel": "Nome",
|
||||
"recordingsLibraryEmptySubtitle": "Le registrazioni che salvi appariranno qui.",
|
||||
"recordingsLibraryEmptyTitle": "Ancora nessuna registrazione",
|
||||
"recordingsLibrarySettingsTooltip": "Impostazioni di registrazione",
|
||||
"recordingsLibraryStorageCaption": "{usedMb} MB di {totalMb} MB usati",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "Le mie registrazioni",
|
||||
"searchClearFiltersAction": "{count, plural, =1{Rimuovi filtro} other{Rimuovi {count} filtri}}",
|
||||
"searchResultsCount": "{count, plural, =1{1 risultato} other{{count} risultati}}",
|
||||
"seeAllAction": "Vedi tutte",
|
||||
"settingsGroupApplicationTitle": "APPLICAZIONE",
|
||||
"settingsGroupAudioTitle": "AUDIO",
|
||||
"settingsGroupRecordingsTitle": "REGISTRAZIONI E MUSICA",
|
||||
"settingsGroupStationsTitle": "EMITTENTI",
|
||||
"stationOrderByPopularity": "Per popolarità",
|
||||
"vacationImpactContinuesLabel": "Continua a suonare: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "In pausa: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "Nessun periodo di vacanza attivo al momento.",
|
||||
"vacationPastSectionTitle": "Periodi passati",
|
||||
"vacationRangesCount": "{count} periodi",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "In corso · mancano {days} giorni",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "Prossimo periodo tra {days} giorni",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "PROGRAMMATI",
|
||||
"welcomeBody": "53.412 emittenti da 238 paesi. Salva le tue preferite, portale in auto e svegliati con loro.",
|
||||
"welcomeBullet1Subtitle": "Più un Preset per ogni dispositivo di uscita",
|
||||
"welcomeBullet1Title": "Equalizzatore per emittente",
|
||||
"welcomeBullet2Subtitle": "Le tue preferite e la tua musica locale in auto",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "Con aumento graduale del volume e modalità vacanza",
|
||||
"welcomeBullet3Title": "Sveglie musicali",
|
||||
"welcomeCtaLabel": "Inizia ad ascoltare",
|
||||
"welcomeHeadline": "Il tuo mondo, in diretta",
|
||||
"yourStationsTitle": "Le tue emittenti"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "ja",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "ホーム",
|
||||
"navHome": "聴く",
|
||||
"navSearch": "検索",
|
||||
"navFavorites": "お気に入り",
|
||||
"navAlarms": "アラーム",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "選択したフォルダー"
|
||||
}
|
||||
"localMusicFolderGenericName": "選択したフォルダー",
|
||||
"addVacationRangeCta": "期間を追加",
|
||||
"alarmAdvancedSectionTitle": "詳細設定",
|
||||
"alarmDeleteConfirmMessage": "この操作は元に戻せません。",
|
||||
"alarmDeleteConfirmTitle": "アラームを削除しますか?",
|
||||
"alarmHeroSkipAction": "スキップ",
|
||||
"alarmInlineHourLabel": "時",
|
||||
"alarmInlineMinuteLabel": "分",
|
||||
"alarmVolumeRisingStatus": "音量を上げています",
|
||||
"countriesAllTitle": "すべての国",
|
||||
"countriesScreenTitle": "国",
|
||||
"countriesYourLanguagesTitle": "あなたの言語",
|
||||
"customStationsAddCta": "カスタム局を追加",
|
||||
"equalizerActiveOutputDefault": "この端末のスピーカー",
|
||||
"equalizerActiveOutputLabel": "アクティブな出力",
|
||||
"equalizerBaseExplainer": "これはベースイコライザーです。専用設定を持たないすべての局に適用されます。特定の局専用のEQはその局の再生画面から設定でき、こちらより優先されます。",
|
||||
"equalizerSaveAsPresetAction": "プリセットとして保存",
|
||||
"equalizerSavePresetConfirm": "保存",
|
||||
"equalizerSavePresetDialogTitle": "プリセットとして保存",
|
||||
"equalizerSavePresetEmptyNameError": "プリセットの名前を入力してください。",
|
||||
"equalizerSavePresetNameLabel": "プリセット名",
|
||||
"equalizerStationsWithOwnEqEmpty": "専用EQを持つ局はまだありません。",
|
||||
"equalizerStationsWithOwnEqSubtitle": "このベースイコライザーを無視します",
|
||||
"equalizerStationsWithOwnEqTitle": "専用EQを持つ局",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "リストを管理",
|
||||
"favoritesFilterAllLabel": "すべて",
|
||||
"infoSectionTitle": "情報",
|
||||
"nothingPlayingSubtitle": "「あなたの局」から局を選ぶか、検索して再生を始めましょう。",
|
||||
"nothingPlayingTitle": "まだ何も再生されていません",
|
||||
"openFullPlayerTooltip": "フルプレーヤーを開く",
|
||||
"playerQualityChangeAction": "変更",
|
||||
"playerToolEqLabel": "専用EQ",
|
||||
"radioCountriesError": "国の一覧を読み込めませんでした。",
|
||||
"recordingActionDelete": "削除",
|
||||
"recordingActionRename": "名前を変更",
|
||||
"recordingActionShare": "共有",
|
||||
"recordingDeleteConfirmMessage": "この操作は元に戻せません。",
|
||||
"recordingDeleteConfirmTitle": "録音を削除しますか?",
|
||||
"recordingRenameDialogTitle": "録音の名前を変更",
|
||||
"recordingRenameEmptyError": "名前を入力してください",
|
||||
"recordingRenameLabel": "名前",
|
||||
"recordingsLibraryEmptySubtitle": "保存した録音はここに表示されます。",
|
||||
"recordingsLibraryEmptyTitle": "まだ録音がありません",
|
||||
"recordingsLibrarySettingsTooltip": "録音設定",
|
||||
"recordingsLibraryStorageCaption": "{totalMb} MB 中 {usedMb} MB 使用済み",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "マイ録音",
|
||||
"searchClearFiltersAction": "{count, plural, =1{フィルターをクリア} other{{count}件のフィルターをクリア}}",
|
||||
"searchResultsCount": "{count, plural, other{{count}件の結果}}",
|
||||
"seeAllAction": "すべて見る",
|
||||
"settingsGroupApplicationTitle": "アプリ",
|
||||
"settingsGroupAudioTitle": "オーディオ",
|
||||
"settingsGroupRecordingsTitle": "録音と音楽",
|
||||
"settingsGroupStationsTitle": "局",
|
||||
"stationOrderByPopularity": "人気順",
|
||||
"vacationImpactContinuesLabel": "引き続き鳴動: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "一時停止: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "現在アクティブな休暇期間はありません。",
|
||||
"vacationPastSectionTitle": "過去の期間",
|
||||
"vacationRangesCount": "{count} 件の期間",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "進行中 · 残り{days}日",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "次の期間まであと{days}日",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "予定",
|
||||
"welcomeBody": "238か国、53,412局のラジオ。お気に入りを保存して車に持ち出し、それで目を覚まそう。",
|
||||
"welcomeBullet1Subtitle": "さらに出力デバイスごとのプリセット",
|
||||
"welcomeBullet1Title": "局ごとのイコライザー",
|
||||
"welcomeBullet2Subtitle": "車の中でお気に入りとローカル音楽を",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "音量の緩やかな上昇と休暇モード付き",
|
||||
"welcomeBullet3Title": "音楽アラーム",
|
||||
"welcomeCtaLabel": "聴き始める",
|
||||
"welcomeHeadline": "あなたの世界を、ライブで",
|
||||
"yourStationsTitle": "あなたの局"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "pt",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "Início",
|
||||
"navHome": "Ouvir",
|
||||
"navSearch": "Buscar",
|
||||
"navFavorites": "Favoritos",
|
||||
"navAlarms": "Alarmes",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Pasta selecionada"
|
||||
}
|
||||
"localMusicFolderGenericName": "Pasta selecionada",
|
||||
"addVacationRangeCta": "Adicionar período",
|
||||
"alarmAdvancedSectionTitle": "Avançado",
|
||||
"alarmDeleteConfirmMessage": "Esta ação não pode ser desfeita.",
|
||||
"alarmDeleteConfirmTitle": "Excluir alarme?",
|
||||
"alarmHeroSkipAction": "Pular",
|
||||
"alarmInlineHourLabel": "Hora",
|
||||
"alarmInlineMinuteLabel": "Minuto",
|
||||
"alarmVolumeRisingStatus": "Aumentando o volume",
|
||||
"countriesAllTitle": "Todos os países",
|
||||
"countriesScreenTitle": "Países",
|
||||
"countriesYourLanguagesTitle": "Seus idiomas",
|
||||
"customStationsAddCta": "Adicionar estação personalizada",
|
||||
"equalizerActiveOutputDefault": "O alto-falante deste dispositivo",
|
||||
"equalizerActiveOutputLabel": "Saída ativa",
|
||||
"equalizerBaseExplainer": "Este é o equalizador base: aplica-se a todas as estações sem ajuste próprio. O EQ próprio de uma estação é definido na sua própria tela de reprodução e tem prioridade sobre este.",
|
||||
"equalizerSaveAsPresetAction": "Salvar como Preset",
|
||||
"equalizerSavePresetConfirm": "Salvar",
|
||||
"equalizerSavePresetDialogTitle": "Salvar como Preset",
|
||||
"equalizerSavePresetEmptyNameError": "Digite um nome para o Preset.",
|
||||
"equalizerSavePresetNameLabel": "Nome do Preset",
|
||||
"equalizerStationsWithOwnEqEmpty": "Nenhuma estação tem EQ próprio ainda.",
|
||||
"equalizerStationsWithOwnEqSubtitle": "Ignoram este equalizador base",
|
||||
"equalizerStationsWithOwnEqTitle": "Estações com EQ próprio",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "Gerenciar listas",
|
||||
"favoritesFilterAllLabel": "Todas",
|
||||
"infoSectionTitle": "Informações",
|
||||
"nothingPlayingSubtitle": "Escolha uma estação em Suas estações ou pesquise uma para começar.",
|
||||
"nothingPlayingTitle": "Ainda não há nada tocando",
|
||||
"openFullPlayerTooltip": "Abrir player completo",
|
||||
"playerQualityChangeAction": "Alterar",
|
||||
"playerToolEqLabel": "EQ próprio",
|
||||
"radioCountriesError": "Não foi possível carregar os países.",
|
||||
"recordingActionDelete": "Excluir",
|
||||
"recordingActionRename": "Renomear",
|
||||
"recordingActionShare": "Compartilhar",
|
||||
"recordingDeleteConfirmMessage": "Esta ação não pode ser desfeita.",
|
||||
"recordingDeleteConfirmTitle": "Excluir gravação?",
|
||||
"recordingRenameDialogTitle": "Renomear gravação",
|
||||
"recordingRenameEmptyError": "Digite um nome",
|
||||
"recordingRenameLabel": "Nome",
|
||||
"recordingsLibraryEmptySubtitle": "As gravações que você salvar vão aparecer aqui.",
|
||||
"recordingsLibraryEmptyTitle": "Ainda não há gravações",
|
||||
"recordingsLibrarySettingsTooltip": "Configurações de gravação",
|
||||
"recordingsLibraryStorageCaption": "{usedMb} MB de {totalMb} MB usados",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "Minhas gravações",
|
||||
"searchClearFiltersAction": "{count, plural, =1{Remover filtro} other{Remover {count} filtros}}",
|
||||
"searchResultsCount": "{count, plural, =1{1 resultado} other{{count} resultados}}",
|
||||
"seeAllAction": "Ver todas",
|
||||
"settingsGroupApplicationTitle": "APLICATIVO",
|
||||
"settingsGroupAudioTitle": "ÁUDIO",
|
||||
"settingsGroupRecordingsTitle": "GRAVAÇÕES E MÚSICA",
|
||||
"settingsGroupStationsTitle": "ESTAÇÕES",
|
||||
"stationOrderByPopularity": "Por popularidade",
|
||||
"vacationImpactContinuesLabel": "Continua tocando: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "Pausado: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "Não há período de férias ativo no momento.",
|
||||
"vacationPastSectionTitle": "Períodos passados",
|
||||
"vacationRangesCount": "{count} períodos",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "Em andamento · faltam {days} dias",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "Próximo período em {days} dias",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "PROGRAMADOS",
|
||||
"welcomeBody": "53.412 estações de 238 países. Salve suas favoritas, leve-as para o carro e acorde com elas.",
|
||||
"welcomeBullet1Subtitle": "Além de um Preset por dispositivo de saída",
|
||||
"welcomeBullet1Title": "Equalizador por estação",
|
||||
"welcomeBullet2Subtitle": "Suas favoritas e sua música local no carro",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "Com aumento progressivo do volume e modo férias",
|
||||
"welcomeBullet3Title": "Alarmes musicais",
|
||||
"welcomeCtaLabel": "Começar a ouvir",
|
||||
"welcomeHeadline": "Seu mundo, ao vivo",
|
||||
"yourStationsTitle": "Suas estações"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "ru",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "Главная",
|
||||
"navHome": "Слушать",
|
||||
"navSearch": "Поиск",
|
||||
"navFavorites": "Избранное",
|
||||
"navAlarms": "Будильники",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "Выбранная папка"
|
||||
}
|
||||
"localMusicFolderGenericName": "Выбранная папка",
|
||||
"addVacationRangeCta": "Добавить период",
|
||||
"alarmAdvancedSectionTitle": "Дополнительно",
|
||||
"alarmDeleteConfirmMessage": "Это действие нельзя отменить.",
|
||||
"alarmDeleteConfirmTitle": "Удалить будильник?",
|
||||
"alarmHeroSkipAction": "Пропустить",
|
||||
"alarmInlineHourLabel": "Час",
|
||||
"alarmInlineMinuteLabel": "Минута",
|
||||
"alarmVolumeRisingStatus": "Громкость нарастает",
|
||||
"countriesAllTitle": "Все страны",
|
||||
"countriesScreenTitle": "Страны",
|
||||
"countriesYourLanguagesTitle": "Ваши языки",
|
||||
"customStationsAddCta": "Добавить пользовательскую станцию",
|
||||
"equalizerActiveOutputDefault": "Динамик этого устройства",
|
||||
"equalizerActiveOutputLabel": "Активный выход",
|
||||
"equalizerBaseExplainer": "Это базовый эквалайзер: он применяется ко всем станциям без собственной настройки. Свой EQ конкретной станции задаётся на экране её воспроизведения и имеет приоритет над этим.",
|
||||
"equalizerSaveAsPresetAction": "Сохранить как пресет",
|
||||
"equalizerSavePresetConfirm": "Сохранить",
|
||||
"equalizerSavePresetDialogTitle": "Сохранить как пресет",
|
||||
"equalizerSavePresetEmptyNameError": "Введите название пресета.",
|
||||
"equalizerSavePresetNameLabel": "Название пресета",
|
||||
"equalizerStationsWithOwnEqEmpty": "Пока ни у одной станции нет своего EQ.",
|
||||
"equalizerStationsWithOwnEqSubtitle": "Игнорируют этот базовый эквалайзер",
|
||||
"equalizerStationsWithOwnEqTitle": "Станции со своим EQ",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "Управление списками",
|
||||
"favoritesFilterAllLabel": "Все",
|
||||
"infoSectionTitle": "Информация",
|
||||
"nothingPlayingSubtitle": "Выберите станцию из раздела «Ваши станции» или найдите её, чтобы начать.",
|
||||
"nothingPlayingTitle": "Пока ничего не воспроизводится",
|
||||
"openFullPlayerTooltip": "Открыть полный плеер",
|
||||
"playerQualityChangeAction": "Изменить",
|
||||
"playerToolEqLabel": "Свой EQ",
|
||||
"radioCountriesError": "Не удалось загрузить страны.",
|
||||
"recordingActionDelete": "Удалить",
|
||||
"recordingActionRename": "Переименовать",
|
||||
"recordingActionShare": "Поделиться",
|
||||
"recordingDeleteConfirmMessage": "Это действие нельзя отменить.",
|
||||
"recordingDeleteConfirmTitle": "Удалить запись?",
|
||||
"recordingRenameDialogTitle": "Переименовать запись",
|
||||
"recordingRenameEmptyError": "Введите название",
|
||||
"recordingRenameLabel": "Название",
|
||||
"recordingsLibraryEmptySubtitle": "Записи, которые вы сохраните, появятся здесь.",
|
||||
"recordingsLibraryEmptyTitle": "Записей пока нет",
|
||||
"recordingsLibrarySettingsTooltip": "Настройки записи",
|
||||
"recordingsLibraryStorageCaption": "Использовано {usedMb} МБ из {totalMb} МБ",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "Мои записи",
|
||||
"searchClearFiltersAction": "{count, plural, =1{Убрать фильтр} few{Убрать {count} фильтра} other{Убрать {count} фильтров}}",
|
||||
"searchResultsCount": "{count, plural, one{{count} результат} few{{count} результата} other{{count} результатов}}",
|
||||
"seeAllAction": "Смотреть все",
|
||||
"settingsGroupApplicationTitle": "ПРИЛОЖЕНИЕ",
|
||||
"settingsGroupAudioTitle": "АУДИО",
|
||||
"settingsGroupRecordingsTitle": "ЗАПИСИ И МУЗЫКА",
|
||||
"settingsGroupStationsTitle": "СТАНЦИИ",
|
||||
"stationOrderByPopularity": "По популярности",
|
||||
"vacationImpactContinuesLabel": "Продолжает звонить: {times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "Пауза: {times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "Сейчас нет активного периода отпуска.",
|
||||
"vacationPastSectionTitle": "Прошедшие периоды",
|
||||
"vacationRangesCount": "{count} периодов",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "Идёт сейчас · осталось {days} дн.",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "Следующий период через {days} дн.",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "ЗАПЛАНИРОВАНО",
|
||||
"welcomeBody": "53 412 станций из 238 стран. Сохраняйте любимые, берите их с собой в машину и просыпайтесь под них.",
|
||||
"welcomeBullet1Subtitle": "А также пресет для каждого устройства вывода",
|
||||
"welcomeBullet1Title": "Эквалайзер для каждой станции",
|
||||
"welcomeBullet2Subtitle": "Ваши избранные и локальная музыка в машине",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "С плавным нарастанием громкости и режимом отпуска",
|
||||
"welcomeBullet3Title": "Музыкальные будильники",
|
||||
"welcomeCtaLabel": "Начать слушать",
|
||||
"welcomeHeadline": "Ваш мир, в прямом эфире",
|
||||
"yourStationsTitle": "Ваши станции"
|
||||
}
|
||||
|
||||
+124
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"@@locale": "zh",
|
||||
"appTitle": "PluriWave",
|
||||
"navHome": "首页",
|
||||
"navHome": "收听",
|
||||
"navSearch": "搜索",
|
||||
"navFavorites": "收藏",
|
||||
"navAlarms": "闹钟",
|
||||
@@ -687,5 +687,126 @@
|
||||
"error": {}
|
||||
}
|
||||
},
|
||||
"localMusicFolderGenericName": "已选文件夹"
|
||||
}
|
||||
"localMusicFolderGenericName": "已选文件夹",
|
||||
"addVacationRangeCta": "添加时间段",
|
||||
"alarmAdvancedSectionTitle": "高级",
|
||||
"alarmDeleteConfirmMessage": "此操作无法撤销。",
|
||||
"alarmDeleteConfirmTitle": "删除闹钟?",
|
||||
"alarmHeroSkipAction": "跳过",
|
||||
"alarmInlineHourLabel": "时",
|
||||
"alarmInlineMinuteLabel": "分",
|
||||
"alarmVolumeRisingStatus": "音量渐强中",
|
||||
"countriesAllTitle": "所有国家",
|
||||
"countriesScreenTitle": "国家",
|
||||
"countriesYourLanguagesTitle": "你的语言",
|
||||
"customStationsAddCta": "添加自定义电台",
|
||||
"equalizerActiveOutputDefault": "此设备的扬声器",
|
||||
"equalizerActiveOutputLabel": "当前输出",
|
||||
"equalizerBaseExplainer": "这是基础均衡器:适用于所有没有专属设置的电台。某个电台的专属EQ可在其自己的播放界面中设置,并优先于此设置生效。",
|
||||
"equalizerSaveAsPresetAction": "保存为预设",
|
||||
"equalizerSavePresetConfirm": "保存",
|
||||
"equalizerSavePresetDialogTitle": "保存为预设",
|
||||
"equalizerSavePresetEmptyNameError": "请输入预设名称。",
|
||||
"equalizerSavePresetNameLabel": "预设名称",
|
||||
"equalizerStationsWithOwnEqEmpty": "目前还没有电台设置专属EQ。",
|
||||
"equalizerStationsWithOwnEqSubtitle": "忽略此基础均衡器",
|
||||
"equalizerStationsWithOwnEqTitle": "拥有专属EQ的电台",
|
||||
"favoriteGroupsChipLabel": "{groupName} · {count}",
|
||||
"@favoriteGroupsChipLabel": {
|
||||
"placeholders": {
|
||||
"groupName": {},
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"favoriteGroupsManage": "管理列表",
|
||||
"favoritesFilterAllLabel": "全部",
|
||||
"infoSectionTitle": "信息",
|
||||
"nothingPlayingSubtitle": "从“你的电台”中选择一个电台,或搜索一个开始收听。",
|
||||
"nothingPlayingTitle": "目前没有正在播放的内容",
|
||||
"openFullPlayerTooltip": "打开完整播放器",
|
||||
"playerQualityChangeAction": "更改",
|
||||
"playerToolEqLabel": "专属EQ",
|
||||
"radioCountriesError": "无法加载国家列表。",
|
||||
"recordingActionDelete": "删除",
|
||||
"recordingActionRename": "重命名",
|
||||
"recordingActionShare": "分享",
|
||||
"recordingDeleteConfirmMessage": "此操作无法撤销。",
|
||||
"recordingDeleteConfirmTitle": "删除录音?",
|
||||
"recordingRenameDialogTitle": "重命名录音",
|
||||
"recordingRenameEmptyError": "请输入名称",
|
||||
"recordingRenameLabel": "名称",
|
||||
"recordingsLibraryEmptySubtitle": "你保存的录音会显示在这里。",
|
||||
"recordingsLibraryEmptyTitle": "暂无录音",
|
||||
"recordingsLibrarySettingsTooltip": "录音设置",
|
||||
"recordingsLibraryStorageCaption": "已使用 {usedMb} MB / 共 {totalMb} MB",
|
||||
"@recordingsLibraryStorageCaption": {
|
||||
"placeholders": {
|
||||
"usedMb": {
|
||||
"type": "int"
|
||||
},
|
||||
"totalMb": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"recordingsLibraryTitle": "我的录音",
|
||||
"searchClearFiltersAction": "{count, plural, =1{清除筛选条件} other{清除 {count} 个筛选条件}}",
|
||||
"searchResultsCount": "{count, plural, other{{count} 个结果}}",
|
||||
"seeAllAction": "查看全部",
|
||||
"settingsGroupApplicationTitle": "应用",
|
||||
"settingsGroupAudioTitle": "音频",
|
||||
"settingsGroupRecordingsTitle": "录音与音乐",
|
||||
"settingsGroupStationsTitle": "电台",
|
||||
"stationOrderByPopularity": "按热度",
|
||||
"vacationImpactContinuesLabel": "仍会响铃:{times}",
|
||||
"@vacationImpactContinuesLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationImpactPausedLabel": "暂停:{times}",
|
||||
"@vacationImpactPausedLabel": {
|
||||
"placeholders": {
|
||||
"times": {}
|
||||
}
|
||||
},
|
||||
"vacationNoActiveRangeHint": "目前没有正在生效的假期时间段。",
|
||||
"vacationPastSectionTitle": "过往时间段",
|
||||
"vacationRangesCount": "{count} 个时间段",
|
||||
"@vacationRangesCount": {
|
||||
"placeholders": {
|
||||
"count": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryActiveCountdown": "进行中 · 还剩 {days} 天",
|
||||
"@vacationSummaryActiveCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationSummaryUpcomingCountdown": "下一个时间段在 {days} 天后",
|
||||
"@vacationSummaryUpcomingCountdown": {
|
||||
"placeholders": {
|
||||
"days": {
|
||||
"type": "int"
|
||||
}
|
||||
}
|
||||
},
|
||||
"vacationUpcomingSectionTitle": "已安排",
|
||||
"welcomeBody": "来自238个国家的53,412个电台。保存你喜爱的电台,带上车,用它们唤醒你的每一天。",
|
||||
"welcomeBullet1Subtitle": "还支持为每个输出设备设置独立预设",
|
||||
"welcomeBullet1Title": "分电台均衡器",
|
||||
"welcomeBullet2Subtitle": "车内畅享你的收藏电台和本地音乐",
|
||||
"welcomeBullet2Title": "Android Auto",
|
||||
"welcomeBullet3Subtitle": "支持音量渐强唤醒和假期模式",
|
||||
"welcomeBullet3Title": "音乐闹钟",
|
||||
"welcomeCtaLabel": "开始收听",
|
||||
"welcomeHeadline": "你的世界,直播中",
|
||||
"yourStationsTitle": "你的电台"
|
||||
}
|
||||
|
||||
@@ -2869,6 +2869,60 @@ abstract class AppLocalizations {
|
||||
/// In es, this message translates to:
|
||||
/// **'Carpeta seleccionada'**
|
||||
String get localMusicFolderGenericName;
|
||||
|
||||
/// No description provided for @welcomeHeadline.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Tu mundo, en directo'**
|
||||
String get welcomeHeadline;
|
||||
|
||||
/// No description provided for @welcomeBody.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'53.412 emisoras de 238 países. Guardá tus favoritas, llevalas al auto y despertate con ellas.'**
|
||||
String get welcomeBody;
|
||||
|
||||
/// No description provided for @welcomeBullet1Title.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Ecualizador por emisora'**
|
||||
String get welcomeBullet1Title;
|
||||
|
||||
/// No description provided for @welcomeBullet1Subtitle.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Y un preset por dispositivo de salida'**
|
||||
String get welcomeBullet1Subtitle;
|
||||
|
||||
/// No description provided for @welcomeBullet2Title.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Android Auto'**
|
||||
String get welcomeBullet2Title;
|
||||
|
||||
/// No description provided for @welcomeBullet2Subtitle.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Tus favoritas y tu música local en el auto'**
|
||||
String get welcomeBullet2Subtitle;
|
||||
|
||||
/// No description provided for @welcomeBullet3Title.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Alarmas musicales'**
|
||||
String get welcomeBullet3Title;
|
||||
|
||||
/// No description provided for @welcomeBullet3Subtitle.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Con subida progresiva y modo vacaciones'**
|
||||
String get welcomeBullet3Subtitle;
|
||||
|
||||
/// No description provided for @welcomeCtaLabel.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Empezar a escuchar'**
|
||||
String get welcomeCtaLabel;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'الرئيسية';
|
||||
String get navHome => 'استماع';
|
||||
|
||||
@override
|
||||
String get navSearch => 'بحث';
|
||||
@@ -100,19 +100,19 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
'تحكم دقيق في الصوت والنسخ الاحتياطية والمحطات المخصصة.';
|
||||
|
||||
@override
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
String get settingsGroupAudioTitle => 'الصوت';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'المحطات';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'التسجيلات والموسيقى';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'التطبيق';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'معلومات';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'اللغة';
|
||||
@@ -225,40 +225,38 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'هذا هو المعادل الأساسي: يُطبَّق على كل محطة لا تملك إعدادًا خاصًا بها. يُحدَّد معادل محطة معينة من شاشة تشغيلها الخاصة، وله الأولوية على هذا المعادل.';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'المخرج النشط';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'مكبر صوت هذا الجهاز';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'محطات لديها معادل خاص';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
String get equalizerStationsWithOwnEqSubtitle => 'تتجاهل هذا المعادل الأساسي';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'لا توجد محطة لديها معادل خاص حتى الآن.';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'حفظ كإعداد مسبق';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'حفظ كإعداد مسبق';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'اسم الإعداد المسبق';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
String get equalizerSavePresetEmptyNameError => 'أدخل اسمًا للإعداد المسبق.';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'حفظ';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'المحطة المفضلة';
|
||||
@@ -433,47 +431,46 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'تسجيلاتي';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return 'تم استخدام $usedMb ميغابايت من أصل $totalMb ميغابايت';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'لا توجد تسجيلات بعد';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'التسجيلات التي تحفظها ستظهر هنا.';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'إعادة تسمية';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'مشاركة';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'حذف';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'إعادة تسمية التسجيل';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'الاسم';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'أدخل اسمًا';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'هل تريد حذف التسجيل؟';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
String get recordingDeleteConfirmMessage => 'لا يمكن التراجع عن هذا الإجراء.';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'إعدادات التسجيل';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'ترتيب المحطات';
|
||||
@@ -485,7 +482,7 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'حسب الجودة';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'حسب الشهرة';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -574,7 +571,7 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'الكل';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -582,10 +579,10 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'إدارة القوائم';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'إضافة محطة مخصصة';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution => 'تم تأجيل المنبه لهذا التشغيل.';
|
||||
@@ -631,8 +628,10 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count نتيجة',
|
||||
few: '$count نتائج',
|
||||
two: 'نتيجتان',
|
||||
one: 'نتيجة واحدة',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -642,23 +641,25 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: 'إزالة $count فلتر',
|
||||
few: 'إزالة $count فلاتر',
|
||||
two: 'إزالة الفلترين',
|
||||
one: 'إزالة الفلتر',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'الدول';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'لغاتك';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'كل الدول';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'تعذّر تحميل الدول.';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'إسبانيا';
|
||||
@@ -733,20 +734,20 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String get qualityHd => 'جودة HD';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'محطاتك';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'عرض الكل';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'فتح المشغل الكامل';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'لا تستمع إلى شيء بعد';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'اختر محطة من محطاتك أو ابحث عن واحدة للبدء.';
|
||||
|
||||
@override
|
||||
String get nearYou => 'بالقرب منك';
|
||||
@@ -878,13 +879,13 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String get deleteTooltip => 'حذف';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'تخطي';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'هل تريد حذف المنبه؟';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => 'لا يمكن التراجع عن هذا الإجراء.';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1042,41 +1043,40 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count فترة';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'جارٍ الآن · تبقّى $days يوم';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'الفترة التالية خلال $days يوم';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'إيقاف مؤقت: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'يستمر الرنين: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'المجدولة';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'الفترات السابقة';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'إضافة فترة';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
String get vacationNoActiveRangeHint => 'لا توجد فترة إجازة نشطة الآن.';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'إجازات';
|
||||
@@ -1361,10 +1361,10 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'إيقاف مؤقت';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'تغيير';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'معادل خاص';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1454,16 +1454,16 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
String get vacationIconLabel => 'وضع الإجازة';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'متقدم';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'الساعة';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => 'الدقيقة';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'رفع مستوى الصوت تدريجيًا';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1580,4 +1580,33 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'مجلد محدد';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'عالمك، على الهواء مباشرة';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53,412 محطة من 238 دولة. احفظ محطاتك المفضلة، خذها معك في السيارة، واستيقظ عليها.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'معادل لكل محطة';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => 'بالإضافة إلى إعداد مسبق لكل جهاز خرج';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'محطاتك المفضلة وموسيقاك المحلية في السيارة';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'منبهات موسيقية';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle => 'مع رفع تدريجي للصوت ووضع الإجازة';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'ابدأ الاستماع';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'হোম';
|
||||
String get navHome => 'শোনা';
|
||||
|
||||
@override
|
||||
String get navSearch => 'অনুসন্ধান';
|
||||
@@ -101,19 +101,19 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
'শব্দ, ব্যাকআপ এবং নিজস্ব স্টেশনের সূক্ষ্ম নিয়ন্ত্রণ।';
|
||||
|
||||
@override
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
String get settingsGroupAudioTitle => 'অডিও';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'স্টেশন';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'রেকর্ডিং ও সংগীত';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'অ্যাপ্লিকেশন';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'তথ্য';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'ভাষা';
|
||||
@@ -228,40 +228,40 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'এটি বেস ইকুয়ালাইজার: এটি নিজস্ব সেটিং নেই এমন সব স্টেশনে প্রযোজ্য। কোনো নির্দিষ্ট স্টেশনের নিজস্ব EQ তার প্লেব্যাক স্ক্রিন থেকে ঠিক করা হয় এবং এটির চেয়ে অগ্রাধিকার পায়।';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'সক্রিয় আউটপুট';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'এই ডিভাইসের স্পিকার';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'নিজস্ব EQ থাকা স্টেশন';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'এই বেস ইকুয়ালাইজার উপেক্ষা করে';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'এখনও কোনো স্টেশনের নিজস্ব EQ নেই।';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'প্রিসেট হিসেবে সংরক্ষণ করুন';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'প্রিসেট হিসেবে সংরক্ষণ করুন';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'প্রিসেটের নাম';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
'প্রিসেটের জন্য একটি নাম লিখুন।';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'সংরক্ষণ করুন';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'পছন্দের স্টেশন';
|
||||
@@ -436,47 +436,47 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'আমার রেকর্ডিং';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '$totalMb MB-এর মধ্যে $usedMb MB ব্যবহৃত';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'এখনও কোনো রেকর্ডিং নেই';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'আপনি যেসব রেকর্ডিং সংরক্ষণ করবেন তা এখানে দেখা যাবে।';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'নাম পরিবর্তন করুন';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'শেয়ার করুন';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'মুছে ফেলুন';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'রেকর্ডিং-এর নাম পরিবর্তন করুন';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'নাম';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'একটি নাম লিখুন';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'রেকর্ডিং মুছবেন?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
'এই পদক্ষেপ ফিরিয়ে নেওয়া যাবে না।';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'রেকর্ডিং সেটিংস';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'স্টেশনের ক্রম';
|
||||
@@ -488,7 +488,7 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'গুণমান অনুযায়ী';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'জনপ্রিয়তা অনুসারে';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -577,7 +577,7 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'সব';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -585,10 +585,10 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'তালিকা পরিচালনা করুন';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'নিজস্ব স্টেশন যোগ করুন';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -635,8 +635,8 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$countটি ফলাফল',
|
||||
one: '১টি ফলাফল',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -646,23 +646,23 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: '$countটি ফিল্টার সরান',
|
||||
one: 'ফিল্টার সরান',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'দেশসমূহ';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'আপনার ভাষাসমূহ';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'সব দেশ';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'দেশগুলো লোড করা যায়নি।';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'স্পেন';
|
||||
@@ -737,20 +737,20 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String get qualityHd => 'HD গুণমান';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'আপনার স্টেশন';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'সব দেখুন';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'সম্পূর্ণ প্লেয়ার খুলুন';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'এখনও কিছু চলছে না';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'শুরু করতে আপনার স্টেশন থেকে একটি বেছে নিন বা একটি খুঁজুন।';
|
||||
|
||||
@override
|
||||
String get nearYou => 'আপনার কাছাকাছি';
|
||||
@@ -883,13 +883,13 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String get deleteTooltip => 'মুছুন';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'এড়িয়ে যান';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'অ্যালার্ম মুছবেন?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => 'এই পদক্ষেপ ফিরিয়ে নেওয়া যাবে না।';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1049,41 +1049,41 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$countটি সময়সীমা';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'চলমান · আর $days দিন বাকি';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'পরবর্তী সময়সীমা $days দিনে';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'বিরতি: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'বাজতেই থাকবে: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'নির্ধারিত';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'অতীত সময়সীমা';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'সময়সীমা যোগ করুন';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
'এই মুহূর্তে কোনো সক্রিয় ছুটির সময়সীমা নেই।';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'ছুটি';
|
||||
@@ -1370,10 +1370,10 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'প্লেব্যাক বিরতি';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'পরিবর্তন করুন';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'নিজস্ব EQ';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1461,16 +1461,16 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
String get vacationIconLabel => 'ছুটির মোড';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'উন্নত';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'ঘণ্টা';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => 'মিনিট';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'ভলিউম বাড়ছে';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1588,4 +1588,33 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'নির্বাচিত ফোল্ডার';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'আপনার বিশ্ব, সরাসরি';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'২৩৮টি দেশের ৫৩,৪১২টি স্টেশন। আপনার প্রিয় স্টেশন সংরক্ষণ করুন, গাড়িতে নিয়ে যান এবং সেগুলো দিয়ে ঘুম থেকে উঠুন।';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'স্টেশন অনুযায়ী ইকুয়ালাইজার';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle =>
|
||||
'এবং প্রতিটি আউটপুট ডিভাইসের জন্য একটি প্রিসেট';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle => 'গাড়িতে আপনার প্রিয় ও স্থানীয় সংগীত';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'সুরেলা অ্যালার্ম';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle => 'ধীরে ভলিউম বৃদ্ধি ও ছুটির মোড সহ';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'শোনা শুরু করুন';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'Start';
|
||||
String get navHome => 'Hören';
|
||||
|
||||
@override
|
||||
String get navSearch => 'Suche';
|
||||
@@ -103,16 +103,16 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'SENDER';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'AUFNAHMEN & MUSIK';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'ANWENDUNG';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'Info';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'Sprache';
|
||||
@@ -228,40 +228,40 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'Dies ist der Basis-Equalizer: Er gilt für alle Sender ohne eigene Einstellung. Der eigene EQ eines Senders wird auf dessen eigenem Wiedergabebildschirm festgelegt und hat Vorrang vor diesem hier.';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'Aktiver Ausgang';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'Der Lautsprecher dieses Geräts';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'Sender mit eigenem EQ';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'Ignorieren diesen Basis-Equalizer';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'Noch kein Sender hat einen eigenen EQ.';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'Als Preset speichern';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'Als Preset speichern';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'Preset-Name';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
'Gib einen Namen für das Preset ein.';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'Speichern';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'Bevorzugter Sender';
|
||||
@@ -439,47 +439,47 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'Meine Aufnahmen';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '$usedMb MB von $totalMb MB belegt';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'Noch keine Aufnahmen';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'Aufnahmen, die du speicherst, erscheinen hier.';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'Umbenennen';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'Teilen';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'Löschen';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'Aufnahme umbenennen';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'Name';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'Gib einen Namen ein';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'Aufnahme löschen?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
'Dies kann nicht rückgängig gemacht werden.';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'Aufnahmeeinstellungen';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'Senderreihenfolge';
|
||||
@@ -491,7 +491,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'Nach Qualität';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'Nach Beliebtheit';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -580,7 +580,7 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'Alle';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -588,10 +588,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'Listen verwalten';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'Benutzerdefinierten Sender hinzufügen';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -638,8 +638,8 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count Ergebnisse',
|
||||
one: '1 Ergebnis',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -649,23 +649,23 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: '$count Filter entfernen',
|
||||
one: 'Filter entfernen',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'Länder';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'Deine Sprachen';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'Alle Länder';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'Die Länder konnten nicht geladen werden.';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'Spanien';
|
||||
@@ -740,20 +740,20 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get qualityHd => 'HD-Qualität';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'Deine Sender';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'Alle ansehen';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'Vollständigen Player öffnen';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'Es läuft noch nichts';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'Wähle einen Sender aus Deine Sender oder suche einen, um zu starten.';
|
||||
|
||||
@override
|
||||
String get nearYou => 'In deiner Nähe';
|
||||
@@ -886,13 +886,14 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get deleteTooltip => 'Löschen';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'Überspringen';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'Alarm löschen?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage =>
|
||||
'Dies kann nicht rückgängig gemacht werden.';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1050,41 +1051,41 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count Zeiträume';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'Läuft gerade · noch $days Tage';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'Nächster Zeitraum in $days Tagen';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'Pausiert: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'Klingelt weiter: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'GEPLANT';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'Vergangene Zeiträume';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'Zeitraum hinzufügen';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
'Momentan ist kein aktiver Urlaubszeitraum vorhanden.';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'Ferien';
|
||||
@@ -1378,10 +1379,10 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'Wiedergabe pausieren';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'Ändern';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'Eigener EQ';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1471,16 +1472,16 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
String get vacationIconLabel => 'Urlaubsmodus';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'Erweitert';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'Stunde';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => 'Minute';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'Lautstärke wird erhöht';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1599,4 +1600,34 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Ausgewählter Ordner';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Deine Welt, live';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53.412 Sender aus 238 Ländern. Speichere deine Favoriten, nimm sie mit ins Auto und wache mit ihnen auf.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Equalizer pro Sender';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => 'Plus ein Preset pro Ausgabegerät';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'Deine Favoriten und lokale Musik im Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Musikalarme';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'Mit sanftem Lautstärkeanstieg und Urlaubsmodus';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Jetzt hören';
|
||||
}
|
||||
|
||||
@@ -1581,4 +1581,34 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Selected folder';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Your world, live';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53,412 stations from 238 countries. Save your favorites, take them to the car, and wake up to them.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Per-station equalizer';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => 'Plus a preset per output device';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'Your favorites and local music in the car';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Music alarms';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'With gradual volume rise and vacation mode';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Start listening';
|
||||
}
|
||||
|
||||
@@ -1594,4 +1594,34 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Carpeta seleccionada';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Tu mundo, en directo';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53.412 emisoras de 238 países. Guardá tus favoritas, llevalas al auto y despertate con ellas.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Ecualizador por emisora';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => 'Y un preset por dispositivo de salida';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'Tus favoritas y tu música local en el auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Alarmas musicales';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'Con subida progresiva y modo vacaciones';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Empezar a escuchar';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'Accueil';
|
||||
String get navHome => 'Écouter';
|
||||
|
||||
@override
|
||||
String get navSearch => 'Recherche';
|
||||
@@ -104,16 +104,16 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'STATIONS';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'ENREGISTREMENTS ET MUSIQUE';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'APPLICATION';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'Infos';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'Langue';
|
||||
@@ -229,40 +229,40 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'Voici l\'égaliseur de base : il s\'applique à toutes les stations sans réglage propre. L\'EQ propre à une station est défini depuis son propre écran de lecture et prime sur celui-ci.';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'Sortie active';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'Le haut-parleur de cet appareil';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'Stations avec un EQ propre';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'Ignorent cet égaliseur de base';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'Aucune station n\'a encore d\'EQ propre.';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'Enregistrer comme Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'Enregistrer comme Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'Nom du Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
'Saisissez un nom pour le Preset.';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'Enregistrer';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'Station préférée';
|
||||
@@ -441,47 +441,47 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'Mes enregistrements';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '$usedMb Mo sur $totalMb Mo utilisés';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle =>
|
||||
'Aucun enregistrement pour l\'instant';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'Les enregistrements que vous sauvegardez apparaîtront ici.';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'Renommer';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'Partager';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'Supprimer';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'Renommer l\'enregistrement';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'Nom';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'Saisissez un nom';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'Supprimer l\'enregistrement ?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
String get recordingDeleteConfirmMessage => 'Cette action est irréversible.';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'Paramètres d\'enregistrement';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'Ordre des stations';
|
||||
@@ -493,7 +493,7 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'Par qualité';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'Par popularité';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -582,7 +582,7 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'Toutes';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -590,10 +590,10 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'Gérer les listes';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'Ajouter une station personnalisée';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -640,8 +640,8 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count résultats',
|
||||
one: '1 résultat',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -651,23 +651,23 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: 'Retirer les $count filtres',
|
||||
one: 'Retirer le filtre',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'Pays';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'Vos langues';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'Tous les pays';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'Impossible de charger les pays.';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'Espagne';
|
||||
@@ -742,20 +742,20 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get qualityHd => 'Qualité HD';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'Vos stations';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'Tout voir';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'Ouvrir le lecteur complet';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'Rien n\'est en cours de lecture';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'Choisissez une station dans Vos stations ou recherchez-en une pour commencer.';
|
||||
|
||||
@override
|
||||
String get nearYou => 'Près de vous';
|
||||
@@ -888,13 +888,13 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get deleteTooltip => 'Supprimer';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'Ignorer';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'Supprimer l\'alarme ?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => 'Cette action est irréversible.';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1054,41 +1054,41 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count périodes';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'En cours · encore $days jours';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'Prochaine période dans $days jours';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'En pause : $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'Continue de sonner : $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMMÉES';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'Périodes passées';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'Ajouter une période';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
'Aucune période de vacances active pour le moment.';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'Vacances';
|
||||
@@ -1383,10 +1383,10 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'Mettre en pause';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'Modifier';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'EQ propre';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1476,16 +1476,16 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
String get vacationIconLabel => 'Mode vacances';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'Avancé';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'Heure';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => 'Minute';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'Augmentation du volume';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1603,4 +1603,35 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Dossier sélectionné';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Votre monde, en direct';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53 412 stations de 238 pays. Enregistrez vos favorites, emmenez-les en voiture et réveillez-vous avec elles.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Égaliseur par station';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle =>
|
||||
'Plus un Preset par périphérique de sortie';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'Vos favorites et votre musique locale en voiture';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Alarmes musicales';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'Avec montée progressive du volume et mode vacances';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Commencer à écouter';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'मुखपृष्ठ';
|
||||
String get navHome => 'सुनना';
|
||||
|
||||
@override
|
||||
String get navSearch => 'खोज';
|
||||
@@ -100,19 +100,19 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
'ध्वनि, बैकअप और मनचाहे स्टेशनों पर बारीक नियंत्रण।';
|
||||
|
||||
@override
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
String get settingsGroupAudioTitle => 'ऑडियो';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'स्टेशन';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'रिकॉर्डिंग और संगीत';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'ऐप्लिकेशन';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'जानकारी';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'भाषा';
|
||||
@@ -227,40 +227,40 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'यह बेस इक्वलाइज़र है: यह उन सभी स्टेशन पर लागू होता है जिनकी अपनी सेटिंग नहीं है। किसी खास स्टेशन का अपना EQ उसकी प्लेबैक स्क्रीन से तय होता है और इस पर प्राथमिकता रखता है।';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'सक्रिय आउटपुट';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'इस डिवाइस का स्पीकर';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'अपना EQ रखने वाले स्टेशन';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'यह बेस इक्वलाइज़र नज़रअंदाज़ करते हैं';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'अभी तक किसी स्टेशन का अपना EQ नहीं है।';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'प्रीसेट के रूप में सहेजें';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'प्रीसेट के रूप में सहेजें';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'प्रीसेट का नाम';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
'प्रीसेट के लिए एक नाम डालें।';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'सहेजें';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'पसंदीदा स्टेशन';
|
||||
@@ -434,47 +434,46 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'मेरी रिकॉर्डिंग';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '$totalMb MB में से $usedMb MB इस्तेमाल हुआ';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'अभी तक कोई रिकॉर्डिंग नहीं';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'आप जो रिकॉर्डिंग सहेजेंगे, वे यहां दिखाई देंगी।';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'नाम बदलें';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'शेयर करें';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'हटाएं';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'रिकॉर्डिंग का नाम बदलें';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'नाम';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'एक नाम डालें';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'रिकॉर्डिंग हटाएं?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
String get recordingDeleteConfirmMessage => 'इसे वापस नहीं लिया जा सकता।';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'रिकॉर्डिंग सेटिंग्स';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'स्टेशन क्रम';
|
||||
@@ -486,7 +485,7 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'गुणवत्ता से';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'लोकप्रियता के अनुसार';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -575,7 +574,7 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'सभी';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -583,10 +582,10 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'सूचियां प्रबंधित करें';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'मनचाहा स्टेशन जोड़ें';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -633,8 +632,8 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count परिणाम',
|
||||
one: '1 परिणाम',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -644,23 +643,23 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: '$count फ़िल्टर हटाएं',
|
||||
one: 'फ़िल्टर हटाएं',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'देश';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'आपकी भाषाएं';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'सभी देश';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'देश लोड नहीं हो सके।';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'स्पेन';
|
||||
@@ -735,20 +734,20 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get qualityHd => 'HD गुणवत्ता';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'आपके स्टेशन';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'सभी देखें';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'पूरा प्लेयर खोलें';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'अभी तक कुछ नहीं चल रहा';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'शुरू करने के लिए आपके स्टेशन में से कोई एक चुनें या खोजें।';
|
||||
|
||||
@override
|
||||
String get nearYou => 'आपके पास';
|
||||
@@ -880,13 +879,13 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get deleteTooltip => 'हटाएँ';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'छोड़ें';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'अलार्म हटाएं?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => 'इसे वापस नहीं लिया जा सकता।';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1045,41 +1044,40 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count अवधियां';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'जारी है · $days दिन बाकी';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'अगली अवधि $days दिन में';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'रोका गया: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'बजना जारी: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'निर्धारित';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'पिछली अवधियां';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'अवधि जोड़ें';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
String get vacationNoActiveRangeHint => 'अभी कोई सक्रिय छुट्टी अवधि नहीं है।';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'छुट्टियाँ';
|
||||
@@ -1368,10 +1366,10 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'प्लेबैक रोकें';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'बदलें';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'अपना EQ';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1460,16 +1458,16 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
String get vacationIconLabel => 'अवकाश मोड';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'उन्नत';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'घंटा';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => 'मिनट';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'आवाज़ बढ़ाई जा रही है';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1586,4 +1584,33 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'चयनित फ़ोल्डर';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'आपकी दुनिया, लाइव';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'238 देशों के 53,412 स्टेशन। अपने पसंदीदा स्टेशन सहेजें, उन्हें गाड़ी में ले जाएं और उनके साथ जागें।';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'प्रति स्टेशन इक्वलाइज़र';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => 'और हर आउटपुट डिवाइस के लिए एक प्रीसेट';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle => 'गाड़ी में आपके पसंदीदा और लोकल संगीत';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'संगीत अलार्म';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'धीरे-धीरे आवाज़ बढ़ाने और छुट्टी मोड के साथ';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'सुनना शुरू करें';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'Beranda';
|
||||
String get navHome => 'Dengar';
|
||||
|
||||
@override
|
||||
String get navSearch => 'Cari';
|
||||
@@ -104,16 +104,16 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'STASIUN';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'REKAMAN & MUSIK';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'APLIKASI';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'Info';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'Bahasa';
|
||||
@@ -227,40 +227,39 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'Ini adalah equalizer dasar: berlaku untuk semua stasiun yang belum punya pengaturan sendiri. EQ khusus suatu stasiun diatur dari layar pemutarannya sendiri dan mengesampingkan yang ini.';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'Output aktif';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'Speaker perangkat ini';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'Stasiun dengan EQ sendiri';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'Mengabaikan equalizer dasar ini';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'Belum ada stasiun yang punya EQ sendiri.';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'Simpan sebagai Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'Simpan sebagai Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'Nama Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
String get equalizerSavePresetEmptyNameError => 'Masukkan nama untuk Preset.';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'Simpan';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'Stasiun pilihan';
|
||||
@@ -435,47 +434,47 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'Rekaman saya';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '$usedMb MB dari $totalMb MB terpakai';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'Belum ada rekaman';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'Rekaman yang Anda simpan akan muncul di sini.';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'Ganti nama';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'Bagikan';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'Hapus';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'Ganti nama rekaman';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'Nama';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'Masukkan nama';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'Hapus rekaman?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
'Tindakan ini tidak dapat dibatalkan.';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'Pengaturan rekaman';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'Urutan stasiun';
|
||||
@@ -487,7 +486,7 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'Berdasarkan kualitas';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'Berdasarkan popularitas';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -576,7 +575,7 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'Semua';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -584,10 +583,10 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'Kelola daftar';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'Tambahkan stasiun khusus';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -634,8 +633,7 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count hasil',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -645,23 +643,23 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: 'Hapus $count filter',
|
||||
one: 'Hapus filter',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'Negara';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'Bahasa Anda';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'Semua negara';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'Negara tidak dapat dimuat.';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'Spanyol';
|
||||
@@ -736,20 +734,20 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get qualityHd => 'Kualitas HD';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'Stasiun Anda';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'Lihat semua';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'Buka pemutar lengkap';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'Belum ada yang diputar';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'Pilih stasiun dari Stasiun Anda atau cari salah satu untuk mulai.';
|
||||
|
||||
@override
|
||||
String get nearYou => 'Di dekat Anda';
|
||||
@@ -883,13 +881,14 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get deleteTooltip => 'Hapus';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'Lewati';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'Hapus alarm?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage =>
|
||||
'Tindakan ini tidak dapat dibatalkan.';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1049,41 +1048,41 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count periode';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'Sedang berlangsung · $days hari lagi';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'Periode berikutnya dalam $days hari';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'Dijeda: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'Tetap berbunyi: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'TERJADWAL';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'Periode lampau';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'Tambahkan periode';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
'Tidak ada periode liburan aktif saat ini.';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'Liburan';
|
||||
@@ -1374,10 +1373,10 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'Jeda pemutaran';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'Ubah';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'EQ sendiri';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1465,16 +1464,16 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
String get vacationIconLabel => 'Mode liburan';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'Lanjutan';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'Jam';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => 'Menit';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'Menaikkan volume';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1592,4 +1591,33 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Folder terpilih';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Duniamu, secara langsung';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53.412 stasiun dari 238 negara. Simpan favorit Anda, bawa ke mobil, dan bangun bersamanya.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Equalizer per stasiun';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => 'Plus satu Preset per perangkat output';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle => 'Favorit dan musik lokal Anda di mobil';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Alarm musik';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'Dengan kenaikan volume bertahap dan mode liburan';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Mulai mendengarkan';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'Inizio';
|
||||
String get navHome => 'Ascolta';
|
||||
|
||||
@override
|
||||
String get navSearch => 'Cerca';
|
||||
@@ -103,16 +103,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'EMITTENTI';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'REGISTRAZIONI E MUSICA';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'APPLICAZIONE';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'Informazioni';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'Lingua';
|
||||
@@ -227,40 +227,41 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'Questo è l\'equalizzatore di base: si applica a tutte le emittenti senza un\'impostazione propria. L\'EQ di un\'emittente specifica si imposta dalla sua schermata di riproduzione e ha la precedenza su questo.';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'Uscita attiva';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault =>
|
||||
'L\'altoparlante di questo dispositivo';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emittenti con EQ proprio';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'Ignorano questo equalizzatore di base';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'Nessuna emittente ha ancora un EQ proprio.';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'Salva come Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'Salva come Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'Nome del Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
'Inserisci un nome per il Preset.';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'Salva';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'Emittente preferita';
|
||||
@@ -437,47 +438,48 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'Le mie registrazioni';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '$usedMb MB di $totalMb MB usati';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'Ancora nessuna registrazione';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'Le registrazioni che salvi appariranno qui.';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'Rinomina';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'Condividi';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'Elimina';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'Rinomina registrazione';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'Nome';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'Inserisci un nome';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'Eliminare la registrazione?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
'Questa azione non può essere annullata.';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip =>
|
||||
'Impostazioni di registrazione';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'Ordine emittenti';
|
||||
@@ -489,7 +491,7 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'Per qualità';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'Per popolarità';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -578,7 +580,7 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'Tutte';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -586,10 +588,10 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'Gestisci liste';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'Aggiungi emittente personalizzata';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -636,8 +638,8 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count risultati',
|
||||
one: '1 risultato',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -647,23 +649,23 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: 'Rimuovi $count filtri',
|
||||
one: 'Rimuovi filtro',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'Paesi';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'Le tue lingue';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'Tutti i paesi';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'Non è stato possibile caricare i paesi.';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'Spagna';
|
||||
@@ -738,20 +740,20 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get qualityHd => 'Qualità HD';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'Le tue emittenti';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'Vedi tutte';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'Apri il player completo';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'Non stai ancora ascoltando nulla';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'Scegli un\'emittente da Le tue emittenti o cercane una per iniziare.';
|
||||
|
||||
@override
|
||||
String get nearYou => 'Vicino a te';
|
||||
@@ -884,13 +886,14 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get deleteTooltip => 'Elimina';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'Salta';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'Eliminare la sveglia?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage =>
|
||||
'Questa azione non può essere annullata.';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1050,41 +1053,41 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count periodi';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'In corso · mancano $days giorni';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'Prossimo periodo tra $days giorni';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'In pausa: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'Continua a suonare: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMMATI';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'Periodi passati';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'Aggiungi periodo';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
'Nessun periodo di vacanza attivo al momento.';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'Vacanze';
|
||||
@@ -1378,10 +1381,10 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'Pausa riproduzione';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'Cambia';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'EQ proprio';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1471,16 +1474,16 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
String get vacationIconLabel => 'Modalità vacanza';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'Avanzate';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'Ora';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'Aumento del volume';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1598,4 +1601,35 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Cartella selezionata';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Il tuo mondo, in diretta';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53.412 emittenti da 238 paesi. Salva le tue preferite, portale in auto e svegliati con loro.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Equalizzatore per emittente';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle =>
|
||||
'Più un Preset per ogni dispositivo di uscita';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'Le tue preferite e la tua musica locale in auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Sveglie musicali';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'Con aumento graduale del volume e modalità vacanza';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Inizia ad ascoltare';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'ホーム';
|
||||
String get navHome => '聴く';
|
||||
|
||||
@override
|
||||
String get navSearch => '検索';
|
||||
@@ -98,19 +98,19 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get settingsSubtitle => '音質、バックアップ、カスタム局を細かく管理します。';
|
||||
|
||||
@override
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
String get settingsGroupAudioTitle => 'オーディオ';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => '局';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => '録音と音楽';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'アプリ';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => '情報';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => '言語';
|
||||
@@ -219,40 +219,37 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'これはベースイコライザーです。専用設定を持たないすべての局に適用されます。特定の局専用のEQはその局の再生画面から設定でき、こちらより優先されます。';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'アクティブな出力';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'この端末のスピーカー';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => '専用EQを持つ局';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
String get equalizerStationsWithOwnEqSubtitle => 'このベースイコライザーを無視します';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
String get equalizerStationsWithOwnEqEmpty => '専用EQを持つ局はまだありません。';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'プリセットとして保存';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'プリセットとして保存';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'プリセット名';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
String get equalizerSavePresetEmptyNameError => 'プリセットの名前を入力してください。';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => '保存';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => '優先局';
|
||||
@@ -424,47 +421,45 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'マイ録音';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '$totalMb MB 中 $usedMb MB 使用済み';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'まだ録音がありません';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
String get recordingsLibraryEmptySubtitle => '保存した録音はここに表示されます。';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => '名前を変更';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => '共有';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => '削除';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => '録音の名前を変更';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => '名前';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => '名前を入力してください';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => '録音を削除しますか?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
String get recordingDeleteConfirmMessage => 'この操作は元に戻せません。';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => '録音設定';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => '局の並び順';
|
||||
@@ -476,7 +471,7 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get stationOrderByQuality => '品質順';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => '人気順';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription => 'お気に入り、検索、近くの局、クイック一覧に適用されます。';
|
||||
@@ -559,7 +554,7 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'すべて';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -567,10 +562,10 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'リストを管理';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'カスタム局を追加';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution => 'この実行のアラームを延期しました。';
|
||||
@@ -613,8 +608,7 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count件の結果',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -624,23 +618,23 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: '$count件のフィルターをクリア',
|
||||
one: 'フィルターをクリア',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => '国';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'あなたの言語';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'すべての国';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => '国の一覧を読み込めませんでした。';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'スペイン';
|
||||
@@ -715,20 +709,19 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get qualityHd => 'HD品質';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'あなたの局';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'すべて見る';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'フルプレーヤーを開く';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'まだ何も再生されていません';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
String get nothingPlayingSubtitle => '「あなたの局」から局を選ぶか、検索して再生を始めましょう。';
|
||||
|
||||
@override
|
||||
String get nearYou => '近く';
|
||||
@@ -858,13 +851,13 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get deleteTooltip => '削除';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'スキップ';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'アラームを削除しますか?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => 'この操作は元に戻せません。';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar => 'アラームをスキップしました。次回実行は残っていません。';
|
||||
@@ -1018,41 +1011,40 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count 件の期間';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return '進行中 · 残り$days日';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return '次の期間まであと$days日';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return '一時停止: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return '引き続き鳴動: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => '予定';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => '過去の期間';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => '期間を追加';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
String get vacationNoActiveRangeHint => '現在アクティブな休暇期間はありません。';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => '休暇';
|
||||
@@ -1330,10 +1322,10 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => '再生を一時停止';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => '変更';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => '専用EQ';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1420,16 +1412,16 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
String get vacationIconLabel => '休暇モード';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => '詳細設定';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => '時';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => '分';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => '音量を上げています';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1545,4 +1537,31 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => '選択したフォルダー';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'あなたの世界を、ライブで';
|
||||
|
||||
@override
|
||||
String get welcomeBody => '238か国、53,412局のラジオ。お気に入りを保存して車に持ち出し、それで目を覚まそう。';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => '局ごとのイコライザー';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => 'さらに出力デバイスごとのプリセット';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle => '車の中でお気に入りとローカル音楽を';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => '音楽アラーム';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle => '音量の緩やかな上昇と休暇モード付き';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => '聴き始める';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'Início';
|
||||
String get navHome => 'Ouvir';
|
||||
|
||||
@override
|
||||
String get navSearch => 'Buscar';
|
||||
@@ -100,19 +100,19 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
'Controle fino de som, backups e estações personalizadas.';
|
||||
|
||||
@override
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
String get settingsGroupAudioTitle => 'ÁUDIO';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'ESTAÇÕES';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'GRAVAÇÕES E MÚSICA';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'APLICATIVO';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'Informações';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'Idioma';
|
||||
@@ -226,40 +226,40 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'Este é o equalizador base: aplica-se a todas as estações sem ajuste próprio. O EQ próprio de uma estação é definido na sua própria tela de reprodução e tem prioridade sobre este.';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'Saída ativa';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'O alto-falante deste dispositivo';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'Estações com EQ próprio';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'Ignoram este equalizador base';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'Nenhuma estação tem EQ próprio ainda.';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'Salvar como Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'Salvar como Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'Nome do Preset';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
'Digite um nome para o Preset.';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'Salvar';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'Estação preferida';
|
||||
@@ -436,7 +436,7 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'Minhas gravações';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
@@ -444,39 +444,39 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'Ainda não há gravações';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'As gravações que você salvar vão aparecer aqui.';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'Renomear';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'Compartilhar';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'Excluir';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'Renomear gravação';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'Nome';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'Digite um nome';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'Excluir gravação?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
'Esta ação não pode ser desfeita.';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'Configurações de gravação';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'Ordem das estações';
|
||||
@@ -488,7 +488,7 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'Por qualidade';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'Por popularidade';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -585,10 +585,10 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'Gerenciar listas';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'Adicionar estação personalizada';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -646,8 +646,8 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: 'Remover $count filtros',
|
||||
one: 'Remover filtro',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -656,13 +656,13 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get countriesScreenTitle => 'Países';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'Seus idiomas';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'Todos os países';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'Não foi possível carregar os países.';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'Espanha';
|
||||
@@ -737,20 +737,20 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get qualityHd => 'Qualidade HD';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'Suas estações';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'Abrir player completo';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'Ainda não há nada tocando';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'Escolha uma estação em Suas estações ou pesquise uma para começar.';
|
||||
|
||||
@override
|
||||
String get nearYou => 'Perto de você';
|
||||
@@ -883,13 +883,13 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get deleteTooltip => 'Excluir';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'Pular';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'Excluir alarme?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => 'Esta ação não pode ser desfeita.';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1047,41 +1047,41 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count períodos';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'Em andamento · faltam $days dias';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'Próximo período em $days dias';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'Pausado: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'Continua tocando: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'Períodos passados';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'Adicionar período';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
'Não há período de férias ativo no momento.';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'Férias';
|
||||
@@ -1370,10 +1370,10 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'Pausar reprodução';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'Alterar';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'EQ próprio';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1463,7 +1463,7 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get vacationIconLabel => 'Modo férias';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'Avançado';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
@@ -1472,7 +1472,7 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'Aumentando o volume';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1590,4 +1590,35 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Pasta selecionada';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Seu mundo, ao vivo';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53.412 estações de 238 países. Salve suas favoritas, leve-as para o carro e acorde com elas.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Equalizador por estação';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle =>
|
||||
'Além de um Preset por dispositivo de saída';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'Suas favoritas e sua música local no carro';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Alarmes musicais';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'Com aumento progressivo do volume e modo férias';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Começar a ouvir';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => 'Главная';
|
||||
String get navHome => 'Слушать';
|
||||
|
||||
@override
|
||||
String get navSearch => 'Поиск';
|
||||
@@ -100,19 +100,19 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
'Точная настройка звука, резервных копий и пользовательских станций.';
|
||||
|
||||
@override
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
String get settingsGroupAudioTitle => 'АУДИО';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => 'СТАНЦИИ';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => 'ЗАПИСИ И МУЗЫКА';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => 'ПРИЛОЖЕНИЕ';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => 'Информация';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => 'Язык';
|
||||
@@ -228,40 +228,39 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'Это базовый эквалайзер: он применяется ко всем станциям без собственной настройки. Свой EQ конкретной станции задаётся на экране её воспроизведения и имеет приоритет над этим.';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => 'Активный выход';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => 'Динамик этого устройства';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => 'Станции со своим EQ';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
'Игнорируют этот базовый эквалайзер';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
'Пока ни у одной станции нет своего EQ.';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => 'Сохранить как пресет';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => 'Сохранить как пресет';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => 'Название пресета';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
String get equalizerSavePresetEmptyNameError => 'Введите название пресета.';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => 'Сохранить';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => 'Предпочитаемая станция';
|
||||
@@ -437,47 +436,46 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => 'Мои записи';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return 'Использовано $usedMb МБ из $totalMb МБ';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => 'Записей пока нет';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
'Записи, которые вы сохраните, появятся здесь.';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => 'Переименовать';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => 'Поделиться';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => 'Удалить';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => 'Переименовать запись';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => 'Название';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => 'Введите название';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => 'Удалить запись?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
String get recordingDeleteConfirmMessage => 'Это действие нельзя отменить.';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => 'Настройки записи';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => 'Порядок станций';
|
||||
@@ -489,7 +487,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get stationOrderByQuality => 'По качеству';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => 'По популярности';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription =>
|
||||
@@ -578,7 +576,7 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => 'Все';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -586,10 +584,10 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => 'Управление списками';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => 'Добавить пользовательскую станцию';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution =>
|
||||
@@ -636,8 +634,9 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count результатов',
|
||||
few: '$count результата',
|
||||
one: '$count результат',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -647,23 +646,24 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: 'Убрать $count фильтров',
|
||||
few: 'Убрать $count фильтра',
|
||||
one: 'Убрать фильтр',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => 'Страны';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => 'Ваши языки';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => 'Все страны';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => 'Не удалось загрузить страны.';
|
||||
|
||||
@override
|
||||
String get countrySpain => 'Испания';
|
||||
@@ -738,20 +738,20 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get qualityHd => 'HD-качество';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => 'Ваши станции';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => 'Смотреть все';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => 'Открыть полный плеер';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => 'Пока ничего не воспроизводится';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
'Выберите станцию из раздела «Ваши станции» или найдите её, чтобы начать.';
|
||||
|
||||
@override
|
||||
String get nearYou => 'Рядом с вами';
|
||||
@@ -884,13 +884,13 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get deleteTooltip => 'Удалить';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => 'Пропустить';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => 'Удалить будильник?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => 'Это действие нельзя отменить.';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar =>
|
||||
@@ -1049,41 +1049,41 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count периодов';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return 'Идёт сейчас · осталось $days дн.';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return 'Следующий период через $days дн.';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return 'Пауза: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return 'Продолжает звонить: $times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => 'ЗАПЛАНИРОВАНО';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => 'Прошедшие периоды';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => 'Добавить период';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
'Сейчас нет активного периода отпуска.';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => 'Отпуск';
|
||||
@@ -1374,10 +1374,10 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => 'Пауза';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => 'Изменить';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => 'Свой EQ';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1467,16 +1467,16 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
String get vacationIconLabel => 'Режим отпуска';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => 'Дополнительно';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => 'Час';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => 'Минута';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => 'Громкость нарастает';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1594,4 +1594,35 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => 'Выбранная папка';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => 'Ваш мир, в прямом эфире';
|
||||
|
||||
@override
|
||||
String get welcomeBody =>
|
||||
'53 412 станций из 238 стран. Сохраняйте любимые, берите их с собой в машину и просыпайтесь под них.';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => 'Эквалайзер для каждой станции';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle =>
|
||||
'А также пресет для каждого устройства вывода';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle =>
|
||||
'Ваши избранные и локальная музыка в машине';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => 'Музыкальные будильники';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle =>
|
||||
'С плавным нарастанием громкости и режимом отпуска';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => 'Начать слушать';
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get appTitle => 'PluriWave';
|
||||
|
||||
@override
|
||||
String get navHome => '首页';
|
||||
String get navHome => '收听';
|
||||
|
||||
@override
|
||||
String get navSearch => '搜索';
|
||||
@@ -98,19 +98,19 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get settingsSubtitle => '精细控制声音、备份和自定义电台。';
|
||||
|
||||
@override
|
||||
String get settingsGroupAudioTitle => 'AUDIO';
|
||||
String get settingsGroupAudioTitle => '音频';
|
||||
|
||||
@override
|
||||
String get settingsGroupStationsTitle => 'EMISORAS';
|
||||
String get settingsGroupStationsTitle => '电台';
|
||||
|
||||
@override
|
||||
String get settingsGroupRecordingsTitle => 'GRABACIONES Y MÚSICA';
|
||||
String get settingsGroupRecordingsTitle => '录音与音乐';
|
||||
|
||||
@override
|
||||
String get settingsGroupApplicationTitle => 'APLICACIÓN';
|
||||
String get settingsGroupApplicationTitle => '应用';
|
||||
|
||||
@override
|
||||
String get infoSectionTitle => 'Información';
|
||||
String get infoSectionTitle => '信息';
|
||||
|
||||
@override
|
||||
String get languageSectionTitle => '语言';
|
||||
@@ -218,40 +218,37 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get equalizerBaseExplainer =>
|
||||
'Este es el ecualizador base: se aplica a todas las emisoras que no tengan un ajuste propio. El de una emisora concreta se define desde su propia reproducción y manda sobre este.';
|
||||
'这是基础均衡器:适用于所有没有专属设置的电台。某个电台的专属EQ可在其自己的播放界面中设置,并优先于此设置生效。';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputLabel => 'Salida activa';
|
||||
String get equalizerActiveOutputLabel => '当前输出';
|
||||
|
||||
@override
|
||||
String get equalizerActiveOutputDefault => 'El altavoz de este dispositivo';
|
||||
String get equalizerActiveOutputDefault => '此设备的扬声器';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqTitle => 'Emisoras con ajuste propio';
|
||||
String get equalizerStationsWithOwnEqTitle => '拥有专属EQ的电台';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqSubtitle =>
|
||||
'Ignoran este ecualizador base';
|
||||
String get equalizerStationsWithOwnEqSubtitle => '忽略此基础均衡器';
|
||||
|
||||
@override
|
||||
String get equalizerStationsWithOwnEqEmpty =>
|
||||
'Ninguna emisora tiene ajuste propio todavía.';
|
||||
String get equalizerStationsWithOwnEqEmpty => '目前还没有电台设置专属EQ。';
|
||||
|
||||
@override
|
||||
String get equalizerSaveAsPresetAction => 'Guardar como preset';
|
||||
String get equalizerSaveAsPresetAction => '保存为预设';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetDialogTitle => 'Guardar como preset';
|
||||
String get equalizerSavePresetDialogTitle => '保存为预设';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetNameLabel => 'Nombre del preset';
|
||||
String get equalizerSavePresetNameLabel => '预设名称';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetEmptyNameError =>
|
||||
'Ingresá un nombre para el preset.';
|
||||
String get equalizerSavePresetEmptyNameError => '请输入预设名称。';
|
||||
|
||||
@override
|
||||
String get equalizerSavePresetConfirm => 'Guardar';
|
||||
String get equalizerSavePresetConfirm => '保存';
|
||||
|
||||
@override
|
||||
String get preferredStationTitle => '首选电台';
|
||||
@@ -422,47 +419,45 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryTitle => 'Mis grabaciones';
|
||||
String get recordingsLibraryTitle => '我的录音';
|
||||
|
||||
@override
|
||||
String recordingsLibraryStorageCaption(int usedMb, int totalMb) {
|
||||
return '$usedMb MB de $totalMb MB usados';
|
||||
return '已使用 $usedMb MB / 共 $totalMb MB';
|
||||
}
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptyTitle => 'Todavía no hay grabaciones';
|
||||
String get recordingsLibraryEmptyTitle => '暂无录音';
|
||||
|
||||
@override
|
||||
String get recordingsLibraryEmptySubtitle =>
|
||||
'Las grabaciones que guardes van a aparecer acá.';
|
||||
String get recordingsLibraryEmptySubtitle => '你保存的录音会显示在这里。';
|
||||
|
||||
@override
|
||||
String get recordingActionRename => 'Renombrar';
|
||||
String get recordingActionRename => '重命名';
|
||||
|
||||
@override
|
||||
String get recordingActionShare => 'Compartir';
|
||||
String get recordingActionShare => '分享';
|
||||
|
||||
@override
|
||||
String get recordingActionDelete => 'Eliminar';
|
||||
String get recordingActionDelete => '删除';
|
||||
|
||||
@override
|
||||
String get recordingRenameDialogTitle => 'Renombrar grabación';
|
||||
String get recordingRenameDialogTitle => '重命名录音';
|
||||
|
||||
@override
|
||||
String get recordingRenameLabel => 'Nombre';
|
||||
String get recordingRenameLabel => '名称';
|
||||
|
||||
@override
|
||||
String get recordingRenameEmptyError => 'Ingresá un nombre';
|
||||
String get recordingRenameEmptyError => '请输入名称';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmTitle => '¿Eliminar grabación?';
|
||||
String get recordingDeleteConfirmTitle => '删除录音?';
|
||||
|
||||
@override
|
||||
String get recordingDeleteConfirmMessage =>
|
||||
'Esta acción no se puede deshacer.';
|
||||
String get recordingDeleteConfirmMessage => '此操作无法撤销。';
|
||||
|
||||
@override
|
||||
String get recordingsLibrarySettingsTooltip => 'Ajustes de grabación';
|
||||
String get recordingsLibrarySettingsTooltip => '录音设置';
|
||||
|
||||
@override
|
||||
String get stationOrderTitle => '电台排序';
|
||||
@@ -474,7 +469,7 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get stationOrderByQuality => '按质量';
|
||||
|
||||
@override
|
||||
String get stationOrderByPopularity => 'Por popularidad';
|
||||
String get stationOrderByPopularity => '按热度';
|
||||
|
||||
@override
|
||||
String get stationOrderScopeDescription => '适用于收藏、搜索、附近电台和快捷列表。';
|
||||
@@ -557,7 +552,7 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoritesFilterAllLabel => 'Todas';
|
||||
String get favoritesFilterAllLabel => '全部';
|
||||
|
||||
@override
|
||||
String favoriteGroupsChipLabel(Object groupName, int count) {
|
||||
@@ -565,10 +560,10 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
}
|
||||
|
||||
@override
|
||||
String get favoriteGroupsManage => 'Gestionar listas';
|
||||
String get favoriteGroupsManage => '管理列表';
|
||||
|
||||
@override
|
||||
String get customStationsAddCta => 'Añadir emisora personalizada';
|
||||
String get customStationsAddCta => '添加自定义电台';
|
||||
|
||||
@override
|
||||
String get alarmPostponedCurrentExecution => '本次闹钟已推迟。';
|
||||
@@ -611,8 +606,7 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: '$count resultados',
|
||||
one: '1 resultado',
|
||||
other: '$count 个结果',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
@@ -622,23 +616,23 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String _temp0 = intl.Intl.pluralLogic(
|
||||
count,
|
||||
locale: localeName,
|
||||
other: 'Quitar los $count filtros',
|
||||
one: 'Quitar el filtro',
|
||||
other: '清除 $count 个筛选条件',
|
||||
one: '清除筛选条件',
|
||||
);
|
||||
return '$_temp0';
|
||||
}
|
||||
|
||||
@override
|
||||
String get countriesScreenTitle => 'Países';
|
||||
String get countriesScreenTitle => '国家';
|
||||
|
||||
@override
|
||||
String get countriesYourLanguagesTitle => 'Tus idiomas';
|
||||
String get countriesYourLanguagesTitle => '你的语言';
|
||||
|
||||
@override
|
||||
String get countriesAllTitle => 'Todos los países';
|
||||
String get countriesAllTitle => '所有国家';
|
||||
|
||||
@override
|
||||
String get radioCountriesError => 'No pudimos cargar los países.';
|
||||
String get radioCountriesError => '无法加载国家列表。';
|
||||
|
||||
@override
|
||||
String get countrySpain => '西班牙';
|
||||
@@ -712,20 +706,19 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get qualityHd => '高清音质';
|
||||
|
||||
@override
|
||||
String get yourStationsTitle => 'Tus emisoras';
|
||||
String get yourStationsTitle => '你的电台';
|
||||
|
||||
@override
|
||||
String get seeAllAction => 'Ver todas';
|
||||
String get seeAllAction => '查看全部';
|
||||
|
||||
@override
|
||||
String get openFullPlayerTooltip => 'Abrir reproductor completo';
|
||||
String get openFullPlayerTooltip => '打开完整播放器';
|
||||
|
||||
@override
|
||||
String get nothingPlayingTitle => 'Todavía no estás escuchando nada';
|
||||
String get nothingPlayingTitle => '目前没有正在播放的内容';
|
||||
|
||||
@override
|
||||
String get nothingPlayingSubtitle =>
|
||||
'Elegí una emisora de Tus emisoras o buscá una para empezar.';
|
||||
String get nothingPlayingSubtitle => '从“你的电台”中选择一个电台,或搜索一个开始收听。';
|
||||
|
||||
@override
|
||||
String get nearYou => '你附近';
|
||||
@@ -854,13 +847,13 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get deleteTooltip => '删除';
|
||||
|
||||
@override
|
||||
String get alarmHeroSkipAction => 'Saltar';
|
||||
String get alarmHeroSkipAction => '跳过';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmTitle => '¿Eliminar alarma?';
|
||||
String get alarmDeleteConfirmTitle => '删除闹钟?';
|
||||
|
||||
@override
|
||||
String get alarmDeleteConfirmMessage => 'Esta acción no se puede deshacer.';
|
||||
String get alarmDeleteConfirmMessage => '此操作无法撤销。';
|
||||
|
||||
@override
|
||||
String get alarmSkippedNoNextSnackbar => '已跳过闹钟。没有剩余的下次执行。';
|
||||
@@ -1014,41 +1007,40 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String vacationRangesCount(int count) {
|
||||
return '$count rangos';
|
||||
return '$count 个时间段';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryActiveCountdown(int days) {
|
||||
return 'En curso · quedan $days días';
|
||||
return '进行中 · 还剩 $days 天';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationSummaryUpcomingCountdown(int days) {
|
||||
return 'Próximo rango en $days días';
|
||||
return '下一个时间段在 $days 天后';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactPausedLabel(Object times) {
|
||||
return 'Pausa: $times';
|
||||
return '暂停:$times';
|
||||
}
|
||||
|
||||
@override
|
||||
String vacationImpactContinuesLabel(Object times) {
|
||||
return 'Sigue sonando: $times';
|
||||
return '仍会响铃:$times';
|
||||
}
|
||||
|
||||
@override
|
||||
String get vacationUpcomingSectionTitle => 'PROGRAMADOS';
|
||||
String get vacationUpcomingSectionTitle => '已安排';
|
||||
|
||||
@override
|
||||
String get vacationPastSectionTitle => 'Rangos pasados';
|
||||
String get vacationPastSectionTitle => '过往时间段';
|
||||
|
||||
@override
|
||||
String get addVacationRangeCta => 'Añadir rango';
|
||||
String get addVacationRangeCta => '添加时间段';
|
||||
|
||||
@override
|
||||
String get vacationNoActiveRangeHint =>
|
||||
'No hay un rango de vacaciones activo ahora mismo.';
|
||||
String get vacationNoActiveRangeHint => '目前没有正在生效的假期时间段。';
|
||||
|
||||
@override
|
||||
String get vacationsDefaultName => '假期';
|
||||
@@ -1325,10 +1317,10 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get pausePlaybackTooltip => '暂停播放';
|
||||
|
||||
@override
|
||||
String get playerQualityChangeAction => 'Cambiar';
|
||||
String get playerQualityChangeAction => '更改';
|
||||
|
||||
@override
|
||||
String get playerToolEqLabel => 'EQ propio';
|
||||
String get playerToolEqLabel => '专属EQ';
|
||||
|
||||
@override
|
||||
String qualityOriginal(Object quality) {
|
||||
@@ -1415,16 +1407,16 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
String get vacationIconLabel => '假期模式';
|
||||
|
||||
@override
|
||||
String get alarmAdvancedSectionTitle => 'Avanzado';
|
||||
String get alarmAdvancedSectionTitle => '高级';
|
||||
|
||||
@override
|
||||
String get alarmInlineHourLabel => 'Hora';
|
||||
String get alarmInlineHourLabel => '时';
|
||||
|
||||
@override
|
||||
String get alarmInlineMinuteLabel => 'Minuto';
|
||||
String get alarmInlineMinuteLabel => '分';
|
||||
|
||||
@override
|
||||
String get alarmVolumeRisingStatus => 'Subiendo volumen';
|
||||
String get alarmVolumeRisingStatus => '音量渐强中';
|
||||
|
||||
@override
|
||||
String get streamUrlHint => 'https://stream.example.com:8000/radio';
|
||||
@@ -1537,4 +1529,31 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get localMusicFolderGenericName => '已选文件夹';
|
||||
|
||||
@override
|
||||
String get welcomeHeadline => '你的世界,直播中';
|
||||
|
||||
@override
|
||||
String get welcomeBody => '来自238个国家的53,412个电台。保存你喜爱的电台,带上车,用它们唤醒你的每一天。';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Title => '分电台均衡器';
|
||||
|
||||
@override
|
||||
String get welcomeBullet1Subtitle => '还支持为每个输出设备设置独立预设';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Title => 'Android Auto';
|
||||
|
||||
@override
|
||||
String get welcomeBullet2Subtitle => '车内畅享你的收藏电台和本地音乐';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Title => '音乐闹钟';
|
||||
|
||||
@override
|
||||
String get welcomeBullet3Subtitle => '支持音量渐强唤醒和假期模式';
|
||||
|
||||
@override
|
||||
String get welcomeCtaLabel => '开始收听';
|
||||
}
|
||||
|
||||
@@ -12,12 +12,6 @@ import '../../widgets/pluri_push_scaffold.dart';
|
||||
/// verbatim from the former `_SeccionGrabaciones` in `pantalla_ajustes.dart`
|
||||
/// — only the panel header's icon and title were removed (the pushed
|
||||
/// screen's title now carries them); every method below is unchanged.
|
||||
///
|
||||
/// Known pre-existing bug, deliberately NOT fixed here (out of scope, moved
|
||||
/// verbatim, tracked separately): [_editarTamanoMaximo] disposes its
|
||||
/// [TextEditingController] immediately after `showModalBottomSheet` resolves,
|
||||
/// racing the sheet's own close animation — the same shape of bug already
|
||||
/// documented for `_editarGrupo` in `pantalla_ajustes_grupos_favoritos.dart`.
|
||||
class PantallaAjustesGrabaciones extends StatelessWidget {
|
||||
const PantallaAjustesGrabaciones({super.key});
|
||||
|
||||
@@ -92,53 +86,16 @@ class _CuerpoGrabaciones extends StatelessWidget {
|
||||
|
||||
Future<void> _editarTamanoMaximo(BuildContext context) async {
|
||||
final estado = context.read<EstadoGrabacion>();
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final actualMb = _bytesAMegabytes(estado.maxBytes);
|
||||
final controller = TextEditingController(text: actualMb.toString());
|
||||
|
||||
final nuevoMb = await showModalBottomSheet<int>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
showDragHandle: true,
|
||||
builder: (ctx) {
|
||||
final bottom = MediaQuery.viewInsetsOf(ctx).bottom;
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, 0, 20, bottom + 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
l10n.recordingsMaxSizeDialogTitle,
|
||||
style: Theme.of(ctx).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.recordingsMaxSizeMbLabel,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton.icon(
|
||||
onPressed: () {
|
||||
final value = int.tryParse(controller.text.trim());
|
||||
if (value == null || value <= 0) return;
|
||||
Navigator.of(ctx).pop(value);
|
||||
},
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
label: Text(l10n.saveQuickAccessButton),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
builder: (ctx) => _HojaTamanoMaximo(actualMb: actualMb),
|
||||
);
|
||||
controller.dispose();
|
||||
if (nuevoMb == null || !context.mounted) return;
|
||||
final l10n = AppLocalizations.of(context);
|
||||
await estado.cambiarMaxBytes(nuevoMb * 1024 * 1024);
|
||||
if (!context.mounted) return;
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
@@ -215,3 +172,74 @@ class _CuerpoGrabaciones extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The "maximum recording size" bottom sheet's own content, as a
|
||||
/// `StatefulWidget` so its `TextEditingController` is owned by the SHEET's
|
||||
/// `State`, not by the caller's `async` function — same bugfix shape as
|
||||
/// `_HojaEditarGrupo` in `pantalla_ajustes_grupos_favoritos.dart` (a
|
||||
/// controller disposed immediately after `showModalBottomSheet` resolves
|
||||
/// races the sheet's own close animation, which still holds a bound
|
||||
/// `TextField` for a couple more frames). Flutter only calls
|
||||
/// `State.dispose()` once this widget is actually removed from the tree,
|
||||
/// i.e. after the close animation finishes.
|
||||
class _HojaTamanoMaximo extends StatefulWidget {
|
||||
const _HojaTamanoMaximo({required this.actualMb});
|
||||
|
||||
final int actualMb;
|
||||
|
||||
@override
|
||||
State<_HojaTamanoMaximo> createState() => _HojaTamanoMaximoState();
|
||||
}
|
||||
|
||||
class _HojaTamanoMaximoState extends State<_HojaTamanoMaximo> {
|
||||
late final TextEditingController _controller = TextEditingController(
|
||||
text: widget.actualMb.toString(),
|
||||
);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _guardar() {
|
||||
final value = int.tryParse(_controller.text.trim());
|
||||
if (value == null || value <= 0) return;
|
||||
Navigator.of(context).pop(value);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final bottom = MediaQuery.viewInsetsOf(context).bottom;
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, 0, 20, bottom + 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
l10n.recordingsMaxSizeDialogTitle,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: _controller,
|
||||
autofocus: true,
|
||||
keyboardType: TextInputType.number,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.recordingsMaxSizeMbLabel,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
FilledButton.icon(
|
||||
onPressed: _guardar,
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
label: Text(l10n.saveQuickAccessButton),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,54 +34,14 @@ class _CuerpoGruposFavoritos extends StatelessWidget {
|
||||
BuildContext context, [
|
||||
GrupoFavoritos? grupo,
|
||||
]) async {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final controller = TextEditingController(text: grupo?.nombre ?? '');
|
||||
final nombre = await showModalBottomSheet<String>(
|
||||
context: context,
|
||||
isScrollControlled: true,
|
||||
showDragHandle: true,
|
||||
builder: (ctx) {
|
||||
final bottom = MediaQuery.viewInsetsOf(ctx).bottom;
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, 0, 20, bottom + 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
grupo == null
|
||||
? l10n.favoriteGroupsAdd
|
||||
: l10n.favoriteGroupsEdit,
|
||||
style: Theme.of(ctx).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: controller,
|
||||
autofocus: true,
|
||||
maxLength: 28,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.favoriteGroupsNameLabel,
|
||||
helperText: l10n.favoriteGroupsNameTooLong,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
FilledButton.icon(
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
label: Text(AppLocalizations.of(ctx).saveQuickAccessButton),
|
||||
onPressed: () {
|
||||
final value = controller.text.trim();
|
||||
if (value.isEmpty || value.length > 28) return;
|
||||
Navigator.pop(ctx, value);
|
||||
},
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
builder: (ctx) => _HojaEditarGrupo(grupo: grupo),
|
||||
);
|
||||
controller.dispose();
|
||||
if (nombre == null || !context.mounted) return;
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final estado = context.read<EstadoRadio>();
|
||||
if (grupo == null) {
|
||||
await estado.crearGrupoFavoritos(nombre);
|
||||
@@ -172,3 +132,77 @@ class _CuerpoGruposFavoritos extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/// The add/rename bottom sheet's own content, as a `StatefulWidget` so its
|
||||
/// `TextEditingController` is owned by the SHEET's `State`, not by the
|
||||
/// caller's `async` function (bugfix: a `TextEditingController` disposed
|
||||
/// immediately after `showModalBottomSheet` resolves races the sheet's own
|
||||
/// close animation, which still holds a `TextField` bound to that controller
|
||||
/// for a couple more frames — "A TextEditingController was used after being
|
||||
/// disposed"). Flutter only calls `State.dispose()` once this widget is
|
||||
/// actually removed from the tree, i.e. after the close animation finishes,
|
||||
/// so there is no dispose-timing decision left for the caller to get wrong.
|
||||
class _HojaEditarGrupo extends StatefulWidget {
|
||||
const _HojaEditarGrupo({required this.grupo});
|
||||
|
||||
final GrupoFavoritos? grupo;
|
||||
|
||||
@override
|
||||
State<_HojaEditarGrupo> createState() => _HojaEditarGrupoState();
|
||||
}
|
||||
|
||||
class _HojaEditarGrupoState extends State<_HojaEditarGrupo> {
|
||||
late final TextEditingController _controller = TextEditingController(
|
||||
text: widget.grupo?.nombre ?? '',
|
||||
);
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void _guardar() {
|
||||
final value = _controller.text.trim();
|
||||
if (value.isEmpty || value.length > 28) return;
|
||||
Navigator.pop(context, value);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final bottom = MediaQuery.viewInsetsOf(context).bottom;
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(20, 0, 20, bottom + 24),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
widget.grupo == null
|
||||
? l10n.favoriteGroupsAdd
|
||||
: l10n.favoriteGroupsEdit,
|
||||
style: Theme.of(context).textTheme.titleLarge,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
TextField(
|
||||
controller: _controller,
|
||||
autofocus: true,
|
||||
maxLength: 28,
|
||||
decoration: InputDecoration(
|
||||
labelText: l10n.favoriteGroupsNameLabel,
|
||||
helperText: l10n.favoriteGroupsNameTooLong,
|
||||
border: const OutlineInputBorder(),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
FilledButton.icon(
|
||||
icon: const Icon(Icons.save_rounded),
|
||||
label: Text(l10n.saveQuickAccessButton),
|
||||
onPressed: _guardar,
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import '../estado/estado_navegacion.dart';
|
||||
import '../l10n/gen/app_localizations.dart';
|
||||
import '../servicios/servicio_bienvenida.dart';
|
||||
import '../tema/pluriwave_theme.dart';
|
||||
|
||||
/// WU17: first-run welcome surface (`onboarding-welcome` spec, mockup
|
||||
/// screen 14) rebuilt WITHOUT its monetization content — no "PRO" pill, no
|
||||
/// "14 días" trial line, no pricing card, and no secondary "free version"
|
||||
/// link (binding no-monetization requirement). Content only: logo,
|
||||
/// headline, body copy, exactly 3 feature bullets, and the single
|
||||
/// "Empezar a escuchar" CTA.
|
||||
///
|
||||
/// A full-screen ROUTE, not a modal `Dialog` — deliberately distinct from
|
||||
/// the pre-existing `PluriOnboardingDialog` (an unrelated "what's new"
|
||||
/// help-content modal already shown from `app.dart`'s launch flow). Both
|
||||
/// surfaces coexist: [mostrarSiProcede] (WU17b) is what actually wires this
|
||||
/// screen into the genuine first-launch flow, called from `app.dart` BEFORE
|
||||
/// `PluriOnboardingDialog.mostrarSiProcede` on every cold start, so the two
|
||||
/// never race — the once-ever welcome resolves first, then the recurring
|
||||
/// what's-new dialog runs its own unrelated per-version check exactly as
|
||||
/// before.
|
||||
class PantallaBienvenida extends StatelessWidget {
|
||||
const PantallaBienvenida({super.key});
|
||||
|
||||
static final ServicioBienvenida _servicio = ServicioBienvenida();
|
||||
|
||||
/// WU17b: shows this screen once, on the genuine first launch, then never
|
||||
/// again. Mirrors `PluriOnboardingDialog.mostrarSiProcede`'s shape
|
||||
/// (check-then-show-then-mark-seen) so both first-launch surfaces share
|
||||
/// the same call convention from `app.dart`.
|
||||
static Future<void> mostrarSiProcede(BuildContext context) async {
|
||||
if (!await _servicio.debeMostrarBienvenida()) return;
|
||||
if (!context.mounted) return;
|
||||
await Navigator.of(
|
||||
context,
|
||||
).push(MaterialPageRoute<void>(builder: (_) => const PantallaBienvenida()));
|
||||
await _servicio.marcarBienvenidaVista();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final l10n = AppLocalizations.of(context);
|
||||
final t = context.pluriTokens;
|
||||
final theme = Theme.of(context);
|
||||
|
||||
return Scaffold(
|
||||
body: SafeArea(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.fromLTRB(24, 48, 24, 28),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.stretch,
|
||||
children: [
|
||||
Image.asset(
|
||||
'assets/icons/pluriwave_app_mark.png',
|
||||
width: 76,
|
||||
height: 76,
|
||||
errorBuilder:
|
||||
(_, __, ___) => Icon(
|
||||
Icons.graphic_eq_rounded,
|
||||
size: 76,
|
||||
color: t.electricMagenta,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 22),
|
||||
Text(
|
||||
l10n.welcomeHeadline,
|
||||
style: theme.textTheme.headlineMedium?.copyWith(
|
||||
fontWeight: FontWeight.w800,
|
||||
height: 1.05,
|
||||
letterSpacing: -1.0,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 12),
|
||||
Text(
|
||||
l10n.welcomeBody,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
color: theme.colorScheme.onSurface.withValues(alpha: 0.72),
|
||||
height: 1.5,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 28),
|
||||
FilaCaracteristicaBienvenida(
|
||||
icon: Icons.equalizer_rounded,
|
||||
iconColor: t.electricMagenta,
|
||||
titulo: l10n.welcomeBullet1Title,
|
||||
subtitulo: l10n.welcomeBullet1Subtitle,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
FilaCaracteristicaBienvenida(
|
||||
icon: Icons.directions_car_rounded,
|
||||
iconColor: t.liveGreen,
|
||||
titulo: l10n.welcomeBullet2Title,
|
||||
subtitulo: l10n.welcomeBullet2Subtitle,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
FilaCaracteristicaBienvenida(
|
||||
icon: Icons.alarm_rounded,
|
||||
iconColor: t.warmCoral,
|
||||
titulo: l10n.welcomeBullet3Title,
|
||||
subtitulo: l10n.welcomeBullet3Subtitle,
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
SizedBox(
|
||||
height: 58,
|
||||
child: FilledButton(
|
||||
onPressed: () => _empezar(context),
|
||||
child: Text(
|
||||
l10n.welcomeCtaLabel,
|
||||
style: const TextStyle(
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _empezar(BuildContext context) {
|
||||
context.read<EstadoNavegacionRaiz>().irA(RaizPluriWave.escuchar);
|
||||
Navigator.of(context).pop();
|
||||
}
|
||||
}
|
||||
|
||||
/// One icon-badge + title/subtitle row. Public (not `_FilaCaracteristica`)
|
||||
/// so the structural "exactly 3 feature bullets" guard in
|
||||
/// `pantalla_bienvenida_test.dart` can target it via `find.byType` — the
|
||||
/// same reason WU4 made `FormularioEmisoraPersonalizada` public.
|
||||
class FilaCaracteristicaBienvenida extends StatelessWidget {
|
||||
const FilaCaracteristicaBienvenida({
|
||||
super.key,
|
||||
required this.icon,
|
||||
required this.iconColor,
|
||||
required this.titulo,
|
||||
required this.subtitulo,
|
||||
});
|
||||
|
||||
final IconData icon;
|
||||
final Color iconColor;
|
||||
final String titulo;
|
||||
final String subtitulo;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final theme = Theme.of(context);
|
||||
return Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
width: 38,
|
||||
height: 38,
|
||||
decoration: BoxDecoration(
|
||||
color: iconColor.withValues(alpha: 0.16),
|
||||
borderRadius: BorderRadius.circular(11),
|
||||
),
|
||||
child: Icon(icon, size: 20, color: iconColor),
|
||||
),
|
||||
const SizedBox(width: 13),
|
||||
Expanded(
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
titulo,
|
||||
style: theme.textTheme.bodyMedium?.copyWith(
|
||||
fontWeight: FontWeight.w800,
|
||||
),
|
||||
),
|
||||
Text(
|
||||
subtitulo,
|
||||
style: theme.textTheme.bodySmall?.copyWith(
|
||||
color: theme.colorScheme.onSurface.withValues(alpha: 0.58),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// WU17b: persists whether the first-run welcome screen (`PantallaBienvenida`,
|
||||
/// `onboarding-welcome` spec) has already been shown, so it renders once
|
||||
/// rather than on every launch.
|
||||
///
|
||||
/// Same injectable-`SharedPreferences`, versioned-key convention as
|
||||
/// `ServicioContenidoApp` (S3-R4) — but a plain one-time boolean flag, since
|
||||
/// this welcome screen is a single first-impression surface, not something
|
||||
/// that re-triggers per app version the way the "what's new" onboarding
|
||||
/// dialog does.
|
||||
class ServicioBienvenida {
|
||||
ServicioBienvenida({SharedPreferences? prefs}) : _prefs = prefs;
|
||||
|
||||
static const _keyBienvenidaVista = 'pluri_bienvenida_vista_v1';
|
||||
|
||||
final SharedPreferences? _prefs;
|
||||
|
||||
/// Injected startup instance (S3-R4); getInstance() is only a fallback.
|
||||
Future<SharedPreferences> _resolverPrefs() async =>
|
||||
_prefs ?? SharedPreferences.getInstance();
|
||||
|
||||
Future<bool> debeMostrarBienvenida() async {
|
||||
final prefs = await _resolverPrefs();
|
||||
return !(prefs.getBool(_keyBienvenidaVista) ?? false);
|
||||
}
|
||||
|
||||
Future<void> marcarBienvenidaVista() async {
|
||||
final prefs = await _resolverPrefs();
|
||||
await prefs.setBool(_keyBienvenidaVista, true);
|
||||
}
|
||||
}
|
||||
@@ -129,20 +129,31 @@ class _MiniReproductorState extends State<MiniReproductor> {
|
||||
EstadoReproduccion.detenido;
|
||||
final activo =
|
||||
s == EstadoReproduccion.reproduciendo;
|
||||
// WU16: reconectando/error are
|
||||
// "connectivity trouble" states —
|
||||
// tinted with offlineAccent so they
|
||||
// read as visually distinct from
|
||||
// ordinary loading/paused/stopped.
|
||||
final conexionEnProblema =
|
||||
s ==
|
||||
EstadoReproduccion.reconectando ||
|
||||
s == EstadoReproduccion.error;
|
||||
return Text(
|
||||
_labelEstado(l10n, s),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.bodySmall?.copyWith(
|
||||
color:
|
||||
activo
|
||||
conexionEnProblema
|
||||
? t.offlineAccent
|
||||
: activo
|
||||
? t.warmCoral
|
||||
: Theme.of(context)
|
||||
.colorScheme
|
||||
.onSurface
|
||||
.withValues(alpha: 0.7),
|
||||
fontWeight:
|
||||
activo
|
||||
(activo || conexionEnProblema)
|
||||
? FontWeight.w600
|
||||
: FontWeight.w400,
|
||||
),
|
||||
@@ -173,12 +184,20 @@ class _MiniReproductorState extends State<MiniReproductor> {
|
||||
// cargando (spinner), never as the error/retry affordance.
|
||||
if (s == EstadoReproduccion.cargando ||
|
||||
s == EstadoReproduccion.reconectando) {
|
||||
return const SizedBox(
|
||||
// WU16: only the reconectando sub-state gets the offline
|
||||
// accent — plain cargando (e.g. the very first play)
|
||||
// keeps the default spinner colour, since it is not a
|
||||
// connectivity problem.
|
||||
final reconectando = s == EstadoReproduccion.reconectando;
|
||||
return SizedBox(
|
||||
width: 48,
|
||||
height: 48,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.all(12),
|
||||
child: CircularProgressIndicator(strokeWidth: 2),
|
||||
padding: const EdgeInsets.all(12),
|
||||
child: CircularProgressIndicator(
|
||||
strokeWidth: 2,
|
||||
color: reconectando ? t.offlineAccent : null,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -187,7 +206,7 @@ class _MiniReproductorState extends State<MiniReproductor> {
|
||||
final emisoraActual = estado.emisoraActual;
|
||||
return IconButton(
|
||||
tooltip: l10n.retryAction,
|
||||
icon: const Icon(Icons.refresh_rounded),
|
||||
icon: Icon(Icons.refresh_rounded, color: t.offlineAccent),
|
||||
onPressed:
|
||||
emisoraActual != null
|
||||
? () => estado.reproducir(emisoraActual)
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
> **WU15b was added mid-apply, not planned upfront** — WU15 shipped `PantallaGrabaciones` (the recordings library)
|
||||
> fully tested but reachable from nowhere in the app. WU15b (below, after WU15's section) is the coordinator-ruled fix
|
||||
> that wires it into Settings navigation. It is small and does not change the 18-commit delivery model's shape.
|
||||
> **WU17b was added mid-apply, not planned upfront — same shape as WU15b.** WU17 shipped `PantallaBienvenida` (the
|
||||
> welcome screen) fully tested but reachable from nowhere in the app (`rg "PantallaBienvenida" lib/app.dart lib/main.dart`
|
||||
> found nothing). WU17b (below, after WU17's section) wires it into the genuine first-launch flow and establishes how
|
||||
> it coexists with the pre-existing, unrelated `PluriOnboardingDialog` ("what's new" modal). It is small and does not
|
||||
> change the 18-commit delivery model's shape.
|
||||
> Strict TDD is ON. Runner: `flutter test`. `flutter analyze` and a **scoped** `dart format` gate every commit.
|
||||
> **`flutter build` is never run.**
|
||||
>
|
||||
@@ -56,8 +61,8 @@
|
||||
| 15 | `feat(grabaciones): add recordings library screen` | 3b | ~~300-400~~ → **REALIZED: 1,767** (1,767+ / 0-, 22 files) | Medium | Monitor§ |
|
||||
| 15b | `fix(grabaciones): wire the recordings library into Settings navigation` | 15 | 60-100 | Low | No |
|
||||
| 16 | `feat(connectivity): restyle offline and reconnect banners` | 1 | 150-250 | Low | No |
|
||||
| 17 | `feat(bienvenida): add monetization-free welcome screen` | 1 | 150-200 | Low | No |
|
||||
| 18 | `feat(i18n): add redesign strings and translate Escuchar rename to 11 locales` | all | ~0 eng. / 400-600 data | Medium (data volume, low logic risk) | No |
|
||||
| 17 | `feat(bienvenida): add monetization-free welcome screen` | 1 | ~~150-200~~ → **REALIZED: 361** (screen + test, 313 / ARB 22 / docs 48) — see the WU15-precedent note below | Low | No — same reasoning as WU15§ |
|
||||
| 18 | `feat(i18n): add redesign strings and translate Escuchar rename to 11 locales` | all | ~~~0 eng. / 400-600 data~~ → **REALIZED: ~3,622** (2,714+ / 908-, 26 files: 11 ARB + 11 regenerated `gen/*.dart` + 4 new `test/l10n/*.dart` + this docs update) | Medium (data volume, low logic risk) | No — same estimating-lesson pattern as WU3a/WU7/WU15§, not a design risk |
|
||||
|
||||
\* **Re-derived after WU3a landed.** The original 500-700 figure was scaled pro-rata from WU3a's *estimate*, which
|
||||
turned out to be wrong by roughly 4x — so the old WU3b number inherited the same error and has been replaced.
|
||||
@@ -85,6 +90,11 @@ unlike WU3a/WU3b's move-only reuse), or (c) the new `servicio_grabacion_radio.da
|
||||
group. Realized 1,767 changed lines / 22 files, all additions (no deletions — nothing pre-existing was touched
|
||||
beyond the 3 new `ServicioGrabacionRadio`/`EstadoGrabacion` methods). Not recorded as `size:exception` since the
|
||||
commit is still a single, cleanly-scoped deliverable (one new screen, its one dependency, no split candidate).
|
||||
**WU17 hit the identical pattern**: 150-200 covered only the screen itself; realized 361 lines across the screen
|
||||
(169) + its test (144) + 9 new ARB keys × 2 locales (22) + this docs update (48), PLUS 13 regenerated
|
||||
`lib/l10n/gen/*.dart` files (~430 more lines, untouched by hand) for a raw `git diff --stat` total of 814. Same
|
||||
ruling: not `size:exception` — one new, cleanly-scoped screen with no split candidate, all-additions except the ARB
|
||||
files (which gain lines, not churn).
|
||||
|
||||
```text
|
||||
Decision needed before apply: No
|
||||
@@ -119,15 +129,19 @@ the proposal's narrative and dependency table.
|
||||
|
||||
## Non-Negotiable Guards (master checklist — verify before the branch is considered done)
|
||||
|
||||
- [ ] `test/pantallas/pantalla_alarma_sonando_dismiss_guard_test.dart` passes **unmodified** (touched by WU9, WU11 — if
|
||||
a restyle appears to require editing it, STOP and escalate; do not edit the test).
|
||||
- [ ] `git diff` is **empty** for `lib/servicios/navegacion_auto.dart` (WU2), `lib/servicios/servicio_ecualizador.dart`
|
||||
(WU13), and the band-application block at `lib/servicios/servicio_audio.dart:749-762` (WU13).
|
||||
- [ ] The equalizer renders exactly **5** sliders (WU13, task 13.1).
|
||||
- [ ] No shipped string contains "PRO", a trial duration, or a price (WU17 task 17.2/17.6; WU18 task 18.6 final
|
||||
whole-app grep).
|
||||
- [ ] All 13 ARB files keep identical key sets (WU18 tasks 18.1, 18.5 — final parity check; WU1 only touches values
|
||||
in 2 of the 13 files, so it cannot break parity on its own).
|
||||
- [x] `test/pantallas/pantalla_alarma_sonando_dismiss_guard_test.dart` passes **unmodified** (touched by WU9, WU11 — if
|
||||
a restyle appears to require editing it, STOP and escalate; do not edit the test). Re-confirmed in isolation
|
||||
after WU18: 13/13 green, file diff empty vs `main`.
|
||||
- [x] `git diff` is **empty** for `lib/servicios/navegacion_auto.dart` (WU2), `lib/servicios/servicio_ecualizador.dart`
|
||||
(WU13), and the band-application block at `lib/servicios/servicio_audio.dart:749-762` (WU13). Re-confirmed
|
||||
after WU18 (plus `lib/modelos/preset_ecualizador.dart` and the 3 other guarded test files — all 8 empty).
|
||||
- [x] The equalizer renders exactly **5** sliders (WU13, task 13.1). Re-confirmed after WU18.
|
||||
- [x] No shipped string contains "PRO", a trial duration, or a price (WU17 task 17.2/17.6; WU18 task 18.6 final
|
||||
whole-app grep). Final ARB-only grep (18.6): zero hits for `\bPRO\b`, €, $, gratis/gratuit/"free version", or
|
||||
a day-count trial phrase in any of the 13 `app_*.arb` files.
|
||||
- [x] All 13 ARB files keep identical key sets (WU18 tasks 18.1, 18.5 — final parity check; WU1 only touches values
|
||||
in 2 of the 13 files, so it cannot break parity on its own). Confirmed: 466 real keys in every one of the 13
|
||||
files, zero missing, zero extra.
|
||||
|
||||
---
|
||||
|
||||
@@ -971,7 +985,7 @@ real capability living in the header, not decorative chrome).
|
||||
- [x] 15b.6 Verify — scoped suite green: 605/605 (up from 604), 2 skipped (unchanged, both pre-existing WU15
|
||||
documented skips). `flutter analyze`: 1 issue, identical to baseline. Literal-encoding scan: zero hits.
|
||||
|
||||
|
||||
## WU16 — Connectivity banner restyle (offline / reconnect)
|
||||
|
||||
**Commit**: `feat(connectivity): restyle offline and reconnect banners`
|
||||
**Depends on**: WU1
|
||||
@@ -979,16 +993,31 @@ real capability living in the header, not decorative chrome).
|
||||
**Verify**: `flutter test test/widgets/reconnect_ui_test.dart test/servicios/servicio_audio_reconnect_test.dart && flutter analyze && dart format --set-exit-if-changed $(git diff --name-only --diff-filter=ACM HEAD -- '*.dart')`
|
||||
**Modified tests**: `reconnect_ui_test.dart`. `servicio_audio_reconnect_test.dart` must pass unmodified.
|
||||
|
||||
- [ ] 16.1 Verify-first — run `servicio_audio_reconnect_test.dart` and inspect the reconnect controller: confirm
|
||||
whether it tracks an attempt count.
|
||||
- [ ] 16.2 RED — restyle test for the offline banner (visual only) and, **only if 16.1 confirms an attempt count
|
||||
exists**, a test for the "Reconectando · intento N de M" label.
|
||||
- [ ] 16.3 GREEN — restyle the offline banner to the new visual language.
|
||||
- [ ] 16.4 GREEN — **conditionally**: wire the attempt-count label only if the controller exposes one; otherwise
|
||||
ship the restyle without the counter — do not add new plumbing to invent one.
|
||||
- [ ] 16.5 REFACTOR — confirm shimmer skeletons (`TarjetaEmisoraShimmer`) are unchanged.
|
||||
- [ ] 16.6 Verify — `reconnect_ui_test.dart` updated and green; `servicio_audio_reconnect_test.dart` unmodified and
|
||||
green.
|
||||
- [x] 16.1 Verify-first — run `servicio_audio_reconnect_test.dart` and inspect the reconnect controller: confirm
|
||||
whether it tracks an attempt count. **Result: it does NOT reach the UI.** `ControladorReconexion.intentos`
|
||||
exists as a getter, but `ServicioAudio` (`lib/servicios/servicio_audio.dart`) only ever reads it inside a
|
||||
`developer.log` debug line (line 413) — its public `estadoStream` maps every playback state to the
|
||||
`EstadoReproduccion` enum (no attempt-count payload) and `_handler.reconectando` is a bare bool. Wiring a
|
||||
count to the UI would require adding a getter/stream to `servicio_audio.dart`, which is one of the four
|
||||
files this change must keep at an **empty git diff vs `main`** — structurally blocked, not just untested.
|
||||
Shipping without the counter per 16.4, exactly as the risk register anticipated.
|
||||
- [x] 16.2 RED — 3 new `testWidgets` cases added to `reconnect_ui_test.dart` (no attempt-count test, per 16.1):
|
||||
reconnecting tints the spinner + status label with `offlineAccent`; plain `cargando` keeps the default
|
||||
spinner colour (regression guard proving the tint is reconnect-specific, not blanket-loading); error tints
|
||||
the retry icon + status label with `offlineAccent`. Confirmed RED: 2 of the 3 failed (`Actual: <null>`)
|
||||
against the pre-restyle widget.
|
||||
- [x] 16.3 GREEN — `lib/widgets/mini_reproductor.dart`: the status-label `Text` and the reconnect spinner /
|
||||
error retry icon now read `context.pluriTokens.offlineAccent` (WU1's previously-unused token, whose own
|
||||
doc comment already named it for this WU) whenever the stream reports `reconectando` or `error`. Plain
|
||||
`cargando` explicitly keeps `color: null` (the theme default) — verified by 16.2's regression test.
|
||||
- [x] 16.4 GREEN — conditional step confirmed moot: no attempt-count label added, no new plumbing introduced.
|
||||
- [x] 16.5 REFACTOR — `TarjetaEmisoraShimmer` (`lib/widgets/tarjeta_emisora.dart`, consumed by
|
||||
`pantalla_buscar.dart`) is untouched by this commit — confirmed via `git diff --stat`, zero lines.
|
||||
- [x] 16.6 Verify — scoped suite green: 16/16 (5 `reconnect_ui_test.dart` + 8 `servicio_audio_reconnect_test.dart`
|
||||
[byte-identical, unmodified] + 3 `mini_reproductor_configurar_test.dart` re-run as an adjacent-file
|
||||
regression check). `flutter analyze`: 1 issue, identical to baseline. Scoped `dart format`: reformatted the
|
||||
hand-written production file once (whitespace only), stable on re-run. Literal-encoding scan: zero hits on
|
||||
the 2 touched files.
|
||||
|
||||
## WU17 — Welcome / onboarding screen
|
||||
|
||||
@@ -998,19 +1027,100 @@ real capability living in the header, not decorative chrome).
|
||||
**Verify**: `flutter test test/pantallas/pantalla_bienvenida_test.dart && flutter analyze && dart format --set-exit-if-changed $(git diff --name-only --diff-filter=ACM HEAD -- '*.dart')`
|
||||
**New tests**: `pantalla_bienvenida_test.dart`
|
||||
|
||||
- [ ] 17.1 RED — the welcome screen renders as a full-screen route (not a modal `Dialog`) with a logo, headline,
|
||||
body copy, exactly 3 feature bullets, and exactly 1 primary CTA.
|
||||
- [ ] 17.2 RED — binding no-monetization guard: scan the rendered widget tree's text content and assert it contains
|
||||
- [x] 17.1 RED — the welcome screen renders as a full-screen route (not a modal `Dialog`) with a logo, headline,
|
||||
body copy, exactly 3 feature bullets, and exactly 1 primary CTA. **Discovered at apply time**: a pre-existing,
|
||||
UNRELATED `PluriOnboardingDialog` (a "what's new"/help-content modal loaded from markdown assets, shown from
|
||||
`app.dart`'s launch flow) already exists — it is NOT the mockup's welcome screen and is not touched or
|
||||
replaced by this WU.
|
||||
- [x] 17.2 RED — binding no-monetization guard: scan the rendered widget tree's text content and assert it contains
|
||||
none of: the substring "PRO", a currency amount, or a day-count trial phrase; no secondary "free version"
|
||||
link.
|
||||
- [ ] 17.3 RED — tapping "Empezar a escuchar" lands on the Escuchar tab (index 0) with the welcome route removed
|
||||
from the back stack.
|
||||
- [ ] 17.4 GREEN — build `lib/pantallas/pantalla_bienvenida.dart` as a full-screen route; content only (logo /
|
||||
headline / body / 3 bullets / 1 CTA) — no PRO pill, no trial duration, no price, no secondary link.
|
||||
- [ ] 17.5 GREEN — wire the CTA to dismiss-and-navigate to Escuchar with the route removed.
|
||||
- [ ] 17.6 REFACTOR — grep `lib/l10n/app_*.arb` for "PRO"/price/day-count trial strings introduced by this WU;
|
||||
confirm none exist.
|
||||
- [ ] 17.7 Verify — all 3 scenario tests green; grep scan clean.
|
||||
- [x] 17.3 RED — tapping "Empezar a escuchar" lands on the Escuchar tab (index 0) with the welcome route removed
|
||||
from the back stack. Test starts `EstadoNavegacionRaiz` on a DIFFERENT tab first so a pass actually proves
|
||||
`irA()` ran, not just that escuchar was already the default.
|
||||
- [x] 17.4 GREEN — built `lib/pantallas/pantalla_bienvenida.dart` as a full-screen route (bare `Scaffold`, no
|
||||
`PluriPushScaffold` — this is an entry screen with no back affordance, not a second-level pushed screen);
|
||||
content only (logo / headline / body / 3 bullets / 1 CTA) — no PRO pill, no trial duration, no price, no
|
||||
secondary link. Content is the mockup's screen 14 copy verbatim MINUS its entire monetization block (the "14
|
||||
días PRO gratis / luego 2,99 €/año" pricing card and the "Seguir con la versión gratuita" link), Spanish
|
||||
re-cast to the app's established voseo register (the raw mockup HTML uses "tú" form; the other ~750 lines of
|
||||
`app_es.arb` consistently use voseo — e.g. "Elegí", "Guardá", "querés" — matched that instead of copying the
|
||||
mockup's grammar verbatim) and "auto" instead of the mockup's "coche" (matching the one existing precedent at
|
||||
`localMusicSectionDescription`). The 3 bullet icon colours reuse existing named tokens
|
||||
(`electricMagenta`/`liveGreen`/`warmCoral`) that happen to be the exact hex values the mockup already used for
|
||||
those 3 icons — no new raw `Color(0x...)` literal introduced. `SingleChildScrollView` used instead of a
|
||||
`Column` + `Spacer()` (the exact overflow hazard WU14 already hit and fixed) since this screen carries
|
||||
meaningfully more content than a typical card. 9 new ARB keys, en/es only (`welcomeHeadline`, `welcomeBody`,
|
||||
`welcomeBullet{1,2,3}{Title,Subtitle}`, `welcomeCtaLabel`).
|
||||
- [x] 17.5 GREEN — CTA wired to `context.read<EstadoNavegacionRaiz>().irA(RaizPluriWave.escuchar)` then
|
||||
`Navigator.of(context).pop()`. **Scope note**: this WU's own verify command and task list only cover
|
||||
`pantalla_bienvenida_test.dart` — wiring the screen into the REAL first-launch flow (i.e. `app.dart`/
|
||||
`main.dart` deciding *when* to push it, analogous to `ServicioContenidoApp.debeMostrarInicio()`'s pattern for
|
||||
`PluriOnboardingDialog`) is NOT part of WU17 as scoped and was deliberately not added here to avoid inventing
|
||||
untested persistence/launch semantics. Flagged as a likely WU17b gap (same shape as WU15/WU15b).
|
||||
- [x] 17.6 REFACTOR — whole-repo grep confirmed clean: `\bPRO\b` (word-boundary) has exactly one hit in all of
|
||||
`lib/` — this WU's own doc comment describing the guard (never rendered). The unqualified substring "PRO"
|
||||
also matches pre-existing, unrelated `"PROGRAMADOS"` (vacation-alarms section title, WU9) and
|
||||
`pluri_premium_widgets.dart` (a pre-existing decorative-hero-card widget file name, "premium" as in visual
|
||||
styling, not a paid tier) — both false positives for a naive substring check, neither a monetization string.
|
||||
No day-count trial phrase, no €/$ amount, no "gratuita"/"gratis"/"free version" string anywhere in
|
||||
`lib/l10n/app_*.arb` or `lib/`.
|
||||
- [x] 17.7 Verify — all 3 scenario tests green; grep scan clean.
|
||||
|
||||
## WU17b — Wire the welcome screen into the first-launch flow
|
||||
|
||||
**Not in the original plan — added to close the WU17 gap noted above, same shape as WU15/WU15b.** WU17 built
|
||||
`PantallaBienvenida` fully tested and committed, but left it unreachable from the app: `rg "PantallaBienvenida"
|
||||
lib/app.dart lib/main.dart` found nothing. This work unit exists solely to fix that.
|
||||
|
||||
**Commit**: `fix(bienvenida): wire the welcome screen into the first-launch flow`
|
||||
**Depends on**: WU17
|
||||
**Spec refs**: `onboarding-welcome` — Full-Screen Welcome Route (reachability; the render/content/no-monetization/CTA
|
||||
scenarios stay WU17's own, unmodified)
|
||||
**Verify**: `flutter test test/servicios/servicio_bienvenida_test.dart test/pantallas/pantalla_bienvenida_primer_lanzamiento_test.dart test/pantallas/pantalla_bienvenida_test.dart test/widget_test.dart && flutter analyze && dart format --set-exit-if-changed $(git diff --cached --name-only --diff-filter=ACM HEAD -- '*.dart')`
|
||||
**New tests**: `test/servicios/servicio_bienvenida_test.dart`, `test/pantallas/pantalla_bienvenida_primer_lanzamiento_test.dart`
|
||||
**Modified tests**: none (WU17's own `pantalla_bienvenida_test.dart` re-run unmodified as a regression check)
|
||||
|
||||
**Coexistence ruling applied.** `PluriOnboardingDialog` (an unrelated, pre-existing "what's new"/help-content modal
|
||||
loaded from markdown assets) is NOT deleted, merged, or replaced — first-launch welcome and a what's-new modal are
|
||||
different things, confirmed by reading `assets/content/onboarding/en.md`: it is a detailed feature-reference
|
||||
walkthrough plus per-version update notes, structurally different content from the welcome screen's 3-bullet
|
||||
marketing intro. Both now run from `app.dart`'s `_PaginaPrincipalState`, in this order on every cold start: the
|
||||
welcome screen's once-ever check resolves FIRST, then the pre-existing what's-new dialog's own independent
|
||||
per-version due-or-not check runs exactly as it did before this WU. Sequencing (not two independent fire-and-forget
|
||||
calls) is what prevents the two from ever racing onto the screen at the same time.
|
||||
|
||||
- [x] 17b.1 RED — `test/servicios/servicio_bienvenida_test.dart`: a new `ServicioBienvenida` (mirroring
|
||||
`ServicioContenidoApp`'s injectable-`SharedPreferences`, versioned-key convention, S3-R4) is due before it has
|
||||
ever been marked seen, is not due after `marcarBienvenidaVista()`, and respects a seen flag already persisted
|
||||
by a prior launch (`SharedPreferences.setMockInitialValues`).
|
||||
- [x] 17b.2 RED — `test/pantallas/pantalla_bienvenida_primer_lanzamiento_test.dart`: a new
|
||||
`PantallaBienvenida.mostrarSiProcede(context)` static method (mirroring `PluriOnboardingDialog.mostrarSiProcede`'s
|
||||
check-then-show-then-mark-seen shape) pushes the welcome screen on a first launch (no seen flag persisted), does
|
||||
NOT push it when the seen flag is already persisted, and — in one continuous session — persists the flag after
|
||||
being shown once so a later check in the same run skips it.
|
||||
- [x] 17b.3 GREEN — created `lib/servicios/servicio_bienvenida.dart` (`ServicioBienvenida`, key
|
||||
`pluri_bienvenida_vista_v1`, plain one-time boolean — no version comparison needed, unlike
|
||||
`ServicioContenidoApp`, since this welcome is a single first-impression surface, not a per-version one).
|
||||
- [x] 17b.4 GREEN — added the static `PantallaBienvenida.mostrarSiProcede(BuildContext)` method to the existing
|
||||
`pantalla_bienvenida.dart` file (no new wrapper class needed — unlike `PluriOnboardingDialog`, there is only one
|
||||
call shape here); updated the class doc comment to describe how it coexists with `PluriOnboardingDialog`.
|
||||
- [x] 17b.5 GREEN — wired `app.dart`: imported `pantalla_bienvenida.dart`; renamed the existing
|
||||
`_onboardingInicialSolicitado` guard flag to `_flujoPrimerLanzamientoSolicitado` (it now covers the combined
|
||||
sequence, not only the dialog); added `_mostrarFlujoPrimerLanzamiento()`, which awaits
|
||||
`PantallaBienvenida.mostrarSiProcede(context)` then calls the pre-existing, untouched
|
||||
`_mostrarOnboardingInicial()` — replacing the single `unawaited(_mostrarOnboardingInicial())` call site with
|
||||
`unawaited(_mostrarFlujoPrimerLanzamiento())`.
|
||||
- [x] 17b.6 REFACTOR — confirmed `_mostrarOnboardingInicial()`'s own body (900ms delay, `_alarmaSonandoActiva` guard,
|
||||
`PluriOnboardingDialog.mostrarSiProcede` call) is byte-for-byte unchanged — only its call site moved one level
|
||||
deeper into the new sequencing method. No scenario in `PantallaBienvenida`'s own WU17 test file needed to
|
||||
change (all 3 pass unmodified, confirming the CTA/content/no-monetization behavior is untouched).
|
||||
- [x] 17b.7 Verify — scoped suite green: 13/13 (3 `servicio_bienvenida_test.dart` + 3
|
||||
`pantalla_bienvenida_primer_lanzamiento_test.dart` + 3 `pantalla_bienvenida_test.dart` [byte-identical,
|
||||
unmodified] + 4 `widget_test.dart`). `flutter analyze`: 1 issue, identical to baseline. Scoped `dart format`:
|
||||
reformatted 1 of 5 touched files (whitespace-only string-literal wrapping), stable on re-run. Literal-encoding
|
||||
scan: one console-rendering false positive on the pre-existing "días" string (verified byte-correct UTF-8 via a
|
||||
direct file read with the encoding pinned), zero real corruption.
|
||||
|
||||
## WU18 — i18n batch (all 13 locales)
|
||||
|
||||
@@ -1021,53 +1131,84 @@ UI copy every other capability introduced
|
||||
**Verify**: `flutter test && flutter analyze && dart format --set-exit-if-changed $(git diff --name-only --diff-filter=ACM HEAD -- '*.dart')`
|
||||
**Modified tests**: ARB key-parity guard test (extend existing or add one if none exists)
|
||||
|
||||
- [ ] 18.1 RED — an ARB-parity test asserting all 13 `lib/l10n/app_*.arb` files contain an identical key set.
|
||||
- [ ] 18.1b RED — **anti-copy guard (a key-parity test is NOT enough).** `l10n.yaml` sets
|
||||
`template-arb-file: app_es.arb`, so any key missing from a locale silently falls back to **Spanish** — that is
|
||||
why untranslated strings currently render as Spanish inside `app_localizations_ja.dart`, `_fr.dart`, etc.
|
||||
A key-parity test would pass just as happily if all 11 locales simply COPIED the Spanish value.
|
||||
Write a test that, for every non-`es` locale, collects every key whose value is byte-identical to the `app_es.arb`
|
||||
value and requires each one to appear in an explicit allowlist (a checked-in file, e.g.
|
||||
`test/l10n/identical_value_allowlist.dart`). Legitimately-identical values exist — brand names, "OK", "Radio",
|
||||
codec names, pure symbols — so the allowlist is the escape hatch, but **each entry must be added deliberately,
|
||||
never in bulk**. Any unlisted identical value fails the test.
|
||||
Seed the allowlist ONLY with entries that are genuinely untranslatable; do not pre-populate it to make the
|
||||
suite green.
|
||||
- [ ] 18.2 RED — `navHome` exists as a key in all 13 locales, and `git diff` for this commit touches exactly 11
|
||||
`navHome` **value** lines (en/es were WU1's job, task 1.9).
|
||||
- [ ] 18.3 GREEN — add the ~35-45 new keys (accumulated from WU4-WU17's English/Spanish-only strings) to all 13
|
||||
ARB files, sourcing translations for the 11 non-en/es locales.
|
||||
- [ ] 18.4 GREEN — set the `navHome` value in the remaining 11 locales to a real translation of "Listen" (not a
|
||||
mechanical copy of the English/Spanish pair).
|
||||
- [ ] 18.5 REFACTOR — run the ARB-parity check across all 13 files; confirm zero missing/extra keys, AND that the
|
||||
18.1b anti-copy guard passes with an allowlist containing only genuinely-untranslatable entries.
|
||||
Sanity figures at the time this was written: `app_es.arb` (template) 540 keys, `app_en.arb` 561, and all 11
|
||||
other locales 518 — i.e. the non-template locales were **22 keys behind**, and those 22 were rendering in
|
||||
Spanish. WU18 is what closes that gap; the count will have grown as WU8-WU17 land, so re-measure rather than
|
||||
trusting these numbers.
|
||||
- [ ] 18.6 Verify — full `flutter test` suite green; `flutter analyze` clean; scoped `dart format` over the files
|
||||
this change touched produces no diff (NEVER bare `dart format .` — see the warning at the top);
|
||||
grep confirms no "PRO"/price/trial-duration string exists in any ARB file (final whole-app Success Criteria
|
||||
check).
|
||||
- [x] 18.1 RED — `test/l10n/arb_parity_test.dart` (+ `test/l10n/arb_test_helpers.dart` shared reader): an ARB-parity
|
||||
test asserting all 13 `lib/l10n/app_*.arb` files contain an identical key set, plus a `navHome`-exists check
|
||||
(task 18.2's first half). Confirmed RED against the pre-merge tree: 11 locales missing 72 keys each.
|
||||
- [x] 18.1b RED — `test/l10n/arb_anti_copy_test.dart` + `test/l10n/identical_value_allowlist.dart` (the anti-copy
|
||||
guard). **Scope correction found at apply time**: read literally ("for every non-`es` locale, collects every
|
||||
key whose value is byte-identical") this must cover the WHOLE file, not only WU18's own new keys — a
|
||||
narrower scope would leave 183 pre-existing identical values (mostly genuine `pt`/`es` Iberian-Romance
|
||||
cognates, plus international genre names, "OK", brand names, symbols) completely unaudited. Built the
|
||||
allowlist to cover both: 207 total entries (after de-duplicating two detection-script bugs found along the
|
||||
way — see 18.5's note), each with an individual justification comment, grouped by category for readability
|
||||
but never wildcarded.
|
||||
**`en` is deliberately excluded** from this guard's locale loop (see the test file's own doc comment): `en`
|
||||
and `es` have been hand-maintained together by every WU throughout this whole change (`en`/`es`-only new
|
||||
keys, never left lagging), so `en` never carries the "silently fell back to the template" risk this guard
|
||||
exists to catch — unlike the other 11, which this WU batch-translates for the first time.
|
||||
- [x] 18.2 RED — `navHome` exists as a key in all 13 locales (part of 18.1's parity test); `git diff` for this
|
||||
commit touches exactly **11** `navHome` **value** lines, confirmed via `git diff | grep -c '"navHome"'` = 22
|
||||
(11 removed + 11 added) after the merge (en/es were WU1's job, task 1.9, untouched here).
|
||||
- [x] 18.3 GREEN — added exactly **72** new keys (measured, not the ~35-45 estimate) to all 13 ARB files, with real,
|
||||
idiomatic translations for the 11 non-en/es locales (ar, bn, de, fr, hi, id, it, ja, pt, ru, zh) — vocabulary
|
||||
cross-checked against ~20 already-translated sibling keys in each locale (e.g. "station"/"favorites"/
|
||||
"preset"/"OK"/genre-name conventions, register — `du`-informal `de`, `vous`-formal `fr`, `tu`-informal `it`,
|
||||
polite-imperative `ru`/`ja`/`hi`/`bn`, `você`-imperative `pt` with no explicit pronoun) so new copy reads as
|
||||
part of the same voice as existing copy, not machine-translated in isolation. 7 of the 72 keys carry ICU
|
||||
placeholders/plurals; their `@key` metadata blocks were added to all 11 locales matching the template's own
|
||||
established convention of replicating metadata into every locale file (confirmed via a diff scan: the
|
||||
53 pre-existing metadata blocks shared between `es` and a sample locale were byte-identical). Arabic and
|
||||
Russian plurals use full CLDR categories (`one`/`two`/`few`/`other` and `one`/`few`/`other`) matching the
|
||||
precedent already set by the pre-existing `stationCount` key, rather than the simpler `=1`/`other` the ES/EN
|
||||
template itself uses for these two new keys.
|
||||
- [x] 18.4 GREEN — set `navHome` in the remaining 11 locales to a real translation of "Listen"/"Escuchar" (ar
|
||||
استماع, bn শোনা, de Hören, fr Écouter, hi सुनना, id Dengar, it Ascolta, ja 聴く, pt Ouvir, ru Слушать,
|
||||
zh 收听) — each cross-checked against that locale's OWN sibling nav-tab labels (`navSearch`/`navFavorites`/
|
||||
etc.) for register/part-of-speech consistency, not a mechanical copy of "Listen" or "Escuchar".
|
||||
- [x] 18.5 REFACTOR — re-ran the parity + anti-copy guard; **two detection-script bugs found and fixed along the
|
||||
way, not left in the final allowlist**: (1) the first draft's collision scanner used PowerShell's default
|
||||
`-eq`, which is **case-insensitive** — it falsely flagged 5 pairs (e.g. `de/durationMinutesOnly` "min" vs
|
||||
"Min") as collisions; re-scanned with `-ceq` (case-sensitive, matching Dart's own `==`) and removed the 5
|
||||
false positives. (2) the first allowlist draft was missing 7 genuine collisions the script had already found
|
||||
but a manual transcription pass dropped (`settingsGroupAudioTitle` ×4, `endField`/`endLabel` fr, `alarmFadeInLabel`
|
||||
pt) — added them back. Final state: zero missing/extra keys across all 13 files; anti-copy guard's own
|
||||
"no stale entries" self-check (added as this test's second assertion, not just the one the task named) also
|
||||
passes, so the allowlist is verified as exactly the current, real collision set — 207 entries, none stale,
|
||||
none missing.
|
||||
- [x] 18.6 Verify — full `flutter test`: **747/747 green, 2 skipped** (up from the 737-baseline this batch started
|
||||
from — +6 WU17b tests + +4 WU18 tests, reconciles exactly). `flutter analyze`: 1 issue, identical to
|
||||
baseline. Scoped `dart format` (11 regenerated `lib/l10n/gen/*.dart` + 4 new `test/l10n/*.dart` files, ARB
|
||||
JSON files are not `dart format` targets): reformatted 3 of 15 files (whitespace/line-wrapping only), stable
|
||||
on re-run. Grep confirms zero `\bPRO\b` (case-sensitive), €, $, "gratis"/"gratuit"/"free version", or
|
||||
day-count trial-phrase hits in any `app_*.arb` file. Literal-encoding scan (Arabic, Bengali, Devanagari,
|
||||
Japanese, Chinese, Cyrillic all touched): zero mojibake hits across all 11 modified ARB files, the 11
|
||||
regenerated `gen/*.dart` files, and the 4 new test files; spot-checked several locales' rendered text
|
||||
directly to confirm.
|
||||
|
||||
---
|
||||
|
||||
## Final Verification Sequence (run once, after WU18's commit)
|
||||
|
||||
1. `flutter test` — full suite green.
|
||||
2. `flutter analyze` — clean.
|
||||
3. `dart format --set-exit-if-changed $(git diff --name-only --diff-filter=ACM main -- '*.dart')` — no diff over the
|
||||
files this change touched. **NEVER bare `dart format .`** — it reformats 27 unrelated pre-existing files and would
|
||||
break the empty-diff guards in steps 4 and 5 below (Engram `reference/dart-format-scope-hazard`, id 2511).
|
||||
4. `git diff --stat lib/servicios/navegacion_auto.dart lib/servicios/servicio_ecualizador.dart` — both empty.
|
||||
5. `git diff lib/servicios/servicio_audio.dart` — band-application block (`749-762`) unchanged.
|
||||
6. Grep `lib/` for `countrycodes` — zero hits.
|
||||
7. Grep `lib/l10n/app_*.arb` for "PRO", a currency amount, or a day-count trial phrase — zero hits.
|
||||
8. Confirm all 13 ARB files have identical key sets and `navHome` present in each.
|
||||
9. Confirm the equalizer screen renders exactly 5 sliders.
|
||||
10. Run `test/pantallas/pantalla_alarma_sonando_dismiss_guard_test.dart` in isolation — passes, file diff empty.
|
||||
All 10 steps run and confirmed after the WU18 commit:
|
||||
|
||||
1. [x] `flutter test` — full suite green: **747/747, 2 skipped**.
|
||||
2. [x] `flutter analyze` — clean: 1 issue, identical to the pre-branch baseline.
|
||||
3. [x] `dart format --set-exit-if-changed $(git diff --name-only --diff-filter=ACM main -- '*.dart')` — no diff over
|
||||
the files this change touched. **NEVER bare `dart format .`** — it reformats 27 unrelated pre-existing files and
|
||||
would break the empty-diff guards in steps 4 and 5 below (Engram `reference/dart-format-scope-hazard`, id 2511).
|
||||
4. [x] `git diff --stat lib/servicios/navegacion_auto.dart lib/servicios/servicio_ecualizador.dart` — both empty.
|
||||
5. [x] `git diff lib/servicios/servicio_audio.dart` — band-application block (`749-762`) unchanged.
|
||||
6. [x] Grep `lib/` for `countrycodes` — zero hits.
|
||||
7. [x] Grep `lib/l10n/app_*.arb` for "PRO", a currency amount, or a day-count trial phrase — zero hits.
|
||||
8. [x] Confirm all 13 ARB files have identical key sets and `navHome` present in each — 466 real keys each, confirmed.
|
||||
9. [x] Confirm the equalizer screen renders exactly 5 sliders — confirmed.
|
||||
10. [x] Run `test/pantallas/pantalla_alarma_sonando_dismiss_guard_test.dart` in isolation — 13/13 passes, file diff
|
||||
empty vs `main`.
|
||||
|
||||
**All 18 work units (+ WU15b, WU17b, and the pre-existing controller-dispose bugfix) are now complete.** Branch
|
||||
`feat/rediseno-funcional` is ready for `sdd-verify`.
|
||||
|
||||
## Next Step
|
||||
|
||||
`sdd-apply` — implement WU1 first (unblocks everything else); honor the `size:exception` commits (WU3a, WU3b, WU10)
|
||||
as recorded above rather than attempting to split them further.
|
||||
`sdd-verify` — validate the completed implementation against `specs/*/spec.md`; `sdd-apply`'s work on this change is
|
||||
done.
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'arb_test_helpers.dart';
|
||||
import 'identical_value_allowlist.dart';
|
||||
|
||||
/// WU18 task 18.1b -- the anti-copy guard.
|
||||
///
|
||||
/// A key-parity test alone is NOT sufficient: it passes just as happily if
|
||||
/// all 11 non-`es` locales simply copy the Spanish template value verbatim
|
||||
/// for every key -- which would certify the exact bug it exists to catch
|
||||
/// (see `reference/l10n-spanish-template-fallback`). This test collects
|
||||
/// every value in a non-`es` locale that is byte-identical to the Spanish
|
||||
/// template's value for the same key and fails unless that (locale, key)
|
||||
/// pair is explicitly, individually allowlisted in
|
||||
/// `identical_value_allowlist.dart`.
|
||||
///
|
||||
/// Scope note: `en` is deliberately excluded from this guard. Unlike the
|
||||
/// other 11 locales -- which this change batch-translates for the first
|
||||
/// time -- `en` and `es` have been hand-maintained together by every work
|
||||
/// unit throughout this whole redesign (`en`/`es`-only new keys, never
|
||||
/// left lagging), so `en` never carries the "silently fell back to the
|
||||
/// template" risk this guard exists to catch.
|
||||
const _auditedLocales = [
|
||||
'ar',
|
||||
'bn',
|
||||
'de',
|
||||
'fr',
|
||||
'hi',
|
||||
'id',
|
||||
'it',
|
||||
'ja',
|
||||
'pt',
|
||||
'ru',
|
||||
'zh',
|
||||
];
|
||||
|
||||
void main() {
|
||||
test('every non-es value identical to the Spanish template is a '
|
||||
'deliberately allowlisted exception, not an accidental untranslated '
|
||||
'copy', () {
|
||||
final es = readArb('es');
|
||||
final unlisted = <String>[];
|
||||
|
||||
for (final locale in _auditedLocales) {
|
||||
final arb = readArb(locale);
|
||||
for (final key in realKeys(arb)) {
|
||||
if (!es.containsKey(key))
|
||||
continue; // arb_parity_test's job, not this one's
|
||||
if (arb[key] == es[key] &&
|
||||
!identicalValueAllowlist.contains((locale, key))) {
|
||||
unlisted.add('$locale/$key = "${arb[key]}"');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expect(
|
||||
unlisted,
|
||||
isEmpty,
|
||||
reason:
|
||||
'Found value(s) identical to the Spanish template that are NOT '
|
||||
'in identical_value_allowlist.dart -- this is very likely an '
|
||||
'untranslated copy-paste, not a deliberate cognate/brand-name/'
|
||||
'symbol exception. Translate it, or add a reviewed, individual '
|
||||
'allowlist entry with a justification comment if it truly is '
|
||||
'untranslatable:\n${unlisted.join('\n')}',
|
||||
);
|
||||
});
|
||||
|
||||
test(
|
||||
'every allowlisted pair is a real, current collision (no stale entries)',
|
||||
() {
|
||||
final es = readArb('es');
|
||||
final stale = <String>[];
|
||||
|
||||
for (final entry in identicalValueAllowlist) {
|
||||
final (locale, key) = entry;
|
||||
final arb = readArb(locale);
|
||||
final stillCollides =
|
||||
arb.containsKey(key) && es.containsKey(key) && arb[key] == es[key];
|
||||
if (!stillCollides) {
|
||||
stale.add('$locale/$key');
|
||||
}
|
||||
}
|
||||
|
||||
expect(
|
||||
stale,
|
||||
isEmpty,
|
||||
reason:
|
||||
'identical_value_allowlist.dart has entries that no longer '
|
||||
'correspond to a real identical value -- remove them, the '
|
||||
'allowlist must only contain genuine, current exceptions:\n'
|
||||
'${stale.join('\n')}',
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'arb_test_helpers.dart';
|
||||
|
||||
/// WU18 task 18.1 / 18.2 -- ARB key-parity guard.
|
||||
///
|
||||
/// `l10n.yaml` sets `template-arb-file: app_es.arb`, so Spanish is the l10n
|
||||
/// template: any key missing from a locale's ARB silently falls back to the
|
||||
/// Spanish value at runtime (not English, which is the more common
|
||||
/// assumption). This test guarantees all 13 locales carry the same key set,
|
||||
/// so nothing can silently render in Spanish because a locale was never
|
||||
/// given that key.
|
||||
void main() {
|
||||
test('all 13 ARB files declare an identical key set', () {
|
||||
final arbs = {
|
||||
for (final locale in supportedArbLocales) locale: readArb(locale),
|
||||
};
|
||||
final templateKeys = realKeys(arbs['es']!);
|
||||
|
||||
for (final locale in supportedArbLocales) {
|
||||
if (locale == 'es') continue;
|
||||
final keys = realKeys(arbs[locale]!);
|
||||
final missing = templateKeys.difference(keys);
|
||||
final extra = keys.difference(templateKeys);
|
||||
|
||||
expect(
|
||||
missing,
|
||||
isEmpty,
|
||||
reason:
|
||||
'app_$locale.arb is missing ${missing.length} key(s) present in '
|
||||
'the es template (these silently fall back to Spanish at '
|
||||
'runtime): $missing',
|
||||
);
|
||||
expect(
|
||||
extra,
|
||||
isEmpty,
|
||||
reason:
|
||||
'app_$locale.arb has ${extra.length} key(s) not present in the '
|
||||
'es template: $extra',
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
test('navHome exists as a key in all 13 locales', () {
|
||||
for (final locale in supportedArbLocales) {
|
||||
final arb = readArb(locale);
|
||||
expect(
|
||||
realKeys(arb).contains('navHome'),
|
||||
isTrue,
|
||||
reason: 'app_$locale.arb is missing the navHome key',
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import 'dart:convert';
|
||||
import 'dart:io';
|
||||
|
||||
/// All 13 supported locale codes backing `lib/l10n/app_*.arb`.
|
||||
///
|
||||
/// `flutter test` always runs with the working directory set to the
|
||||
/// package root, so `lib/l10n/...` below resolves correctly without any
|
||||
/// extra path juggling.
|
||||
const List<String> supportedArbLocales = [
|
||||
'ar',
|
||||
'bn',
|
||||
'de',
|
||||
'en',
|
||||
'es',
|
||||
'fr',
|
||||
'hi',
|
||||
'id',
|
||||
'it',
|
||||
'ja',
|
||||
'pt',
|
||||
'ru',
|
||||
'zh',
|
||||
];
|
||||
|
||||
/// Reads and decodes `lib/l10n/app_<locale>.arb` as a JSON map.
|
||||
Map<String, dynamic> readArb(String locale) {
|
||||
final file = File('lib/l10n/app_$locale.arb');
|
||||
return json.decode(file.readAsStringSync()) as Map<String, dynamic>;
|
||||
}
|
||||
|
||||
/// Real translation keys only -- excludes ICU metadata entries (`@key`)
|
||||
/// and the `@@locale` marker, which are not themselves translatable
|
||||
/// strings.
|
||||
Set<String> realKeys(Map<String, dynamic> arb) {
|
||||
return arb.keys.where((key) => !key.startsWith('@')).toSet();
|
||||
}
|
||||
@@ -0,0 +1,275 @@
|
||||
/// WU18 anti-copy guard allowlist (task 18.1b).
|
||||
///
|
||||
/// A key-parity check alone is not enough to prove a locale was actually
|
||||
/// translated: it passes just as happily if a locale simply copies the
|
||||
/// Spanish (`app_es.arb`, the l10n template) value verbatim. `arb_anti_copy_test.dart`
|
||||
/// scans every non-`es` locale for values that are byte-identical to the
|
||||
/// Spanish template and fails unless each one is listed here.
|
||||
///
|
||||
/// Legitimately-identical values DO exist -- brand names, international
|
||||
/// loanwords, pure symbols, and words that are simply spelled the same in
|
||||
/// closely related Romance languages (Spanish/Portuguese/Italian/French all
|
||||
/// share a huge amount of short, common vocabulary by descent, not by
|
||||
/// accident). This file is the deliberate, reviewed escape hatch for those.
|
||||
///
|
||||
/// Every entry below was reviewed individually and is grouped only for
|
||||
/// readability -- this file must NEVER be bulk-populated to silence the
|
||||
/// test. If you find an unlisted collision, translate it; do not add it
|
||||
/// here unless it is genuinely untranslatable.
|
||||
library;
|
||||
|
||||
/// (locale, ARB key) pairs whose value is intentionally identical to the
|
||||
/// Spanish template's value for that key.
|
||||
const Set<(String locale, String key)> identicalValueAllowlist = {
|
||||
// ---------------------------------------------------------------------
|
||||
// Brand / product names -- never translated in any language.
|
||||
// ---------------------------------------------------------------------
|
||||
('ar', 'appTitle'), // "PluriWave"
|
||||
('bn', 'appTitle'),
|
||||
('de', 'appTitle'),
|
||||
('fr', 'appTitle'),
|
||||
('hi', 'appTitle'),
|
||||
('id', 'appTitle'),
|
||||
('it', 'appTitle'),
|
||||
('ja', 'appTitle'),
|
||||
('pt', 'appTitle'),
|
||||
('ru', 'appTitle'),
|
||||
('zh', 'appTitle'),
|
||||
('ar', 'welcomeBullet2Title'), // "Android Auto" -- Google product name
|
||||
('bn', 'welcomeBullet2Title'),
|
||||
('de', 'welcomeBullet2Title'),
|
||||
('fr', 'welcomeBullet2Title'),
|
||||
('hi', 'welcomeBullet2Title'),
|
||||
('id', 'welcomeBullet2Title'),
|
||||
('it', 'welcomeBullet2Title'),
|
||||
('ja', 'welcomeBullet2Title'),
|
||||
('pt', 'welcomeBullet2Title'),
|
||||
('ru', 'welcomeBullet2Title'),
|
||||
('zh', 'welcomeBullet2Title'),
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Pure symbols / placeholders -- no translatable text at all.
|
||||
// ---------------------------------------------------------------------
|
||||
('ar', 'dash'), // "—" (em dash)
|
||||
('bn', 'dash'),
|
||||
('de', 'dash'),
|
||||
('fr', 'dash'),
|
||||
('hi', 'dash'),
|
||||
('id', 'dash'),
|
||||
('it', 'dash'),
|
||||
('ja', 'dash'),
|
||||
('pt', 'dash'),
|
||||
('ru', 'dash'),
|
||||
('zh', 'dash'),
|
||||
('ar', 'streamUrlHint'), // example URL shown as form hint text, not prose
|
||||
('bn', 'streamUrlHint'),
|
||||
('de', 'streamUrlHint'),
|
||||
('fr', 'streamUrlHint'),
|
||||
('hi', 'streamUrlHint'),
|
||||
('id', 'streamUrlHint'),
|
||||
('it', 'streamUrlHint'),
|
||||
('ja', 'streamUrlHint'),
|
||||
('pt', 'streamUrlHint'),
|
||||
('ru', 'streamUrlHint'),
|
||||
('zh', 'streamUrlHint'),
|
||||
(
|
||||
'ar',
|
||||
'favoriteGroupsChipLabel',
|
||||
), // "{groupName} · {count}" -- placeholders + separator only
|
||||
('bn', 'favoriteGroupsChipLabel'),
|
||||
('de', 'favoriteGroupsChipLabel'),
|
||||
('fr', 'favoriteGroupsChipLabel'),
|
||||
('hi', 'favoriteGroupsChipLabel'),
|
||||
('id', 'favoriteGroupsChipLabel'),
|
||||
('it', 'favoriteGroupsChipLabel'),
|
||||
('ja', 'favoriteGroupsChipLabel'),
|
||||
('pt', 'favoriteGroupsChipLabel'),
|
||||
('ru', 'favoriteGroupsChipLabel'),
|
||||
('zh', 'favoriteGroupsChipLabel'),
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// International music-genre labels -- treated as proper nouns and left
|
||||
// untranslated by convention across virtually every music app/catalog
|
||||
// (Spotify, Apple Music, YouTube Music, etc. all do the same).
|
||||
// ---------------------------------------------------------------------
|
||||
('de', 'genrePop'), ('de', 'genreRock'), ('de', 'genreJazz'),
|
||||
('de', 'genreHipHop'), ('de', 'genreCountry'), ('de', 'genreMetal'),
|
||||
('de', 'genreReggae'),
|
||||
('fr', 'genrePop'), ('fr', 'genreRock'), ('fr', 'genreJazz'),
|
||||
('fr', 'genreHipHop'), ('fr', 'genreCountry'), ('fr', 'genreMetal'),
|
||||
('fr', 'genreReggae'),
|
||||
('id', 'genrePop'), ('id', 'genreRock'), ('id', 'genreJazz'),
|
||||
('id', 'genreHipHop'), ('id', 'genreCountry'), ('id', 'genreMetal'),
|
||||
('id', 'genreReggae'),
|
||||
('it', 'genrePop'), ('it', 'genreRock'), ('it', 'genreJazz'),
|
||||
('it', 'genreHipHop'), ('it', 'genreCountry'), ('it', 'genreMetal'),
|
||||
('it', 'genreReggae'),
|
||||
('it', 'genreLatin'), // "Latina" -- also an es/it cognate
|
||||
('pt', 'genrePop'), ('pt', 'genreRock'), ('pt', 'genreJazz'),
|
||||
('pt', 'genreHipHop'), ('pt', 'genreCountry'), ('pt', 'genreMetal'),
|
||||
('pt', 'genreReggae'),
|
||||
('pt', 'genreLatin'), // "Latina" -- also an es/pt cognate
|
||||
// Same genre names re-used verbatim as equalizer preset names.
|
||||
('de', 'equalizerPresetRock'),
|
||||
('de', 'equalizerPresetPop'),
|
||||
('de', 'equalizerPresetJazz'),
|
||||
('fr', 'equalizerPresetRock'),
|
||||
('fr', 'equalizerPresetPop'),
|
||||
('fr', 'equalizerPresetJazz'),
|
||||
('id', 'equalizerPresetRock'),
|
||||
('id', 'equalizerPresetPop'),
|
||||
('id', 'equalizerPresetJazz'),
|
||||
('it', 'equalizerPresetRock'),
|
||||
('it', 'equalizerPresetPop'),
|
||||
('it', 'equalizerPresetJazz'),
|
||||
('pt', 'equalizerPresetRock'),
|
||||
('pt', 'equalizerPresetPop'),
|
||||
('pt', 'equalizerPresetJazz'),
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// "Preset"/"OK" -- international tech loanwords already established
|
||||
// throughout this file (see `advancedEqDevicePresetLabel`, `actionOk`).
|
||||
// ---------------------------------------------------------------------
|
||||
('de', 'actionOk'), ('de', 'statusOk'),
|
||||
('fr', 'actionOk'), ('fr', 'statusOk'),
|
||||
('it', 'actionOk'), ('it', 'statusOk'),
|
||||
('pt', 'actionOk'), ('pt', 'statusOk'),
|
||||
('de', 'advancedEqDevicePresetLabel'), // "Preset: {presetName}"
|
||||
('id', 'advancedEqDevicePresetLabel'),
|
||||
('it', 'advancedEqDevicePresetLabel'),
|
||||
('pt', 'advancedEqDevicePresetLabel'),
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Duration / count unit abbreviations -- "min", "h", "s" are
|
||||
// internationally understood abbreviations kept literal across many
|
||||
// languages in this file already (not English left in place; German,
|
||||
// French, Italian and Portuguese all natively abbreviate their own words
|
||||
// for minute/hour/second the same way).
|
||||
// ---------------------------------------------------------------------
|
||||
('fr', 'durationHoursMinutesSeconds'), ('fr', 'durationMinutesSeconds'),
|
||||
('fr', 'durationMinutesOnly'), ('fr', 'durationSecondsOnly'),
|
||||
('fr', 'alarmSnoozeOptionLabel'), // "{minutes} min"
|
||||
('it', 'durationHoursMinutesSeconds'), ('it', 'durationMinutesSeconds'),
|
||||
('it', 'durationMinutesOnly'), ('it', 'durationSecondsOnly'),
|
||||
('it', 'alarmSnoozeOptionLabel'),
|
||||
('pt', 'durationHoursMinutesSeconds'), ('pt', 'durationMinutesSeconds'),
|
||||
('pt', 'durationMinutesOnly'), ('pt', 'durationSecondsOnly'),
|
||||
('pt', 'alarmSnoozeOptionLabel'),
|
||||
(
|
||||
'fr',
|
||||
'stationsCount',
|
||||
), // "{count} radios" -- "radios" is a real French cognate plural
|
||||
(
|
||||
'de',
|
||||
'alarmFadeInLabel',
|
||||
), // "Fade-in {seconds}s" -- "fade-in" is a standard audio-production term
|
||||
('it', 'alarmFadeInLabel'),
|
||||
('pt', 'alarmFadeInLabel'),
|
||||
(
|
||||
'de',
|
||||
'settingsGroupAudioTitle',
|
||||
), // "AUDIO" -- shared international/Latin-root term (WU18 new key)
|
||||
('fr', 'settingsGroupAudioTitle'),
|
||||
('id', 'settingsGroupAudioTitle'),
|
||||
('it', 'settingsGroupAudioTitle'),
|
||||
|
||||
// ---------------------------------------------------------------------
|
||||
// Short weekday abbreviations that happen to coincide across Romance
|
||||
// languages even though the full weekday names differ (only the
|
||||
// 3-letter abbreviation collides, e.g. lunes/lundi/lunedì -> "Lun").
|
||||
// ---------------------------------------------------------------------
|
||||
('fr', 'weekdayShortMonday'), ('fr', 'weekdayShortTuesday'),
|
||||
('it', 'weekdayShortMonday'),
|
||||
('it', 'weekdayShortTuesday'),
|
||||
('it', 'weekdayShortSunday'),
|
||||
('pt', 'weekdayShortSaturday'), ('pt', 'weekdayShortSunday'),
|
||||
('fr', 'endField'), // "Fin" -- es/fr cognate ("end")
|
||||
('fr', 'endLabel'), // "Fin"
|
||||
// ---------------------------------------------------------------------
|
||||
// Country / language endonyms and cognate proper nouns -- country and
|
||||
// language names are frequently identical or near-identical across
|
||||
// Romance languages (and beyond); several are also the country's own
|
||||
// official native name.
|
||||
// ---------------------------------------------------------------------
|
||||
('id', 'countryArgentina'),
|
||||
('it', 'countryArgentina'),
|
||||
('pt', 'countryArgentina'),
|
||||
('id', 'countryItaly'),
|
||||
('it', 'countryItaly'), // "Italia" -- Italy's own endonym
|
||||
('id', 'countryBrazil'),
|
||||
(
|
||||
'pt',
|
||||
'countryBrazil',
|
||||
), // "Brasil" -- Brazil's own official (Portuguese) name
|
||||
('it', 'countryFrance'), // "Francia"
|
||||
('pt', 'countryMexico'), // "México"
|
||||
('pt', 'countryUk'), // "Reino Unido" -- identical es/pt calque
|
||||
('it', 'languageSystemDefault'), // "Sistema"
|
||||
('pt', 'languageSystemDefault'),
|
||||
('pt', 'languageSectionTitle'), // "Idioma"
|
||||
('pt', 'searchLanguageFilterLabel'), // "Idioma"
|
||||
('pt', 'searchCountryFilterLabel'), // "País"
|
||||
('pt', 'countryOptionalLabel'), // "País (opcional)"
|
||||
// ---------------------------------------------------------------------
|
||||
// Portuguese/Spanish close-cognate vocabulary. Portuguese and Spanish
|
||||
// are both Iberian Romance languages and share an unusually large amount
|
||||
// of short, common UI vocabulary verbatim -- these are correct,
|
||||
// independently-chosen Portuguese words that happen to be spelled the
|
||||
// same as their Spanish counterpart, not an untranslated leftover.
|
||||
// ---------------------------------------------------------------------
|
||||
('pt', 'navSearch'), // "Buscar"
|
||||
('pt', 'navFavorites'), // "Favoritos"
|
||||
('pt', 'favoritesTitle'), // "Favoritos"
|
||||
('pt', 'cancelAction'), // "Cancelar"
|
||||
('pt', 'cancelTimer'), // "Cancelar timer"
|
||||
('pt', 'startTimer'), // "Iniciar timer"
|
||||
('pt', 'hoursLabel'), // "Horas"
|
||||
('pt', 'minutesLabel'), // "Minutos"
|
||||
('pt', 'secondsLabel'), // "Segundos"
|
||||
('pt', 'timeField'), // "Hora"
|
||||
('pt', 'alarmInlineHourLabel'), // "Hora" (WU18 new key, task 18.3)
|
||||
('it', 'alarmInlineMinuteLabel'), // "Minuto" (WU18 new key, task 18.3)
|
||||
('pt', 'alarmInlineMinuteLabel'), // "Minuto" (WU18 new key, task 18.3)
|
||||
('pt', 'countriesScreenTitle'), // "Países" (WU18 new key, task 18.3)
|
||||
('pt', 'favoritesFilterAllLabel'), // "Todas" (WU18 new key, task 18.3)
|
||||
('pt', 'seeAllAction'), // "Ver todas" (WU18 new key, task 18.3)
|
||||
(
|
||||
'pt',
|
||||
'vacationUpcomingSectionTitle',
|
||||
), // "PROGRAMADOS" (WU18 new key, task 18.3)
|
||||
('pt', 'settingsSafeStatus'), // "Seguro"
|
||||
('pt', 'preferredStationAutomaticFallback'), // "Fallback automático"
|
||||
('pt', 'recordingsMaxSizeMbLabel'), // "Megabytes máximos"
|
||||
('pt', 'favoriteGroupsTitle'), // "Listas de favoritos"
|
||||
('pt', 'favoriteGroupsEdit'), // "Editar lista"
|
||||
('pt', 'searchFiltersLabel'), // "Filtros"
|
||||
('pt', 'detectAction'), // "Detectar"
|
||||
('pt', 'alarmScreenTitle'), // "Despertar musical"
|
||||
('pt', 'editAction'), // "Editar"
|
||||
('pt', 'defaultAlarmName'), // "Despertador musical"
|
||||
('pt', 'soundDigitalPulse'), // "Pulso digital"
|
||||
('pt', 'pauseAction'), // "Pausar"
|
||||
('pt', 'playbackStatusConnecting'), // "Conectando..."
|
||||
('pt', 'playbackStatusPaused'), // "Pausado"
|
||||
('pt', 'playbackStatusReconnecting'), // "Reconectando..."
|
||||
('it', 'equalizerBandLabel'), // "Banda {band}"
|
||||
('pt', 'equalizerBandLabel'), // "Banda {band}"
|
||||
('pt', 'equalizerPresetFlat'), // "Plano"
|
||||
('pt', 'equalizerPresetVoice'), // "Voz"
|
||||
('pt', 'equalizerPresetCustom'), // "Personalizado"
|
||||
('pt', 'customOption'), // "Personalizada"
|
||||
('pt', 'indefiniteOption'), // "Indefinida"
|
||||
('pt', 'invalidNumber'), // "Número inválido"
|
||||
('pt', 'stopAction'), // "Parar"
|
||||
('pt', 'eqDeviceEditTitle'), // "Editar dispositivo"
|
||||
('pt', 'eqDeviceConnected'), // "Conectado"
|
||||
('pt', 'localMusicSectionTitle'), // "Música local (Android Auto)"
|
||||
(
|
||||
'pt',
|
||||
'recordingsLibraryStorageCaption',
|
||||
), // WU18 new key (task 18.3) -- "usados"/"MB"/"de" all coincide
|
||||
(
|
||||
'pt',
|
||||
'searchResultsCount',
|
||||
), // WU18 new key (task 18.3) -- "resultado(s)" is an es/pt cognate
|
||||
};
|
||||
@@ -28,14 +28,6 @@ void _suppressListTileInkAssertion() {
|
||||
/// WU3b task 3b.1: the GRABACIONES Y MÚSICA detail screen for "Grabaciones"
|
||||
/// renders inside a [PluriPushScaffold] and its moved controls still respond
|
||||
/// exactly as they did inside the old `_SeccionGrabaciones`.
|
||||
///
|
||||
/// This file deliberately does NOT interact with "Maximum recording size"
|
||||
/// (`_editarTamanoMaximo`): that control has a pre-existing, out-of-scope
|
||||
/// controller-dispose race (documented in `pantalla_ajustes_grabaciones.dart`
|
||||
/// and, for the analogous `_editarGrupo` case, in
|
||||
/// `pantalla_ajustes_grupos_favoritos_test.dart`) that this move does not
|
||||
/// fix. "Restore default path" is exercised instead — a real, moved
|
||||
/// capability with no such hazard.
|
||||
void main() {
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
@@ -100,4 +92,37 @@ void main() {
|
||||
await tester.pump(const Duration(seconds: 5));
|
||||
await tester.pumpAndSettle();
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'moved control still responds: editing the maximum recording size '
|
||||
'persists it',
|
||||
(tester) async {
|
||||
_suppressListTileInkAssertion();
|
||||
final estado = EstadoGrabacion(
|
||||
servicio: FakeServicioGrabacionRadioInactiva(),
|
||||
);
|
||||
addTearDown(estado.dispose);
|
||||
expect(estado.maxBytes, 500 * 1024 * 1024, reason: 'default, not 250');
|
||||
|
||||
await tester.pumpWidget(buildScreen(estado));
|
||||
await tester.pump();
|
||||
await tester.pump(const Duration(milliseconds: 100));
|
||||
|
||||
await tester.tap(find.text('Maximum recording size'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.enterText(find.byType(TextField), '250');
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('Save quick access'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(estado.maxBytes, 250 * 1024 * 1024);
|
||||
expect(find.text('Recording limit updated to 250 MB'), findsOneWidget);
|
||||
|
||||
// SnackBar's own dismiss Timer is not frame-scheduled — let it resolve
|
||||
// before teardown (WU3a batch discovery) instead of leaving a pending
|
||||
// Timer behind.
|
||||
await tester.pump(const Duration(seconds: 5));
|
||||
await tester.pumpAndSettle();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -33,39 +33,6 @@ void _suppressListTileInkAssertion() {
|
||||
addTearDown(() => FlutterError.onError = original);
|
||||
}
|
||||
|
||||
/// Pre-existing bug, out of scope for this move-only WU: `_editarGrupo`
|
||||
/// (copied verbatim from the old `_SeccionGruposFavoritos`) disposes its
|
||||
/// `TextEditingController` immediately after `showModalBottomSheet` resolves,
|
||||
/// racing the sheet's own close animation, which still holds a `TextField`
|
||||
/// bound to that controller for a couple more frames. It does not stop
|
||||
/// `crearGrupoFavoritos` from running correctly, and reproduces identically
|
||||
/// against the pre-WU3a combined screen (this widget's body is unmodified).
|
||||
/// Fixing the dispose timing would be a logic edit, which this WU's
|
||||
/// verbatim-move contract forbids; flagged for a future fix instead.
|
||||
///
|
||||
/// The one race produces a cascade of framework-internal symptoms while the
|
||||
/// sheet's close animation and the disposed controller fight over the same
|
||||
/// frame (an overlay `_dependents.isEmpty` assertion, and a transient
|
||||
/// RenderFlex overflow against this file's bottom-sheet Column). All are
|
||||
/// suppressed together as one documented, narrowly-scoped exception.
|
||||
void _suppressDisposedControllerCascade() {
|
||||
final original = FlutterError.onError;
|
||||
FlutterError.onError = (details) {
|
||||
final message = details.exceptionAsString();
|
||||
final full = details.toString();
|
||||
final isKnownCascade =
|
||||
message.contains(
|
||||
'A TextEditingController was used after being disposed',
|
||||
) ||
|
||||
message.contains("'_dependents.isEmpty': is not true") ||
|
||||
(message.contains('RenderFlex overflowed') &&
|
||||
full.contains('pantalla_ajustes_grupos_favoritos.dart'));
|
||||
if (isKnownCascade) return;
|
||||
original?.call(details);
|
||||
};
|
||||
addTearDown(() => FlutterError.onError = original);
|
||||
}
|
||||
|
||||
void main() {
|
||||
setUp(() {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
@@ -124,7 +91,6 @@ void main() {
|
||||
tester,
|
||||
) async {
|
||||
_suppressListTileInkAssertion();
|
||||
_suppressDisposedControllerCascade();
|
||||
final estado = await crearEstado();
|
||||
addTearDown(estado.dispose);
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
||||
import 'package:pluriwave/pantallas/pantalla_bienvenida.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// WU17b: `PantallaBienvenida.mostrarSiProcede` wires the welcome screen
|
||||
/// into the genuine first-launch flow. WU17 built and tested the screen
|
||||
/// fully in isolation, but nothing in `lib/app.dart` or `lib/main.dart`
|
||||
/// ever referenced it — it was unreachable. These tests pin the actual
|
||||
/// gap: the screen must show on a genuine first launch and never again
|
||||
/// once `ServicioBienvenida` has recorded it as seen.
|
||||
Widget _appConDisparador(GlobalKey<NavigatorState> navigatorKey) {
|
||||
return MaterialApp(
|
||||
navigatorKey: navigatorKey,
|
||||
locale: const Locale('es'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: Builder(
|
||||
builder:
|
||||
(context) => Scaffold(
|
||||
body: Center(
|
||||
child: ElevatedButton(
|
||||
onPressed: () => PantallaBienvenida.mostrarSiProcede(context),
|
||||
child: const Text('disparar'),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
testWidgets(
|
||||
'first launch (no seen flag persisted) shows the welcome screen',
|
||||
(tester) async {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
await tester.pumpWidget(_appConDisparador(navigatorKey));
|
||||
await tester.tap(find.text('disparar'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(PantallaBienvenida), findsOneWidget);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'second launch (seen flag already persisted) does not show it again',
|
||||
(tester) async {
|
||||
SharedPreferences.setMockInitialValues({
|
||||
'pluri_bienvenida_vista_v1': true,
|
||||
});
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
await tester.pumpWidget(_appConDisparador(navigatorKey));
|
||||
await tester.tap(find.text('disparar'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.byType(PantallaBienvenida), findsNothing);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('showing it once persists the flag so a later check in the same '
|
||||
'session skips it', (tester) async {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
await tester.pumpWidget(_appConDisparador(navigatorKey));
|
||||
await tester.tap(find.text('disparar'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(PantallaBienvenida), findsOneWidget);
|
||||
|
||||
// Dismiss it the same way the CTA does (a plain pop), simulating the
|
||||
// welcome screen being resolved before the next check ever happens.
|
||||
navigatorKey.currentState!.pop();
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('disparar'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(PantallaBienvenida), findsNothing);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,144 @@
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/estado/estado_navegacion.dart';
|
||||
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
||||
import 'package:pluriwave/pantallas/pantalla_bienvenida.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
/// WU17: `onboarding-welcome` spec — full-screen route (not a modal),
|
||||
/// content only (logo/headline/body/3 bullets/1 CTA), binding
|
||||
/// no-monetization guard, and CTA dismisses to Escuchar with the route
|
||||
/// popped.
|
||||
Widget _app({required EstadoNavegacionRaiz navegacion}) {
|
||||
return ChangeNotifierProvider<EstadoNavegacionRaiz>.value(
|
||||
value: navegacion,
|
||||
child: const MaterialApp(
|
||||
locale: Locale('es'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: PantallaBienvenida(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets(
|
||||
'renders as a full-screen route with a logo, headline, body copy, '
|
||||
'exactly 3 feature bullets, and exactly one primary CTA',
|
||||
(tester) async {
|
||||
final navegacion = EstadoNavegacionRaiz();
|
||||
addTearDown(navegacion.dispose);
|
||||
|
||||
await tester.pumpWidget(_app(navegacion: navegacion));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// A full-screen route, never a modal dialog.
|
||||
expect(find.byType(Dialog), findsNothing);
|
||||
expect(find.byType(AlertDialog), findsNothing);
|
||||
expect(find.byType(Scaffold), findsOneWidget);
|
||||
|
||||
expect(find.byType(Image), findsOneWidget, reason: 'the logo mark');
|
||||
expect(find.text('Tu mundo, en directo'), findsOneWidget);
|
||||
expect(
|
||||
find.textContaining('53.412 emisoras de 238 países'),
|
||||
findsOneWidget,
|
||||
);
|
||||
expect(
|
||||
find.byType(FilaCaracteristicaBienvenida),
|
||||
findsNWidgets(3),
|
||||
reason: 'exactly 3 feature bullets',
|
||||
);
|
||||
expect(
|
||||
find.byType(FilledButton),
|
||||
findsOneWidget,
|
||||
reason: 'exactly 1 primary CTA',
|
||||
);
|
||||
expect(find.text('Empezar a escuchar'), findsOneWidget);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets('rendered content contains no monetization strings', (
|
||||
tester,
|
||||
) async {
|
||||
final navegacion = EstadoNavegacionRaiz();
|
||||
addTearDown(navegacion.dispose);
|
||||
|
||||
await tester.pumpWidget(_app(navegacion: navegacion));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
final textoCompleto = tester
|
||||
.widgetList<Text>(find.byType(Text))
|
||||
.map((widget) => widget.data ?? '')
|
||||
.join('\n');
|
||||
|
||||
expect(textoCompleto.contains('PRO'), isFalse);
|
||||
expect(textoCompleto.contains('€'), isFalse);
|
||||
expect(textoCompleto.contains(r'$'), isFalse);
|
||||
expect(
|
||||
RegExp(r'\d+\s*d[ií]as?\b', caseSensitive: false).hasMatch(
|
||||
textoCompleto,
|
||||
),
|
||||
isFalse,
|
||||
reason: 'no day-count trial phrase (e.g. "14 días")',
|
||||
);
|
||||
expect(
|
||||
find.textContaining('gratuita', findRichText: true),
|
||||
findsNothing,
|
||||
reason: 'no secondary "free version" link',
|
||||
);
|
||||
expect(
|
||||
find.textContaining('gratis', findRichText: true),
|
||||
findsNothing,
|
||||
reason: 'no secondary "free version" link',
|
||||
);
|
||||
// Only one tappable action on the whole screen: the primary CTA.
|
||||
expect(find.byType(TextButton), findsNothing);
|
||||
expect(find.byType(FilledButton), findsOneWidget);
|
||||
});
|
||||
|
||||
testWidgets(
|
||||
'tapping the primary CTA switches to Escuchar and pops the welcome route',
|
||||
(tester) async {
|
||||
// Start on a DIFFERENT tab so a pass actually proves irA() ran,
|
||||
// rather than coasting on EstadoNavegacionRaiz's own escuchar default.
|
||||
final navegacion = EstadoNavegacionRaiz()
|
||||
..irA(RaizPluriWave.ajustes);
|
||||
addTearDown(navegacion.dispose);
|
||||
final navigatorKey = GlobalKey<NavigatorState>();
|
||||
|
||||
await tester.pumpWidget(
|
||||
ChangeNotifierProvider<EstadoNavegacionRaiz>.value(
|
||||
value: navegacion,
|
||||
child: MaterialApp(
|
||||
navigatorKey: navigatorKey,
|
||||
locale: const Locale('es'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: const Scaffold(body: Center(child: Text('home stand-in'))),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
unawaited(
|
||||
navigatorKey.currentState!.push(
|
||||
MaterialPageRoute<void>(builder: (_) => const PantallaBienvenida()),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.byType(PantallaBienvenida), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Empezar a escuchar'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(navegacion.actual, RaizPluriWave.escuchar);
|
||||
expect(
|
||||
find.byType(PantallaBienvenida),
|
||||
findsNothing,
|
||||
reason: 'the welcome route was removed from the back stack',
|
||||
);
|
||||
expect(find.text('home stand-in'), findsOneWidget);
|
||||
},
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/servicios/servicio_bienvenida.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
/// WU17b: `ServicioBienvenida` decides whether the first-run welcome
|
||||
/// screen (`PantallaBienvenida`) is still due — same injectable-prefs,
|
||||
/// versioned-key convention as `ServicioContenidoApp` (S3-R4), but a plain
|
||||
/// boolean flag since this welcome is a one-time, not per-version, surface.
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('ServicioBienvenida', () {
|
||||
test(
|
||||
'debeMostrarBienvenida is true before it has ever been marked seen',
|
||||
() async {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
final servicio = ServicioBienvenida();
|
||||
|
||||
expect(await servicio.debeMostrarBienvenida(), isTrue);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'debeMostrarBienvenida is false after marcarBienvenidaVista',
|
||||
() async {
|
||||
SharedPreferences.setMockInitialValues({});
|
||||
final servicio = ServicioBienvenida();
|
||||
|
||||
await servicio.marcarBienvenidaVista();
|
||||
|
||||
expect(await servicio.debeMostrarBienvenida(), isFalse);
|
||||
},
|
||||
);
|
||||
|
||||
test('respects a seen flag already persisted by a prior launch', () async {
|
||||
SharedPreferences.setMockInitialValues({
|
||||
'pluri_bienvenida_vista_v1': true,
|
||||
});
|
||||
final servicio = ServicioBienvenida();
|
||||
|
||||
expect(await servicio.debeMostrarBienvenida(), isFalse);
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -3,6 +3,7 @@ import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:pluriwave/estado/estado_radio.dart';
|
||||
import 'package:pluriwave/l10n/gen/app_localizations.dart';
|
||||
import 'package:pluriwave/servicios/servicio_audio.dart';
|
||||
import 'package:pluriwave/tema/pluriwave_tokens.dart';
|
||||
import 'package:pluriwave/widgets/mini_reproductor.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
@@ -93,4 +94,120 @@ void main() {
|
||||
expect(find.byType(AlertDialog), findsNothing);
|
||||
expect(find.byIcon(Icons.refresh_rounded), findsOneWidget);
|
||||
});
|
||||
|
||||
// WU16: the offline/reconnect banner restyle. `offlineAccent` (added in
|
||||
// WU1, previously unused by any screen) tints the connectivity-trouble
|
||||
// sub-states so they read as visually distinct from ordinary loading.
|
||||
testWidgets(
|
||||
'reconnecting state tints the spinner and status label with the offline accent',
|
||||
(tester) async {
|
||||
final audio = FakeServicioAudio();
|
||||
final estado = _estadoRadio(audio);
|
||||
addTearDown(estado.dispose);
|
||||
await audio.reproducir(emisoraDemo(uuid: 'r1', nombre: 'Radio Uno'));
|
||||
|
||||
await tester.pumpWidget(
|
||||
ChangeNotifierProvider<EstadoRadio>.value(
|
||||
value: estado,
|
||||
child: MaterialApp(
|
||||
locale: const Locale('es'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: const Scaffold(body: MiniReproductor()),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
audio.emitirEstado(EstadoReproduccion.reconectando);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(
|
||||
tester
|
||||
.widget<CircularProgressIndicator>(
|
||||
find.byType(CircularProgressIndicator),
|
||||
)
|
||||
.color,
|
||||
PluriWaveTokens.dark.offlineAccent,
|
||||
);
|
||||
expect(
|
||||
tester.widget<Text>(find.text('Reconectando...')).style?.color,
|
||||
PluriWaveTokens.dark.offlineAccent,
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'plain buffering keeps the default spinner colour, not the offline accent',
|
||||
(tester) async {
|
||||
final audio = FakeServicioAudio();
|
||||
final estado = _estadoRadio(audio);
|
||||
addTearDown(estado.dispose);
|
||||
await audio.reproducir(emisoraDemo(uuid: 'r1', nombre: 'Radio Uno'));
|
||||
|
||||
await tester.pumpWidget(
|
||||
ChangeNotifierProvider<EstadoRadio>.value(
|
||||
value: estado,
|
||||
child: MaterialApp(
|
||||
locale: const Locale('es'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: const Scaffold(body: MiniReproductor()),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
audio.emitirEstado(EstadoReproduccion.cargando);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(
|
||||
tester
|
||||
.widget<CircularProgressIndicator>(
|
||||
find.byType(CircularProgressIndicator),
|
||||
)
|
||||
.color,
|
||||
isNull,
|
||||
reason: 'cargando is not a connectivity problem, keep the default',
|
||||
);
|
||||
},
|
||||
);
|
||||
|
||||
testWidgets(
|
||||
'error state tints the retry icon and status label with the offline accent',
|
||||
(tester) async {
|
||||
final audio = FakeServicioAudio();
|
||||
final estado = _estadoRadio(audio);
|
||||
addTearDown(estado.dispose);
|
||||
await audio.reproducir(emisoraDemo(uuid: 'r1', nombre: 'Radio Uno'));
|
||||
|
||||
await tester.pumpWidget(
|
||||
ChangeNotifierProvider<EstadoRadio>.value(
|
||||
value: estado,
|
||||
child: MaterialApp(
|
||||
locale: const Locale('es'),
|
||||
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
||||
supportedLocales: AppLocalizations.supportedLocales,
|
||||
home: const Scaffold(body: MiniReproductor()),
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
audio.emitirEstado(EstadoReproduccion.error);
|
||||
await tester.pump();
|
||||
await tester.pump();
|
||||
|
||||
expect(
|
||||
tester.widget<Icon>(find.byIcon(Icons.refresh_rounded)).color,
|
||||
PluriWaveTokens.dark.offlineAccent,
|
||||
);
|
||||
expect(
|
||||
tester.widget<Text>(find.text('Error de conexión')).style?.color,
|
||||
PluriWaveTokens.dark.offlineAccent,
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user