[mob][photos] Many changes to subscription page
This commit is contained in:
@@ -48,6 +48,10 @@ class Subscription {
|
||||
return 'year' == period;
|
||||
}
|
||||
|
||||
bool isFreePlan() {
|
||||
return productID == freeProductID;
|
||||
}
|
||||
|
||||
static fromMap(Map<String, dynamic>? map) {
|
||||
if (map == null) return null;
|
||||
return Subscription(
|
||||
|
||||
@@ -2,7 +2,9 @@ import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import "package:logging/logging.dart";
|
||||
import "package:photos/core/event_bus.dart";
|
||||
import 'package:photos/ente_theme_data.dart';
|
||||
import "package:photos/events/subscription_purchased_event.dart";
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import 'package:photos/models/billing_plan.dart';
|
||||
import 'package:photos/models/subscription.dart';
|
||||
@@ -24,6 +26,7 @@ import 'package:photos/ui/payment/skip_subscription_widget.dart';
|
||||
import 'package:photos/ui/payment/subscription_common_widgets.dart';
|
||||
import 'package:photos/ui/payment/subscription_plan_widget.dart';
|
||||
import "package:photos/ui/payment/view_add_on_widget.dart";
|
||||
import "package:photos/ui/tabs/home_widget.dart";
|
||||
import "package:photos/utils/data_util.dart";
|
||||
import 'package:photos/utils/dialog_util.dart';
|
||||
import 'package:photos/utils/toast_util.dart';
|
||||
@@ -244,38 +247,10 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
||||
);
|
||||
}
|
||||
|
||||
// only active subscription can be renewed/canceled
|
||||
if (_hasActiveSubscription && _isStripeSubscriber) {
|
||||
widgets.add(_stripeRenewOrCancelButton());
|
||||
}
|
||||
|
||||
if (_currentSubscription!.productID != freeProductID) {
|
||||
widgets.add(
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 40, 16, 4),
|
||||
child: MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: S.of(context).paymentDetails,
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 4,
|
||||
alignCaptionedTextToLeft: true,
|
||||
onTap: () async {
|
||||
_redirectToPaymentPortal();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
if (!widget.isOnboarding) {
|
||||
widgets.add(
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 0, 16, 0),
|
||||
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
|
||||
child: MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: S.of(context).manageFamily,
|
||||
@@ -295,6 +270,40 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
||||
),
|
||||
);
|
||||
widgets.add(ViewAddOnButton(_userDetails.bonusData));
|
||||
}
|
||||
|
||||
if (_currentSubscription!.productID != freeProductID) {
|
||||
widgets.add(
|
||||
Padding(
|
||||
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
|
||||
child: MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: S.of(context).paymentDetails,
|
||||
),
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 4,
|
||||
alignCaptionedTextToLeft: true,
|
||||
onTap: () async {
|
||||
_redirectToPaymentPortal();
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// only active subscription can be renewed/canceled
|
||||
if (_hasActiveSubscription && _isStripeSubscriber) {
|
||||
widgets.add(
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 2),
|
||||
child: _stripeRenewOrCancelButton(),
|
||||
),
|
||||
);
|
||||
|
||||
widgets.add(const SizedBox(height: 80));
|
||||
}
|
||||
|
||||
@@ -365,16 +374,18 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
||||
final String title = isRenewCancelled
|
||||
? S.of(context).renewSubscription
|
||||
: S.of(context).cancelSubscription;
|
||||
return TextButton(
|
||||
child: Text(
|
||||
title,
|
||||
style: TextStyle(
|
||||
color: (isRenewCancelled
|
||||
? colorScheme.primary700
|
||||
: colorScheme.textMuted),
|
||||
),
|
||||
return MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: title,
|
||||
),
|
||||
onPressed: () async {
|
||||
menuItemColor: colorScheme.fillFaint,
|
||||
trailingWidget: Icon(
|
||||
Icons.chevron_right_outlined,
|
||||
color: colorScheme.strokeBase,
|
||||
),
|
||||
singleBorderRadius: 4,
|
||||
alignCaptionedTextToLeft: true,
|
||||
onTap: () async {
|
||||
bool confirmAction = false;
|
||||
if (isRenewCancelled) {
|
||||
final choice = await showChoiceDialog(
|
||||
@@ -457,9 +468,27 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
||||
foundActivePlan = true;
|
||||
}
|
||||
planWidgets.add(
|
||||
Material(
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
GestureDetector(
|
||||
onTap: () async {
|
||||
if (widget.isOnboarding && plan.id == freeProductID) {
|
||||
Bus.instance.fire(SubscriptionPurchasedEvent());
|
||||
// ignore: unawaited_futures
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const HomeWidget();
|
||||
},
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
unawaited(
|
||||
BillingService.instance.verifySubscription(
|
||||
freeProductID,
|
||||
"",
|
||||
paymentProvider: "ente",
|
||||
),
|
||||
);
|
||||
} else {
|
||||
if (isActive) {
|
||||
return;
|
||||
}
|
||||
@@ -520,14 +549,14 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
||||
},
|
||||
),
|
||||
).then((value) => onWebPaymentGoBack(value));
|
||||
},
|
||||
child: SubscriptionPlanWidget(
|
||||
storage: plan.storage,
|
||||
price: plan.price,
|
||||
period: plan.period,
|
||||
isActive: isActive && !_hideCurrentPlanSelection,
|
||||
isPopular: _isPopularPlan(plan),
|
||||
),
|
||||
}
|
||||
},
|
||||
child: SubscriptionPlanWidget(
|
||||
storage: plan.storage,
|
||||
price: plan.price,
|
||||
period: plan.period,
|
||||
isActive: isActive && !_hideCurrentPlanSelection,
|
||||
isPopular: _isPopularPlan(plan),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -550,6 +579,7 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
||||
void _addCurrentPlanWidget(List<Widget> planWidgets) {
|
||||
// don't add current plan if it's monthly plan but UI is showing yearly plans
|
||||
// and vice versa.
|
||||
|
||||
if (_showYearlyPlan != _currentSubscription!.isYearlyPlan() &&
|
||||
_currentSubscription!.productID != freeProductID) {
|
||||
return;
|
||||
@@ -562,15 +592,33 @@ class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
|
||||
}
|
||||
planWidgets.insert(
|
||||
activePlanIndex,
|
||||
Material(
|
||||
child: InkWell(
|
||||
onTap: () {},
|
||||
child: SubscriptionPlanWidget(
|
||||
storage: _currentSubscription!.storage,
|
||||
price: _currentSubscription!.price,
|
||||
period: _currentSubscription!.period,
|
||||
isActive: _currentSubscription!.isValid(),
|
||||
),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
if (_currentSubscription!.isFreePlan()) {
|
||||
Bus.instance.fire(SubscriptionPurchasedEvent());
|
||||
// ignore: unawaited_futures
|
||||
Navigator.of(context).pushAndRemoveUntil(
|
||||
MaterialPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return const HomeWidget();
|
||||
},
|
||||
),
|
||||
(route) => false,
|
||||
);
|
||||
unawaited(
|
||||
BillingService.instance.verifySubscription(
|
||||
freeProductID,
|
||||
"",
|
||||
paymentProvider: "ente",
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
child: SubscriptionPlanWidget(
|
||||
storage: _currentSubscription!.storage,
|
||||
price: _currentSubscription!.price,
|
||||
period: _currentSubscription!.period,
|
||||
isActive: _currentSubscription!.isValid(),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -4,7 +4,6 @@ import 'package:photos/ente_theme_data.dart';
|
||||
import "package:photos/generated/l10n.dart";
|
||||
import "package:photos/models/api/storage_bonus/bonus.dart";
|
||||
import 'package:photos/models/subscription.dart';
|
||||
import "package:photos/services/update_service.dart";
|
||||
import "package:photos/theme/ente_theme.dart";
|
||||
import "package:photos/ui/components/captioned_text_widget.dart";
|
||||
import "package:photos/ui/components/menu_item_widget/menu_item_widget.dart";
|
||||
@@ -69,15 +68,15 @@ class ValidityWidget extends StatelessWidget {
|
||||
final Subscription? currentSubscription;
|
||||
final BonusData? bonusData;
|
||||
|
||||
const ValidityWidget({Key? key, this.currentSubscription, this.bonusData})
|
||||
: super(key: key);
|
||||
const ValidityWidget({super.key, this.currentSubscription, this.bonusData});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (currentSubscription == null) {
|
||||
final List<Bonus> addOnBonus = bonusData?.getAddOnBonuses() ?? <Bonus>[];
|
||||
if (currentSubscription == null ||
|
||||
(currentSubscription!.isFreePlan() && addOnBonus.isEmpty)) {
|
||||
return const SizedBox.shrink();
|
||||
}
|
||||
final List<Bonus> addOnBonus = bonusData?.getAddOnBonuses() ?? <Bonus>[];
|
||||
final bool isFreeTrialSub = currentSubscription!.productID == freeProductID;
|
||||
bool hideSubValidityView = false;
|
||||
if (isFreeTrialSub && addOnBonus.isNotEmpty) {
|
||||
@@ -92,11 +91,7 @@ class ValidityWidget extends StatelessWidget {
|
||||
);
|
||||
|
||||
var message = S.of(context).renewsOn(endDate);
|
||||
if (isFreeTrialSub) {
|
||||
message = UpdateService.instance.isPlayStoreFlavor()
|
||||
? S.of(context).playStoreFreeTrialValidTill(endDate)
|
||||
: S.of(context).freeTrialValidTill(endDate);
|
||||
} else if (currentSubscription!.attributes?.isCancelled ?? false) {
|
||||
if (currentSubscription!.attributes?.isCancelled ?? false) {
|
||||
message = S.of(context).subWillBeCancelledOn(endDate);
|
||||
if (addOnBonus.isNotEmpty) {
|
||||
hideSubValidityView = true;
|
||||
@@ -153,7 +148,7 @@ class SubFaqWidget extends StatelessWidget {
|
||||
Widget build(BuildContext context) {
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
return Padding(
|
||||
padding: EdgeInsets.fromLTRB(16, 40, 16, isOnboarding ? 40 : 4),
|
||||
padding: const EdgeInsets.fromLTRB(16, 2, 16, 2),
|
||||
child: MenuItemWidget(
|
||||
captionedTextWidget: CaptionedTextWidget(
|
||||
title: S.of(context).faqs,
|
||||
|
||||
@@ -41,7 +41,6 @@ class _SubscriptionPlanWidgetState extends State<SubscriptionPlanWidget> {
|
||||
final numAndUnit = convertBytesToNumberAndUnit(widget.storage);
|
||||
final String storageValue = numAndUnit.$1.toString();
|
||||
final String storageUnit = numAndUnit.$2;
|
||||
final colorScheme = getEnteColorScheme(context);
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 10),
|
||||
child: Container(
|
||||
|
||||
Reference in New Issue
Block a user