Datumfels Focus verbessert
This commit is contained in:
+106
-10
@@ -15,6 +15,15 @@ const DEFAULT_ENTITIES = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class SternwarteCard extends HTMLElement {
|
class SternwarteCard extends HTMLElement {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this._scheduleInputState = {
|
||||||
|
open: { draft: "", editing: false, pending: false },
|
||||||
|
close: { draft: "", editing: false, pending: false },
|
||||||
|
};
|
||||||
|
this._pendingRender = false;
|
||||||
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this._ensureClockTimer();
|
this._ensureClockTimer();
|
||||||
}
|
}
|
||||||
@@ -36,7 +45,7 @@ class SternwarteCard extends HTMLElement {
|
|||||||
set hass(hass) {
|
set hass(hass) {
|
||||||
this._hass = hass;
|
this._hass = hass;
|
||||||
this._ensureClockTimer();
|
this._ensureClockTimer();
|
||||||
this.render();
|
this._requestRender();
|
||||||
}
|
}
|
||||||
|
|
||||||
getCardSize() {
|
getCardSize() {
|
||||||
@@ -58,10 +67,73 @@ class SternwarteCard extends HTMLElement {
|
|||||||
_ensureClockTimer() {
|
_ensureClockTimer() {
|
||||||
if (this._clockTimer) return;
|
if (this._clockTimer) return;
|
||||||
this._clockTimer = window.setInterval(() => {
|
this._clockTimer = window.setInterval(() => {
|
||||||
if (this._hass) this.render();
|
if (this._hass) this._requestRender();
|
||||||
}, 30000);
|
}, 30000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_requestRender() {
|
||||||
|
if (this._isScheduleEditing()) {
|
||||||
|
this._pendingRender = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._pendingRender = false;
|
||||||
|
this.render();
|
||||||
|
}
|
||||||
|
|
||||||
|
_isScheduleEditing() {
|
||||||
|
return Object.values(this._scheduleInputState).some((field) => field.editing);
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduleFieldState(key) {
|
||||||
|
return this._scheduleInputState[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
_scheduleInputValue(key, fallbackState) {
|
||||||
|
const field = this._scheduleFieldState(key);
|
||||||
|
if (field.draft) return field.draft;
|
||||||
|
return this._isoForInput(fallbackState);
|
||||||
|
}
|
||||||
|
|
||||||
|
_resetScheduleDrafts() {
|
||||||
|
for (const field of Object.values(this._scheduleInputState)) {
|
||||||
|
field.draft = "";
|
||||||
|
field.editing = false;
|
||||||
|
field.pending = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_beginScheduleEdit(key, fallbackState) {
|
||||||
|
const field = this._scheduleFieldState(key);
|
||||||
|
field.editing = true;
|
||||||
|
field.pending = false;
|
||||||
|
if (!field.draft) {
|
||||||
|
field.draft = this._isoForInput(fallbackState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateScheduleDraft(key, value) {
|
||||||
|
const field = this._scheduleFieldState(key);
|
||||||
|
field.draft = value;
|
||||||
|
field.pending = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_endScheduleEdit(key, event) {
|
||||||
|
const field = this._scheduleFieldState(key);
|
||||||
|
field.editing = false;
|
||||||
|
if (!this._isScheduleEditing() && this._pendingRender) {
|
||||||
|
this._requestRender();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_bindScheduleInput(key, inputId, fallbackState) {
|
||||||
|
const input = this.shadowRoot.getElementById(inputId);
|
||||||
|
if (!input) return;
|
||||||
|
input.addEventListener("focus", () => this._beginScheduleEdit(key, fallbackState));
|
||||||
|
input.addEventListener("input", (event) => this._updateScheduleDraft(key, event.target.value));
|
||||||
|
input.addEventListener("change", (event) => this._updateScheduleDraft(key, event.target.value));
|
||||||
|
input.addEventListener("blur", (event) => this._endScheduleEdit(key, event));
|
||||||
|
}
|
||||||
|
|
||||||
_firstExistingEntityId(entityIds) {
|
_firstExistingEntityId(entityIds) {
|
||||||
for (const entityId of entityIds) {
|
for (const entityId of entityIds) {
|
||||||
if (entityId && this._state(entityId)) return entityId;
|
if (entityId && this._state(entityId)) return entityId;
|
||||||
@@ -128,14 +200,22 @@ class SternwarteCard extends HTMLElement {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
_setDateTime(entityId, inputId) {
|
_setDateTime(entityId, inputId, key) {
|
||||||
const input = this.shadowRoot.getElementById(inputId);
|
const input = this.shadowRoot.getElementById(inputId);
|
||||||
if (!input || !input.value) return;
|
const field = this._scheduleFieldState(key);
|
||||||
|
const value = field?.draft || input?.value || "";
|
||||||
|
if (!value) return;
|
||||||
if (!entityId) return;
|
if (!entityId) return;
|
||||||
|
field.pending = true;
|
||||||
|
field.editing = false;
|
||||||
|
field.draft = value;
|
||||||
this._hass.callService("datetime", "set_value", {
|
this._hass.callService("datetime", "set_value", {
|
||||||
entity_id: entityId,
|
entity_id: entityId,
|
||||||
datetime: input.value,
|
datetime: value,
|
||||||
});
|
});
|
||||||
|
if (this._pendingRender) {
|
||||||
|
this._requestRender();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_isoForInput(state) {
|
_isoForInput(state) {
|
||||||
@@ -527,6 +607,16 @@ class SternwarteCard extends HTMLElement {
|
|||||||
const closeScheduleEntityId = this._scheduleCloseEntityId();
|
const closeScheduleEntityId = this._scheduleCloseEntityId();
|
||||||
const openSchedule = this._state(openScheduleEntityId);
|
const openSchedule = this._state(openScheduleEntityId);
|
||||||
const closeSchedule = this._state(closeScheduleEntityId);
|
const closeSchedule = this._state(closeScheduleEntityId);
|
||||||
|
const openInputValue = this._scheduleInputValue("open", openSchedule);
|
||||||
|
const closeInputValue = this._scheduleInputValue("close", closeSchedule);
|
||||||
|
if (openInputValue === this._isoForInput(openSchedule)) {
|
||||||
|
this._scheduleFieldState("open").draft = "";
|
||||||
|
this._scheduleFieldState("open").pending = false;
|
||||||
|
}
|
||||||
|
if (closeInputValue === this._isoForInput(closeSchedule)) {
|
||||||
|
this._scheduleFieldState("close").draft = "";
|
||||||
|
this._scheduleFieldState("close").pending = false;
|
||||||
|
}
|
||||||
const roofPosition = this._roofPositionValue();
|
const roofPosition = this._roofPositionValue();
|
||||||
const windIndicator = this._windIndicatorState();
|
const windIndicator = this._windIndicatorState();
|
||||||
const rainOn = rain?.state === "on";
|
const rainOn = rain?.state === "on";
|
||||||
@@ -1040,11 +1130,11 @@ class SternwarteCard extends HTMLElement {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="schedule-grid">
|
<div class="schedule-grid">
|
||||||
<input id="open-schedule-input" type="datetime-local" value="${this._isoForInput(openSchedule)}">
|
<input id="open-schedule-input" type="datetime-local" value="${openInputValue}">
|
||||||
<button type="button" class="secondary" id="open-schedule-btn">\u00d6ffnen setzen</button>
|
<button type="button" class="secondary" id="open-schedule-btn">\u00d6ffnen setzen</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="schedule-grid">
|
<div class="schedule-grid">
|
||||||
<input id="close-schedule-input" type="datetime-local" value="${this._isoForInput(closeSchedule)}">
|
<input id="close-schedule-input" type="datetime-local" value="${closeInputValue}">
|
||||||
<button type="button" class="secondary" id="close-schedule-btn">Schlie\u00dfen setzen</button>
|
<button type="button" class="secondary" id="close-schedule-btn">Schlie\u00dfen setzen</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-actions">
|
<div class="inline-actions">
|
||||||
@@ -1062,9 +1152,15 @@ class SternwarteCard extends HTMLElement {
|
|||||||
this._bindClick("power-on-btn", () => this._callEntity("switch", "turn_on", powerEntityId));
|
this._bindClick("power-on-btn", () => this._callEntity("switch", "turn_on", powerEntityId));
|
||||||
this._bindClick("power-off-btn", () => this._callEntity("switch", "turn_off", powerEntityId));
|
this._bindClick("power-off-btn", () => this._callEntity("switch", "turn_off", powerEntityId));
|
||||||
this._bindClick("nautical-btn", () => this._call("sternwarte", "set_nautical_schedule"));
|
this._bindClick("nautical-btn", () => this._call("sternwarte", "set_nautical_schedule"));
|
||||||
this._bindClick("clear-schedule-btn", () => this._call("sternwarte", "clear_schedule"));
|
this._bindClick("clear-schedule-btn", () => {
|
||||||
this._bindClick("open-schedule-btn", () => this._setDateTime(openScheduleEntityId, "open-schedule-input"));
|
this._resetScheduleDrafts();
|
||||||
this._bindClick("close-schedule-btn", () => this._setDateTime(closeScheduleEntityId, "close-schedule-input"));
|
this._call("sternwarte", "clear_schedule");
|
||||||
|
this._requestRender();
|
||||||
|
});
|
||||||
|
this._bindClick("open-schedule-btn", () => this._setDateTime(openScheduleEntityId, "open-schedule-input", "open"));
|
||||||
|
this._bindClick("close-schedule-btn", () => this._setDateTime(closeScheduleEntityId, "close-schedule-input", "close"));
|
||||||
|
this._bindScheduleInput("open", "open-schedule-input", openSchedule);
|
||||||
|
this._bindScheduleInput("close", "close-schedule-input", closeSchedule);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user