This commit is contained in:
estevez-dev 2019-08-28 19:23:04 +03:00
parent b112ff980a
commit bc1a791608
8 changed files with 108 additions and 51 deletions

1
.gitignore vendored
View File

@ -11,4 +11,5 @@ build/
.idea/
key.properties
premium_features_manager.class.dart
pubspec.lock

View File

@ -7,6 +7,7 @@
-->
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
@ -14,7 +15,7 @@
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:name=".Application"
android:label="HA Client"
android:icon="@mipmap/ic_launcher"
android:usesCleartextTraffic="true">
@ -46,5 +47,12 @@
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver android:name="com.lyokone.location.BackgroundLocationBroadcastReceiver"
android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.lyokone.location.BackgroundLocationBroadcastReceiver.ACTION_PROCESS_UPDATES" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -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);
}
}

41
flutter_01.log Normal file
View File

@ -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<String, dynamic>: {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!
```

View File

@ -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<MainPage> with WidgetsBindingObserver, Ticker
flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: onSelectNotification);
_settingsSubscription = eventBus.on<SettingsChangedEvent>().listen((event) {
Logger.d("Settings change event: reconnect=${event.reconnect}");
if (event.reconnect) {
@ -247,6 +252,8 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
});
_fullLoad();
}
Future onSelectNotification(String payload) async {
@ -274,6 +281,7 @@ class _MainPageState extends State<MainPage> 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<MainPage> with WidgetsBindingObserver, Ticker
void _handlePurchaseUpdates(purchase) {
if (purchase is List<PurchaseDetails>) {
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<MainPage> with WidgetsBindingObserver, Ticker
Widget _buildScaffoldBody(bool empty) {
List<PopupMenuItem<String>> popupMenuItems = [];
popupMenuItems.add(PopupMenuItem<String>(
child: new Text("Reload"),
value: "reload",

View File

@ -10,66 +10,29 @@ class PurchasePage extends StatefulWidget {
}
class _PurchasePageState extends State<PurchasePage> {
bool _loaded = false;
String _error = "";
List<ProductDetails> _products;
List<PurchaseDetails> _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<String> _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<Widget> 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(

View File

@ -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:

View File

@ -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: