Error messages refactored

This commit is contained in:
estevez-dev 2019-09-03 23:25:39 +03:00
parent 620aa3b8d8
commit 8efeb3da8a
8 changed files with 330 additions and 68 deletions

View File

@ -4,13 +4,11 @@ import io.flutter.app.FlutterApplication;
import io.flutter.plugin.common.PluginRegistry; import io.flutter.plugin.common.PluginRegistry;
import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback; import io.flutter.plugin.common.PluginRegistry.PluginRegistrantCallback;
import io.flutter.plugins.GeneratedPluginRegistrant; import io.flutter.plugins.GeneratedPluginRegistrant;
import io.flutter.plugins.androidalarmmanager.AlarmService;
public class Application extends FlutterApplication implements PluginRegistrantCallback { public class Application extends FlutterApplication implements PluginRegistrantCallback {
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
AlarmService.setPluginRegistrant(this);
} }
@Override @Override

View File

@ -96,4 +96,28 @@ class CardType {
static const conditional = "conditional"; static const conditional = "conditional";
static const alarmPanel = "alarm-panel"; static const alarmPanel = "alarm-panel";
static const markdown = "markdown"; static const markdown = "markdown";
}
class UserError {
final int code;
final String message;
UserError({@required this.code, this.message: ""});
}
class ErrorCode {
static const UNKNOWN = 0;
static const NOT_CONFIGURED = 1;
static const AUTH_INVALID = 2;
static const NO_MOBILE_APP_COMPONENT = 3;
static const ERROR_GETTING_CONFIG = 4;
static const ERROR_GETTING_STATES = 5;
static const ERROR_GETTING_LOVELACE_CONFIG = 6;
static const ERROR_GETTING_PANELS = 7;
static const CONNECTION_TIMEOUT = 8;
static const DISCONNECTED = 9;
static const UNABLE_TO_CONNECT = 10;
static const GENERAL_AUTH_ERROR = 11;
static const AUTH_ERROR = 12;
static const NOT_LOGGED_IN = 13;
} }

View File

@ -68,7 +68,7 @@ class HomeAssistant {
_fetchCompleter.complete(); _fetchCompleter.complete();
MobileAppIntegrationManager.checkAppRegistration(); MobileAppIntegrationManager.checkAppRegistration();
} else { } else {
_fetchCompleter.completeError(HAError("Mobile app component not found", actions: [HAErrorAction.tryAgain(), HAErrorAction(type: HAErrorActionType.URL ,title: "Help",url: "http://ha-client.homemade.systems/docs#mobile-app")])); _fetchCompleter.completeError(UserError(code: ErrorCode.NO_MOBILE_APP_COMPONENT));
} }
}).catchError((e) { }).catchError((e) {
_fetchCompleter.completeError(e); _fetchCompleter.completeError(e);
@ -89,7 +89,7 @@ class HomeAssistant {
await ConnectionManager().sendSocketMessage(type: "get_config").then((data) { await ConnectionManager().sendSocketMessage(type: "get_config").then((data) {
_instanceConfig = Map.from(data); _instanceConfig = Map.from(data);
}).catchError((e) { }).catchError((e) {
throw HAError("Error getting config: ${e}"); throw UserError(code: ErrorCode.ERROR_GETTING_CONFIG, message: "$e");
}); });
} }
@ -97,26 +97,26 @@ class HomeAssistant {
await ConnectionManager().sendSocketMessage(type: "get_states").then( await ConnectionManager().sendSocketMessage(type: "get_states").then(
(data) => entities.parse(data) (data) => entities.parse(data)
).catchError((e) { ).catchError((e) {
throw HAError("Error getting states: $e"); throw UserError(code: ErrorCode.ERROR_GETTING_STATES, message: "$e");
}); });
} }
Future _getLovelace() async { Future _getLovelace() async {
await ConnectionManager().sendSocketMessage(type: "lovelace/config").then((data) => _rawLovelaceData = data).catchError((e) { await ConnectionManager().sendSocketMessage(type: "lovelace/config").then((data) => _rawLovelaceData = data).catchError((e) {
throw HAError("Error getting lovelace config: $e"); throw UserError(code: ErrorCode.ERROR_GETTING_LOVELACE_CONFIG, message: "$e");
}); });
} }
Future _getUserInfo() async { Future _getUserInfo() async {
_userName = null; _userName = null;
await ConnectionManager().sendSocketMessage(type: "auth/current_user").then((data) => _userName = data["name"]).catchError((e) { await ConnectionManager().sendSocketMessage(type: "auth/current_user").then((data) => _userName = data["name"]).catchError((e) {
Logger.w("Can't get user info: ${e}"); Logger.w("Can't get user info: $e");
}); });
} }
Future _getServices() async { Future _getServices() async {
await ConnectionManager().sendSocketMessage(type: "get_services").then((data) => Logger.d("Services received")).catchError((e) { await ConnectionManager().sendSocketMessage(type: "get_services").then((data) => Logger.d("Services received")).catchError((e) {
Logger.w("Can't get services: ${e}"); Logger.w("Can't get services: $e");
}); });
} }
@ -136,7 +136,7 @@ class HomeAssistant {
); );
}); });
}).catchError((e) { }).catchError((e) {
throw HAError("Error getting panels list: $e"); throw UserError(code: ErrorCode.ERROR_GETTING_PANELS, message: "$e");
}); });
} }

View File

@ -114,6 +114,7 @@ part 'ui_widgets/card_widget.dart';
part 'ui_widgets/card_header_widget.dart'; part 'ui_widgets/card_header_widget.dart';
part 'panels/config_panel_widget.dart'; part 'panels/config_panel_widget.dart';
part 'panels/widgets/link_to_web_config.dart'; part 'panels/widgets/link_to_web_config.dart';
part 'user_error_screen.widget.dart';
EventBus eventBus = new EventBus(); EventBus eventBus = new EventBus();
@ -217,8 +218,9 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
StreamSubscription _reloadUISubscription; StreamSubscription _reloadUISubscription;
StreamSubscription _showPageSubscription; StreamSubscription _showPageSubscription;
int _previousViewCount; int _previousViewCount;
bool _showLoginButton = false; //bool _showLoginButton = false;
bool _preventAppRefresh = false; bool _preventAppRefresh = false;
UserError _userError;
@override @override
void initState() { void initState() {
@ -292,25 +294,29 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
} }
void _fullLoad() async { void _fullLoad() async {
setState(() {
_userError = null;
});
_showInfoBottomBar(progress: true,); _showInfoBottomBar(progress: true,);
_subscribe().then((_) { _subscribe().then((_) {
ConnectionManager().init(loadSettings: true, forceReconnect: true).then((__){ ConnectionManager().init(loadSettings: true, forceReconnect: true).then((__){
_fetchData(); _fetchData();
StartupUserMessagesManager().checkMessagesToShow(); }, onError: (code) {
}, onError: (e) { _setErrorState(code);
_setErrorState(e);
}); });
}); });
} }
void _quickLoad() { void _quickLoad() {
setState(() {
_userError = null;
});
_hideBottomBar(); _hideBottomBar();
_showInfoBottomBar(progress: true,); _showInfoBottomBar(progress: true,);
ConnectionManager().init(loadSettings: false, forceReconnect: false).then((_){ ConnectionManager().init(loadSettings: false, forceReconnect: false).then((_){
_fetchData(); _fetchData();
StartupUserMessagesManager().checkMessagesToShow(); }, onError: (code) {
}, onError: (e) { _setErrorState(code);
_setErrorState(e);
}); });
} }
@ -323,12 +329,8 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
_viewsTabController = TabController(vsync: this, length: currentViewCount); _viewsTabController = TabController(vsync: this, length: currentViewCount);
_previousViewCount = currentViewCount; _previousViewCount = currentViewCount;
} }
}).catchError((e) { }).catchError((code) {
if (e is HAError) { _setErrorState(code);
_setErrorState(e);
} else {
_setErrorState(HAError(e.toString()));
}
}); });
eventBus.fire(RefreshDataFinishedEvent()); eventBus.fire(RefreshDataFinishedEvent());
} }
@ -371,7 +373,10 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
} }
if (_reloadUISubscription == null) { if (_reloadUISubscription == null) {
_reloadUISubscription = eventBus.on<ReloadUIEvent>().listen((event){ _reloadUISubscription = eventBus.on<ReloadUIEvent>().listen((event){
_quickLoad(); if (event.full)
_fullLoad();
else
_quickLoad();
}); });
} }
if (_showPopupDialogSubscription == null) { if (_showPopupDialogSubscription == null) {
@ -421,20 +426,20 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
if (_showErrorSubscription == null) { if (_showErrorSubscription == null) {
_showErrorSubscription = eventBus.on<ShowErrorEvent>().listen((event){ _showErrorSubscription = eventBus.on<ShowErrorEvent>().listen((event){
_showErrorBottomBar(event.error); _setErrorState(event.error);
}); });
} }
if (_startAuthSubscription == null) { if (_startAuthSubscription == null) {
_startAuthSubscription = eventBus.on<StartAuthEvent>().listen((event){ _startAuthSubscription = eventBus.on<StartAuthEvent>().listen((event){
setState(() { if (event.starting) {
_showLoginButton = event.showButton;
});
if (event.showButton) {
_showOAuth(); _showOAuth();
} else { } else {
_preventAppRefresh = false; _preventAppRefresh = false;
Navigator.of(context).pop(); Navigator.of(context).pop();
setState(() {
_userError = null;
});
} }
}); });
} }
@ -448,17 +453,27 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
void _showOAuth() { void _showOAuth() {
_preventAppRefresh = true; _preventAppRefresh = true;
_setErrorState(UserError(code: ErrorCode.NOT_LOGGED_IN));
Navigator.of(context).pushNamed('/login'); Navigator.of(context).pushNamed('/login');
} }
_setErrorState(HAError e) { _setErrorState(error) {
if (e == null) { if (error is UserError) {
setState(() {
_userError = error;
});
} else {
setState(() {
_userError = UserError(code: ErrorCode.UNKNOWN);
});
}
/*if (e == null) {
_showErrorBottomBar( _showErrorBottomBar(
HAError("Unknown error") HAError("Unknown error")
); );
} else { } else {
_showErrorBottomBar(e); _showErrorBottomBar(e);
} }*/
} }
void _showPopupDialog({String title, String body, var onPositive, var onNegative, String positiveText, String negativeText}) { void _showPopupDialog({String title, String body, var onPositive, var onNegative, String positiveText, String negativeText}) {
@ -739,6 +754,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
} }
} }
/*
void _showErrorBottomBar(HAError error) { void _showErrorBottomBar(HAError error) {
TextStyle textStyle = TextStyle( TextStyle textStyle = TextStyle(
color: Colors.blue, color: Colors.blue,
@ -803,7 +819,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
_bottomBarText = "${error.message}"; _bottomBarText = "${error.message}";
_showBottomBar = true; _showBottomBar = true;
}); });
} }*/
final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>(); final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
@ -814,18 +830,33 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
child: new Text("Reload"), child: new Text("Reload"),
value: "reload", value: "reload",
)); ));
List<Widget> emptyBody = [ /*List<Widget> emptyBody = [
Text("."), Text("."),
]; ];*/
if (ConnectionManager().isAuthenticated) { if (ConnectionManager().isAuthenticated) {
_showLoginButton = false; //_showLoginButton = false;
popupMenuItems.add( popupMenuItems.add(
PopupMenuItem<String>( PopupMenuItem<String>(
child: new Text("Logout"), child: new Text("Logout"),
value: "logout", value: "logout",
)); ));
} }
if (_showLoginButton) { Widget bodyWidget;
if (_userError != null) {
bodyWidget = UserErrorScreen(error: _userError);
} else if (empty) {
bodyWidget = Row(
mainAxisSize: MainAxisSize.max,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator()
],
);
} else {
bodyWidget = HomeAssistant().buildViews(context, _viewsTabController);
}
/*if (_showLoginButton) {
emptyBody = [ emptyBody = [
FlatButton( FlatButton(
child: Text("Login with Home Assistant", style: TextStyle(fontSize: 16.0, color: Colors.white)), child: Text("Login with Home Assistant", style: TextStyle(fontSize: 16.0, color: Colors.white)),
@ -833,7 +864,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
onPressed: () => _fullLoad(), onPressed: () => _fullLoad(),
) )
]; ];
} }*/
return NestedScrollView( return NestedScrollView(
headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) { headerSliverBuilder: (BuildContext context, bool innerBoxIsScrolled) {
return <Widget>[ return <Widget>[
@ -869,7 +900,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
_scaffoldKey.currentState.openDrawer(); _scaffoldKey.currentState.openDrawer();
}, },
), ),
bottom: empty ? null : TabBar( bottom: (empty || _userError != null) ? null : TabBar(
controller: _viewsTabController, controller: _viewsTabController,
tabs: buildUIViewTabs(), tabs: buildUIViewTabs(),
isScrollable: true, isScrollable: true,
@ -878,15 +909,7 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
]; ];
}, },
body: empty ? body: bodyWidget,
Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: emptyBody
),
)
:
HomeAssistant().buildViews(context, _viewsTabController),
); );
} }

View File

@ -33,7 +33,7 @@ class AuthManager {
//flutterWebviewPlugin.close(); //flutterWebviewPlugin.close();
Logger.e("Error getting temp token: ${e.toString()}"); Logger.e("Error getting temp token: ${e.toString()}");
eventBus.fire(StartAuthEvent(oauthUrl, false)); eventBus.fire(StartAuthEvent(oauthUrl, false));
completer.completeError(HAError("Error getting temp token")); completer.completeError(UserError(code: ErrorCode.AUTH_ERROR));
}); });
} }
}); });

View File

@ -40,6 +40,7 @@ class ConnectionManager {
if (loadSettings) { if (loadSettings) {
Logger.e("Loading settings..."); Logger.e("Loading settings...");
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
await prefs.reload();
useLovelace = prefs.getBool('use-lovelace') ?? true; useLovelace = prefs.getBool('use-lovelace') ?? true;
_domain = prefs.getString('hassio-domain'); _domain = prefs.getString('hassio-domain');
_port = prefs.getString('hassio-port'); _port = prefs.getString('hassio-port');
@ -51,14 +52,12 @@ class ConnectionManager {
"${prefs.getString('hassio-res-protocol')}://$_domain:$_port"; "${prefs.getString('hassio-res-protocol')}://$_domain:$_port";
if ((_domain == null) || (_port == null) || if ((_domain == null) || (_port == null) ||
(_domain.isEmpty) || (_port.isEmpty)) { (_domain.isEmpty) || (_port.isEmpty)) {
completer.completeError(HAError.checkConnectionSettings()); completer.completeError(UserError(code: ErrorCode.NOT_CONFIGURED));
stopInit = true; stopInit = true;
} else { } else {
//_token = prefs.getString('hassio-token');
final storage = new FlutterSecureStorage(); final storage = new FlutterSecureStorage();
try { try {
_token = await storage.read(key: "hacl_llt"); _token = await storage.read(key: "hacl_llt");
Logger.e("Long-lived token read successful");
} catch (e) { } catch (e) {
Logger.e("Cannt read secure storage. Need to relogin."); Logger.e("Cannt read secure storage. Need to relogin.");
_token = null; _token = null;
@ -73,7 +72,7 @@ class ConnectionManager {
} else { } else {
if ((_domain == null) || (_port == null) || if ((_domain == null) || (_port == null) ||
(_domain.isEmpty) || (_port.isEmpty)) { (_domain.isEmpty) || (_port.isEmpty)) {
completer.completeError(HAError.checkConnectionSettings()); completer.completeError(UserError(code: ErrorCode.NOT_CONFIGURED));
stopInit = true; stopInit = true;
} }
} }
@ -101,7 +100,7 @@ class ConnectionManager {
if (forceReconnect || !isConnected) { if (forceReconnect || !isConnected) {
_connect().timeout(connectTimeout, onTimeout: () { _connect().timeout(connectTimeout, onTimeout: () {
_disconnect().then((_) { _disconnect().then((_) {
completer?.completeError(HAError("Connection timeout")); completer?.completeError(UserError(code: ErrorCode.CONNECTION_TIMEOUT));
}); });
}).then((_) { }).then((_) {
completer?.complete(); completer?.complete();
@ -146,10 +145,11 @@ class ConnectionManager {
} }
} 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(HAError("${data["message"]}", actions: [HAErrorAction.loginAgain()])); _messageResolver["auth"]?.completeError(UserError(code: ErrorCode.AUTH_INVALID, message: "${data["message"]}"));
_messageResolver.remove("auth"); _messageResolver.remove("auth");
//TODO dont logout, show variants to User
logout().then((_) { logout().then((_) {
if (!connecting.isCompleted) connecting.completeError(HAError("${data["message"]}", actions: [HAErrorAction.loginAgain()])); if (!connecting.isCompleted) connecting.completeError(UserError(code: ErrorCode.AUTH_INVALID, message: "${data["message"]}"));
}); });
} else { } else {
_handleMessage(data); _handleMessage(data);
@ -214,14 +214,14 @@ class ConnectionManager {
Logger.d("Socket disconnected."); Logger.d("Socket disconnected.");
if (!connectionCompleter.isCompleted) { if (!connectionCompleter.isCompleted) {
isConnected = false; isConnected = false;
connectionCompleter.completeError(HAError("Disconnected", actions: [HAErrorAction.reconnect()])); connectionCompleter.completeError(UserError(code: ErrorCode.DISCONNECTED));
} else { } else {
_disconnect().then((_) { _disconnect().then((_) {
Timer(Duration(seconds: 5), () { Timer(Duration(seconds: 5), () {
Logger.d("Trying to reconnect..."); Logger.d("Trying to reconnect...");
_connect().catchError((e) { _connect().catchError((e) {
isConnected = false; isConnected = false;
eventBus.fire(ShowErrorEvent(HAError("Unable to connect to Home Assistant"))); eventBus.fire(UserError(code: ErrorCode.UNABLE_TO_CONNECT));
}); });
}); });
}); });
@ -232,14 +232,14 @@ class ConnectionManager {
Logger.e("Socket stream Error: $e"); Logger.e("Socket stream Error: $e");
if (!connectionCompleter.isCompleted) { if (!connectionCompleter.isCompleted) {
isConnected = false; isConnected = false;
connectionCompleter.completeError(HAError("Unable to connect to Home Assistant")); connectionCompleter.completeError(UserError(code: ErrorCode.UNABLE_TO_CONNECT));
} else { } else {
_disconnect().then((_) { _disconnect().then((_) {
Timer(Duration(seconds: 5), () { Timer(Duration(seconds: 5), () {
Logger.d("Trying to reconnect..."); Logger.d("Trying to reconnect...");
_connect().catchError((e) { _connect().catchError((e) {
isConnected = false; isConnected = false;
eventBus.fire(ShowErrorEvent(HAError("Unable to connect to Home Assistant"))); eventBus.fire(ShowErrorEvent(UserError(code: ErrorCode.UNABLE_TO_CONNECT)));
}); });
}); });
}); });
@ -275,7 +275,7 @@ class ConnectionManager {
}); });
}).catchError((e) => completer.completeError(e)); }).catchError((e) => completer.completeError(e));
} else { } else {
completer.completeError(HAError("General login error")); completer.completeError(UserError(code: ErrorCode.GENERAL_AUTH_ERROR));
} }
return completer.future; return completer.future;
} }
@ -309,8 +309,9 @@ class ConnectionManager {
throw e; throw e;
}); });
}).catchError((e) { }).catchError((e) {
//TODO dont logout, show variants
logout(); logout();
completer.completeError(HAError("Authentication error: $e", actions: [HAErrorAction.loginAgain()])); completer.completeError(UserError(code: ErrorCode.AUTH_ERROR, message: "$e"));
}); });
return completer.future; return completer.future;
} }
@ -333,7 +334,7 @@ class ConnectionManager {
String rawMessage = json.encode(dataObject); String rawMessage = json.encode(dataObject);
if (!isConnected) { if (!isConnected) {
_connect().timeout(connectTimeout, onTimeout: (){ _connect().timeout(connectTimeout, onTimeout: (){
_completer.completeError(HAError("No connection to Home Assistant", actions: [HAErrorAction.reconnect()])); _completer.completeError(UserError(code: ErrorCode.UNABLE_TO_CONNECT));
}).then((_) { }).then((_) {
Logger.d("[Sending] ==> ${auth ? "type="+dataObject['type'] : rawMessage}"); Logger.d("[Sending] ==> ${auth ? "type="+dataObject['type'] : rawMessage}");
_socket.sink.add(rawMessage); _socket.sink.add(rawMessage);

View File

@ -0,0 +1,214 @@
part of 'main.dart';
class UserErrorScreen extends StatelessWidget {
final UserError error;
const UserErrorScreen({Key key, this.error}) : super(key: key);
void _goToAppSettings(BuildContext context) {
Navigator.pushNamed(context, '/connection-settings');
}
void _reload() {
eventBus.fire(ReloadUIEvent(true));
}
void _disableLovelace() {
SharedPreferences.getInstance().then((prefs){
prefs.setBool("use-lovelace", false);
eventBus.fire(ReloadUIEvent(true));
});
}
void _reLogin() {
ConnectionManager().logout().then((_) => eventBus.fire(ReloadUIEvent(true)));
}
@override
Widget build(BuildContext context) {
String errorText;
List<Widget> buttons = [];
switch (this.error.code) {
case ErrorCode.AUTH_ERROR: {
errorText = "There was an error logging in to Home Assistant";
buttons.add(RaisedButton(
onPressed: () => _reload(),
child: Text("Retry"),
));
buttons.add(RaisedButton(
onPressed: () => _reLogin(),
child: Text("Login again"),
));
break;
}
case ErrorCode.UNABLE_TO_CONNECT: {
errorText = "Unable to connect to Home Assistant";
buttons.addAll(<Widget>[
RaisedButton(
onPressed: () => _reload(),
child: Text("Retry")
),
Container(width: 15.0,),
RaisedButton(
onPressed: () => _goToAppSettings(context),
child: Text("Check application settings"),
)
]
);
break;
}
case ErrorCode.AUTH_INVALID: {
errorText = "${error.message ?? "Can't login to Home Assistant"}";
buttons.addAll(<Widget>[
RaisedButton(
onPressed: () => _reload(),
child: Text("Retry")
),
Container(width: 15.0,),
RaisedButton(
onPressed: () => _reLogin(),
child: Text("Login again"),
)
]
);
break;
}
case ErrorCode.GENERAL_AUTH_ERROR: {
buttons.addAll(<Widget>[
RaisedButton(
onPressed: () => _reload(),
child: Text("Retry")
),
Container(width: 15.0,),
RaisedButton(
onPressed: () => _reLogin(),
child: Text("Login again"),
)
]
);
break;
}
case ErrorCode.DISCONNECTED: {
errorText = "Disconnected";
buttons.addAll(<Widget>[
RaisedButton(
onPressed: () => _reload(),
child: Text("Reconnect")
),
Container(width: 15.0,),
RaisedButton(
onPressed: () => _goToAppSettings(context),
child: Text("Check application settings"),
)
]
);
break;
}
case ErrorCode.CONNECTION_TIMEOUT: {
errorText = "Connection timeout";
buttons.addAll(<Widget>[
RaisedButton(
onPressed: () => _reload(),
child: Text("Reconnect")
),
Container(width: 15.0,),
RaisedButton(
onPressed: () => _goToAppSettings(context),
child: Text("Check application settings"),
)
]
);
break;
}
case ErrorCode.NOT_CONFIGURED: {
errorText = "Looks like HA Client is not configured yet.";
buttons.add(RaisedButton(
onPressed: () => _goToAppSettings(context),
child: Text("Open application settings"),
));
break;
}
case ErrorCode.ERROR_GETTING_PANELS:
case ErrorCode.ERROR_GETTING_CONFIG:
case ErrorCode.ERROR_GETTING_STATES: {
errorText = "Couldn't get data from Home Assistant. ${error.message ?? ""}";
buttons.add(RaisedButton(
onPressed: () => _reload(),
child: Text("Try again"),
));
break;
}
case ErrorCode.ERROR_GETTING_LOVELACE_CONFIG: {
errorText = "Couldn't get Lovelace UI config. You can try to disable it and use group-based UI istead.";
buttons.addAll(<Widget>[
RaisedButton(
onPressed: () => _reload(),
child: Text("Retry"),
),
Container(width: 15.0,),
RaisedButton(
onPressed: () => _disableLovelace(),
child: Text("Disable Lovelace UI"),
)
]);
break;
}
case ErrorCode.NOT_LOGGED_IN: {
errorText = "You are not logged in yet. Please login.";
buttons.add(RaisedButton(
onPressed: () => _reload(),
child: Text("Login"),
));
break;
}
default: {
errorText = "???";
buttons.add(RaisedButton(
onPressed: () => _reload(),
child: Text("Reload"),
));
}
}
return Padding(
padding: EdgeInsets.only(left: Sizes.leftWidgetPadding, right: Sizes.rightWidgetPadding),
child: Row(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Flexible(
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: EdgeInsets.only(top: 100.0, bottom: 20.0),
child: Icon(
Icons.error,
color: Colors.redAccent,
size: 48.0
)
),
Text(
errorText,
textAlign: TextAlign.center,
style: TextStyle(color: Colors.black45, fontSize: Sizes.largeFontSize),
softWrap: true,
maxLines: 5,
),
Container(height: Sizes.rowPadding,),
Row(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center,
children: buttons.isNotEmpty ? buttons : Container(height: 0.0, width: 0.0,),
)
],
),
)
],
),
);
}
}

View File

@ -45,7 +45,7 @@ class Logger {
} }
class HAError { /*class HAError {
String message; String message;
final List<HAErrorAction> actions; final List<HAErrorAction> actions;
@ -87,7 +87,7 @@ class HAErrorActionType {
static const LOGOUT = 2; static const LOGOUT = 2;
static const URL = 3; static const URL = 3;
static const OPEN_CONNECTION_SETTINGS = 4; static const OPEN_CONNECTION_SETTINGS = 4;
} }*/
class StateChangedEvent { class StateChangedEvent {
String entityId; String entityId;
@ -112,14 +112,16 @@ class RefreshDataFinishedEvent {
} }
class ReloadUIEvent { class ReloadUIEvent {
ReloadUIEvent(); final bool full;
ReloadUIEvent(this.full);
} }
class StartAuthEvent { class StartAuthEvent {
String oauthUrl; String oauthUrl;
bool showButton; bool starting;
StartAuthEvent(this.oauthUrl, this.showButton); StartAuthEvent(this.oauthUrl, this.starting);
} }
class ServiceCallEvent { class ServiceCallEvent {
@ -165,7 +167,7 @@ class ShowPageEvent {
} }
class ShowErrorEvent { class ShowErrorEvent {
final HAError error; final UserError error;
ShowErrorEvent(this.error); ShowErrorEvent(this.error);
} }