Begun framework for frontend settings across devices

This commit is contained in:
2022-07-20 22:45:03 +00:00
parent 77554aa86c
commit c7ce90883b
11 changed files with 593 additions and 88 deletions

View File

@@ -398,13 +398,67 @@ const ConnectionMixin = (SuperClass) => {
data: Object.assign(Object.assign({}, this.browsers[this.browserID]), newData),
});
}
get meta() {
if (!this.registered)
return null;
return this.browsers[this.browserID].meta;
get global_settings() {
var _a;
const settings = {};
const global = (_a = this._data.settings) !== null && _a !== void 0 ? _a : {};
for (const [k, v] of Object.entries(global)) {
if (v !== null)
settings[k] = v;
}
return settings;
}
set meta(value) {
this._reregister({ meta: value });
get user_settings() {
var _a;
const settings = {};
const user = (_a = this._data.user_settings[this.hass.user.id]) !== null && _a !== void 0 ? _a : {};
for (const [k, v] of Object.entries(user)) {
if (v !== null)
settings[k] = v;
}
return settings;
}
get browser_settings() {
var _a, _b;
const settings = {};
const browser = (_b = (_a = this.browsers[this.browserID]) === null || _a === void 0 ? void 0 : _a.settings) !== null && _b !== void 0 ? _b : {};
for (const [k, v] of Object.entries(browser)) {
if (v !== null)
settings[k] = v;
}
return settings;
}
get settings() {
return Object.assign(Object.assign(Object.assign({}, this.global_settings), this.user_settings), this.browser_settings);
}
set_setting(key, value, level) {
var _a;
switch (level) {
case "global": {
this.connection.sendMessage({
type: "browser_mod/settings",
key,
value,
});
break;
}
case "user": {
const user = this.hass.user.id;
this.connection.sendMessage({
type: "browser_mod/settings",
user,
key,
value,
});
break;
}
case "browser": {
const settings = (_a = this.browsers[this.browserID]) === null || _a === void 0 ? void 0 : _a.settings;
settings[key] = value;
this._reregister({ settings });
break;
}
}
}
get cameraEnabled() {
if (!this.registered)
@@ -1769,6 +1823,25 @@ __decorate([
customElements.define("popup-card", PopupCard);
})();
const AutoSettingsMixin = (SuperClass) => {
return class AutoSettingsMixinClass extends SuperClass {
constructor() {
super();
this._auto_settings_setup();
}
async _auto_settings_setup() {
await this.connectionPromise;
const settings = this.settings;
if (settings.sidebarPanelOrder) {
localStorage.setItem("sidebarPanelOrder", settings.sidebarPanelOrder);
}
if (settings.sidebarHiddenPanels) {
localStorage.setItem("sidebarHiddenPanels", settings.sidebarHiddenPanels);
}
}
};
};
/*
TODO:
- Fix nomenclature
@@ -1802,11 +1875,13 @@ __decorate([
x Redesign services to target devices
- frontend editor for popup cards
- also screensavers
- Tweaks
- Save sidebar
- Save sidebar per user
- Saved frontend settings
X Framework
x Save sidebar
- Kiosk mode
- Kiosk mode per user
- Default panel?
- Screensaver?
- Tweaks
- Favicon templates
- Title templates
- Quickbar tweaks (ctrl+enter)?
@@ -1814,7 +1889,7 @@ __decorate([
- Media_seek
- Screensavers
*/
class BrowserMod extends ServicesMixin(PopupMixin(ActivityMixin(BrowserStateMixin(CameraMixin(MediaPlayerMixin(ScreenSaverMixin(FullyMixin(RequireInteractMixin(ConnectionMixin(EventTarget)))))))))) {
class BrowserMod extends ServicesMixin(PopupMixin(ActivityMixin(BrowserStateMixin(CameraMixin(MediaPlayerMixin(ScreenSaverMixin(AutoSettingsMixin(FullyMixin(RequireInteractMixin(ConnectionMixin(EventTarget))))))))))) {
constructor() {
super();
this.connect();

File diff suppressed because one or more lines are too long

View File

@@ -1,4 +1,5 @@
import logging
from typing import Any
import voluptuous as vol
from datetime import datetime, timezone
@@ -130,8 +131,30 @@ async def async_setup_connection(hass):
dev = getBrowser(hass, browserID)
dev.update(hass, msg.get("data", {}))
@websocket_api.websocket_command(
{
vol.Required("type"): "browser_mod/settings",
vol.Required("key"): str,
vol.Optional("value"): vol.Any(int, str, bool, list, object, None),
vol.Optional("user"): str,
}
)
@websocket_api.async_response
async def handle_settings(hass, connection, msg):
store = hass.data[DOMAIN]["store"]
if "user" in msg:
# Set user setting
await store.set_user_settings(
msg["user"], **{msg["key"]: msg.get("value", None)}
)
else:
# Set global setting
await store.set_global_settings(**{msg["key"]: msg.get("value", None)})
pass
async_register_command(hass, handle_connect)
async_register_command(hass, handle_register)
async_register_command(hass, handle_unregister)
async_register_command(hass, handle_reregister)
async_register_command(hass, handle_update)
async_register_command(hass, handle_settings)

View File

@@ -10,11 +10,11 @@ _LOGGER = logging.getLogger(__name__)
@attr.s
class BrowserStoreData:
last_seen = attr.ib(type=int, default=0)
enabled = attr.ib(type=bool, default=False)
camera = attr.ib(type=bool, default=False)
meta = attr.ib(type=str, default="default")
class Settings:
kiosk = attr.ib(type=bool, default=None)
defaultPanel = attr.ib(type=str, default=None)
sidebarPanelOrder = attr.ib(type=list, default=None)
sidebarHiddenPanels = attr.ib(type=list, default=None)
@classmethod
def from_dict(cls, data):
@@ -24,21 +24,54 @@ class BrowserStoreData:
return attr.asdict(self)
@attr.s
class BrowserStoreData:
last_seen = attr.ib(type=int, default=0)
enabled = attr.ib(type=bool, default=False)
camera = attr.ib(type=bool, default=False)
settings = attr.ib(type=Settings, factory=Settings)
meta = attr.ib(type=str, default="default")
@classmethod
def from_dict(cls, data):
settings = Settings.from_dict(data.get("settings", {}))
return cls(
**(
data
| {
"settings": settings,
}
)
)
def asdict(self):
return attr.asdict(self)
@attr.s
class ConfigStoreData:
browsers = attr.ib(type=dict[str:BrowserStoreData], factory=dict)
version = attr.ib(type=str, default="2.0")
settings = attr.ib(type=Settings, factory=Settings)
user_settings = attr.ib(type=dict[str:Settings], factory=dict)
@classmethod
def from_dict(cls, data={}):
browsers = {
k: BrowserStoreData.from_dict(v) for k, v in data["browsers"].items()
k: BrowserStoreData.from_dict(v)
for k, v in data.get("browsers", {}).items()
}
user_settings = {
k: Settings.from_dict(v) for k, v in data.get("user_settings", {}).items()
}
settings = Settings.from_dict(data.get("settings", {}))
return cls(
**(
data
| {
"browsers": browsers,
"settings": settings,
"user_settings": user_settings,
}
)
)
@@ -97,3 +130,19 @@ class BrowserModStore:
async def delete_browser(self, browserID):
del self.data.browsers[browserID]
await self.updated()
def get_user_settings(self, name):
return self.data.user_settings.get(name, Settings())
async def set_user_settings(self, name, **data):
settings = self.data.user_settings.get(name, Settings())
settings.__dict__.update(data)
self.data.user_settings[name] = settings
await self.updated()
def get_global_settings(self):
return self.data.settings
async def set_global_settings(self, **data):
self.data.settings.__dict__.update(data)
await self.updated()