diff --git a/lib/generated/intl/messages_en.dart b/lib/generated/intl/messages_en.dart index ad75c50ab..0ba42a0d0 100644 --- a/lib/generated/intl/messages_en.dart +++ b/lib/generated/intl/messages_en.dart @@ -23,6 +23,9 @@ class MessageLookup extends MessageLookupByLibrary { static String m0(count) => "${Intl.plural(count, one: 'Add item', other: 'Add items')}"; + static String m64(storageAmount, endDate) => + "Your ${storageAmount} add-on is valid till ${endDate}"; + static String m1(emailOrName) => "Added by ${emailOrName}"; static String m2(albumName) => "Added successfully to ${albumName}"; @@ -135,9 +138,9 @@ class MessageLookup extends MessageLookupByLibrary { static String m40(userEmail) => "${userEmail} will be removed from this shared album\n\nAny photos added by them will also be removed from the album"; - static String m41(endDate) => "Renews on ${endDate}"; + static String m41(endDate) => "Subscription renews on ${endDate}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, one: '${count} result found', other: '${count} results found')}"; static String m42(count) => "${count} selected"; @@ -190,7 +193,7 @@ class MessageLookup extends MessageLookupByLibrary { static String m59(count) => "${Intl.plural(count, zero: '', one: '1 day', other: '${count} days')}"; - static String m65(endDate) => "Valid till ${endDate}"; + static String m66(endDate) => "Valid till ${endDate}"; static String m60(email) => "Verify ${email}"; @@ -226,6 +229,7 @@ class MessageLookup extends MessageLookupByLibrary { "addNew": MessageLookupByLibrary.simpleMessage("Add new"), "addOnPageSubtitle": MessageLookupByLibrary.simpleMessage("Details of add-ons"), + "addOnValidTill": m64, "addOns": MessageLookupByLibrary.simpleMessage("Add-ons"), "addPhotos": MessageLookupByLibrary.simpleMessage("Add photos"), "addSelected": MessageLookupByLibrary.simpleMessage("Add selected"), @@ -1132,7 +1136,7 @@ class MessageLookup extends MessageLookupByLibrary { "Group photos that are taken within some radius of a photo"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Invite people, and you\'ll see all photos shared by them here"), - "searchResultCount": m64, + "searchResultCount": m65, "security": MessageLookupByLibrary.simpleMessage("Security"), "selectAlbum": MessageLookupByLibrary.simpleMessage("Select album"), "selectAll": MessageLookupByLibrary.simpleMessage("Select all"), @@ -1381,7 +1385,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Use selected photo"), "usedSpace": MessageLookupByLibrary.simpleMessage("Used space"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Verification failed, please try again"), diff --git a/lib/generated/intl/messages_fr.dart b/lib/generated/intl/messages_fr.dart index 79391df74..4a76e7b4e 100644 --- a/lib/generated/intl/messages_fr.dart +++ b/lib/generated/intl/messages_fr.dart @@ -140,7 +140,7 @@ class MessageLookup extends MessageLookupByLibrary { static String m41(endDate) => "Renouvellement le ${endDate}"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, one: '${count} résultat trouvé', other: '${count} résultats trouvés')}"; static String m42(count) => "${count} sélectionné(s)"; @@ -192,7 +192,7 @@ class MessageLookup extends MessageLookupByLibrary { static String m59(count) => "${Intl.plural(count, zero: '0 jour', one: '1 jour', other: '${count} jours')}"; - static String m65(endDate) => "Valable jusqu\'au ${endDate}"; + static String m66(endDate) => "Valable jusqu\'au ${endDate}"; static String m60(email) => "Vérifier ${email}"; @@ -1193,7 +1193,7 @@ class MessageLookup extends MessageLookupByLibrary { "Grouper les photos qui sont prises dans un certain angle d\'une photo"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage( "Invitez des gens, et vous verrez ici toutes les photos qu\'ils partagent"), - "searchResultCount": m64, + "searchResultCount": m65, "security": MessageLookupByLibrary.simpleMessage("Sécurité"), "selectAlbum": MessageLookupByLibrary.simpleMessage("Sélectionner album"), @@ -1463,7 +1463,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage( "Utiliser la photo sélectionnée"), "usedSpace": MessageLookupByLibrary.simpleMessage("Mémoire utilisée"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "La vérification a échouée, veuillez réessayer"), diff --git a/lib/generated/intl/messages_it.dart b/lib/generated/intl/messages_it.dart index 359f6d569..eaabb326b 100644 --- a/lib/generated/intl/messages_it.dart +++ b/lib/generated/intl/messages_it.dart @@ -187,7 +187,7 @@ class MessageLookup extends MessageLookupByLibrary { static String m59(count) => "${Intl.plural(count, zero: '', one: '1 giorno', other: '${count} giorni')}"; - static String m65(endDate) => "Valido fino al ${endDate}"; + static String m66(endDate) => "Valido fino al ${endDate}"; static String m60(email) => "Verifica ${email}"; @@ -1391,7 +1391,7 @@ class MessageLookup extends MessageLookupByLibrary { "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("Usa la foto selezionata"), "usedSpace": MessageLookupByLibrary.simpleMessage("Spazio utilizzato"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage( "Verifica fallita, per favore prova di nuovo"), diff --git a/lib/generated/intl/messages_zh.dart b/lib/generated/intl/messages_zh.dart index 9370da75e..674da416c 100644 --- a/lib/generated/intl/messages_zh.dart +++ b/lib/generated/intl/messages_zh.dart @@ -127,7 +127,7 @@ class MessageLookup extends MessageLookupByLibrary { static String m41(endDate) => "在 ${endDate} 前续费"; - static String m64(count) => + static String m65(count) => "${Intl.plural(count, other: '已找到 ${count} 个结果')}"; static String m42(count) => "已选择 ${count} 个"; @@ -173,7 +173,7 @@ class MessageLookup extends MessageLookupByLibrary { static String m59(count) => "${Intl.plural(count, zero: '', one: '1天', other: '${count} 天')}"; - static String m65(endDate) => "有效期至 ${endDate}"; + static String m66(endDate) => "有效期至 ${endDate}"; static String m60(email) => "验证 ${email}"; @@ -749,6 +749,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("没有隐藏的照片或视频"), "noImagesWithLocation": MessageLookupByLibrary.simpleMessage("没有带有位置的图像"), + "noInternetConnection": MessageLookupByLibrary.simpleMessage("无互联网连接"), "noPhotosAreBeingBackedUpRightNow": MessageLookupByLibrary.simpleMessage("目前没有照片正在备份"), "noPhotosFoundHere": MessageLookupByLibrary.simpleMessage("这里没有找到照片"), @@ -807,6 +808,8 @@ class MessageLookup extends MessageLookupByLibrary { "playStoreFreeTrialValidTill": m35, "playstoreSubscription": MessageLookupByLibrary.simpleMessage("PlayStore 订阅"), + "pleaseCheckYourInternetConnectionAndTryAgain": + MessageLookupByLibrary.simpleMessage("请检查您的互联网连接,然后重试。"), "pleaseContactSupportAndWeWillBeHappyToHelp": MessageLookupByLibrary.simpleMessage( "请用英语联系 support@ente.io ,我们将乐意提供帮助!"), @@ -944,7 +947,7 @@ class MessageLookup extends MessageLookupByLibrary { MessageLookupByLibrary.simpleMessage("在照片的一定半径内拍摄的几组照片"), "searchPeopleEmptySection": MessageLookupByLibrary.simpleMessage("邀请他人,您将在此看到他们分享的所有照片"), - "searchResultCount": m64, + "searchResultCount": m65, "security": MessageLookupByLibrary.simpleMessage("安全"), "selectAlbum": MessageLookupByLibrary.simpleMessage("选择相册"), "selectAll": MessageLookupByLibrary.simpleMessage("全选"), @@ -1155,7 +1158,7 @@ class MessageLookup extends MessageLookupByLibrary { "useRecoveryKey": MessageLookupByLibrary.simpleMessage("使用恢复密钥"), "useSelectedPhoto": MessageLookupByLibrary.simpleMessage("使用所选照片"), "usedSpace": MessageLookupByLibrary.simpleMessage("已用空间"), - "validTill": m65, + "validTill": m66, "verificationFailedPleaseTryAgain": MessageLookupByLibrary.simpleMessage("验证失败,请重试"), "verificationId": MessageLookupByLibrary.simpleMessage("验证 ID"), diff --git a/lib/generated/l10n.dart b/lib/generated/l10n.dart index 1c2421f77..9dbddb101 100644 --- a/lib/generated/l10n.dart +++ b/lib/generated/l10n.dart @@ -3894,10 +3894,10 @@ class S { ); } - /// `Renews on {endDate}` + /// `Subscription renews on {endDate}` String renewsOn(Object endDate) { return Intl.message( - 'Renews on $endDate', + 'Subscription renews on $endDate', name: 'renewsOn', desc: '', args: [endDate], @@ -3924,6 +3924,16 @@ class S { ); } + /// `Your {storageAmount} add-on is valid till {endDate}` + String addOnValidTill(Object storageAmount, Object endDate) { + return Intl.message( + 'Your $storageAmount add-on is valid till $endDate', + name: 'addOnValidTill', + desc: '', + args: [storageAmount, endDate], + ); + } + /// `Free trial valid till {endDate}.\nYou can choose a paid plan afterwards.` String playStoreFreeTrialValidTill(Object endDate) { return Intl.message( diff --git a/lib/l10n/intl_en.arb b/lib/l10n/intl_en.arb index 92b293cd9..39ff3f697 100644 --- a/lib/l10n/intl_en.arb +++ b/lib/l10n/intl_en.arb @@ -555,9 +555,10 @@ "type": "text" }, "faqs": "FAQs", - "renewsOn": "Renews on {endDate}", + "renewsOn": "Subscription renews on {endDate}", "freeTrialValidTill": "Free trial valid till {endDate}", "validTill": "Valid till {endDate}", + "addOnValidTill": "Your {storageAmount} add-on is valid till {endDate}", "playStoreFreeTrialValidTill": "Free trial valid till {endDate}.\nYou can choose a paid plan afterwards.", "subWillBeCancelledOn": "Your subscription will be cancelled on {endDate}", "subscription": "Subscription", diff --git a/lib/ui/payment/store_subscription_page.dart b/lib/ui/payment/store_subscription_page.dart index d9a95f684..722d6d5d2 100644 --- a/lib/ui/payment/store_subscription_page.dart +++ b/lib/ui/payment/store_subscription_page.dart @@ -52,6 +52,7 @@ class _StoreSubscriptionPageState extends State { late ProgressDialog _dialog; late UserDetails _userDetails; late bool _hasActiveSubscription; + bool _hideCurrentPlanSelection = false; late FreePlan _freePlan; late List _plans; bool _hasLoadedData = false; @@ -177,7 +178,10 @@ class _StoreSubscriptionPageState extends State { _userService.getUserDetailsV2(memoryCount: false).then((userDetails) async { _userDetails = userDetails; _currentSubscription = userDetails.subscription; + _hasActiveSubscription = _currentSubscription!.isValid(); + _hideCurrentPlanSelection = + _currentSubscription?.attributes?.isCancelled ?? false; showYearlyPlan = _currentSubscription!.isYearlyPlan(); final billingPlans = await _billingService.getBillingPlans(); _isActiveStripeSubscriber = @@ -239,7 +243,7 @@ class _StoreSubscriptionPageState extends State { widgets.add(_showSubscriptionToggle()); } - if (_hasActiveSubscription) { + if (_currentSubscription != null) { widgets.add( ValidityWidget( currentSubscription: _currentSubscription, @@ -458,7 +462,7 @@ class _StoreSubscriptionPageState extends State { storage: plan.storage, price: plan.price, period: plan.period, - isActive: isActive, + isActive: isActive && !_hideCurrentPlanSelection, ), ), ), diff --git a/lib/ui/payment/stripe_subscription_page.dart b/lib/ui/payment/stripe_subscription_page.dart index 54a551b7d..e205fb062 100644 --- a/lib/ui/payment/stripe_subscription_page.dart +++ b/lib/ui/payment/stripe_subscription_page.dart @@ -53,6 +53,7 @@ class _StripeSubscriptionPageState extends State { // indicates if user's subscription plan is still active late bool _hasActiveSubscription; + bool _hideCurrentPlanSelection = false; late FreePlan _freePlan; List _plans = []; bool _hasLoadedData = false; @@ -73,7 +74,11 @@ class _StripeSubscriptionPageState extends State { .then((userDetails) async { _userDetails = userDetails; _currentSubscription = userDetails.subscription; + _showYearlyPlan = _currentSubscription!.isYearlyPlan(); + _hideCurrentPlanSelection = + (_currentSubscription?.attributes?.isCancelled ?? false) && + userDetails.hasPaidAddon(); _hasActiveSubscription = _currentSubscription!.isValid(); _isStripeSubscriber = _currentSubscription!.paymentProvider == stripe; return _filterStripeForUI().then((value) { @@ -210,7 +215,7 @@ class _StripeSubscriptionPageState extends State { widgets.add(_showSubscriptionToggle()); - if (_hasActiveSubscription) { + if (_currentSubscription != null) { widgets.add( ValidityWidget( currentSubscription: _currentSubscription, @@ -340,6 +345,9 @@ class _StripeSubscriptionPageState extends State { Widget _stripeRenewOrCancelButton() { final bool isRenewCancelled = _currentSubscription!.attributes?.isCancelled ?? false; + if (isRenewCancelled && _userDetails.hasPaidAddon()) { + return const SizedBox.shrink(); + } final String title = isRenewCancelled ? S.of(context).renewSubscription : S.of(context).cancelSubscription; @@ -503,7 +511,7 @@ class _StripeSubscriptionPageState extends State { storage: plan.storage, price: plan.price, period: plan.period, - isActive: isActive, + isActive: isActive && !_hideCurrentPlanSelection, ), ), ), @@ -594,7 +602,7 @@ class _StripeSubscriptionPageState extends State { storage: _currentSubscription!.storage, price: _currentSubscription!.price, period: _currentSubscription!.period, - isActive: true, + isActive: !_hasActiveSubscription, ), ), ), diff --git a/lib/ui/payment/subscription_common_widgets.dart b/lib/ui/payment/subscription_common_widgets.dart index f2b8fe23f..c33f26d79 100644 --- a/lib/ui/payment/subscription_common_widgets.dart +++ b/lib/ui/payment/subscription_common_widgets.dart @@ -98,9 +98,14 @@ class ValidityWidget extends StatelessWidget { if (currentSubscription == null) { return const SizedBox.shrink(); } + final List addOnBonus = bonusData?.getAddOnBonuses() ?? []; final bool isFreeTrialSub = currentSubscription!.productID == freeProductID; - if (isFreeTrialSub && (bonusData?.getAddOnBonuses().isNotEmpty ?? false)) { - return const SizedBox.shrink(); + bool hideSubValidityView = false; + if (isFreeTrialSub && addOnBonus.isNotEmpty) { + hideSubValidityView = true; + } + if (!currentSubscription!.isValid()) { + hideSubValidityView = true; } final endDate = DateFormat.yMMMd(Localizations.localeOf(context).languageCode).format( @@ -114,11 +119,45 @@ class ValidityWidget extends StatelessWidget { : S.of(context).freeTrialValidTill(endDate); } else if (currentSubscription!.attributes?.isCancelled ?? false) { message = S.of(context).subWillBeCancelledOn(endDate); + if (addOnBonus.isNotEmpty) { + hideSubValidityView = true; + } } + return Padding( - padding: const EdgeInsets.only(top: 8), + padding: const EdgeInsets.only(top: 0), + child: Column( + children: [ + if (!hideSubValidityView) + Text( + message, + style: Theme.of(context).textTheme.bodySmall, + textAlign: TextAlign.center, + ), + if (addOnBonus.isNotEmpty) + ...addOnBonus.map((bonus) => AddOnBonusValidity(bonus)).toList(), + ], + ), + ); + } +} + +class AddOnBonusValidity extends StatelessWidget { + final Bonus bonus; + + const AddOnBonusValidity(this.bonus, {super.key}); + + @override + Widget build(BuildContext context) { + final endDate = + DateFormat.yMMMd(Localizations.localeOf(context).languageCode).format( + DateTime.fromMicrosecondsSinceEpoch(bonus.validTill), + ); + final String storage = convertBytesToReadableFormat(bonus.storage); + return Padding( + padding: const EdgeInsets.only(top: 8, bottom: 8), child: Text( - message, + S.of(context).addOnValidTill(storage, endDate), style: Theme.of(context).textTheme.bodySmall, textAlign: TextAlign.center, ), diff --git a/pubspec.yaml b/pubspec.yaml index e5ca90dd6..769948d6c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -12,7 +12,7 @@ description: ente photos application # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.8.0+520 +version: 0.8.1+521 environment: sdk: ">=3.0.0 <4.0.0"