WIP #48 Notifications

This commit is contained in:
estevez-dev 2019-03-30 00:29:52 +02:00
parent 102b10ade0
commit a7cda2a35e
6 changed files with 49 additions and 26 deletions

View File

@ -27,10 +27,10 @@
<!-- This keeps the window background of the activity showing <!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen there is no splash screen (such as the default splash screen
defined in @style/LaunchTheme). --> defined in @style/LaunchTheme).
<meta-data <meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame" android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" /> android:value="true" />-->
<intent-filter> <intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" /> <action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.DEFAULT" />

View File

@ -16,6 +16,7 @@ class Connection {
String _token; String _token;
String _tempToken; String _tempToken;
String oauthUrl; String oauthUrl;
String deviceName;
bool get isAuthenticated => _token != null; bool get isAuthenticated => _token != null;
StreamSubscription _socketSubscription; StreamSubscription _socketSubscription;
Duration connectTimeout = Duration(seconds: 15); Duration connectTimeout = Duration(seconds: 15);
@ -51,6 +52,9 @@ class Connection {
(domain.length == 0) || (port.length == 0)) { (domain.length == 0) || (port.length == 0)) {
completer.completeError({"errorCode": 5, "errorMessage": "Check connection settings"}); completer.completeError({"errorCode": 5, "errorMessage": "Check connection settings"});
} else { } else {
DeviceInfoPlugin deviceInfo = DeviceInfoPlugin();
AndroidDeviceInfo androidInfo = await deviceInfo.androidInfo;
deviceName = androidInfo.model;
oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent('http://ha-client.homemade.systems/')}&redirect_uri=${Uri.encodeComponent('http://ha-client.homemade.systems/service/auth_callback.html')}"; oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent('http://ha-client.homemade.systems/')}&redirect_uri=${Uri.encodeComponent('http://ha-client.homemade.systems/service/auth_callback.html')}";
if (_token == null) { if (_token == null) {
await AuthManager().getTempToken( await AuthManager().getTempToken(
@ -97,10 +101,7 @@ class Connection {
Logger.d("[Received] <== ${data.toString()}"); Logger.d("[Received] <== ${data.toString()}");
_messageResolver["auth"]?.complete(); _messageResolver["auth"]?.complete();
_messageResolver.remove("auth"); _messageResolver.remove("auth");
if (!connecting.isCompleted) connecting.complete(sendSocketMessage( if (!connecting.isCompleted) connecting.complete();
type: "subscribe_events",
additionalData: {"event_type": "state_changed"},
));
} else if (data["type"] == "auth_invalid") { } else if (data["type"] == "auth_invalid") {
Logger.d("[Received] <== ${data.toString()}"); Logger.d("[Received] <== ${data.toString()}");
_messageResolver["auth"]?.completeError({"errorCode": 62, "errorMessage": "${data["message"]}"}); _messageResolver["auth"]?.completeError({"errorCode": 62, "errorMessage": "${data["message"]}"});
@ -119,12 +120,16 @@ class Connection {
return connecting.future; return connecting.future;
} }
Future _disconnect() async { _disconnect() async {
Logger.d( "Socket disconnecting..."); Logger.d( "Socket disconnecting...");
await _socketSubscription?.cancel(); if (_socketSubscription != null) {
await _socket?.sink?.close()?.timeout(Duration(seconds: 4), await _socketSubscription?.cancel();
onTimeout: () => Logger.d( "Socket sink close timeout") }
); if (_socket != null && _socket.sink != null) {
await _socket.sink.close().timeout(Duration(seconds: 5),
onTimeout: () => Logger.d("Socket sink close timeout")
);
}
Logger.d( "..Disconnected"); Logger.d( "..Disconnected");
} }
@ -335,7 +340,6 @@ class Connection {
}).catchError((e) { }).catchError((e) {
completer.completeError(e); completer.completeError(e);
}); });
return completer.future; return completer.future;
} }

View File

@ -76,6 +76,10 @@ class HomeAssistant {
futures.add(_getPanels()); futures.add(_getPanels());
Future.wait(futures).then((_) { Future.wait(futures).then((_) {
_createUI(); _createUI();
Connection().sendSocketMessage(
type: "subscribe_events",
additionalData: {"event_type": "state_changed"},
);
_fetchCompleter.complete(); _fetchCompleter.complete();
}).catchError((e) { }).catchError((e) {
_fetchCompleter.completeError(e); _fetchCompleter.completeError(e);

View File

@ -20,6 +20,7 @@ import 'package:flutter_custom_tabs/flutter_custom_tabs.dart';
import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart'; import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:flutter_secure_storage/flutter_secure_storage.dart'; import 'package:flutter_secure_storage/flutter_secure_storage.dart';
import 'package:device_info/device_info.dart';
part 'entity_class/const.dart'; part 'entity_class/const.dart';
part 'entity_class/entity.class.dart'; part 'entity_class/entity.class.dart';
@ -104,6 +105,7 @@ part 'ui_widgets/config_panel_widget.dart';
EventBus eventBus = new EventBus(); EventBus eventBus = new EventBus();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
const String appName = "HA Client"; const String appName = "HA Client";
const appVersion = "0.6.0-alpha1"; const appVersion = "0.6.0-alpha1";
@ -168,7 +170,6 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
StreamSubscription _startAuthSubscription; StreamSubscription _startAuthSubscription;
StreamSubscription _reloadUISubscription; StreamSubscription _reloadUISubscription;
int _previousViewCount; int _previousViewCount;
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
@override @override
void initState() { void initState() {
@ -199,8 +200,8 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
void _initialLoad() async { void _initialLoad() async {
_showInfoBottomBar(progress: true,); _showInfoBottomBar(progress: true,);
await _subscribe();
widget.homeAssistant.init().then((_){ widget.homeAssistant.init().then((_){
_subscribe();
_fetchData(); _fetchData();
}, onError: (e) { }, onError: (e) {
_setErrorState(e); _setErrorState(e);
@ -285,13 +286,16 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
} }
_firebaseMessaging.getToken().then((String token) { _firebaseMessaging.getToken().then((String token) {
//Logger.d("FCM token: $token"); Logger.d("Device name: ${json.encode(Connection().deviceName)}");
widget.homeAssistant.connection.sendHTTPPost( widget.homeAssistant.connection.sendHTTPPost(
endPoint: '/api/notify.fcm-android', endPoint: '/api/notify.ha-client',
data: '{"token": "$token"}' data: '{"token": "$token", "device": ${json.encode(Connection().deviceName)}}'
).then((_) { ).then((_) {
Logger.d("Notificatin listener registered."); Logger.d("Notificatin listener registered.");
completer.complete(); completer.complete();
}).catchError((e) {
Logger.e("Error registering notification listener: ${e.toString()}");
completer.complete();
}); });
}).catchError((e) { }).catchError((e) {
Logger.e("Error registering notification listener: ${e.toString()}"); Logger.e("Error registering notification listener: ${e.toString()}");
@ -319,9 +323,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
} }
_setErrorState(e) { _setErrorState(e) {
if (e is Error) { if (e["errorCode"] == null) {
Logger.e(e.toString());
Logger.e("${e.stackTrace}");
_showErrorBottomBar( _showErrorBottomBar(
message: "Unknown error", message: "Unknown error",
errorCode: 13 errorCode: 13
@ -566,7 +568,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
case 10: { case 10: {
_bottomBarAction = FlatButton( _bottomBarAction = FlatButton(
child: Text("Refresh", style: textStyle), child: Text("Reload", style: textStyle),
onPressed: () { onPressed: () {
//_scaffoldKey?.currentState?.hideCurrentSnackBar(); //_scaffoldKey?.currentState?.hideCurrentSnackBar();
_reLoad(); _reLoad();
@ -588,7 +590,12 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
} }
default: { default: {
_bottomBarAction = Container(width: 0.0, height: 0.0,); _bottomBarAction = FlatButton(
child: Text("Try again", style: textStyle),
onPressed: () {
_reLoad();
},
);
break; break;
} }
} }

View File

@ -94,13 +94,20 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.6" version: "1.0.6"
device_info:
dependency: "direct main"
description:
name: device_info
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.0+1"
event_bus: event_bus:
dependency: "direct main" dependency: "direct main"
description: description:
name: event_bus name: event_bus
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.3" version: "1.1.0"
firebase_messaging: firebase_messaging:
dependency: "direct main" dependency: "direct main"
description: description:
@ -166,7 +173,7 @@ packages:
name: flutter_webview_plugin name: flutter_webview_plugin
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.3.1" version: "0.3.3"
http: http:
dependency: transitive dependency: transitive
description: description:
@ -194,7 +201,7 @@ packages:
name: intl name: intl
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.15.7" version: "0.15.8"
logging: logging:
dependency: transitive dependency: transitive
description: description:
@ -388,7 +395,7 @@ packages:
name: web_socket_channel name: web_socket_channel
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "1.0.9" version: "1.0.12"
xml: xml:
dependency: transitive dependency: transitive
description: description:

View File

@ -23,6 +23,7 @@ dependencies:
firebase_messaging: ^4.0.0+1 firebase_messaging: ^4.0.0+1
flutter_webview_plugin: ^0.3.1 flutter_webview_plugin: ^0.3.1
flutter_secure_storage: ^3.2.0 flutter_secure_storage: ^3.2.0
device_info: ^0.4.0+1
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: