Resolves #525 Support Lovelace dashboards
This commit is contained in:
parent
c40fceea4f
commit
a3548455eb
@ -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') {
|
||||||
|
dashboards.add(
|
||||||
|
Panel(
|
||||||
id: k,
|
id: k,
|
||||||
type: v["component_name"],
|
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,
|
title: title,
|
||||||
urlPath: v["url_path"],
|
urlPath: v["url_path"],
|
||||||
config: v["config"],
|
config: v["config"],
|
||||||
icon: v["icon"]
|
icon: v["icon"]
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
panels.insertAll(0, dashboards);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future getCameraStream(String entityId) {
|
Future getCameraStream(String entityId) {
|
||||||
|
@ -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) {
|
||||||
|
HomeAssistant().lovelaceDashboardUrl = prefs.getString('lovelace_dashboard_url') ?? HomeAssistant.DEFAULT_DASHBOARD;
|
||||||
|
_fetchData(useCache: true);
|
||||||
LocationManager();
|
LocationManager();
|
||||||
StartupUserMessagesManager().checkMessagesToShow();
|
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((_) {
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user