Resolves #525 Support Lovelace dashboards

This commit is contained in:
Yegor Vialov 2020-03-19 22:59:53 +00:00
parent c40fceea4f
commit a3548455eb
3 changed files with 81 additions and 26 deletions

View File

@ -2,6 +2,8 @@ part of 'main.dart';
class HomeAssistant { class HomeAssistant {
static const DEFAULT_DASHBOARD = 'lovelace';
static final HomeAssistant _instance = HomeAssistant._internal(); static final HomeAssistant _instance = HomeAssistant._internal();
factory HomeAssistant() { factory HomeAssistant() {
@ -12,6 +14,7 @@ class HomeAssistant {
HomeAssistantUI ui; HomeAssistantUI ui;
Map _instanceConfig = {}; Map _instanceConfig = {};
String _userName; String _userName;
String _lovelaceDashbordUrl;
HSVColor savedColor; HSVColor savedColor;
int savedPlayerPosition; int savedPlayerPosition;
String sendToPlayerId; String sendToPlayerId;
@ -25,6 +28,8 @@ class HomeAssistant {
var _rawUserInfo; var _rawUserInfo;
var _rawPanels; var _rawPanels;
set lovelaceDashboardUrl(String val) => _lovelaceDashbordUrl = val;
List<Panel> panels = []; List<Panel> panels = [];
Duration fetchTimeout = Duration(seconds: 30); Duration fetchTimeout = Duration(seconds: 30);
@ -182,7 +187,12 @@ class HomeAssistant {
return Future.value(); return Future.value();
} else { } else {
Completer completer = Completer(); 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; _rawLovelaceData = data;
completer.complete(); completer.complete();
}).catchError((e) { }).catchError((e) {
@ -228,7 +238,6 @@ class HomeAssistant {
} }
Future _getPanels(SharedPreferences sharedPrefs) async { Future _getPanels(SharedPreferences sharedPrefs) async {
panels.clear();
if (sharedPrefs != null) { if (sharedPrefs != null) {
try { try {
var data = json.decode(sharedPrefs.getString('cached_panels')); var data = json.decode(sharedPrefs.getString('cached_panels'));
@ -245,18 +254,35 @@ class HomeAssistant {
void _parsePanels(data) { void _parsePanels(data) {
_rawPanels = data; _rawPanels = data;
panels.clear();
List<Panel> dashboards = [];
data.forEach((k,v) { data.forEach((k,v) {
String title = v['title'] == null ? "${k[0].toUpperCase()}${k.substring(1)}" : "${v['title'][0].toUpperCase()}${v['title'].substring(1)}"; String title = v['title'] == null ? "${k[0].toUpperCase()}${k.substring(1)}" : "${v['title'][0].toUpperCase()}${v['title'].substring(1)}";
panels.add(Panel( if (v['component_name'] != null && v['component_name'] == 'lovelace') {
id: k, dashboards.add(
type: v["component_name"], Panel(
title: title, id: k,
urlPath: v["url_path"], componentName: v["component_name"],
config: v["config"], title: title,
icon: v["icon"] 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) { Future getCameraStream(String entityId) {

View File

@ -90,13 +90,16 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
); );
} }
void _fullLoad() async { void _fullLoad() {
_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(true); SharedPreferences.getInstance().then((prefs) {
LocationManager(); HomeAssistant().lovelaceDashboardUrl = prefs.getString('lovelace_dashboard_url') ?? HomeAssistant.DEFAULT_DASHBOARD;
StartupUserMessagesManager().checkMessagesToShow(); _fetchData(useCache: true);
LocationManager();
StartupUserMessagesManager().checkMessagesToShow();
});
}, onError: (e) { }, onError: (e) {
_setErrorState(e); _setErrorState(e);
}); });
@ -107,13 +110,13 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
_hideBottomBar(); _hideBottomBar();
_showInfoBottomBar(progress: true,); _showInfoBottomBar(progress: true,);
ConnectionManager().init(loadSettings: false, forceReconnect: false).then((_){ ConnectionManager().init(loadSettings: false, forceReconnect: false).then((_){
_fetchData(false); _fetchData(useCache: false);
}, onError: (e) { }, onError: (e) {
_setErrorState(e); _setErrorState(e);
}); });
} }
_fetchData(bool useCache) async { _fetchData({useCache: false}) async {
if (useCache) { if (useCache) {
HomeAssistant().fetchDataFromCache().then((_) { HomeAssistant().fetchDataFromCache().then((_) {
setState((){}); setState((){});
@ -758,7 +761,9 @@ class _MainPageState extends State<MainPage> with WidgetsBindingObserver, Ticker
context: context, context: context,
items: serviceMenuItems items: serviceMenuItems
).then((String val) { ).then((String val) {
HomeAssistant().lovelaceDashboardUrl = HomeAssistant.DEFAULT_DASHBOARD;
if (val == "reload") { if (val == "reload") {
_quickLoad(); _quickLoad();
} else if (val == "logout") { } else if (val == "logout") {
HomeAssistant().logout().then((_) { HomeAssistant().logout().then((_) {

View File

@ -11,7 +11,7 @@ class Panel {
}; };
final String id; final String id;
final String type; final String componentName;
final String title; final String title;
final String urlPath; final String urlPath;
final Map config; final Map config;
@ -19,34 +19,58 @@ class Panel {
bool isHidden = true; bool isHidden = true;
bool isWebView = false; 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:")) { 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'); isHidden = (componentName == 'kiosk' || componentName == 'states' || componentName == 'profile' || componentName == 'developer-tools');
isWebView = (type != 'config'); isWebView = (componentName != 'config' && componentName != 'lovelace');
} }
void handleOpen(BuildContext context) { void handleOpen(BuildContext context) {
if (type == "config") { if (componentName == "config") {
Navigator.of(context).push( Navigator.of(context).push(
MaterialPageRoute( MaterialPageRoute(
builder: (context) => PanelPage(title: "$title", panel: this), 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 { } else {
Launcher.launchAuthenticatedWebView(context: context, url: "${ConnectionManager().httpWebHost}/$urlPath", title: "${this.title}"); 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: <Widget>[
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() { Widget getWidget() {
switch (type) { switch (componentName) {
case "config": { case "config": {
return ConfigPanelWidget(); return ConfigPanelWidget();
} }
default: { default: {
return Text("Unsupported panel component: $type"); return Text("Unsupported panel component: $componentName");
} }
} }
} }