PurchaseScreen: Move to purchasing code to its own widget

All of this is way too complicated
This commit is contained in:
Vishesh Handa
2020-07-09 12:21:20 +02:00
parent 309917d165
commit e5d4965844

View File

@ -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<PurchaseScreen> {
List<Offering> _offerings;
Offering _selectedOffering;
var _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> 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(<String, dynamic>{
'identifier': 'monthly_fake_offering',
'monthly': fakePackageJson,
'availablePackages': [fakePackageJson],
});
_offerings = [fakeOffer];
_selectedOffering = _offerings[0];
}
});
}
class PurchaseScreen extends StatelessWidget {
final _scaffoldKey = GlobalKey<ScaffoldState>();
@override
Widget build(BuildContext context) {
@ -97,7 +21,7 @@ class _PurchaseScreenState extends State<PurchaseScreen> {
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<PurchaseScreen> {
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: <Widget>[
@ -189,8 +83,7 @@ class _PurchaseScreenState extends State<PurchaseScreen> {
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<PurchaseWidget> {
List<Offering> _offerings;
Offering _selectedOffering;
var _scaffoldKey = GlobalKey<ScaffoldState>();
@override
void initState() {
super.initState();
initPlatformState();
}
Future<void> 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(<String, dynamic>{
'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: <Widget>[
slider,
const SizedBox(height: 16.0),
PurchaseButton(_selectedOffering?.monthly),
],
mainAxisAlignment: MainAxisAlignment.spaceAround,
);
}
}