diff --git a/lib/l10n/app_ar.arb b/lib/l10n/app_ar.arb index 47e952b..54c33ef 100644 --- a/lib/l10n/app_ar.arb +++ b/lib/l10n/app_ar.arb @@ -904,5 +904,13 @@ "restaurarCompras": "استعادة المشتريات", "compraError": "تعذّر إتمام عملية الشراء. حاول مرة أخرى.", "restauracionSinCompras": "لم نجد أي عملية شراء سابقة في هذا الحساب.", - "premiumActivo": "النسخة المميزة مفعّلة" + "premiumActivo": "النسخة المميزة مفعّلة", + "premiumHojaTitulo": "افتح PluriWave Premium", + "premiumBeneficioSinAnuncios": "بدون إعلانات في التطبيق بالكامل", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "تسجيل المحطات", + "premiumBeneficioVacaciones": "فترات إجازة للمنبهات", + "premiumBeneficioAlarmasIlimitadas": "منبهات غير محدودة (تسمح الخطة المجانية بحتى 5)", + "premiumPagoUnico": "دفعة واحدة، للأبد. ليس اشتراكًا.", + "premiumAhoraNo": "ليس الآن" } diff --git a/lib/l10n/app_bn.arb b/lib/l10n/app_bn.arb index ac9312a..e8c907a 100644 --- a/lib/l10n/app_bn.arb +++ b/lib/l10n/app_bn.arb @@ -904,5 +904,13 @@ "restaurarCompras": "কেনাকাটা পুনরুদ্ধার করুন", "compraError": "কেনাকাটা সম্পূর্ণ করা যায়নি। আবার চেষ্টা করুন।", "restauracionSinCompras": "এই অ্যাকাউন্টে আমরা আগের কোনো কেনাকাটা খুঁজে পাইনি।", - "premiumActivo": "প্রিমিয়াম সক্রিয়" + "premiumActivo": "প্রিমিয়াম সক্রিয়", + "premiumHojaTitulo": "PluriWave Premium আনলক করুন", + "premiumBeneficioSinAnuncios": "পুরো অ্যাপে কোনো বিজ্ঞাপন নেই", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "স্টেশন রেকর্ডিং", + "premiumBeneficioVacaciones": "অ্যালার্মের জন্য ছুটির সময়কাল", + "premiumBeneficioAlarmasIlimitadas": "সীমাহীন অ্যালার্ম (ফ্রি প্ল্যানে সর্বোচ্চ ৫টি অনুমোদিত)", + "premiumPagoUnico": "একবারের পেমেন্ট, চিরকালের জন্য। এটি সাবস্ক্রিপশন নয়।", + "premiumAhoraNo": "এখন নয়" } diff --git a/lib/l10n/app_de.arb b/lib/l10n/app_de.arb index 55432d7..ad852ba 100644 --- a/lib/l10n/app_de.arb +++ b/lib/l10n/app_de.arb @@ -904,5 +904,13 @@ "restaurarCompras": "Käufe wiederherstellen", "compraError": "Der Kauf konnte nicht abgeschlossen werden. Bitte versuche es erneut.", "restauracionSinCompras": "Wir haben auf diesem Konto keinen früheren Kauf gefunden.", - "premiumActivo": "Premium aktiv" + "premiumActivo": "Premium aktiv", + "premiumHojaTitulo": "PluriWave Premium freischalten", + "premiumBeneficioSinAnuncios": "Keine Werbung in der gesamten App", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Sender aufnehmen", + "premiumBeneficioVacaciones": "Urlaubszeiträume für Wecker", + "premiumBeneficioAlarmasIlimitadas": "Unbegrenzte Wecker (die kostenlose Version erlaubt bis zu 5)", + "premiumPagoUnico": "Einmalzahlung, für immer. Kein Abonnement.", + "premiumAhoraNo": "Nicht jetzt" } diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 19f7e7d..68865fc 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -904,5 +904,13 @@ "restaurarCompras": "Restore purchases", "compraError": "We couldn't complete the purchase. Please try again.", "restauracionSinCompras": "We didn't find any previous purchase on this account.", - "premiumActivo": "Premium active" + "premiumActivo": "Premium active", + "premiumHojaTitulo": "Unlock PluriWave Premium", + "premiumBeneficioSinAnuncios": "No ads anywhere in the app", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Station recording", + "premiumBeneficioVacaciones": "Vacation ranges for alarms", + "premiumBeneficioAlarmasIlimitadas": "Unlimited alarms (the free plan allows up to 5)", + "premiumPagoUnico": "One-time purchase, forever. Not a subscription.", + "premiumAhoraNo": "Not now" } diff --git a/lib/l10n/app_es.arb b/lib/l10n/app_es.arb index b9805cf..0805e81 100644 --- a/lib/l10n/app_es.arb +++ b/lib/l10n/app_es.arb @@ -863,5 +863,13 @@ "restaurarCompras": "Restaurar compras", "compraError": "No se ha podido completar la compra. Inténtalo de nuevo.", "restauracionSinCompras": "No hemos encontrado ninguna compra anterior en esta cuenta.", - "premiumActivo": "Premium activo" + "premiumActivo": "Premium activo", + "premiumHojaTitulo": "Desbloquea PluriWave Premium", + "premiumBeneficioSinAnuncios": "Sin publicidad en toda la app", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Grabación de emisoras", + "premiumBeneficioVacaciones": "Rangos de vacaciones para las alarmas", + "premiumBeneficioAlarmasIlimitadas": "Alarmas ilimitadas (el plan gratuito permite hasta 5)", + "premiumPagoUnico": "Pago único, para siempre. No es una suscripción.", + "premiumAhoraNo": "Ahora no" } diff --git a/lib/l10n/app_fr.arb b/lib/l10n/app_fr.arb index 0350120..6ff0fe3 100644 --- a/lib/l10n/app_fr.arb +++ b/lib/l10n/app_fr.arb @@ -904,5 +904,13 @@ "restaurarCompras": "Restaurer les achats", "compraError": "Impossible de finaliser l'achat. Veuillez réessayer.", "restauracionSinCompras": "Nous n'avons trouvé aucun achat antérieur sur ce compte.", - "premiumActivo": "Premium actif" + "premiumActivo": "Premium actif", + "premiumHojaTitulo": "Débloquer PluriWave Premium", + "premiumBeneficioSinAnuncios": "Aucune publicité dans toute l'application", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Enregistrement des stations", + "premiumBeneficioVacaciones": "Périodes de vacances pour les alarmes", + "premiumBeneficioAlarmasIlimitadas": "Alarmes illimitées (la version gratuite en autorise jusqu'à 5)", + "premiumPagoUnico": "Achat unique, pour toujours. Ce n'est pas un abonnement.", + "premiumAhoraNo": "Plus tard" } diff --git a/lib/l10n/app_hi.arb b/lib/l10n/app_hi.arb index 022c0ca..9df9299 100644 --- a/lib/l10n/app_hi.arb +++ b/lib/l10n/app_hi.arb @@ -904,5 +904,13 @@ "restaurarCompras": "खरीदारी पुनर्स्थापित करें", "compraError": "खरीद पूरी नहीं हो सकी। कृपया फिर से प्रयास करें।", "restauracionSinCompras": "इस खाते में हमें कोई पिछली खरीद नहीं मिली।", - "premiumActivo": "प्रीमियम सक्रिय" + "premiumActivo": "प्रीमियम सक्रिय", + "premiumHojaTitulo": "PluriWave Premium अनलॉक करें", + "premiumBeneficioSinAnuncios": "पूरे ऐप में कोई विज्ञापन नहीं", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "स्टेशन रिकॉर्डिंग", + "premiumBeneficioVacaciones": "अलार्म के लिए छुट्टी की अवधि", + "premiumBeneficioAlarmasIlimitadas": "असीमित अलार्म (मुफ़्त प्लान में अधिकतम 5 की अनुमति है)", + "premiumPagoUnico": "एकमुश्त भुगतान, हमेशा के लिए। यह सदस्यता नहीं है।", + "premiumAhoraNo": "अभी नहीं" } diff --git a/lib/l10n/app_id.arb b/lib/l10n/app_id.arb index 0cd5ee3..4fd5dda 100644 --- a/lib/l10n/app_id.arb +++ b/lib/l10n/app_id.arb @@ -904,5 +904,13 @@ "restaurarCompras": "Pulihkan pembelian", "compraError": "Pembelian tidak dapat diselesaikan. Silakan coba lagi.", "restauracionSinCompras": "Kami tidak menemukan pembelian sebelumnya di akun ini.", - "premiumActivo": "Premium aktif" + "premiumActivo": "Premium aktif", + "premiumHojaTitulo": "Buka PluriWave Premium", + "premiumBeneficioSinAnuncios": "Tanpa iklan di seluruh aplikasi", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Perekaman stasiun", + "premiumBeneficioVacaciones": "Rentang liburan untuk alarm", + "premiumBeneficioAlarmasIlimitadas": "Alarm tanpa batas (paket gratis mengizinkan hingga 5)", + "premiumPagoUnico": "Pembelian sekali bayar, untuk selamanya. Bukan langganan.", + "premiumAhoraNo": "Nanti saja" } diff --git a/lib/l10n/app_it.arb b/lib/l10n/app_it.arb index e71c341..04b322c 100644 --- a/lib/l10n/app_it.arb +++ b/lib/l10n/app_it.arb @@ -904,5 +904,13 @@ "restaurarCompras": "Ripristina acquisti", "compraError": "Non è stato possibile completare l'acquisto. Riprova.", "restauracionSinCompras": "Non abbiamo trovato acquisti precedenti su questo account.", - "premiumActivo": "Premium attivo" + "premiumActivo": "Premium attivo", + "premiumHojaTitulo": "Sblocca PluriWave Premium", + "premiumBeneficioSinAnuncios": "Nessuna pubblicità in tutta l'app", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Registrazione delle stazioni", + "premiumBeneficioVacaciones": "Intervalli di vacanza per le sveglie", + "premiumBeneficioAlarmasIlimitadas": "Sveglie illimitate (il piano gratuito ne consente fino a 5)", + "premiumPagoUnico": "Acquisto unico, per sempre. Non è un abbonamento.", + "premiumAhoraNo": "Non ora" } diff --git a/lib/l10n/app_ja.arb b/lib/l10n/app_ja.arb index da8fa0e..6a4f0c0 100644 --- a/lib/l10n/app_ja.arb +++ b/lib/l10n/app_ja.arb @@ -904,5 +904,13 @@ "restaurarCompras": "購入を復元", "compraError": "購入を完了できませんでした。もう一度お試しください。", "restauracionSinCompras": "このアカウントでは以前の購入が見つかりませんでした。", - "premiumActivo": "プレミアム有効" + "premiumActivo": "プレミアム有効", + "premiumHojaTitulo": "PluriWave Premiumのロックを解除", + "premiumBeneficioSinAnuncios": "アプリ全体で広告なし", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "放送局の録音", + "premiumBeneficioVacaciones": "アラームの休暇期間設定", + "premiumBeneficioAlarmasIlimitadas": "アラーム数無制限(無料プランは5個まで)", + "premiumPagoUnico": "買い切りの一度きりの支払いで永久に使用可能。サブスクリプションではありません。", + "premiumAhoraNo": "後で" } diff --git a/lib/l10n/app_pt.arb b/lib/l10n/app_pt.arb index df0a5b3..53fcc29 100644 --- a/lib/l10n/app_pt.arb +++ b/lib/l10n/app_pt.arb @@ -904,5 +904,13 @@ "restaurarCompras": "Restaurar compras", "compraError": "Não foi possível concluir a compra. Tente novamente.", "restauracionSinCompras": "Não encontramos nenhuma compra anterior nesta conta.", - "premiumActivo": "Premium ativo" + "premiumActivo": "Premium ativo", + "premiumHojaTitulo": "Desbloqueie o PluriWave Premium", + "premiumBeneficioSinAnuncios": "Sem anúncios em todo o app", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Gravação de emissoras", + "premiumBeneficioVacaciones": "Períodos de férias para os alarmes", + "premiumBeneficioAlarmasIlimitadas": "Alarmes ilimitados (o plano gratuito permite até 5)", + "premiumPagoUnico": "Pagamento único, para sempre. Não é uma assinatura.", + "premiumAhoraNo": "Agora não" } diff --git a/lib/l10n/app_ru.arb b/lib/l10n/app_ru.arb index f11ede4..162f35e 100644 --- a/lib/l10n/app_ru.arb +++ b/lib/l10n/app_ru.arb @@ -904,5 +904,13 @@ "restaurarCompras": "Восстановить покупки", "compraError": "Не удалось завершить покупку. Попробуйте ещё раз.", "restauracionSinCompras": "Мы не нашли предыдущих покупок на этом аккаунте.", - "premiumActivo": "Премиум активен" + "premiumActivo": "Премиум активен", + "premiumHojaTitulo": "Разблокировать PluriWave Premium", + "premiumBeneficioSinAnuncios": "Никакой рекламы во всём приложении", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "Запись радиостанций", + "premiumBeneficioVacaciones": "Периоды отпуска для будильников", + "premiumBeneficioAlarmasIlimitadas": "Неограниченное количество будильников (бесплатный план позволяет до 5)", + "premiumPagoUnico": "Единоразовая покупка, навсегда. Это не подписка.", + "premiumAhoraNo": "Не сейчас" } diff --git a/lib/l10n/app_zh.arb b/lib/l10n/app_zh.arb index 2d48b57..17fb190 100644 --- a/lib/l10n/app_zh.arb +++ b/lib/l10n/app_zh.arb @@ -904,5 +904,13 @@ "restaurarCompras": "恢复购买", "compraError": "无法完成购买,请重试。", "restauracionSinCompras": "未在此账户中找到以前的购买记录。", - "premiumActivo": "高级版已解锁" + "premiumActivo": "高级版已解锁", + "premiumHojaTitulo": "解锁 PluriWave Premium", + "premiumBeneficioSinAnuncios": "全应用无广告", + "premiumBeneficioAndroidAuto": "Android Auto", + "premiumBeneficioGrabacion": "电台录音", + "premiumBeneficioVacaciones": "闹钟的假期时间段", + "premiumBeneficioAlarmasIlimitadas": "无限闹钟(免费版最多支持5个)", + "premiumPagoUnico": "一次性付费,永久使用,不是订阅。", + "premiumAhoraNo": "以后再说" } diff --git a/lib/l10n/gen/app_localizations.dart b/lib/l10n/gen/app_localizations.dart index 6be60e2..82e28c5 100644 --- a/lib/l10n/gen/app_localizations.dart +++ b/lib/l10n/gen/app_localizations.dart @@ -3367,6 +3367,54 @@ abstract class AppLocalizations { /// In es, this message translates to: /// **'Premium activo'** String get premiumActivo; + + /// No description provided for @premiumHojaTitulo. + /// + /// In es, this message translates to: + /// **'Desbloquea PluriWave Premium'** + String get premiumHojaTitulo; + + /// No description provided for @premiumBeneficioSinAnuncios. + /// + /// In es, this message translates to: + /// **'Sin publicidad en toda la app'** + String get premiumBeneficioSinAnuncios; + + /// No description provided for @premiumBeneficioAndroidAuto. + /// + /// In es, this message translates to: + /// **'Android Auto'** + String get premiumBeneficioAndroidAuto; + + /// No description provided for @premiumBeneficioGrabacion. + /// + /// In es, this message translates to: + /// **'Grabación de emisoras'** + String get premiumBeneficioGrabacion; + + /// No description provided for @premiumBeneficioVacaciones. + /// + /// In es, this message translates to: + /// **'Rangos de vacaciones para las alarmas'** + String get premiumBeneficioVacaciones; + + /// No description provided for @premiumBeneficioAlarmasIlimitadas. + /// + /// In es, this message translates to: + /// **'Alarmas ilimitadas (el plan gratuito permite hasta 5)'** + String get premiumBeneficioAlarmasIlimitadas; + + /// No description provided for @premiumPagoUnico. + /// + /// In es, this message translates to: + /// **'Pago único, para siempre. No es una suscripción.'** + String get premiumPagoUnico; + + /// No description provided for @premiumAhoraNo. + /// + /// In es, this message translates to: + /// **'Ahora no'** + String get premiumAhoraNo; } class _AppLocalizationsDelegate diff --git a/lib/l10n/gen/app_localizations_ar.dart b/lib/l10n/gen/app_localizations_ar.dart index e2b0952..856a93b 100644 --- a/lib/l10n/gen/app_localizations_ar.dart +++ b/lib/l10n/gen/app_localizations_ar.dart @@ -1863,4 +1863,29 @@ class AppLocalizationsAr extends AppLocalizations { @override String get premiumActivo => 'النسخة المميزة مفعّلة'; + + @override + String get premiumHojaTitulo => 'افتح PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => 'بدون إعلانات في التطبيق بالكامل'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'تسجيل المحطات'; + + @override + String get premiumBeneficioVacaciones => 'فترات إجازة للمنبهات'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'منبهات غير محدودة (تسمح الخطة المجانية بحتى 5)'; + + @override + String get premiumPagoUnico => 'دفعة واحدة، للأبد. ليس اشتراكًا.'; + + @override + String get premiumAhoraNo => 'ليس الآن'; } diff --git a/lib/l10n/gen/app_localizations_bn.dart b/lib/l10n/gen/app_localizations_bn.dart index dffb7b5..89fe034 100644 --- a/lib/l10n/gen/app_localizations_bn.dart +++ b/lib/l10n/gen/app_localizations_bn.dart @@ -1874,4 +1874,30 @@ class AppLocalizationsBn extends AppLocalizations { @override String get premiumActivo => 'প্রিমিয়াম সক্রিয়'; + + @override + String get premiumHojaTitulo => 'PluriWave Premium আনলক করুন'; + + @override + String get premiumBeneficioSinAnuncios => 'পুরো অ্যাপে কোনো বিজ্ঞাপন নেই'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'স্টেশন রেকর্ডিং'; + + @override + String get premiumBeneficioVacaciones => 'অ্যালার্মের জন্য ছুটির সময়কাল'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'সীমাহীন অ্যালার্ম (ফ্রি প্ল্যানে সর্বোচ্চ ৫টি অনুমোদিত)'; + + @override + String get premiumPagoUnico => + 'একবারের পেমেন্ট, চিরকালের জন্য। এটি সাবস্ক্রিপশন নয়।'; + + @override + String get premiumAhoraNo => 'এখন নয়'; } diff --git a/lib/l10n/gen/app_localizations_de.dart b/lib/l10n/gen/app_localizations_de.dart index 771a63d..71e29b4 100644 --- a/lib/l10n/gen/app_localizations_de.dart +++ b/lib/l10n/gen/app_localizations_de.dart @@ -1888,4 +1888,29 @@ class AppLocalizationsDe extends AppLocalizations { @override String get premiumActivo => 'Premium aktiv'; + + @override + String get premiumHojaTitulo => 'PluriWave Premium freischalten'; + + @override + String get premiumBeneficioSinAnuncios => 'Keine Werbung in der gesamten App'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Sender aufnehmen'; + + @override + String get premiumBeneficioVacaciones => 'Urlaubszeiträume für Wecker'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Unbegrenzte Wecker (die kostenlose Version erlaubt bis zu 5)'; + + @override + String get premiumPagoUnico => 'Einmalzahlung, für immer. Kein Abonnement.'; + + @override + String get premiumAhoraNo => 'Nicht jetzt'; } diff --git a/lib/l10n/gen/app_localizations_en.dart b/lib/l10n/gen/app_localizations_en.dart index e0e278c..4b26591 100644 --- a/lib/l10n/gen/app_localizations_en.dart +++ b/lib/l10n/gen/app_localizations_en.dart @@ -1867,4 +1867,30 @@ class AppLocalizationsEn extends AppLocalizations { @override String get premiumActivo => 'Premium active'; + + @override + String get premiumHojaTitulo => 'Unlock PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => 'No ads anywhere in the app'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Station recording'; + + @override + String get premiumBeneficioVacaciones => 'Vacation ranges for alarms'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Unlimited alarms (the free plan allows up to 5)'; + + @override + String get premiumPagoUnico => + 'One-time purchase, forever. Not a subscription.'; + + @override + String get premiumAhoraNo => 'Not now'; } diff --git a/lib/l10n/gen/app_localizations_es.dart b/lib/l10n/gen/app_localizations_es.dart index 81b57e5..5026540 100644 --- a/lib/l10n/gen/app_localizations_es.dart +++ b/lib/l10n/gen/app_localizations_es.dart @@ -1881,4 +1881,31 @@ class AppLocalizationsEs extends AppLocalizations { @override String get premiumActivo => 'Premium activo'; + + @override + String get premiumHojaTitulo => 'Desbloquea PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => 'Sin publicidad en toda la app'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Grabación de emisoras'; + + @override + String get premiumBeneficioVacaciones => + 'Rangos de vacaciones para las alarmas'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Alarmas ilimitadas (el plan gratuito permite hasta 5)'; + + @override + String get premiumPagoUnico => + 'Pago único, para siempre. No es una suscripción.'; + + @override + String get premiumAhoraNo => 'Ahora no'; } diff --git a/lib/l10n/gen/app_localizations_fr.dart b/lib/l10n/gen/app_localizations_fr.dart index 3bcfd4c..65d1c6a 100644 --- a/lib/l10n/gen/app_localizations_fr.dart +++ b/lib/l10n/gen/app_localizations_fr.dart @@ -1894,4 +1894,32 @@ class AppLocalizationsFr extends AppLocalizations { @override String get premiumActivo => 'Premium actif'; + + @override + String get premiumHojaTitulo => 'Débloquer PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => + 'Aucune publicité dans toute l\'application'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Enregistrement des stations'; + + @override + String get premiumBeneficioVacaciones => + 'Périodes de vacances pour les alarmes'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Alarmes illimitées (la version gratuite en autorise jusqu\'à 5)'; + + @override + String get premiumPagoUnico => + 'Achat unique, pour toujours. Ce n\'est pas un abonnement.'; + + @override + String get premiumAhoraNo => 'Plus tard'; } diff --git a/lib/l10n/gen/app_localizations_hi.dart b/lib/l10n/gen/app_localizations_hi.dart index c2d7c44..13ed2c7 100644 --- a/lib/l10n/gen/app_localizations_hi.dart +++ b/lib/l10n/gen/app_localizations_hi.dart @@ -1867,4 +1867,30 @@ class AppLocalizationsHi extends AppLocalizations { @override String get premiumActivo => 'प्रीमियम सक्रिय'; + + @override + String get premiumHojaTitulo => 'PluriWave Premium अनलॉक करें'; + + @override + String get premiumBeneficioSinAnuncios => 'पूरे ऐप में कोई विज्ञापन नहीं'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'स्टेशन रिकॉर्डिंग'; + + @override + String get premiumBeneficioVacaciones => 'अलार्म के लिए छुट्टी की अवधि'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'असीमित अलार्म (मुफ़्त प्लान में अधिकतम 5 की अनुमति है)'; + + @override + String get premiumPagoUnico => + 'एकमुश्त भुगतान, हमेशा के लिए। यह सदस्यता नहीं है।'; + + @override + String get premiumAhoraNo => 'अभी नहीं'; } diff --git a/lib/l10n/gen/app_localizations_id.dart b/lib/l10n/gen/app_localizations_id.dart index 08dbd8b..a44e4c0 100644 --- a/lib/l10n/gen/app_localizations_id.dart +++ b/lib/l10n/gen/app_localizations_id.dart @@ -1878,4 +1878,30 @@ class AppLocalizationsId extends AppLocalizations { @override String get premiumActivo => 'Premium aktif'; + + @override + String get premiumHojaTitulo => 'Buka PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => 'Tanpa iklan di seluruh aplikasi'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Perekaman stasiun'; + + @override + String get premiumBeneficioVacaciones => 'Rentang liburan untuk alarm'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Alarm tanpa batas (paket gratis mengizinkan hingga 5)'; + + @override + String get premiumPagoUnico => + 'Pembelian sekali bayar, untuk selamanya. Bukan langganan.'; + + @override + String get premiumAhoraNo => 'Nanti saja'; } diff --git a/lib/l10n/gen/app_localizations_it.dart b/lib/l10n/gen/app_localizations_it.dart index 280c271..2344dc5 100644 --- a/lib/l10n/gen/app_localizations_it.dart +++ b/lib/l10n/gen/app_localizations_it.dart @@ -1891,4 +1891,32 @@ class AppLocalizationsIt extends AppLocalizations { @override String get premiumActivo => 'Premium attivo'; + + @override + String get premiumHojaTitulo => 'Sblocca PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => + 'Nessuna pubblicità in tutta l\'app'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Registrazione delle stazioni'; + + @override + String get premiumBeneficioVacaciones => + 'Intervalli di vacanza per le sveglie'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Sveglie illimitate (il piano gratuito ne consente fino a 5)'; + + @override + String get premiumPagoUnico => + 'Acquisto unico, per sempre. Non è un abbonamento.'; + + @override + String get premiumAhoraNo => 'Non ora'; } diff --git a/lib/l10n/gen/app_localizations_ja.dart b/lib/l10n/gen/app_localizations_ja.dart index 9e3b48a..fd3abcb 100644 --- a/lib/l10n/gen/app_localizations_ja.dart +++ b/lib/l10n/gen/app_localizations_ja.dart @@ -1812,4 +1812,28 @@ class AppLocalizationsJa extends AppLocalizations { @override String get premiumActivo => 'プレミアム有効'; + + @override + String get premiumHojaTitulo => 'PluriWave Premiumのロックを解除'; + + @override + String get premiumBeneficioSinAnuncios => 'アプリ全体で広告なし'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => '放送局の録音'; + + @override + String get premiumBeneficioVacaciones => 'アラームの休暇期間設定'; + + @override + String get premiumBeneficioAlarmasIlimitadas => 'アラーム数無制限(無料プランは5個まで)'; + + @override + String get premiumPagoUnico => '買い切りの一度きりの支払いで永久に使用可能。サブスクリプションではありません。'; + + @override + String get premiumAhoraNo => '後で'; } diff --git a/lib/l10n/gen/app_localizations_pt.dart b/lib/l10n/gen/app_localizations_pt.dart index 77af60d..e18ff5e 100644 --- a/lib/l10n/gen/app_localizations_pt.dart +++ b/lib/l10n/gen/app_localizations_pt.dart @@ -1878,4 +1878,30 @@ class AppLocalizationsPt extends AppLocalizations { @override String get premiumActivo => 'Premium ativo'; + + @override + String get premiumHojaTitulo => 'Desbloqueie o PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => 'Sem anúncios em todo o app'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Gravação de emissoras'; + + @override + String get premiumBeneficioVacaciones => 'Períodos de férias para os alarmes'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Alarmes ilimitados (o plano gratuito permite até 5)'; + + @override + String get premiumPagoUnico => + 'Pagamento único, para sempre. Não é uma assinatura.'; + + @override + String get premiumAhoraNo => 'Agora não'; } diff --git a/lib/l10n/gen/app_localizations_ru.dart b/lib/l10n/gen/app_localizations_ru.dart index e30d9a6..51bcdd2 100644 --- a/lib/l10n/gen/app_localizations_ru.dart +++ b/lib/l10n/gen/app_localizations_ru.dart @@ -1884,4 +1884,31 @@ class AppLocalizationsRu extends AppLocalizations { @override String get premiumActivo => 'Премиум активен'; + + @override + String get premiumHojaTitulo => 'Разблокировать PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => + 'Никакой рекламы во всём приложении'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => 'Запись радиостанций'; + + @override + String get premiumBeneficioVacaciones => 'Периоды отпуска для будильников'; + + @override + String get premiumBeneficioAlarmasIlimitadas => + 'Неограниченное количество будильников (бесплатный план позволяет до 5)'; + + @override + String get premiumPagoUnico => + 'Единоразовая покупка, навсегда. Это не подписка.'; + + @override + String get premiumAhoraNo => 'Не сейчас'; } diff --git a/lib/l10n/gen/app_localizations_zh.dart b/lib/l10n/gen/app_localizations_zh.dart index 8c15f6d..7486964 100644 --- a/lib/l10n/gen/app_localizations_zh.dart +++ b/lib/l10n/gen/app_localizations_zh.dart @@ -1797,4 +1797,28 @@ class AppLocalizationsZh extends AppLocalizations { @override String get premiumActivo => '高级版已解锁'; + + @override + String get premiumHojaTitulo => '解锁 PluriWave Premium'; + + @override + String get premiumBeneficioSinAnuncios => '全应用无广告'; + + @override + String get premiumBeneficioAndroidAuto => 'Android Auto'; + + @override + String get premiumBeneficioGrabacion => '电台录音'; + + @override + String get premiumBeneficioVacaciones => '闹钟的假期时间段'; + + @override + String get premiumBeneficioAlarmasIlimitadas => '无限闹钟(免费版最多支持5个)'; + + @override + String get premiumPagoUnico => '一次性付费,永久使用,不是订阅。'; + + @override + String get premiumAhoraNo => '以后再说'; } diff --git a/lib/widgets/hoja_premium.dart b/lib/widgets/hoja_premium.dart index 3c9b585..d7def7d 100644 --- a/lib/widgets/hoja_premium.dart +++ b/lib/widgets/hoja_premium.dart @@ -53,14 +53,42 @@ class HojaPremium extends StatelessWidget { const SizedBox(width: 10), Expanded( child: Text( - l10n.funcionPremium, + l10n.premiumHojaTitulo, style: Theme.of(context).textTheme.titleLarge?.copyWith( fontWeight: FontWeight.w900, ), ), ), + // Explicit, obvious dismiss affordance (fix/import-alarmas-y- + // paywall): a purchase sheet the user cannot easily escape is + // a dark pattern and a Play policy risk. Reachable without + // buying or restoring, same weight as any other icon button. + IconButton( + key: const ValueKey('hoja-premium-cerrar'), + icon: const Icon(Icons.close_rounded), + tooltip: l10n.closeAction, + onPressed: () => Navigator.of(context).maybePop(), + ), ], ), + const SizedBox(height: 12), + // Concrete, honest value list — accuracy is non-negotiable here: + // these five are the ONLY things premium unlocks. The phone + // equalizer stays free for everyone and must NEVER appear here; + // only its Android Auto surface is affected, as a consequence of + // Auto itself being gated. + _BeneficioPremium(texto: l10n.premiumBeneficioSinAnuncios), + _BeneficioPremium(texto: l10n.premiumBeneficioAndroidAuto), + _BeneficioPremium(texto: l10n.premiumBeneficioGrabacion), + _BeneficioPremium(texto: l10n.premiumBeneficioVacaciones), + _BeneficioPremium(texto: l10n.premiumBeneficioAlarmasIlimitadas), + const SizedBox(height: 12), + Text( + l10n.premiumPagoUnico, + style: Theme.of( + context, + ).textTheme.bodyMedium?.copyWith(fontWeight: FontWeight.w600), + ), const SizedBox(height: 20), // FIX 3 (code review): user-facing feedback for a failed // purchase/restore, or a restore that found nothing — before @@ -143,9 +171,49 @@ class HojaPremium extends StatelessWidget { : () => entitlement.restaurar(), child: Text(l10n.restaurarCompras), ), + if (!entitlement.esPremium) ...[ + const SizedBox(height: 4), + // Clearly-labelled, always-reachable decline — same weight as + // any other secondary action, never made harder to find than + // buying (hard constraint: no dark patterns, no guilt-shaming + // decline copy). + TextButton( + key: const ValueKey('hoja-premium-ahora-no'), + onPressed: () => Navigator.of(context).maybePop(), + child: Text(l10n.premiumAhoraNo), + ), + ], ], ), ), ); } } + +/// One concrete, honest value-list row (fix/import-alarmas-y-paywall). +class _BeneficioPremium extends StatelessWidget { + const _BeneficioPremium({required this.texto}); + + final String texto; + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(bottom: 8), + child: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Icon( + Icons.check_circle_rounded, + size: 18, + color: PluriWaveTokens.brand, + ), + const SizedBox(width: 8), + Expanded( + child: Text(texto, style: Theme.of(context).textTheme.bodyMedium), + ), + ], + ), + ); + } +} diff --git a/test/l10n/identical_value_allowlist.dart b/test/l10n/identical_value_allowlist.dart index 73ba388..11f3661 100644 --- a/test/l10n/identical_value_allowlist.dart +++ b/test/l10n/identical_value_allowlist.dart @@ -46,6 +46,20 @@ const Set<(String locale, String key)> identicalValueAllowlist = { ('pt', 'welcomeBullet2Title'), ('ru', 'welcomeBullet2Title'), ('zh', 'welcomeBullet2Title'), + ( + 'ar', + 'premiumBeneficioAndroidAuto', + ), // "Android Auto" -- Google product name (fix/import-alarmas-y-paywall) + ('bn', 'premiumBeneficioAndroidAuto'), + ('de', 'premiumBeneficioAndroidAuto'), + ('fr', 'premiumBeneficioAndroidAuto'), + ('hi', 'premiumBeneficioAndroidAuto'), + ('id', 'premiumBeneficioAndroidAuto'), + ('it', 'premiumBeneficioAndroidAuto'), + ('ja', 'premiumBeneficioAndroidAuto'), + ('pt', 'premiumBeneficioAndroidAuto'), + ('ru', 'premiumBeneficioAndroidAuto'), + ('zh', 'premiumBeneficioAndroidAuto'), // --------------------------------------------------------------------- // Pure symbols / placeholders -- no translatable text at all. diff --git a/test/widgets/hoja_premium_test.dart b/test/widgets/hoja_premium_test.dart index 9dc15b6..dc7d92b 100644 --- a/test/widgets/hoja_premium_test.dart +++ b/test/widgets/hoja_premium_test.dart @@ -9,6 +9,12 @@ import 'package:pluriwave/widgets/hoja_premium.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; +/// fix/import-alarmas-y-paywall: a purchase sheet the user cannot escape is +/// a dark pattern and a Play policy risk. These cover the dismiss +/// affordance, the honest/concrete feature list, and the equalizer guard +/// (the phone equalizer is free for everyone and must never be presented as +/// a premium feature — this has regressed conceptually before). + /// Fake [PuertoCompras] (mirrors `app_test.dart`'s own fake): lets a test /// drive [EstadoEntitlement]'s purchase-stream events without touching /// `in_app_purchase`. @@ -68,6 +74,150 @@ void main() { return estado; } + /// Presents `HojaPremium` through the REAL `mostrarHojaPremium` modal + /// route (unlike [bombear], which embeds it directly with no route to + /// pop) so the dismiss controls can be exercised end-to-end exactly as a + /// user would encounter them. + Future bombearComoHoja( + WidgetTester tester, { + required _PuertoComprasFalso compras, + }) async { + await tester.pumpWidget( + MultiProvider( + providers: [ + ChangeNotifierProvider( + create: (_) => EstadoEntitlement(prefs: null, compras: compras), + ), + ], + child: MaterialApp( + locale: const Locale('es'), + localizationsDelegates: AppLocalizations.localizationsDelegates, + supportedLocales: AppLocalizations.supportedLocales, + home: Builder( + builder: + (context) => Scaffold( + body: TextButton( + onPressed: () => mostrarHojaPremium(context), + child: const Text('abrir'), + ), + ), + ), + ), + ), + ); + await tester.pump(); + await tester.tap(find.text('abrir')); + await tester.pumpAndSettle(); + l10n = AppLocalizations.of(tester.element(find.byType(HojaPremium))); + } + + group('fix/import-alarmas-y-paywall — dismissibility', () { + testWidgets('the close (X) control closes the sheet without purchasing or ' + 'restoring', (tester) async { + final compras = _PuertoComprasFalso(); + addTearDown(compras.dispose); + await bombearComoHoja(tester, compras: compras); + + expect(find.byType(HojaPremium), findsOneWidget); + + await tester.tap(find.byKey(const ValueKey('hoja-premium-cerrar'))); + await tester.pumpAndSettle(); + + expect(find.byType(HojaPremium), findsNothing); + }); + + testWidgets( + 'the "not now" secondary action closes the sheet without purchasing ' + 'or restoring', + (tester) async { + final compras = _PuertoComprasFalso(); + addTearDown(compras.dispose); + await bombearComoHoja(tester, compras: compras); + + expect(find.byType(HojaPremium), findsOneWidget); + + await tester.tap(find.byKey(const ValueKey('hoja-premium-ahora-no'))); + await tester.pumpAndSettle(); + + expect(find.byType(HojaPremium), findsNothing); + }, + ); + + testWidgets('the system back gesture also closes the sheet (default ' + 'isDismissible/enableDrag, no PopScope blocking it)', (tester) async { + final compras = _PuertoComprasFalso(); + addTearDown(compras.dispose); + await bombearComoHoja(tester, compras: compras); + + expect(find.byType(HojaPremium), findsOneWidget); + + await tester.binding.handlePopRoute(); + await tester.pumpAndSettle(); + + expect(find.byType(HojaPremium), findsNothing); + }); + + testWidgets( + 'an already-premium user still gets the close control (no decline ' + 'needed) and no "not now" button', + (tester) async { + SharedPreferences.setMockInitialValues({'compra_premium_v1': true}); + final compras = _PuertoComprasFalso(); + addTearDown(compras.dispose); + await bombearComoHoja(tester, compras: compras); + + expect( + find.byKey(const ValueKey('hoja-premium-cerrar')), + findsOneWidget, + ); + expect( + find.byKey(const ValueKey('hoja-premium-ahora-no')), + findsNothing, + ); + }, + ); + }); + + group('fix/import-alarmas-y-paywall — honest, concrete copy', () { + testWidgets('lists the 5 features premium actually unlocks', ( + tester, + ) async { + final compras = _PuertoComprasFalso(); + addTearDown(compras.dispose); + await bombear(tester, compras: compras); + + expect(find.text(l10n.premiumBeneficioSinAnuncios), findsOneWidget); + expect(find.text(l10n.premiumBeneficioAndroidAuto), findsOneWidget); + expect(find.text(l10n.premiumBeneficioGrabacion), findsOneWidget); + expect(find.text(l10n.premiumBeneficioVacaciones), findsOneWidget); + expect(find.text(l10n.premiumBeneficioAlarmasIlimitadas), findsOneWidget); + }); + + testWidgets('states this is a one-time purchase, not a subscription', ( + tester, + ) async { + final compras = _PuertoComprasFalso(); + addTearDown(compras.dispose); + await bombear(tester, compras: compras); + + expect(find.text(l10n.premiumPagoUnico), findsOneWidget); + }); + + testWidgets( + 'GUARD: the phone equalizer is never presented as a premium feature', + (tester) async { + final compras = _PuertoComprasFalso(); + addTearDown(compras.dispose); + await bombear(tester, compras: compras); + + expect(find.text(l10n.equalizerTitle), findsNothing); + expect(find.text(l10n.equalizerActive), findsNothing); + expect(find.textContaining('cualizador'), findsNothing); + expect(find.textContaining('qualizer'), findsNothing); + }, + ); + }); + group( 'FIX 9 — la etiqueta de premium activo es propia, no la del ecualizador', () {