diff --git a/lib/screens/purchase_screen.dart b/lib/screens/purchase_screen.dart index d776bba2..c9c80c40 100644 --- a/lib/screens/purchase_screen.dart +++ b/lib/screens/purchase_screen.dart @@ -12,84 +12,8 @@ import 'package:gitjournal/settings.dart'; import 'package:purchases_flutter/purchases_flutter.dart'; -class PurchaseScreen extends StatefulWidget { - @override - _PurchaseScreenState createState() => _PurchaseScreenState(); -} - -class _PurchaseScreenState extends State { - List _offerings; - Offering _selectedOffering; - var _scaffoldKey = GlobalKey(); - - @override - void initState() { - super.initState(); - initPlatformState(); - } - - Future initPlatformState() async { - await InAppPurchases.confirmProPurchase(); - if (Settings.instance.proMode) { - Navigator.of(context).pop(); - } - - await Purchases.setup( - environment['revenueCat'], - appUserId: Settings.instance.pseudoId, - ); - - Offerings offerings; - try { - offerings = await Purchases.getOfferings(); - } catch (e) { - if (e is PlatformException) { - var snackBar = SnackBar(content: Text(e.message)); - _scaffoldKey.currentState - ..removeCurrentSnackBar() - ..showSnackBar(snackBar); - return; - } - } - var offeringList = offerings.all.values.toList(); - offeringList.retainWhere((Offering o) => o.identifier.contains("monthly")); - offeringList.sort((Offering a, Offering b) => - a.monthly.product.price.compareTo(b.monthly.product.price)); - print("Offerings: $offeringList"); - - // If the widget was removed from the tree while the asynchronous platform - // message was in flight, we want to discard the reply rather than calling - // setState to update our non-existent appearance. - if (!mounted) return; - - setState(() { - _offerings = offeringList; - _selectedOffering = _offerings.isNotEmpty ? _offerings.first : null; - - if (_offerings.length > 1) { - _selectedOffering = _offerings[1]; - } else { - var fakePackageJson = { - 'identifier': 'monthly_fake', - 'product': { - 'identifier': 'fake_product', - 'title': 'Fake Product', - 'priceString': '0 Fake', - 'price': 0.0, - }, - }; - - var fakeOffer = Offering.fromJson({ - 'identifier': 'monthly_fake_offering', - 'monthly': fakePackageJson, - 'availablePackages': [fakePackageJson], - }); - - _offerings = [fakeOffer]; - _selectedOffering = _offerings[0]; - } - }); - } +class PurchaseScreen extends StatelessWidget { + final _scaffoldKey = GlobalKey(); @override Widget build(BuildContext context) { @@ -97,7 +21,7 @@ class _PurchaseScreenState extends State { child: Scaffold( key: _scaffoldKey, appBar: EmptyAppBar(), - body: _offerings == null ? const LoadingWidget() : buildBody(context), + body: buildBody(context), ), onWillPop: _onWillPop, ); @@ -150,36 +74,6 @@ class _PurchaseScreenState extends State { var titleStyle = textTheme.headline3.copyWith(color: textTheme.headline6.color); - var slider = Slider( - min: _offerings.first.monthly.product.price, - max: _offerings.last.monthly.product.price + 0.50, - value: _selectedOffering.monthly.product.price, - onChanged: (double val) { - int i = -1; - for (i = 1; i < _offerings.length; i++) { - var prev = _offerings[i - 1].monthly.product; - var cur = _offerings[i].monthly.product; - - if (prev.price < val && val <= cur.price) { - i--; - break; - } - } - if (val == _offerings.first.monthly.product.price) { - i = 0; - } else if (val >= _offerings.last.monthly.product.price) { - i = _offerings.length - 1; - } - - if (i != -1) { - setState(() { - _selectedOffering = _offerings[i]; - }); - } - }, - label: _selectedOffering.monthly.product.priceString, - divisions: _offerings.length, - ); Widget w = Column( children: [ @@ -189,8 +83,7 @@ class _PurchaseScreenState extends State { textAlign: TextAlign.center, ), body, - slider, - PurchaseButton(_selectedOffering?.monthly), + PurchaseWidget(), ], mainAxisAlignment: MainAxisAlignment.spaceAround, ); @@ -373,3 +266,130 @@ class _SingleChildScrollViewExpanded extends StatelessWidget { ); } } + +class PurchaseWidget extends StatefulWidget { + @override + _PurchaseWidgetState createState() => _PurchaseWidgetState(); +} + +class _PurchaseWidgetState extends State { + List _offerings; + Offering _selectedOffering; + var _scaffoldKey = GlobalKey(); + + @override + void initState() { + super.initState(); + initPlatformState(); + } + + Future initPlatformState() async { + await InAppPurchases.confirmProPurchase(); + if (Settings.instance.proMode) { + Navigator.of(context).pop(); + } + + await Purchases.setup( + environment['revenueCat'], + appUserId: Settings.instance.pseudoId, + ); + + Offerings offerings; + try { + offerings = await Purchases.getOfferings(); + } catch (e) { + if (e is PlatformException) { + var snackBar = SnackBar(content: Text(e.message)); + _scaffoldKey.currentState + ..removeCurrentSnackBar() + ..showSnackBar(snackBar); + return; + } + } + var offeringList = offerings.all.values.toList(); + offeringList.retainWhere((Offering o) => o.identifier.contains("monthly")); + offeringList.sort((Offering a, Offering b) => + a.monthly.product.price.compareTo(b.monthly.product.price)); + print("Offerings: $offeringList"); + + // If the widget was removed from the tree while the asynchronous platform + // message was in flight, we want to discard the reply rather than calling + // setState to update our non-existent appearance. + if (!mounted) return; + + setState(() { + _offerings = offeringList; + _selectedOffering = _offerings.isNotEmpty ? _offerings.first : null; + + if (_offerings.length > 1) { + _selectedOffering = _offerings[1]; + } else { + var fakePackageJson = { + 'identifier': 'monthly_fake', + 'product': { + 'identifier': 'fake_product', + 'title': 'Fake Product', + 'priceString': '0 Fake', + 'price': 0.0, + }, + }; + + var fakeOffer = Offering.fromJson({ + 'identifier': 'monthly_fake_offering', + 'monthly': fakePackageJson, + 'availablePackages': [fakePackageJson], + }); + + _offerings = [fakeOffer]; + _selectedOffering = _offerings[0]; + } + }); + } + + @override + Widget build(BuildContext context) { + return _offerings == null ? const LoadingWidget() : buildBody(context); + } + + Widget buildBody(BuildContext context) { + var slider = Slider( + min: _offerings.first.monthly.product.price, + max: _offerings.last.monthly.product.price + 0.50, + value: _selectedOffering.monthly.product.price, + onChanged: (double val) { + int i = -1; + for (i = 1; i < _offerings.length; i++) { + var prev = _offerings[i - 1].monthly.product; + var cur = _offerings[i].monthly.product; + + if (prev.price < val && val <= cur.price) { + i--; + break; + } + } + if (val == _offerings.first.monthly.product.price) { + i = 0; + } else if (val >= _offerings.last.monthly.product.price) { + i = _offerings.length - 1; + } + + if (i != -1) { + setState(() { + _selectedOffering = _offerings[i]; + }); + } + }, + label: _selectedOffering.monthly.product.priceString, + divisions: _offerings.length, + ); + + return Column( + children: [ + slider, + const SizedBox(height: 16.0), + PurchaseButton(_selectedOffering?.monthly), + ], + mainAxisAlignment: MainAxisAlignment.spaceAround, + ); + } +}