diff --git a/.gitignore b/.gitignore index 6a3815d..8347dfb 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,5 @@ build/ .idea/ key.properties +premium_features_manager.class.dart pubspec.lock \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 57c694b..59be133 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -7,6 +7,7 @@ --> + @@ -46,5 +47,12 @@ + + + + + + diff --git a/android/app/src/main/java/com/keyboardcrumbs/hassclient/Application.java b/android/app/src/main/java/com/keyboardcrumbs/hassclient/Application.java new file mode 100644 index 0000000..d77e627 --- /dev/null +++ b/android/app/src/main/java/com/keyboardcrumbs/hassclient/Application.java @@ -0,0 +1,20 @@ +package com.keyboardcrumbs.hassclient; + +import io.flutter.app.FlutterApplication; +import io.flutter.plugin.common.PluginRegistry; +import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback; +import io.flutter.plugins.GeneratedPluginRegistrant; +import com.lyokone.location.LocationPlugin; + +public class Application extends FlutterApplication implements PluginRegistrantCallback { + @Override + public void onCreate() { + super.onCreate(); + LocationPlugin.setPluginRegistrant(this); + } + + @Override + public void registerWith(PluginRegistry registry) { + GeneratedPluginRegistrant.registerWith(registry); + } +} \ No newline at end of file diff --git a/flutter_01.log b/flutter_01.log new file mode 100644 index 0000000..b4dfb04 --- /dev/null +++ b/flutter_01.log @@ -0,0 +1,41 @@ +Flutter crash report; please file at https://github.com/flutter/flutter/issues. + +## command + +flutter --no-color run --machine --track-widget-creation --device-id=89AY052S4 lib/main.dart + +## exception + +_InternalLinkedHashMap: {code: 105, message: Isolate must be runnable, data: {request: {method: _reloadSources, params: {pause: true, rootLibUri: file:///data/user/0/com.keyboardcrumbs.haclient/code_cache/ha_clientSYJJZI/ha_client/lib/main.dart.incremental.dill, packagesUri: file:///data/user/0/com.keyboardcrumbs.haclient/code_cache/ha_clientSYJJZI/ha_client/.packages, isolateId: isolates/68989666}}, details: Isolate must be runnable before this request is made.}} + +``` +null``` + +## flutter doctor + +``` +[✓] Flutter (Channel stable, v1.7.8+hotfix.4, on Linux, locale en_US.UTF-8) + • Flutter version 1.7.8+hotfix.4 at /home/estevez/sdk/flutter + • Framework revision 20e59316b8 (6 weeks ago), 2019-07-18 20:04:33 -0700 + • Engine revision fee001c93f + • Dart version 2.4.0 + +[✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2) + • Android SDK at /home/estevez/Android/Sdk + • Android NDK location not configured (optional; useful for native profiling support) + • Platform android-29, build-tools 29.0.2 + • Java binary at: /home/estevez/bin/android-studio/jre/bin/java + • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405) + • All Android licenses accepted. + +[✓] Android Studio (version 3.5) + • Android Studio at /home/estevez/bin/android-studio + • Flutter plugin version 38.2.3 + • Dart plugin version 191.8423 + • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405) + +[✓] Connected device (1 available) + • Pixel 3 XL • 89AY052S4 • android-arm64 • Android 9 (API 28) + +• No issues found! +``` diff --git a/lib/main.dart b/lib/main.dart index 2d311a7..ccdc68b 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -15,7 +15,6 @@ import 'package:http/http.dart' as http; import 'package:charts_flutter/flutter.dart' as charts; import 'package:progress_indicators/progress_indicators.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; -//import 'package:flutter_svg/flutter_svg.dart'; import 'package:flutter_custom_tabs/flutter_custom_tabs.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; @@ -23,8 +22,10 @@ import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:device_info/device_info.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:in_app_purchase/in_app_purchase.dart'; +import 'package:location/location.dart'; part 'const.dart'; +part 'premium_features_manager.class.dart'; part 'entities/entity.class.dart'; part 'entities/entity_wrapper.class.dart'; part 'entities/timer/timer_entity.class.dart'; @@ -118,7 +119,7 @@ FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin = new FlutterLoc const String appName = "HA Client"; const appVersion = "0.6.4"; -void main() { +void main() async { FlutterError.onError = (errorDetails) { Logger.e( "${errorDetails.exception}"); if (Logger.isInDebugMode) { @@ -127,7 +128,9 @@ void main() { }; runZoned(() { + runApp(new HAClientApp()); + }, onError: (error, stack) { Logger.e("$error"); Logger.e("$stack"); @@ -239,6 +242,8 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker flutterLocalNotificationsPlugin.initialize(initializationSettings, onSelectNotification: onSelectNotification); + + _settingsSubscription = eventBus.on().listen((event) { Logger.d("Settings change event: reconnect=${event.reconnect}"); if (event.reconnect) { @@ -247,6 +252,8 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker }); _fullLoad(); + + } Future onSelectNotification(String payload) async { @@ -274,6 +281,7 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker _showInfoBottomBar(progress: true,); _subscribe().then((_) { Connection().init(loadSettings: true, forceReconnect: true).then((__){ + PremiumFeaturesManager(); _fetchData(); }, onError: (e) { _setErrorState(e); @@ -321,6 +329,7 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker void _handlePurchaseUpdates(purchase) { if (purchase is List) { if (purchase[0].status == PurchaseStatus.purchased) { + PremiumFeaturesManager().updatePurchases(purchase[0]); eventBus.fire(ShowPopupMessageEvent( title: "Thanks a lot!", body: "Thank you for supporting HA Client development!", @@ -752,6 +761,7 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker Widget _buildScaffoldBody(bool empty) { List> popupMenuItems = []; + popupMenuItems.add(PopupMenuItem( child: new Text("Reload"), value: "reload", diff --git a/lib/pages/purchase.page.dart b/lib/pages/purchase.page.dart index ef4c733..8b0d7d1 100644 --- a/lib/pages/purchase.page.dart +++ b/lib/pages/purchase.page.dart @@ -10,66 +10,29 @@ class PurchasePage extends StatefulWidget { } class _PurchasePageState extends State { - + bool _loaded = false; String _error = ""; - List _products; - List _purchases; + @override void initState() { super.initState(); - _loadProducts(); - } - - _loadProducts() async { - final bool available = await InAppPurchaseConnection.instance.isAvailable(); - if (!available) { - setState(() { - _error = "Error connecting to store"; - }); + if (PremiumFeaturesManager().products.isEmpty) { + _error = "Subscription is not loaded"; } else { - const Set _kIds = {'just_few_bucks_per_year', 'app_fan_support_per_year', 'grateful_user_support_per_year'}; - final ProductDetailsResponse response = await InAppPurchaseConnection.instance.queryProductDetails(_kIds); - if (!response.notFoundIDs.isEmpty) { - Logger.d("Products not found: ${response.notFoundIDs}"); - } - _products = response.productDetails; - _loadPreviousPurchases(); + _loaded = true; } } - _loadPreviousPurchases() async { - final QueryPurchaseDetailsResponse response = await InAppPurchaseConnection.instance.queryPastPurchases(); - if (response.error != null) { - setState(() { - _error = "Error loading previous purchases"; - }); - } else { - _purchases = response.pastPurchases; - for (PurchaseDetails purchase in _purchases) { - Logger.d("Previous purchase: ${purchase.status}"); - } - if (_products.isEmpty) { - setState(() { - _error = "No data found in store"; - }); - } else { - setState(() { - _loaded = true; - }); - } - } - } - Widget _buildProducts() { List productWidgets = []; - for (ProductDetails product in _products) { + for (ProductDetails product in PremiumFeaturesManager().products) { productWidgets.add( ProductPurchase( product: product, onBuy: (product) => _buyProduct(product), - purchased: _purchases.any((purchase) { return purchase.productID == product.id;}),) + purchased: PremiumFeaturesManager().purchases.any((purchase) { return purchase.productID == product.id;}),) ); } return ListView( diff --git a/pubspec.lock b/pubspec.lock index 0dc0c35..c51d396 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,14 +49,14 @@ packages: name: charts_common url: "https://pub.dartlang.org" source: hosted - version: "0.6.0" + version: "0.7.0" charts_flutter: dependency: "direct main" description: name: charts_flutter url: "https://pub.dartlang.org" source: hosted - version: "0.6.0" + version: "0.7.0" collection: dependency: transitive description: @@ -77,7 +77,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "2.1.1+1" + version: "2.1.2" date_format: dependency: "direct main" description: @@ -207,6 +207,15 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.4.0" + location: + dependency: "direct main" + description: + path: "." + ref: background_location + resolved-ref: "7c089fad38acbb7be7c46f207f601ac8e6b21caf" + url: "git://github.com/Lyokone/flutterlocation.git" + source: git + version: "2.3.5" logging: dependency: transitive description: @@ -309,7 +318,7 @@ packages: name: sqflite url: "https://pub.dartlang.org" source: hosted - version: "1.1.6+3" + version: "1.1.6+4" stack_trace: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 26fe385..a2cdb7e 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -26,6 +26,11 @@ dependencies: flutter_secure_storage: ^3.2.1+1 device_info: ^0.4.0+2 flutter_local_notifications: ^0.8.2 + location: + git: + url: git://github.com/Lyokone/flutterlocation.git + ref: background_location + dev_dependencies: flutter_test: