fix(iap): address code review defects in freemium/IAP change
Fixes 9 of 10 review findings (10th requires a manual Play Console step, no code change): 1. app.dart/banner_anuncio_superior.dart: move the top SafeArea inside BannerAnuncioSuperior so it only reserves status-bar height when an ad actually renders, restoring edge-to-edge layout for premium and free-unloaded users. 2. servicio_anuncios.dart: bound every interstitial await (load, presentation, and the injected implementation itself) with injectable timeouts so a callback that never fires can no longer hang a caller. 3. estado_entitlement.dart/hoja_premium.dart: expose a typed resultadoUsuario signal for purchase/restore failures and restore-found-nothing, with dedicated localized messages (compraError, restauracionSinCompras) across all 13 locales -- never the raw developer/exception string. 4. main.dart/servicio_consentimiento.dart: add a GDPR/UMP consent flow (ConsentInformation/ConsentForm) that gates Mobile Ads SDK init on canRequestAds(); premium users never see a consent form; failures degrade to no ads instead of crashing or blocking startup. 6. servicio_anuncios.dart: track real ad presentation (onAdShowedFullScreenContent) so a failed-to-show interstitial no longer consumes a session cap slot. 7. banner_anuncio_superior.dart: add an explicit load-attempted guard so repeated didChangeDependencies (e.g. entitlement notifyListeners during a purchase) can only ever trigger one banner load attempt. 8. servicio_anuncios.dart: make esPremium a required constructor parameter, matching the hardened contract already applied to EstadoAlarmas/EstadoGrabacion/EstadoRadio. 9. hoja_premium.dart: add a dedicated premiumActivo localized string instead of reusing the equalizer's equalizerActive translation, across all 13 locales. All fixes implemented RED-first (failing test before production code). Full suite: 1261 passed, 2 pre-existing skips, 0 failures. flutter analyze: 5 pre-existing issues only, 0 new. [version set]
This commit is contained in:
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "ميزة مميزة",
|
||||
"limiteAlarmasAlcanzado": "لقد وصلت إلى الحد المجاني وهو 5 منبهات.",
|
||||
"desbloquearPremium": "فتح النسخة المميزة",
|
||||
"restaurarCompras": "استعادة المشتريات"
|
||||
"restaurarCompras": "استعادة المشتريات",
|
||||
"compraError": "تعذّر إتمام عملية الشراء. حاول مرة أخرى.",
|
||||
"restauracionSinCompras": "لم نجد أي عملية شراء سابقة في هذا الحساب.",
|
||||
"premiumActivo": "النسخة المميزة مفعّلة"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "প্রিমিয়াম বৈশিষ্ট্য",
|
||||
"limiteAlarmasAlcanzado": "আপনি বিনামূল্যে ৫টি অ্যালার্মের সীমায় পৌঁছেছেন।",
|
||||
"desbloquearPremium": "প্রিমিয়াম আনলক করুন",
|
||||
"restaurarCompras": "কেনাকাটা পুনরুদ্ধার করুন"
|
||||
"restaurarCompras": "কেনাকাটা পুনরুদ্ধার করুন",
|
||||
"compraError": "কেনাকাটা সম্পূর্ণ করা যায়নি। আবার চেষ্টা করুন।",
|
||||
"restauracionSinCompras": "এই অ্যাকাউন্টে আমরা আগের কোনো কেনাকাটা খুঁজে পাইনি।",
|
||||
"premiumActivo": "প্রিমিয়াম সক্রিয়"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "Premium-Funktion",
|
||||
"limiteAlarmasAlcanzado": "Du hast das kostenlose Limit von 5 Weckern erreicht.",
|
||||
"desbloquearPremium": "Premium freischalten",
|
||||
"restaurarCompras": "Käufe wiederherstellen"
|
||||
"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"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "Premium Feature",
|
||||
"limiteAlarmasAlcanzado": "You've reached the free 5-alarm limit.",
|
||||
"desbloquearPremium": "Unlock Premium",
|
||||
"restaurarCompras": "Restore purchases"
|
||||
"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"
|
||||
}
|
||||
|
||||
+4
-1
@@ -860,5 +860,8 @@
|
||||
"funcionPremium": "Función Premium",
|
||||
"limiteAlarmasAlcanzado": "Has alcanzado el límite de 5 alarmas gratuitas.",
|
||||
"desbloquearPremium": "Desbloquear Premium",
|
||||
"restaurarCompras": "Restaurar compras"
|
||||
"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"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "Fonctionnalité Premium",
|
||||
"limiteAlarmasAlcanzado": "Vous avez atteint la limite gratuite de 5 alarmes.",
|
||||
"desbloquearPremium": "Débloquer Premium",
|
||||
"restaurarCompras": "Restaurer les achats"
|
||||
"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"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "प्रीमियम सुविधा",
|
||||
"limiteAlarmasAlcanzado": "आप मुफ़्त 5 अलार्म की सीमा तक पहुँच गए हैं।",
|
||||
"desbloquearPremium": "प्रीमियम अनलॉक करें",
|
||||
"restaurarCompras": "खरीदारी पुनर्स्थापित करें"
|
||||
"restaurarCompras": "खरीदारी पुनर्स्थापित करें",
|
||||
"compraError": "खरीद पूरी नहीं हो सकी। कृपया फिर से प्रयास करें।",
|
||||
"restauracionSinCompras": "इस खाते में हमें कोई पिछली खरीद नहीं मिली।",
|
||||
"premiumActivo": "प्रीमियम सक्रिय"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "Fitur Premium",
|
||||
"limiteAlarmasAlcanzado": "Anda telah mencapai batas gratis 5 alarm.",
|
||||
"desbloquearPremium": "Buka Premium",
|
||||
"restaurarCompras": "Pulihkan pembelian"
|
||||
"restaurarCompras": "Pulihkan pembelian",
|
||||
"compraError": "Pembelian tidak dapat diselesaikan. Silakan coba lagi.",
|
||||
"restauracionSinCompras": "Kami tidak menemukan pembelian sebelumnya di akun ini.",
|
||||
"premiumActivo": "Premium aktif"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "Funzione Premium",
|
||||
"limiteAlarmasAlcanzado": "Hai raggiunto il limite gratuito di 5 sveglie.",
|
||||
"desbloquearPremium": "Sblocca Premium",
|
||||
"restaurarCompras": "Ripristina acquisti"
|
||||
"restaurarCompras": "Ripristina acquisti",
|
||||
"compraError": "Non è stato possibile completare l'acquisto. Riprova.",
|
||||
"restauracionSinCompras": "Non abbiamo trovato acquisti precedenti su questo account.",
|
||||
"premiumActivo": "Premium attivo"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "プレミアム機能",
|
||||
"limiteAlarmasAlcanzado": "無料プランのアラーム上限(5件)に達しました。",
|
||||
"desbloquearPremium": "プレミアムを解除",
|
||||
"restaurarCompras": "購入を復元"
|
||||
"restaurarCompras": "購入を復元",
|
||||
"compraError": "購入を完了できませんでした。もう一度お試しください。",
|
||||
"restauracionSinCompras": "このアカウントでは以前の購入が見つかりませんでした。",
|
||||
"premiumActivo": "プレミアム有効"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "Recurso Premium",
|
||||
"limiteAlarmasAlcanzado": "Você atingiu o limite gratuito de 5 alarmes.",
|
||||
"desbloquearPremium": "Desbloquear Premium",
|
||||
"restaurarCompras": "Restaurar compras"
|
||||
"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"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "Премиум-функция",
|
||||
"limiteAlarmasAlcanzado": "Вы достигли бесплатного лимита в 5 будильников.",
|
||||
"desbloquearPremium": "Разблокировать Премиум",
|
||||
"restaurarCompras": "Восстановить покупки"
|
||||
"restaurarCompras": "Восстановить покупки",
|
||||
"compraError": "Не удалось завершить покупку. Попробуйте ещё раз.",
|
||||
"restauracionSinCompras": "Мы не нашли предыдущих покупок на этом аккаунте.",
|
||||
"premiumActivo": "Премиум активен"
|
||||
}
|
||||
|
||||
+4
-1
@@ -901,5 +901,8 @@
|
||||
"funcionPremium": "高级功能",
|
||||
"limiteAlarmasAlcanzado": "您已达到免费版 5 个闹钟的上限。",
|
||||
"desbloquearPremium": "解锁高级版",
|
||||
"restaurarCompras": "恢复购买"
|
||||
"restaurarCompras": "恢复购买",
|
||||
"compraError": "无法完成购买,请重试。",
|
||||
"restauracionSinCompras": "未在此账户中找到以前的购买记录。",
|
||||
"premiumActivo": "高级版已解锁"
|
||||
}
|
||||
|
||||
@@ -3349,6 +3349,24 @@ abstract class AppLocalizations {
|
||||
/// In es, this message translates to:
|
||||
/// **'Restaurar compras'**
|
||||
String get restaurarCompras;
|
||||
|
||||
/// No description provided for @compraError.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'No se ha podido completar la compra. Inténtalo de nuevo.'**
|
||||
String get compraError;
|
||||
|
||||
/// No description provided for @restauracionSinCompras.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'No hemos encontrado ninguna compra anterior en esta cuenta.'**
|
||||
String get restauracionSinCompras;
|
||||
|
||||
/// No description provided for @premiumActivo.
|
||||
///
|
||||
/// In es, this message translates to:
|
||||
/// **'Premium activo'**
|
||||
String get premiumActivo;
|
||||
}
|
||||
|
||||
class _AppLocalizationsDelegate
|
||||
|
||||
@@ -1853,4 +1853,14 @@ class AppLocalizationsAr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'استعادة المشتريات';
|
||||
|
||||
@override
|
||||
String get compraError => 'تعذّر إتمام عملية الشراء. حاول مرة أخرى.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'لم نجد أي عملية شراء سابقة في هذا الحساب.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'النسخة المميزة مفعّلة';
|
||||
}
|
||||
|
||||
@@ -1864,4 +1864,14 @@ class AppLocalizationsBn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'কেনাকাটা পুনরুদ্ধার করুন';
|
||||
|
||||
@override
|
||||
String get compraError => 'কেনাকাটা সম্পূর্ণ করা যায়নি। আবার চেষ্টা করুন।';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'এই অ্যাকাউন্টে আমরা আগের কোনো কেনাকাটা খুঁজে পাইনি।';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'প্রিমিয়াম সক্রিয়';
|
||||
}
|
||||
|
||||
@@ -1877,4 +1877,15 @@ class AppLocalizationsDe extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Käufe wiederherstellen';
|
||||
|
||||
@override
|
||||
String get compraError =>
|
||||
'Der Kauf konnte nicht abgeschlossen werden. Bitte versuche es erneut.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'Wir haben auf diesem Konto keinen früheren Kauf gefunden.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Premium aktiv';
|
||||
}
|
||||
|
||||
@@ -1856,4 +1856,15 @@ class AppLocalizationsEn extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Restore purchases';
|
||||
|
||||
@override
|
||||
String get compraError =>
|
||||
'We couldn\'t complete the purchase. Please try again.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'We didn\'t find any previous purchase on this account.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Premium active';
|
||||
}
|
||||
|
||||
@@ -1870,4 +1870,15 @@ class AppLocalizationsEs extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Restaurar compras';
|
||||
|
||||
@override
|
||||
String get compraError =>
|
||||
'No se ha podido completar la compra. Inténtalo de nuevo.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'No hemos encontrado ninguna compra anterior en esta cuenta.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Premium activo';
|
||||
}
|
||||
|
||||
@@ -1883,4 +1883,15 @@ class AppLocalizationsFr extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Restaurer les achats';
|
||||
|
||||
@override
|
||||
String get compraError =>
|
||||
'Impossible de finaliser l\'achat. Veuillez réessayer.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'Nous n\'avons trouvé aucun achat antérieur sur ce compte.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Premium actif';
|
||||
}
|
||||
|
||||
@@ -1857,4 +1857,14 @@ class AppLocalizationsHi extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'खरीदारी पुनर्स्थापित करें';
|
||||
|
||||
@override
|
||||
String get compraError => 'खरीद पूरी नहीं हो सकी। कृपया फिर से प्रयास करें।';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'इस खाते में हमें कोई पिछली खरीद नहीं मिली।';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'प्रीमियम सक्रिय';
|
||||
}
|
||||
|
||||
@@ -1867,4 +1867,15 @@ class AppLocalizationsId extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Pulihkan pembelian';
|
||||
|
||||
@override
|
||||
String get compraError =>
|
||||
'Pembelian tidak dapat diselesaikan. Silakan coba lagi.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'Kami tidak menemukan pembelian sebelumnya di akun ini.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Premium aktif';
|
||||
}
|
||||
|
||||
@@ -1880,4 +1880,15 @@ class AppLocalizationsIt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Ripristina acquisti';
|
||||
|
||||
@override
|
||||
String get compraError =>
|
||||
'Non è stato possibile completare l\'acquisto. Riprova.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'Non abbiamo trovato acquisti precedenti su questo account.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Premium attivo';
|
||||
}
|
||||
|
||||
@@ -1803,4 +1803,13 @@ class AppLocalizationsJa extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => '購入を復元';
|
||||
|
||||
@override
|
||||
String get compraError => '購入を完了できませんでした。もう一度お試しください。';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras => 'このアカウントでは以前の購入が見つかりませんでした。';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'プレミアム有効';
|
||||
}
|
||||
|
||||
@@ -1867,4 +1867,15 @@ class AppLocalizationsPt extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Restaurar compras';
|
||||
|
||||
@override
|
||||
String get compraError =>
|
||||
'Não foi possível concluir a compra. Tente novamente.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'Não encontramos nenhuma compra anterior nesta conta.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Premium ativo';
|
||||
}
|
||||
|
||||
@@ -1874,4 +1874,14 @@ class AppLocalizationsRu extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => 'Восстановить покупки';
|
||||
|
||||
@override
|
||||
String get compraError => 'Не удалось завершить покупку. Попробуйте ещё раз.';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras =>
|
||||
'Мы не нашли предыдущих покупок на этом аккаунте.';
|
||||
|
||||
@override
|
||||
String get premiumActivo => 'Премиум активен';
|
||||
}
|
||||
|
||||
@@ -1788,4 +1788,13 @@ class AppLocalizationsZh extends AppLocalizations {
|
||||
|
||||
@override
|
||||
String get restaurarCompras => '恢复购买';
|
||||
|
||||
@override
|
||||
String get compraError => '无法完成购买,请重试。';
|
||||
|
||||
@override
|
||||
String get restauracionSinCompras => '未在此账户中找到以前的购买记录。';
|
||||
|
||||
@override
|
||||
String get premiumActivo => '高级版已解锁';
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user