Apple IAP
This commit is contained in:
parent
cb39924f19
commit
ca9541026b
|
|
@ -61,6 +61,8 @@ PODS:
|
||||||
- TOCropViewController (~> 2.6.1)
|
- TOCropViewController (~> 2.6.1)
|
||||||
- image_picker_ios (0.0.1):
|
- image_picker_ios (0.0.1):
|
||||||
- Flutter
|
- Flutter
|
||||||
|
- in_app_purchase_storekit (0.0.1):
|
||||||
|
- Flutter
|
||||||
- in_app_review (0.2.0):
|
- in_app_review (0.2.0):
|
||||||
- Flutter
|
- Flutter
|
||||||
- local_auth (0.0.1):
|
- local_auth (0.0.1):
|
||||||
|
|
@ -108,6 +110,7 @@ DEPENDENCIES:
|
||||||
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
|
- google_sign_in_ios (from `.symlinks/plugins/google_sign_in_ios/ios`)
|
||||||
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
|
- image_cropper (from `.symlinks/plugins/image_cropper/ios`)
|
||||||
- image_picker_ios (from `.symlinks/plugins/image_picker_ios/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`)
|
- in_app_review (from `.symlinks/plugins/in_app_review/ios`)
|
||||||
- local_auth (from `.symlinks/plugins/local_auth/ios`)
|
- local_auth (from `.symlinks/plugins/local_auth/ios`)
|
||||||
- package_info (from `.symlinks/plugins/package_info/ios`)
|
- package_info (from `.symlinks/plugins/package_info/ios`)
|
||||||
|
|
@ -150,6 +153,8 @@ EXTERNAL SOURCES:
|
||||||
:path: ".symlinks/plugins/image_cropper/ios"
|
:path: ".symlinks/plugins/image_cropper/ios"
|
||||||
image_picker_ios:
|
image_picker_ios:
|
||||||
:path: ".symlinks/plugins/image_picker_ios/ios"
|
:path: ".symlinks/plugins/image_picker_ios/ios"
|
||||||
|
in_app_purchase_storekit:
|
||||||
|
:path: ".symlinks/plugins/in_app_purchase_storekit/ios"
|
||||||
in_app_review:
|
in_app_review:
|
||||||
:path: ".symlinks/plugins/in_app_review/ios"
|
:path: ".symlinks/plugins/in_app_review/ios"
|
||||||
local_auth:
|
local_auth:
|
||||||
|
|
@ -193,6 +198,7 @@ SPEC CHECKSUMS:
|
||||||
GTMSessionFetcher: 5595ec75acf5be50814f81e9189490412bad82ba
|
GTMSessionFetcher: 5595ec75acf5be50814f81e9189490412bad82ba
|
||||||
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
|
image_cropper: 60c2789d1f1a78c873235d4319ca0c34a69f2d98
|
||||||
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
|
image_picker_ios: b786a5dcf033a8336a657191401bfdf12017dabb
|
||||||
|
in_app_purchase_storekit: d7fcf4646136ec258e237872755da8ea6c1b6096
|
||||||
in_app_review: 4a97249f7a2f539a0f294c2d9196b7fe35e49541
|
in_app_review: 4a97249f7a2f539a0f294c2d9196b7fe35e49541
|
||||||
local_auth: 1740f55d7af0a2e2a8684ce225fe79d8931e808c
|
local_auth: 1740f55d7af0a2e2a8684ce225fe79d8931e808c
|
||||||
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
|
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:flutter_styled_toast/flutter_styled_toast.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/auth/auth_actions.dart';
|
import 'package:invoiceninja_flutter/redux/auth/auth_actions.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/settings/settings_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:invoiceninja_flutter/utils/app_review.dart';
|
||||||
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
|
||||||
import 'package:pointer_interceptor/pointer_interceptor.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 &&
|
state.isHosted &&
|
||||||
!isPaidAccount(context) &&
|
!isPaidAccount(context) &&
|
||||||
!isApple() &&
|
!isApple() &&
|
||||||
|
|
@ -397,15 +398,14 @@ class MenuDrawer extends StatelessWidget {
|
||||||
dense: true,
|
dense: true,
|
||||||
tileColor: Colors.green,
|
tileColor: Colors.green,
|
||||||
leading: Padding(
|
leading: Padding(
|
||||||
padding: const EdgeInsets.only(left: 9),
|
padding: const EdgeInsets.only(left: 6),
|
||||||
child: Icon(
|
child: Icon(
|
||||||
Icons.arrow_circle_up,
|
Icons.arrow_circle_up,
|
||||||
size: 22,
|
size: 22,
|
||||||
color: Colors.white,
|
color: Colors.white,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
contentPadding:
|
contentPadding: const EdgeInsets.only(left: 20),
|
||||||
const EdgeInsets.only(left: 12),
|
|
||||||
title: state.isMenuCollapsed
|
title: state.isMenuCollapsed
|
||||||
? SizedBox()
|
? SizedBox()
|
||||||
: Text(
|
: Text(
|
||||||
|
|
@ -419,11 +419,16 @@ class MenuDrawer extends StatelessWidget {
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
|
|
||||||
|
showDialog<void>(context: context, builder: (BuildContext context) => UpgradeDialog());
|
||||||
|
|
||||||
|
/*
|
||||||
store.dispatch(ViewSettings(
|
store.dispatch(ViewSettings(
|
||||||
clearFilter: true,
|
clearFilter: true,
|
||||||
company: company,
|
company: company,
|
||||||
user: state.user,
|
user: state.user,
|
||||||
section: kSettingsAccountManagement));
|
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:in_app_purchase_storekit/store_kit_wrappers.dart';
|
||||||
import 'package:invoiceninja_flutter/constants.dart';
|
import 'package:invoiceninja_flutter/constants.dart';
|
||||||
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
|
||||||
|
import 'package:invoiceninja_flutter/ui/dashboard/dashboard_chart.dart';
|
||||||
|
|
||||||
class UpgradeDialog extends StatefulWidget {
|
class UpgradeDialog extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
|
|
@ -22,7 +23,6 @@ class UpgradeDialog extends StatefulWidget {
|
||||||
class _UpgradeDialogState extends State<UpgradeDialog> {
|
class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
final InAppPurchase _inAppPurchase = InAppPurchase.instance;
|
final InAppPurchase _inAppPurchase = InAppPurchase.instance;
|
||||||
StreamSubscription<List<PurchaseDetails>> _subscription;
|
StreamSubscription<List<PurchaseDetails>> _subscription;
|
||||||
List<String> _notFoundIds = <String>[];
|
|
||||||
List<ProductDetails> _products = <ProductDetails>[];
|
List<ProductDetails> _products = <ProductDetails>[];
|
||||||
List<PurchaseDetails> _purchases = <PurchaseDetails>[];
|
List<PurchaseDetails> _purchases = <PurchaseDetails>[];
|
||||||
bool _isAvailable = false;
|
bool _isAvailable = false;
|
||||||
|
|
@ -53,7 +53,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
_isAvailable = isAvailable;
|
_isAvailable = isAvailable;
|
||||||
_products = <ProductDetails>[];
|
_products = <ProductDetails>[];
|
||||||
_purchases = <PurchaseDetails>[];
|
_purchases = <PurchaseDetails>[];
|
||||||
_notFoundIds = <String>[];
|
|
||||||
_purchasePending = false;
|
_purchasePending = false;
|
||||||
_loading = false;
|
_loading = false;
|
||||||
});
|
});
|
||||||
|
|
@ -75,7 +74,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
_isAvailable = isAvailable;
|
_isAvailable = isAvailable;
|
||||||
_products = productDetailResponse.productDetails;
|
_products = productDetailResponse.productDetails;
|
||||||
_purchases = <PurchaseDetails>[];
|
_purchases = <PurchaseDetails>[];
|
||||||
_notFoundIds = productDetailResponse.notFoundIDs;
|
|
||||||
_purchasePending = false;
|
_purchasePending = false;
|
||||||
_loading = false;
|
_loading = false;
|
||||||
});
|
});
|
||||||
|
|
@ -88,7 +86,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
_isAvailable = isAvailable;
|
_isAvailable = isAvailable;
|
||||||
_products = productDetailResponse.productDetails;
|
_products = productDetailResponse.productDetails;
|
||||||
_purchases = <PurchaseDetails>[];
|
_purchases = <PurchaseDetails>[];
|
||||||
_notFoundIds = productDetailResponse.notFoundIDs;
|
|
||||||
_purchasePending = false;
|
_purchasePending = false;
|
||||||
_loading = false;
|
_loading = false;
|
||||||
});
|
});
|
||||||
|
|
@ -98,7 +95,6 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
setState(() {
|
setState(() {
|
||||||
_isAvailable = isAvailable;
|
_isAvailable = isAvailable;
|
||||||
_products = productDetailResponse.productDetails;
|
_products = productDetailResponse.productDetails;
|
||||||
_notFoundIds = productDetailResponse.notFoundIDs;
|
|
||||||
_purchasePending = false;
|
_purchasePending = false;
|
||||||
_loading = false;
|
_loading = false;
|
||||||
});
|
});
|
||||||
|
|
@ -150,7 +146,7 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return Stack(children: stack);
|
return AlertDialog(content: Stack(children: stack));
|
||||||
}
|
}
|
||||||
|
|
||||||
Card _buildConnectionCheckTile() {
|
Card _buildConnectionCheckTile() {
|
||||||
|
|
@ -194,13 +190,7 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
final store = StoreProvider.of<AppState>(context);
|
final store = StoreProvider.of<AppState>(context);
|
||||||
final account = store.state.account;
|
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.
|
// 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.
|
// In your app you should always verify the purchase data using the `verificationData` inside the [PurchaseDetails] object before trusting it.
|
||||||
|
|
@ -216,14 +206,28 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
productList.addAll(_products.map(
|
productList.addAll(_products.map(
|
||||||
(ProductDetails productDetails) {
|
(ProductDetails productDetails) {
|
||||||
final PurchaseDetails previousPurchase = purchases[productDetails.id];
|
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(
|
return ListTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
productDetails.title,
|
title
|
||||||
),
|
),
|
||||||
subtitle: Text(
|
subtitle: Column(
|
||||||
productDetails.description,
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(
|
||||||
|
description
|
||||||
),
|
),
|
||||||
trailing: previousPurchase != null
|
previousPurchase != null
|
||||||
? IconButton(
|
? IconButton(
|
||||||
onPressed: () => confirmPriceChange(context),
|
onPressed: () => confirmPriceChange(context),
|
||||||
icon: const Icon(Icons.upgrade))
|
icon: const Icon(Icons.upgrade))
|
||||||
|
|
@ -254,6 +258,9 @@ class _UpgradeDialogState extends State<UpgradeDialog> {
|
||||||
},
|
},
|
||||||
child: Text(productDetails.price),
|
child: Text(productDetails.price),
|
||||||
),
|
),
|
||||||
|
SizedBox(height: 20),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue