Apple IAP
This commit is contained in:
parent
cb39924f19
commit
ca9541026b
|
|
@ -61,6 +61,8 @@ PODS:
|
|||
- TOCropViewController (~> 2.6.1)
|
||||
- image_picker_ios (0.0.1):
|
||||
- Flutter
|
||||
- in_app_purchase_storekit (0.0.1):
|
||||
- Flutter
|
||||
- in_app_review (0.2.0):
|
||||
- Flutter
|
||||
- local_auth (0.0.1):
|
||||
|
|
@ -108,6 +110,7 @@ DEPENDENCIES:
|
|||
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
|
||||
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
|
||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/ios`)
|
||||
- in_app_purchase_storekit (from `.symlinks/plugins/in_app_purchase_storekit/ios`)
|
||||
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
|
||||
- local_auth (from `.symlinks/plugins/local_auth/ios`)
|
||||
- package_info (from `.symlinks/plugins/package_info/ios`)
|
||||
|
|
@ -150,6 +153,8 @@ EXTERNAL SOURCES:
|
|||
:path: ".symlinks/plugins/image_cropper/ios"
|
||||
image_picker_ios:
|
||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||
in_app_purchase_storekit:
|
||||
:path: ".symlinks/plugins/in_app_purchase_storekit/ios"
|
||||
in_app_review:
|
||||
:path: ".symlinks/plugins/in_app_review/ios"
|
||||
local_auth:
|
||||
|
|
@ -193,6 +198,7 @@ SPEC CHECKSUMS:
|
|||
GTMSessionFetcher: 5595ec75acf5be50814f81e9189490412bad82ba
|
||||
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
|
||||
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
|
||||
in_app_purchase_storekit: d7fcf4646136ec258e237872755da8ea6c1b6096
|
||||
in_app_review: 4a97249f7a2f539a0f294c2d9196b7fe35e49541
|
||||
local_auth: 1740f55d7af0a2e2a8684ce225fe79d8931e808c
|
||||
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import 'package:flutter_redux/flutter_redux.dart';
|
|||
import 'package:flutter_styled_toast/flutter_styled_toast.dart';
|
||||
import 'package:invoiceninja_flutter/redux/auth/auth_actions.dart';
|
||||
import 'package:invoiceninja_flutter/redux/settings/settings_actions.dart';
|
||||
import 'package:invoiceninja_flutter/ui/app/upgrade_dialog.dart';
|
||||
import 'package:invoiceninja_flutter/utils/app_review.dart';
|
||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||
import 'package:pointer_interceptor/pointer_interceptor.dart';
|
||||
|
|
@ -383,7 +384,7 @@ class MenuDrawer extends StatelessWidget {
|
|||
},
|
||||
),
|
||||
),
|
||||
if (state.userCompany.isOwner &&
|
||||
if (true || state.userCompany.isOwner &&
|
||||
state.isHosted &&
|
||||
!isPaidAccount(context) &&
|
||||
!isApple() &&
|
||||
|
|
@ -397,15 +398,14 @@ class MenuDrawer extends StatelessWidget {
|
|||
dense: true,
|
||||
tileColor: Colors.green,
|
||||
leading: Padding(
|
||||
padding: const EdgeInsets.only(left: 9),
|
||||
padding: const EdgeInsets.only(left: 6),
|
||||
child: Icon(
|
||||
Icons.arrow_circle_up,
|
||||
size: 22,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
contentPadding:
|
||||
const EdgeInsets.only(left: 12),
|
||||
contentPadding: const EdgeInsets.only(left: 20),
|
||||
title: state.isMenuCollapsed
|
||||
? SizedBox()
|
||||
: Text(
|
||||
|
|
@ -419,11 +419,16 @@ class MenuDrawer extends StatelessWidget {
|
|||
),
|
||||
),
|
||||
onTap: () {
|
||||
|
||||
showDialog<void>(context: context, builder: (BuildContext context) => UpgradeDialog());
|
||||
|
||||
/*
|
||||
store.dispatch(ViewSettings(
|
||||
clearFilter: true,
|
||||
company: company,
|
||||
user: state.user,
|
||||
section: kSettingsAccountManagement));
|
||||
*/
|
||||
},
|
||||
),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@ import 'package:in_app_purchase_storekit/in_app_purchase_storekit.dart';
|
|||
import 'package:in_app_purchase_storekit/store_kit_wrappers.dart';
|
||||
import 'package:invoiceninja_flutter/constants.dart';
|
||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||
import 'package:invoiceninja_flutter/ui/dashboard/dashboard_chart.dart';
|
||||
|
||||
class UpgradeDialog extends StatefulWidget {
|
||||
@override
|
||||
|
|
@ -22,7 +23,6 @@ class UpgradeDialog extends StatefulWidget {
|
|||
class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||
final InAppPurchase _inAppPurchase = InAppPurchase.instance;
|
||||
StreamSubscription<List<PurchaseDetails>> _subscription;
|
||||
List<String> _notFoundIds = <String>[];
|
||||
List<ProductDetails> _products = <ProductDetails>[];
|
||||
List<PurchaseDetails> _purchases = <PurchaseDetails>[];
|
||||
bool _isAvailable = false;
|
||||
|
|
@ -53,7 +53,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
|||
_isAvailable = isAvailable;
|
||||
_products = <ProductDetails>[];
|
||||
_purchases = <PurchaseDetails>[];
|
||||
_notFoundIds = <String>[];
|
||||
_purchasePending = false;
|
||||
_loading = false;
|
||||
});
|
||||
|
|
@ -75,7 +74,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
|||
_isAvailable = isAvailable;
|
||||
_products = productDetailResponse.productDetails;
|
||||
_purchases = <PurchaseDetails>[];
|
||||
_notFoundIds = productDetailResponse.notFoundIDs;
|
||||
_purchasePending = false;
|
||||
_loading = false;
|
||||
});
|
||||
|
|
@ -88,7 +86,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
|||
_isAvailable = isAvailable;
|
||||
_products = productDetailResponse.productDetails;
|
||||
_purchases = <PurchaseDetails>[];
|
||||
_notFoundIds = productDetailResponse.notFoundIDs;
|
||||
_purchasePending = false;
|
||||
_loading = false;
|
||||
});
|
||||
|
|
@ -98,7 +95,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
|||
setState(() {
|
||||
_isAvailable = isAvailable;
|
||||
_products = productDetailResponse.productDetails;
|
||||
_notFoundIds = productDetailResponse.notFoundIDs;
|
||||
_purchasePending = false;
|
||||
_loading = false;
|
||||
});
|
||||
|
|
@ -150,7 +146,7 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
|||
);
|
||||
}
|
||||
|
||||
return Stack(children: stack);
|
||||
return AlertDialog(content: Stack(children: stack));
|
||||
}
|
||||
|
||||
Card _buildConnectionCheckTile() {
|
||||
|
|
@ -194,13 +190,7 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
|||
final store = StoreProvider.of<AppState>(context);
|
||||
final account = store.state.account;
|
||||
|
||||
if (_notFoundIds.isNotEmpty) {
|
||||
productList.add(ListTile(
|
||||
title: Text('[${_notFoundIds.join(", ")}] not found',
|
||||
style: TextStyle(color: ThemeData.light().errorColor)),
|
||||
subtitle: const Text(
|
||||
'This app needs special configuration to run. Please see example/README.md for instructions.')));
|
||||
}
|
||||
|
||||
|
||||
// This loading previous purchases code is just a demo. Please do not use this as it is.
|
||||
// In your app you should always verify the purchase data using the `verificationData` inside the [PurchaseDetails] object before trusting it.
|
||||
|
|
@ -216,44 +206,61 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
|||
productList.addAll(_products.map(
|
||||
(ProductDetails productDetails) {
|
||||
final PurchaseDetails previousPurchase = purchases[productDetails.id];
|
||||
|
||||
String title = productDetails.title;
|
||||
String description = productDetails.description;
|
||||
|
||||
// TODO remove this code
|
||||
// Workaround for product in app store with blank values
|
||||
if (title.isEmpty && productDetails.id == kProductEnterprisePlanMonth_10) {
|
||||
title = 'Enterprise - Month (6-10)';
|
||||
description = 'One month of the Enterprise Plan (10 users)';
|
||||
}
|
||||
|
||||
return ListTile(
|
||||
title: Text(
|
||||
productDetails.title,
|
||||
title
|
||||
),
|
||||
subtitle: Text(
|
||||
productDetails.description,
|
||||
),
|
||||
trailing: previousPurchase != null
|
||||
? IconButton(
|
||||
subtitle: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
description
|
||||
),
|
||||
previousPurchase != null
|
||||
? IconButton(
|
||||
onPressed: () => confirmPriceChange(context),
|
||||
icon: const Icon(Icons.upgrade))
|
||||
: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.green[800],
|
||||
// TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
|
||||
// ignore: deprecated_member_use
|
||||
primary: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
PurchaseParam purchaseParam;
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
purchaseParam = GooglePlayPurchaseParam(
|
||||
productDetails: productDetails,
|
||||
applicationUserName: account.id);
|
||||
} else {
|
||||
purchaseParam = PurchaseParam(
|
||||
productDetails: productDetails,
|
||||
applicationUserName: account.id,
|
||||
);
|
||||
}
|
||||
|
||||
_inAppPurchase.buyNonConsumable(
|
||||
purchaseParam: purchaseParam,
|
||||
);
|
||||
},
|
||||
child: Text(productDetails.price),
|
||||
: TextButton(
|
||||
style: TextButton.styleFrom(
|
||||
backgroundColor: Colors.green[800],
|
||||
// TODO(darrenaustin): Migrate to new API once it lands in stable: https://github.com/flutter/flutter/issues/105724
|
||||
// ignore: deprecated_member_use
|
||||
primary: Colors.white,
|
||||
),
|
||||
onPressed: () {
|
||||
PurchaseParam purchaseParam;
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
purchaseParam = GooglePlayPurchaseParam(
|
||||
productDetails: productDetails,
|
||||
applicationUserName: account.id);
|
||||
} else {
|
||||
purchaseParam = PurchaseParam(
|
||||
productDetails: productDetails,
|
||||
applicationUserName: account.id,
|
||||
);
|
||||
}
|
||||
|
||||
_inAppPurchase.buyNonConsumable(
|
||||
purchaseParam: purchaseParam,
|
||||
);
|
||||
},
|
||||
child: Text(productDetails.price),
|
||||
),
|
||||
SizedBox(height: 20),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
));
|
||||
|
|
|
|||
Loading…
Reference in New Issue