diff --git a/lib/home_assistant.class.dart b/lib/home_assistant.class.dart index 3b6945b..33b6dfd 100644 --- a/lib/home_assistant.class.dart +++ b/lib/home_assistant.class.dart @@ -2,6 +2,8 @@ part of 'main.dart'; class HomeAssistant { + static const DEFAULT_DASHBOARD = 'lovelace'; + static final HomeAssistant _instance = HomeAssistant._internal(); factory HomeAssistant() { @@ -12,6 +14,7 @@ class HomeAssistant { HomeAssistantUI ui; Map _instanceConfig = {}; String _userName; + String _lovelaceDashbordUrl; HSVColor savedColor; int savedPlayerPosition; String sendToPlayerId; @@ -25,6 +28,8 @@ class HomeAssistant { var _rawUserInfo; var _rawPanels; + set lovelaceDashboardUrl(String val) => _lovelaceDashbordUrl = val; + List panels = []; Duration fetchTimeout = Duration(seconds: 30); @@ -182,7 +187,12 @@ class HomeAssistant { return Future.value(); } else { Completer completer = Completer(); - ConnectionManager().sendSocketMessage(type: "lovelace/config").then((data) { + ConnectionManager().sendSocketMessage( + type: 'lovelace/config', + additionalData: { + 'url_path': _lovelaceDashbordUrl == HomeAssistant.DEFAULT_DASHBOARD ? null : _lovelaceDashbordUrl + } + ).then((data) { _rawLovelaceData = data; completer.complete(); }).catchError((e) { @@ -228,7 +238,6 @@ class HomeAssistant { } Future _getPanels(SharedPreferences sharedPrefs) async { - panels.clear(); if (sharedPrefs != null) { try { var data = json.decode(sharedPrefs.getString('cached_panels')); @@ -245,18 +254,35 @@ class HomeAssistant { void _parsePanels(data) { _rawPanels = data; + panels.clear(); + List dashboards = []; data.forEach((k,v) { String title = v['title'] == null ? "${k[0].toUpperCase()}${k.substring(1)}" : "${v['title'][0].toUpperCase()}${v['title'].substring(1)}"; - panels.add(Panel( - id: k, - type: v["component_name"], - title: title, - urlPath: v["url_path"], - config: v["config"], - icon: v["icon"] - ) - ); - }); + if (v['component_name'] != null && v['component_name'] == 'lovelace') { + dashboards.add( + Panel( + id: k, + componentName: v["component_name"], + title: title, + urlPath: v["url_path"], + config: v["config"], + icon: v["icon"] ?? 'mdi:view-dashboard' + ) + ); + } else { + panels.add( + Panel( + id: k, + componentName: v["component_name"], + title: title, + urlPath: v["url_path"], + config: v["config"], + icon: v["icon"] + ) + ); + } + }); + panels.insertAll(0, dashboards); } Future getCameraStream(String entityId) { diff --git a/lib/pages/main/main.page.dart b/lib/pages/main/main.page.dart index 8df7486..2b670b7 100644 --- a/lib/pages/main/main.page.dart +++ b/lib/pages/main/main.page.dart @@ -90,13 +90,16 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker ); } - void _fullLoad() async { + void _fullLoad() { _showInfoBottomBar(progress: true,); _subscribe().then((_) { ConnectionManager().init(loadSettings: true, forceReconnect: true).then((__){ - _fetchData(true); - LocationManager(); - StartupUserMessagesManager().checkMessagesToShow(); + SharedPreferences.getInstance().then((prefs) { + HomeAssistant().lovelaceDashboardUrl = prefs.getString('lovelace_dashboard_url') ?? HomeAssistant.DEFAULT_DASHBOARD; + _fetchData(useCache: true); + LocationManager(); + StartupUserMessagesManager().checkMessagesToShow(); + }); }, onError: (e) { _setErrorState(e); }); @@ -107,13 +110,13 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker _hideBottomBar(); _showInfoBottomBar(progress: true,); ConnectionManager().init(loadSettings: false, forceReconnect: false).then((_){ - _fetchData(false); + _fetchData(useCache: false); }, onError: (e) { _setErrorState(e); }); } - _fetchData(bool useCache) async { + _fetchData({useCache: false}) async { if (useCache) { HomeAssistant().fetchDataFromCache().then((_) { setState((){}); @@ -758,7 +761,9 @@ class _MainPageState extends State with WidgetsBindingObserver, Ticker context: context, items: serviceMenuItems ).then((String val) { + HomeAssistant().lovelaceDashboardUrl = HomeAssistant.DEFAULT_DASHBOARD; if (val == "reload") { + _quickLoad(); } else if (val == "logout") { HomeAssistant().logout().then((_) { diff --git a/lib/panels/panel_class.dart b/lib/panels/panel_class.dart index 2be9775..fb8017e 100644 --- a/lib/panels/panel_class.dart +++ b/lib/panels/panel_class.dart @@ -11,7 +11,7 @@ class Panel { }; final String id; - final String type; + final String componentName; final String title; final String urlPath; final Map config; @@ -19,34 +19,58 @@ class Panel { bool isHidden = true; bool isWebView = false; - Panel({this.id, this.type, this.title, this.urlPath, this.icon, this.config}) { + Panel({this.id, this.componentName, this.title, this.urlPath, this.icon, this.config}) { if (icon == null || !icon.startsWith("mdi:")) { - icon = Panel.iconsByComponent[type]; + icon = Panel.iconsByComponent[componentName]; } - isHidden = (type == 'lovelace' || type == 'kiosk' || type == 'states' || type == 'profile' || type == 'developer-tools'); - isWebView = (type != 'config'); + isHidden = (componentName == 'kiosk' || componentName == 'states' || componentName == 'profile' || componentName == 'developer-tools'); + isWebView = (componentName != 'config' && componentName != 'lovelace'); } void handleOpen(BuildContext context) { - if (type == "config") { + if (componentName == "config") { Navigator.of(context).push( MaterialPageRoute( builder: (context) => PanelPage(title: "$title", panel: this), ) ); + } else if (componentName == 'lovelace') { + HomeAssistant().lovelaceDashboardUrl = this.urlPath; + SharedPreferences.getInstance().then((prefs) { + prefs.setString('lovelace_dashboard_url', this.urlPath); + eventBus.fire(ReloadUIEvent()); + }); } else { Launcher.launchAuthenticatedWebView(context: context, url: "${ConnectionManager().httpWebHost}/$urlPath", title: "${this.title}"); } } + Widget getMenuItemWidget(BuildContext context) { + return ListTile( + leading: Icon(MaterialDesignIcons.getIconDataFromIconName(this.icon)), + title: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text("${this.title}"), + Container(width: 4.0,), + isWebView ? Text("webview", style: TextStyle(fontSize: 8.0, color: Colors.black45),) : Container(width: 1.0,) + ], + ), + onTap: () { + Navigator.of(context).pop(); + this.handleOpen(context); + } + ); + } + Widget getWidget() { - switch (type) { + switch (componentName) { case "config": { return ConfigPanelWidget(); } default: { - return Text("Unsupported panel component: $type"); + return Text("Unsupported panel component: $componentName"); } } }