WIP: AppSettings
This commit is contained in:
parent
24d42c9597
commit
a20dfaf05e
@ -153,6 +153,7 @@ part 'pages/whats_new.page.dart';
|
|||||||
part 'pages/fullscreen.page.dart';
|
part 'pages/fullscreen.page.dart';
|
||||||
part 'popups.dart';
|
part 'popups.dart';
|
||||||
part 'cards/badges.dart';
|
part 'cards/badges.dart';
|
||||||
|
part 'managers/app_settings.dart';
|
||||||
|
|
||||||
EventBus eventBus = new EventBus();
|
EventBus eventBus = new EventBus();
|
||||||
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
|
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
|
||||||
|
74
lib/managers/app_settings.dart
Normal file
74
lib/managers/app_settings.dart
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
part of '../main.dart';
|
||||||
|
|
||||||
|
class AppSettings {
|
||||||
|
|
||||||
|
static final AppSettings _instance = AppSettings._internal();
|
||||||
|
|
||||||
|
factory AppSettings() {
|
||||||
|
return _instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppSettings._internal();
|
||||||
|
|
||||||
|
String mobileAppDeviceName;
|
||||||
|
String _domain;
|
||||||
|
String _port;
|
||||||
|
String displayHostname;
|
||||||
|
String webSocketAPIEndpoint;
|
||||||
|
String httpWebHost;
|
||||||
|
String _token;
|
||||||
|
String _tempToken;
|
||||||
|
String oauthUrl;
|
||||||
|
String webhookId;
|
||||||
|
double haVersion;
|
||||||
|
bool scrollBadges;
|
||||||
|
int appIntegrationVersion;
|
||||||
|
|
||||||
|
bool get isAuthenticated => _token != null;
|
||||||
|
|
||||||
|
Future load(bool quick) async {
|
||||||
|
if (!quick) {
|
||||||
|
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||||
|
_domain = prefs.getString('hassio-domain');
|
||||||
|
_port = prefs.getString('hassio-port');
|
||||||
|
webhookId = prefs.getString('app-webhook-id');
|
||||||
|
mobileAppDeviceName = prefs.getString('app-integration-device-name');
|
||||||
|
appIntegrationVersion = prefs.getInt('app-integration-version') ?? 0;
|
||||||
|
scrollBadges = prefs.getBool('scroll-badges') ?? true;
|
||||||
|
displayHostname = "$_domain:$_port";
|
||||||
|
_webSocketAPIEndpoint =
|
||||||
|
"${prefs.getString('hassio-protocol')}://$_domain:$_port/api/websocket";
|
||||||
|
httpWebHost =
|
||||||
|
"${prefs.getString('hassio-res-protocol')}://$_domain:$_port";
|
||||||
|
try {
|
||||||
|
final storage = new FlutterSecureStorage();
|
||||||
|
_token = await storage.read(key: "hacl_llt");
|
||||||
|
Logger.d("Long-lived token read successful");
|
||||||
|
oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent(
|
||||||
|
'https://ha-client.app')}&redirect_uri=${Uri
|
||||||
|
.encodeComponent(
|
||||||
|
'https://ha-client.app/service/auth_callback.html')}";
|
||||||
|
} catch (e, stacktrace) {
|
||||||
|
Logger.e("Error reading secure storage: $e", stacktrace: stacktrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future startAuth() {
|
||||||
|
return AuthManager().start(
|
||||||
|
oauthUrl: oauthUrl
|
||||||
|
).then((token) {
|
||||||
|
Logger.d("Token from AuthManager recived");
|
||||||
|
_tempToken = token;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isNotConfigured() {
|
||||||
|
return _domain == null && _port == null && webhookId == null && mobileAppDeviceName == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSomethingMissed() {
|
||||||
|
return (_domain == null) || (_port == null) || (_domain.isEmpty) || (_port.isEmpty);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -10,25 +10,11 @@ class ConnectionManager {
|
|||||||
|
|
||||||
ConnectionManager._internal();
|
ConnectionManager._internal();
|
||||||
|
|
||||||
String _domain;
|
|
||||||
String _port;
|
|
||||||
String displayHostname;
|
|
||||||
String _webSocketAPIEndpoint;
|
|
||||||
String httpWebHost;
|
|
||||||
String _token;
|
|
||||||
String _tempToken;
|
|
||||||
String oauthUrl;
|
|
||||||
String webhookId;
|
|
||||||
double haVersion;
|
|
||||||
bool scrollBadges;
|
|
||||||
String mobileAppDeviceName;
|
|
||||||
bool settingsLoaded = false;
|
|
||||||
int appIntegrationVersion;
|
|
||||||
bool get isAuthenticated => _token != null;
|
|
||||||
StreamSubscription _socketSubscription;
|
StreamSubscription _socketSubscription;
|
||||||
Duration connectTimeout = Duration(seconds: 15);
|
Duration connectTimeout = Duration(seconds: 15);
|
||||||
|
|
||||||
bool isConnected = false;
|
bool isConnected = false;
|
||||||
|
bool settingsLoaded = false;
|
||||||
|
|
||||||
var onStateChangeCallback;
|
var onStateChangeCallback;
|
||||||
var onLovelaceUpdatedCallback;
|
var onLovelaceUpdatedCallback;
|
||||||
@ -38,62 +24,15 @@ class ConnectionManager {
|
|||||||
int _currentMessageId = 0;
|
int _currentMessageId = 0;
|
||||||
Map<String, Completer> _messageResolver = {};
|
Map<String, Completer> _messageResolver = {};
|
||||||
|
|
||||||
Future init({bool loadSettings, bool forceReconnect: false}) async {
|
Future init({bool loadSettings, bool forceReconnect: false}) {
|
||||||
Completer completer = Completer();
|
Completer completer = Completer();
|
||||||
bool stopInit = false;
|
AppSettings().load(loadSettings).then((_) {
|
||||||
if (loadSettings) {
|
if (AppSettings().isNotConfigured()) {
|
||||||
Logger.d("Loading settings...");
|
|
||||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
|
||||||
_domain = prefs.getString('hassio-domain');
|
|
||||||
_port = prefs.getString('hassio-port');
|
|
||||||
webhookId = prefs.getString('app-webhook-id');
|
|
||||||
appIntegrationVersion = prefs.getInt('app-integration-version') ?? 0;
|
|
||||||
mobileAppDeviceName = prefs.getString('app-integration-device-name');
|
|
||||||
scrollBadges = prefs.getBool('scroll-badges') ?? true;
|
|
||||||
displayHostname = "$_domain:$_port";
|
|
||||||
_webSocketAPIEndpoint =
|
|
||||||
"${prefs.getString('hassio-protocol')}://$_domain:$_port/api/websocket";
|
|
||||||
httpWebHost =
|
|
||||||
"${prefs.getString('hassio-res-protocol')}://$_domain:$_port";
|
|
||||||
Logger.d('$_domain$_port');
|
|
||||||
if (_domain == null && _port == null && webhookId == null && mobileAppDeviceName == null) {
|
|
||||||
completer.completeError(HACNotSetUpException());
|
completer.completeError(HACNotSetUpException());
|
||||||
stopInit = true;
|
} else if (AppSettings().isSomethingMissed()) {
|
||||||
} else if ((_domain == null) || (_port == null) ||
|
|
||||||
(_domain.isEmpty) || (_port.isEmpty)) {
|
|
||||||
completer.completeError(HACException.checkConnectionSettings());
|
completer.completeError(HACException.checkConnectionSettings());
|
||||||
stopInit = true;
|
} else if (!AppSettings().isAuthenticated) {
|
||||||
} else {
|
AppSettings().startAuth().then((_) {
|
||||||
final storage = new FlutterSecureStorage();
|
|
||||||
try {
|
|
||||||
_token = await storage.read(key: "hacl_llt");
|
|
||||||
Logger.d("Long-lived token read successful");
|
|
||||||
oauthUrl = "$httpWebHost/auth/authorize?client_id=${Uri.encodeComponent(
|
|
||||||
'https://ha-client.app')}&redirect_uri=${Uri
|
|
||||||
.encodeComponent(
|
|
||||||
'https://ha-client.app/service/auth_callback.html')}";
|
|
||||||
settingsLoaded = true;
|
|
||||||
} catch (e, stacktrace) {
|
|
||||||
completer.completeError(HACException("Error reading login details", actions: [HAErrorAction.tryAgain(type: HAErrorActionType.FULL_RELOAD), HAErrorAction.loginAgain()]));
|
|
||||||
Logger.e("Error reading secure storage: $e", stacktrace: stacktrace);
|
|
||||||
stopInit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ((_domain == null) || (_port == null) ||
|
|
||||||
(_domain.isEmpty) || (_port.isEmpty)) {
|
|
||||||
completer.completeError(HACException.checkConnectionSettings());
|
|
||||||
stopInit = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stopInit) {
|
|
||||||
if (_token == null) {
|
|
||||||
AuthManager().start(
|
|
||||||
oauthUrl: oauthUrl
|
|
||||||
).then((token) {
|
|
||||||
Logger.d("Token from AuthManager recived");
|
|
||||||
_tempToken = token;
|
|
||||||
_doConnect(completer: completer, forceReconnect: forceReconnect);
|
_doConnect(completer: completer, forceReconnect: forceReconnect);
|
||||||
}).catchError((e) {
|
}).catchError((e) {
|
||||||
completer.completeError(e);
|
completer.completeError(e);
|
||||||
@ -101,7 +40,7 @@ class ConnectionManager {
|
|||||||
} else {
|
} else {
|
||||||
_doConnect(completer: completer, forceReconnect: forceReconnect);
|
_doConnect(completer: completer, forceReconnect: forceReconnect);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
return completer.future;
|
return completer.future;
|
||||||
}
|
}
|
||||||
@ -143,7 +82,7 @@ class ConnectionManager {
|
|||||||
Logger.d("Socket connecting...");
|
Logger.d("Socket connecting...");
|
||||||
try {
|
try {
|
||||||
_socket = IOWebSocketChannel.connect(
|
_socket = IOWebSocketChannel.connect(
|
||||||
_webSocketAPIEndpoint, pingInterval: Duration(seconds: 15));
|
AppSettings().webSocketAPIEndpoint, pingInterval: Duration(seconds: 15));
|
||||||
_socketSubscription = _socket.stream.listen(
|
_socketSubscription = _socket.stream.listen(
|
||||||
(message) {
|
(message) {
|
||||||
isConnected = true;
|
isConnected = true;
|
||||||
@ -159,9 +98,9 @@ class ConnectionManager {
|
|||||||
} else if (data["type"] == "auth_ok") {
|
} else if (data["type"] == "auth_ok") {
|
||||||
String v = data["ha_version"];
|
String v = data["ha_version"];
|
||||||
if (v != null && v.isNotEmpty) {
|
if (v != null && v.isNotEmpty) {
|
||||||
haVersion = double.tryParse(v.replaceFirst('0.','')) ?? 0;
|
AppSettings().haVersion = double.tryParse(v.replaceFirst('0.','')) ?? 0;
|
||||||
}
|
}
|
||||||
Logger.d("Home assistant version: $v ($haVersion)");
|
Logger.d("Home assistant version: $v (${AppSettings().haVersion})");
|
||||||
Crashlytics.instance.setString('ha_version', v);
|
Crashlytics.instance.setString('ha_version', v);
|
||||||
Logger.d("[Connection] Subscribing to events");
|
Logger.d("[Connection] Subscribing to events");
|
||||||
sendSocketMessage(
|
sendSocketMessage(
|
||||||
@ -174,7 +113,7 @@ class ConnectionManager {
|
|||||||
).whenComplete((){
|
).whenComplete((){
|
||||||
_messageResolver["auth"]?.complete();
|
_messageResolver["auth"]?.complete();
|
||||||
_messageResolver.remove("auth");
|
_messageResolver.remove("auth");
|
||||||
if (_token != null) {
|
if (AppSettings().isAuthenticated) {
|
||||||
if (!connecting.isCompleted) connecting.complete();
|
if (!connecting.isCompleted) connecting.complete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -268,7 +207,7 @@ class ConnectionManager {
|
|||||||
|
|
||||||
Future _authenticate() {
|
Future _authenticate() {
|
||||||
Completer completer = Completer();
|
Completer completer = Completer();
|
||||||
if (_token != null) {
|
if (AppSettings().isAuthenticated) {
|
||||||
Logger.d( "Long-lived token exist");
|
Logger.d( "Long-lived token exist");
|
||||||
Logger.d( "[Sending] ==> auth request");
|
Logger.d( "[Sending] ==> auth request");
|
||||||
sendSocketMessage(
|
sendSocketMessage(
|
||||||
|
Reference in New Issue
Block a user