Pārlūkot izejas kodu

Move stripe subscription management in separate page

Neeraj Gupta 4 gadi atpakaļ
vecāks
revīzija
43f1ade544

+ 1 - 0
lib/ui/common/dialogs.dart

@@ -6,6 +6,7 @@ enum DialogUserChoice {
   secondChoice
 }
 
+// if dialog is dismissed by tapping outside, this will return null
 Future<T> showChoiceDialog<T>(
   BuildContext context,
   String title,

+ 518 - 0
lib/ui/payment/stripe_subscription_page.dart

@@ -0,0 +1,518 @@
+import 'dart:async';
+import 'dart:io';
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:in_app_purchase/in_app_purchase.dart';
+import 'package:logging/logging.dart';
+import 'package:photos/core/event_bus.dart';
+import 'package:photos/events/subscription_purchased_event.dart';
+import 'package:photos/models/billing_plan.dart';
+import 'package:photos/models/subscription.dart';
+import 'package:photos/services/billing_service.dart';
+import 'package:photos/services/update_service.dart';
+import 'package:photos/ui/billing_questions_widget.dart';
+import 'package:photos/ui/common/dialogs.dart';
+import 'package:photos/ui/loading_widget.dart';
+import 'package:photos/ui/payment/payment_web_page.dart';
+import 'package:photos/ui/payment/skip_subscription_widget.dart';
+import 'package:photos/ui/payment/subscription_plan_widget.dart';
+import 'package:photos/ui/progress_dialog.dart';
+import 'package:photos/utils/data_util.dart';
+import 'package:photos/utils/date_time_util.dart';
+import 'package:photos/utils/dialog_util.dart';
+import 'package:photos/utils/toast_util.dart';
+import 'package:url_launcher/url_launcher.dart';
+
+import '../web_page.dart';
+
+class StripeSubscriptionPage extends StatefulWidget {
+  final bool isOnboarding;
+
+  const StripeSubscriptionPage({
+    this.isOnboarding = false,
+    Key key,
+  }) : super(key: key);
+
+  @override
+  _StripeSubscriptionPageState createState() => _StripeSubscriptionPageState();
+}
+
+class _StripeSubscriptionPageState extends State<StripeSubscriptionPage> {
+  final _logger = Logger("StripeSubscriptionPage");
+  final _billingService = BillingService.instance;
+  Subscription _currentSubscription;
+  ProgressDialog _dialog;
+  Future<int> _usageFuture;
+
+  // indicates if user's subscription plan is still active
+  bool _hasActiveSubscription;
+  bool _isAutoReviewCancelled;
+  FreePlan _freePlan;
+  List<BillingPlan> _plans = [];
+  bool _hasLoadedData = false;
+  bool _isActiveStripeSubscriber;
+
+  // based on this flag, we would show ente payment page with stripe plans
+  bool _isIndependentApk;
+  bool _showYearlyPlan = false;
+
+  @override
+  void initState() {
+    _billingService.setIsOnSubscriptionPage(true);
+    _isIndependentApk = UpdateService.instance.isIndependentFlavor();
+    _fetchSub();
+    _dialog = createProgressDialog(context, "please wait...");
+    super.initState();
+  }
+
+  Future<void> _fetchSub() async {
+    return _billingService.fetchSubscription().then((subscription) async {
+      _currentSubscription = subscription;
+      _showYearlyPlan = _currentSubscription.isYearlyPlan();
+      _hasActiveSubscription = _currentSubscription.isValid();
+      _isAutoReviewCancelled =
+          _currentSubscription.attributes?.isCancelled ?? false;
+      _isActiveStripeSubscriber =
+          _currentSubscription.paymentProvider == kStripe &&
+              _currentSubscription.isValid();
+      _usageFuture = _billingService.fetchUsage();
+      return _filterPlansForUI().then((value) {
+        _hasLoadedData = true;
+        setState(() {});
+      });
+    });
+  }
+
+  // _filterPlansForUI is used for initializing initState & plan toggle states
+  Future<void> _filterPlansForUI() async {
+    final billingPlans = await _billingService.getBillingPlans();
+    _freePlan = billingPlans.freePlan;
+    _plans = billingPlans.plans.where((plan) {
+      final productID = (_showStripePlans())
+          ? plan.stripeID
+          : Platform.isAndroid
+              ? plan.androidID
+              : plan.iosID;
+      var isYearlyPlan = plan.period == 'year';
+      return productID != null &&
+          productID.isNotEmpty &&
+          isYearlyPlan == _showYearlyPlan;
+    }).toList();
+    setState(() {});
+  }
+
+  FutureOr onWebPaymentGoBack(dynamic value) async {
+    if (widget.isOnboarding) {
+      Navigator.of(context).popUntil((route) => route.isFirst);
+    } else {
+      // refresh subscription
+      await _dialog.show();
+      try {
+        await _fetchSub();
+      } catch (e) {
+        showToast("failed to refresh subscription");
+      }
+      await _dialog.hide();
+    }
+  }
+
+  bool _showStripePlans() {
+    return _isActiveStripeSubscriber || _isIndependentApk;
+  }
+
+
+  @override
+  void dispose() {
+    super.dispose();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    final appBar = AppBar(
+      title: Text("subscription"),
+    );
+    return Scaffold(
+      appBar: appBar,
+      body: _getBody(),
+    );
+  }
+
+  Widget _getBody() {
+    if (_hasLoadedData) {
+      return _buildPlans();
+    }
+    return loadWidget;
+  }
+
+  Widget _buildPlans() {
+    final widgets = <Widget>[];
+    if (widget.isOnboarding) {
+      widgets.add(Padding(
+        padding: const EdgeInsets.fromLTRB(20, 20, 20, 24),
+        child: Text(
+          "ente preserves your memories, so they're always available to you, even if you lose your device",
+          style: TextStyle(
+            color: Colors.white54,
+            height: 1.2,
+          ),
+        ),
+      ));
+    } else {
+      widgets.add(
+        SizedBox(
+          height: 50,
+          child: FutureBuilder(
+            future: _usageFuture,
+            builder: (BuildContext context, AsyncSnapshot snapshot) {
+              if (snapshot.hasData) {
+                return Padding(
+                  padding: const EdgeInsets.all(16.0),
+                  child: Text("current usage is " + formatBytes(snapshot.data)),
+                );
+              } else if (snapshot.hasError) {
+                return Container();
+              } else {
+                return Padding(
+                  padding: const EdgeInsets.all(16.0),
+                  child: loadWidget,
+                );
+              }
+            },
+          ),
+        ),
+      );
+    }
+    widgets.addAll([
+      Column(
+        mainAxisAlignment: MainAxisAlignment.center,
+        children:_getStripePlanWidgets()
+      ),
+      Padding(padding: EdgeInsets.all(8)),
+    ]);
+
+    widgets.add(_showSubscriptionToggle());
+
+    if (_hasActiveSubscription) {
+      var endDate = getDateAndMonthAndYear(
+          DateTime.fromMicrosecondsSinceEpoch(_currentSubscription.expiryTime));
+      var message = "renews on $endDate";
+      if (_currentSubscription.productID == kFreeProductID) {
+        message = "free plan valid till $endDate";
+      } else if (_isAutoReviewCancelled) {
+        message = "your subscription will be cancelled on $endDate";
+      }
+      widgets.add(
+        Text(
+          message,
+          style: TextStyle(
+            color: Colors.white.withOpacity(0.6),
+            fontSize: 14,
+          ),
+        ),
+      );
+    }
+
+    if (_isIndependentApk &&
+        _hasActiveSubscription &&
+        _isActiveStripeSubscriber) {
+      widgets.add(_stripeSubscriptionToggleButton(_isAutoReviewCancelled));
+    }
+
+    if (_hasActiveSubscription &&
+        _currentSubscription.productID != kFreeProductID) {
+      widgets.addAll([
+        Align(
+          alignment: Alignment.center,
+          child: GestureDetector(
+            onTap: () async {
+              if (_isActiveStripeSubscriber) {
+                if (_isIndependentApk) {
+                  await _launchStripePortal();
+                  return;
+                } else {
+                  return;
+                }
+              }
+              if (Platform.isAndroid) {
+                launch(
+                    "https://play.google.com/store/account/subscriptions?sku=" +
+                        _currentSubscription.productID +
+                        "&package=io.ente.photos");
+              } else {
+                launch("https://apps.apple.com/account/billing");
+              }
+            },
+            child: Container(
+              padding: EdgeInsets.fromLTRB(40, 80, 40, 80),
+              child: Column(
+                children: [
+                  RichText(
+                    text: TextSpan(
+                      text: _isActiveStripeSubscriber && !_isIndependentApk
+                          ? "visit web.ente.io to manage your subscription"
+                          : "payment details",
+                      style: TextStyle(
+                        color: _isActiveStripeSubscriber
+                            ? Colors.white
+                            : Colors.blue,
+                        fontFamily: 'Ubuntu',
+                        fontSize: 15,
+                      ),
+                    ),
+                    textAlign: TextAlign.center,
+                  ),
+                ],
+              ),
+            ),
+          ),
+        ),
+      ]);
+    }
+    if (widget.isOnboarding &&
+        _currentSubscription.productID == kFreeProductID) {
+      widgets.addAll([SkipSubscriptionWidget(freePlan: _freePlan)]);
+    }
+    if (_currentSubscription.productID == kFreeProductID) {
+      widgets.addAll([
+        Align(
+          alignment: Alignment.center,
+          child: GestureDetector(
+            behavior: HitTestBehavior.translucent,
+            onTap: () {
+              showModalBottomSheet<void>(
+                backgroundColor: Color.fromRGBO(10, 15, 15, 1.0),
+                barrierColor: Colors.black87,
+                context: context,
+                builder: (context) {
+                  return BillingQuestionsWidget();
+                },
+              );
+            },
+            child: Container(
+              padding: EdgeInsets.all(40),
+              child: RichText(
+                text: TextSpan(
+                  text: "questions?",
+                  style: TextStyle(
+                    color: Colors.blue,
+                    fontFamily: 'Ubuntu',
+                  ),
+                ),
+              ),
+            ),
+          ),
+        ),
+      ]);
+    }
+    return SingleChildScrollView(
+      child: Column(
+        mainAxisAlignment: MainAxisAlignment.spaceEvenly,
+        children: widgets,
+      ),
+    );
+  }
+
+  Future<void> _launchStripePortal() async {
+    await _dialog.show();
+    try {
+      String url = await _billingService.getStripeCustomerPortalUrl();
+      Navigator.of(context).push(
+        MaterialPageRoute(
+          builder: (BuildContext context) {
+            return WebPage("payment details", url);
+          },
+        ),
+      ).then((value) => onWebPaymentGoBack);
+    } catch (e) {
+      await _dialog.hide();
+      showGenericErrorDialog(context);
+    }
+    await _dialog.hide();
+  }
+
+  Widget _stripeSubscriptionToggleButton(bool isCurrentlyCancelled) {
+    return TextButton(
+      child: Text(
+        isCurrentlyCancelled ? "renew subscription" : "cancel subscription",
+        style: TextStyle(
+          color: isCurrentlyCancelled ? Colors.greenAccent : Colors.redAccent,
+        ),
+      ),
+      onPressed: () async {
+        var result = await showChoiceDialog(
+            context,
+            isCurrentlyCancelled
+                ? 'subscription renewal'
+                : 'subscription cancellation',
+            isCurrentlyCancelled
+                ? 'are you sure you want to renew?'
+                : 'are you sure you want to cancel?',
+            firstAction: 'yes',
+            secondAction: 'no');
+        if (result == DialogUserChoice.firstChoice) {
+          toggleStripeSubscription(isCurrentlyCancelled);
+        }
+      },
+    );
+  }
+
+  Future<void> toggleStripeSubscription(bool isCurrentlyCancelled) async {
+    await _dialog.show();
+    try {
+      if (isCurrentlyCancelled) {
+        await _billingService.activateStripeSubscription();
+      } else {
+        await _billingService.cancelStripeSubscription();
+      }
+      await _fetchSub();
+    } catch (e) {
+      showToast(isCurrentlyCancelled ? 'failed to renew' : 'failed to cancel');
+    }
+    await _dialog.hide();
+  }
+
+  List<Widget> _getStripePlanWidgets() {
+    final List<Widget> planWidgets = [];
+    bool foundActivePlan = false;
+    for (final plan in _plans) {
+      final productID = plan.stripeID;
+      if (productID == null || productID.isEmpty) {
+        continue;
+      }
+      final isActive =
+          _hasActiveSubscription && _currentSubscription.productID == productID;
+      if (isActive) {
+        foundActivePlan = true;
+      }
+      planWidgets.add(
+        Material(
+          child: InkWell(
+            onTap: () async {
+              if (isActive) {
+                return;
+              }
+              if (_isActiveStripeSubscriber && !_isIndependentApk) {
+                showErrorDialog(context, "sorry",
+                    "please visit web.ente.io to manage your subscription");
+                return;
+              }
+              await _dialog.show();
+              if (_usageFuture != null) {
+                final usage = await _usageFuture;
+                await _dialog.hide();
+                if (usage > plan.storage) {
+                  showErrorDialog(
+                      context, "sorry", "you cannot downgrade to this plan");
+                  return;
+                }
+              }
+              String stripPurChaseAction = 'buy';
+              if (_isActiveStripeSubscriber) {
+                // confirm if user wants to change plan or not
+                var result = await showChoiceDialog(
+                    context,
+                    "confirm plan change",
+                    "are you sure you want to change your plan?",
+                    firstAction: "yes",
+                    secondAction: 'no');
+                if (result != DialogUserChoice.firstChoice) {
+                  return;
+                }
+                stripPurChaseAction = 'update';
+              }
+              Navigator.push(
+                context,
+                MaterialPageRoute(
+                  builder: (BuildContext context) {
+                    return PaymentWebPage(
+                      planId: plan.stripeID,
+                      actionType: stripPurChaseAction,
+                    );
+                  },
+                ),
+              ).then((value) => onWebPaymentGoBack(value));
+            },
+            child: SubscriptionPlanWidget(
+              storage: plan.storage,
+              price: plan.price,
+              period: plan.period,
+              isActive: isActive,
+            ),
+          ),
+        ),
+      );
+    }
+    if (!foundActivePlan) {
+      _addCurrentPlanWidget(planWidgets);
+    }
+    return planWidgets;
+  }
+
+  Widget _showSubscriptionToggle() {
+    return Container(
+      padding: EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
+      margin: EdgeInsets.only(bottom: 12),
+      // color: Color.fromRGBO(10, 40, 40, 0.3),
+      child: Row(
+        mainAxisAlignment: MainAxisAlignment.spaceAround,
+        children: [
+          Text(
+            "monthly plans",
+            style: TextStyle(
+              color: Theme.of(context)
+                  .buttonColor
+                  .withOpacity(_showYearlyPlan ? 0.2 : 1.0),
+            ),
+          ),
+          Switch(
+            value: _showYearlyPlan,
+            onChanged: (value) async {
+              _showYearlyPlan = value;
+              await _filterPlansForUI();
+              setState(() {});
+            },
+          ),
+          Text(
+            "yearly plans",
+            style: TextStyle(
+              color: Theme.of(context)
+                  .buttonColor
+                  .withOpacity(_showYearlyPlan ? 1.0 : 0.2),
+            ),
+          ),
+        ],
+      ),
+    );
+  }
+
+  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 != kFreeProductID) {
+      return;
+    }
+    int activePlanIndex = 0;
+    for (; activePlanIndex < _plans.length; activePlanIndex++) {
+      if (_plans[activePlanIndex].storage > _currentSubscription.storage) {
+        break;
+      }
+    }
+    planWidgets.insert(
+      activePlanIndex,
+      Material(
+        child: InkWell(
+          onTap: () {},
+          child: SubscriptionPlanWidget(
+            storage: _currentSubscription.storage,
+            price: _currentSubscription.price,
+            period: _currentSubscription.period,
+            isActive: true,
+          ),
+        ),
+      ),
+    );
+  }
+}

+ 33 - 238
lib/ui/payment/subscription_page.dart

@@ -11,11 +11,9 @@ import 'package:photos/events/subscription_purchased_event.dart';
 import 'package:photos/models/billing_plan.dart';
 import 'package:photos/models/subscription.dart';
 import 'package:photos/services/billing_service.dart';
-import 'package:photos/services/update_service.dart';
 import 'package:photos/ui/billing_questions_widget.dart';
-import 'package:photos/ui/common/dialogs.dart';
+import 'package:photos/ui/common_elements.dart';
 import 'package:photos/ui/loading_widget.dart';
-import 'package:photos/ui/payment/payment_web_page.dart';
 import 'package:photos/ui/payment/skip_subscription_widget.dart';
 import 'package:photos/ui/payment/subscription_plan_widget.dart';
 import 'package:photos/ui/progress_dialog.dart';
@@ -25,8 +23,6 @@ import 'package:photos/utils/dialog_util.dart';
 import 'package:photos/utils/toast_util.dart';
 import 'package:url_launcher/url_launcher.dart';
 
-import '../web_page.dart';
-
 class SubscriptionPage extends StatefulWidget {
   final bool isOnboarding;
 
@@ -46,82 +42,39 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
   StreamSubscription _purchaseUpdateSubscription;
   ProgressDialog _dialog;
   Future<int> _usageFuture;
-
-  // indicates if user's subscription plan is still active
   bool _hasActiveSubscription;
-  bool _isAutoReviewCancelled;
   FreePlan _freePlan;
-  List<BillingPlan> _plans = [];
+  List<BillingPlan> _plans;
   bool _hasLoadedData = false;
   bool _isActiveStripeSubscriber;
 
-  // based on this flag, we would show ente payment page with stripe plans
-  bool _isIndependentApk;
-  bool _showYearlyPlan = false;
-
   @override
   void initState() {
     _billingService.setIsOnSubscriptionPage(true);
-    _isIndependentApk = UpdateService.instance.isIndependentFlavor();
-    _fetchSub();
-    _setupPurchaseUpdateStreamListener();
-    _dialog = createProgressDialog(context, "please wait...");
-    super.initState();
-  }
-
-  Future<void> _fetchSub() async {
-    return _billingService.fetchSubscription().then((subscription) async {
+    _billingService.fetchSubscription().then((subscription) async {
       _currentSubscription = subscription;
-      _showYearlyPlan = _currentSubscription.isYearlyPlan();
       _hasActiveSubscription = _currentSubscription.isValid();
-      _isAutoReviewCancelled =
-          _currentSubscription.attributes?.isCancelled ?? false;
+      final billingPlans = await _billingService.getBillingPlans();
       _isActiveStripeSubscriber =
           _currentSubscription.paymentProvider == kStripe &&
               _currentSubscription.isValid();
+      _plans = billingPlans.plans.where((plan) {
+        final productID = _isActiveStripeSubscriber
+            ? plan.stripeID
+            : Platform.isAndroid
+            ? plan.androidID
+            : plan.iosID;
+        return productID != null && productID.isNotEmpty;
+      }).toList();
+      _freePlan = billingPlans.freePlan;
+
       _usageFuture = _billingService.fetchUsage();
-      return _filterPlansForUI().then((value) {
-        _hasLoadedData = true;
-        setState(() {});
-      });
+      _hasLoadedData = true;
+      setState(() {});
     });
-  }
-
-  // _filterPlansForUI is used for initializing initState & plan toggle states
-  Future<void> _filterPlansForUI() async {
-    final billingPlans = await _billingService.getBillingPlans();
-    _freePlan = billingPlans.freePlan;
-    _plans = billingPlans.plans.where((plan) {
-      final productID = (_showStripePlans())
-          ? plan.stripeID
-          : Platform.isAndroid
-              ? plan.androidID
-              : plan.iosID;
-      var isYearlyPlan = plan.period == 'year';
-      return productID != null &&
-          productID.isNotEmpty &&
-          isYearlyPlan == _showYearlyPlan;
-    }).toList();
-    setState(() {});
-  }
-
-  FutureOr onWebPaymentGoBack(dynamic value) async {
-    if (widget.isOnboarding) {
-      Navigator.of(context).popUntil((route) => route.isFirst);
-    } else {
-      // refresh subscription
-      await _dialog.show();
-      try {
-        await _fetchSub();
-      } catch (e) {
-        showToast("failed to refresh subscription");
-      }
-      await _dialog.hide();
-    }
-  }
-
-  bool _showStripePlans() {
-    return _isActiveStripeSubscriber || _isIndependentApk;
+    _setupPurchaseUpdateStreamListener();
+    _dialog = createProgressDialog(context, "please wait...");
+    super.initState();
   }
 
   void _setupPurchaseUpdateStreamListener() {
@@ -248,29 +201,19 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
     widgets.addAll([
       Column(
         mainAxisAlignment: MainAxisAlignment.center,
-        children: _showStripePlans()
+        children: _isActiveStripeSubscriber
             ? _getStripePlanWidgets()
             : _getMobilePlanWidgets(),
       ),
       Padding(padding: EdgeInsets.all(8)),
     ]);
 
-    if (_showStripePlans()) {
-      widgets.add(_showSubscriptionToggle());
-    }
-
     if (_hasActiveSubscription) {
-      var endDate = getDateAndMonthAndYear(
-          DateTime.fromMicrosecondsSinceEpoch(_currentSubscription.expiryTime));
-      var message = "renews on $endDate";
-      if (_currentSubscription.productID == kFreeProductID) {
-        message = "free plan valid till $endDate";
-      } else if (_isAutoReviewCancelled) {
-        message = "your subscription will be cancelled on $endDate";
-      }
       widgets.add(
         Text(
-          message,
+          "valid till " +
+              getDateAndMonthAndYear(DateTime.fromMicrosecondsSinceEpoch(
+                  _currentSubscription.expiryTime)),
           style: TextStyle(
             color: Colors.white.withOpacity(0.6),
             fontSize: 14,
@@ -279,26 +222,15 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
       );
     }
 
-    if (_isIndependentApk &&
-        _hasActiveSubscription &&
-        _isActiveStripeSubscriber) {
-      widgets.add(_stripeSubscriptionToggleButton(_isAutoReviewCancelled));
-    }
-
     if (_hasActiveSubscription &&
         _currentSubscription.productID != kFreeProductID) {
       widgets.addAll([
         Align(
           alignment: Alignment.center,
           child: GestureDetector(
-            onTap: () async {
+            onTap: () {
               if (_isActiveStripeSubscriber) {
-                if (_isIndependentApk) {
-                  await _launchStripePortal();
-                  return;
-                } else {
-                  return;
-                }
+                return;
               }
               if (Platform.isAndroid) {
                 launch(
@@ -315,7 +247,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
                 children: [
                   RichText(
                     text: TextSpan(
-                      text: _isActiveStripeSubscriber && !_isIndependentApk
+                      text: _isActiveStripeSubscriber
                           ? "visit web.ente.io to manage your subscription"
                           : "payment details",
                       style: TextStyle(
@@ -379,65 +311,6 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
     );
   }
 
-  Future<void> _launchStripePortal() async {
-    await _dialog.show();
-    try {
-      String url = await _billingService.getStripeCustomerPortalUrl();
-      Navigator.of(context).push(
-        MaterialPageRoute(
-          builder: (BuildContext context) {
-            return WebPage("payment details", url);
-          },
-        ),
-      ).then((value) => onWebPaymentGoBack);
-    } catch (e) {
-      await _dialog.hide();
-      showGenericErrorDialog(context);
-    }
-    await _dialog.hide();
-  }
-
-  Widget _stripeSubscriptionToggleButton(bool isCurrentlyCancelled) {
-    return TextButton(
-      child: Text(
-        isCurrentlyCancelled ? "renew subscription" : "cancel subscription",
-        style: TextStyle(
-          color: isCurrentlyCancelled ? Colors.greenAccent : Colors.redAccent,
-        ),
-      ),
-      onPressed: () async {
-        var result = await showChoiceDialog(
-            context,
-            isCurrentlyCancelled
-                ? 'subscription renewal'
-                : 'subscription cancellation',
-            isCurrentlyCancelled
-                ? 'are you sure you want to renew?'
-                : 'are you sure you want to cancel?',
-            firstAction: 'yes',
-            secondAction: 'no');
-        if (result == DialogUserChoice.firstChoice) {
-          toggleStripeSubscription(isCurrentlyCancelled);
-        }
-      },
-    );
-  }
-
-  Future<void> toggleStripeSubscription(bool isCurrentlyCancelled) async {
-    await _dialog.show();
-    try {
-      if (isCurrentlyCancelled) {
-        await _billingService.activateStripeSubscription();
-      } else {
-        await _billingService.cancelStripeSubscription();
-      }
-      await _fetchSub();
-    } catch (e) {
-      showToast(isCurrentlyCancelled ? 'failed to renew' : 'failed to cancel');
-    }
-    await _dialog.hide();
-  }
-
   List<Widget> _getStripePlanWidgets() {
     final List<Widget> planWidgets = [];
     bool foundActivePlan = false;
@@ -458,45 +331,8 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
               if (isActive) {
                 return;
               }
-              if (_isActiveStripeSubscriber && !_isIndependentApk) {
-                showErrorDialog(context, "sorry",
-                    "please visit web.ente.io to manage your subscription");
-                return;
-              }
-              await _dialog.show();
-              if (_usageFuture != null) {
-                final usage = await _usageFuture;
-                await _dialog.hide();
-                if (usage > plan.storage) {
-                  showErrorDialog(
-                      context, "sorry", "you cannot downgrade to this plan");
-                  return;
-                }
-              }
-              String stripPurChaseAction = 'buy';
-              if (_isActiveStripeSubscriber) {
-                // confirm if user wants to change plan or not
-                var result = await showChoiceDialog(
-                    context,
-                    "confirm plan change",
-                    "are you sure you want to change your plan?",
-                    firstAction: "yes",
-                    secondAction: 'no');
-                if (result == DialogUserChoice.secondChoice) {
-                  return;
-                }
-                stripPurChaseAction = 'update';
-              }
-              Navigator.push(
-                context, MaterialPageRoute(
-                  builder: (BuildContext context) {
-                    return PaymentWebPage(
-                      planId: plan.stripeID,
-                      actionType: stripPurChaseAction,
-                    );
-                  },
-                ),
-              ).then((value) => onWebPaymentGoBack(value));
+              showErrorDialog(context, "sorry",
+                  "please visit web.ente.io to manage your subscription");
             },
             child: SubscriptionPlanWidget(
               storage: plan.storage,
@@ -554,8 +390,8 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
                 }
               }
               final ProductDetailsResponse response =
-                  await InAppPurchaseConnection.instance
-                      .queryProductDetails({productID});
+              await InAppPurchaseConnection.instance
+                  .queryProductDetails({productID});
               if (response.notFoundIDs.isNotEmpty) {
                 _logger.severe("Could not find products: " +
                     response.notFoundIDs.toString());
@@ -569,8 +405,8 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
                   _currentSubscription.productID != plan.androidID;
               if (isCrossGradingOnAndroid) {
                 final existingProductDetailsResponse =
-                    await InAppPurchaseConnection.instance
-                        .queryProductDetails({_currentSubscription.productID});
+                await InAppPurchaseConnection.instance
+                    .queryProductDetails({_currentSubscription.productID});
                 if (existingProductDetailsResponse.notFoundIDs.isNotEmpty) {
                   _logger.severe("Could not find existing products: " +
                       response.notFoundIDs.toString());
@@ -616,49 +452,7 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
     return planWidgets;
   }
 
-  Widget _showSubscriptionToggle() {
-    return Container(
-      padding: EdgeInsets.only(left: 8, right: 8, top: 4, bottom: 4),
-      margin: EdgeInsets.only(bottom: 12),
-      // color: Color.fromRGBO(10, 40, 40, 0.3),
-      child: Row(
-        mainAxisAlignment: MainAxisAlignment.spaceAround,
-        children: [
-          Text(
-            "monthly plans",
-            style: TextStyle(
-              color: Theme.of(context)
-                  .buttonColor
-                  .withOpacity(_showYearlyPlan ? 0.2 : 1.0),
-            ),
-          ),
-          Switch(
-            value: _showYearlyPlan,
-            onChanged: (value) async {
-              _showYearlyPlan = value;
-              await _filterPlansForUI();
-              setState(() {});
-            },
-          ),
-          Text(
-            "yearly plans",
-            style: TextStyle(
-              color: Theme.of(context)
-                  .buttonColor
-                  .withOpacity(_showYearlyPlan ? 1.0 : 0.2),
-            ),
-          ),
-        ],
-      ),
-    );
-  }
-
   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 != kFreeProductID) {
-      return;
-    }
     int activePlanIndex = 0;
     for (; activePlanIndex < _plans.length; activePlanIndex++) {
       if (_plans[activePlanIndex].storage > _currentSubscription.storage) {
@@ -681,3 +475,4 @@ class _SubscriptionPageState extends State<SubscriptionPage> {
     );
   }
 }
+