Update Subscription UX based on add on pack (#1527)
This commit is contained in:
commit
2a978bc9a4
10 changed files with 97 additions and 28 deletions
14
lib/generated/intl/messages_en.dart
generated
14
lib/generated/intl/messages_en.dart
generated
|
@ -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"),
|
||||
|
|
8
lib/generated/intl/messages_fr.dart
generated
8
lib/generated/intl/messages_fr.dart
generated
|
@ -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"),
|
||||
|
|
4
lib/generated/intl/messages_it.dart
generated
4
lib/generated/intl/messages_it.dart
generated
|
@ -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"),
|
||||
|
|
11
lib/generated/intl/messages_zh.dart
generated
11
lib/generated/intl/messages_zh.dart
generated
|
@ -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"),
|
||||
|
|
14
lib/generated/l10n.dart
generated
14
lib/generated/l10n.dart
generated
|
@ -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(
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -52,6 +52,7 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
|
|||
late ProgressDialog _dialog;
|
||||
late UserDetails _userDetails;
|
||||
late bool _hasActiveSubscription;
|
||||
bool _hideCurrentPlanSelection = false;
|
||||
late FreePlan _freePlan;
|
||||
late List<BillingPlan> _plans;
|
||||
bool _hasLoadedData = false;
|
||||
|
@ -177,7 +178,10 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
|
|||
_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<StoreSubscriptionPage> {
|
|||
widgets.add(_showSubscriptionToggle());
|
||||
}
|
||||
|
||||
if (_hasActiveSubscription) {
|
||||
if (_currentSubscription != null) {
|
||||
widgets.add(
|
||||
ValidityWidget(
|
||||
currentSubscription: _currentSubscription,
|
||||
|
@ -458,7 +462,7 @@ class _StoreSubscriptionPageState extends State<StoreSubscriptionPage> {
|
|||
storage: plan.storage,
|
||||
price: plan.price,
|
||||
period: plan.period,
|
||||
isActive: isActive,
|
||||
isActive: isActive && !_hideCurrentPlanSelection,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -53,6 +53,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
|||
|
||||
// indicates if user's subscription plan is still active
|
||||
late bool _hasActiveSubscription;
|
||||
bool _hideCurrentPlanSelection = false;
|
||||
late FreePlan _freePlan;
|
||||
List<BillingPlan> _plans = [];
|
||||
bool _hasLoadedData = false;
|
||||
|
@ -73,7 +74,11 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
|||
.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<StripeSubscriptionPage> {
|
|||
|
||||
widgets.add(_showSubscriptionToggle());
|
||||
|
||||
if (_hasActiveSubscription) {
|
||||
if (_currentSubscription != null) {
|
||||
widgets.add(
|
||||
ValidityWidget(
|
||||
currentSubscription: _currentSubscription,
|
||||
|
@ -340,6 +345,9 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
|||
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<StripeSubscriptionPage> {
|
|||
storage: plan.storage,
|
||||
price: plan.price,
|
||||
period: plan.period,
|
||||
isActive: isActive,
|
||||
isActive: isActive && !_hideCurrentPlanSelection,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
@ -594,7 +602,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
|||
storage: _currentSubscription!.storage,
|
||||
price: _currentSubscription!.price,
|
||||
period: _currentSubscription!.period,
|
||||
isActive: true,
|
||||
isActive: !_hasActiveSubscription,
|
||||
),
|
||||
),
|
||||
),
|
||||
|
|
|
@ -98,9 +98,14 @@ class ValidityWidget extends StatelessWidget {
|
|||
if (currentSubscription == null) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final List<Bonus> addOnBonus = bonusData?.getAddOnBonuses() ?? <Bonus>[];
|
||||
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,
|
||||
),
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Add table
Reference in a new issue