fix(widgets): replace setTimeout with transitionend in minimize

Fixes race condition where openWidget() during the 250ms timeout would
be overridden. Uses _minimizing flag to cancel in-flight transitions.
Dispatches widget:minimize and widget:open events.
This commit is contained in:
2026-04-16 20:10:30 +02:00
parent fde1fdd002
commit b92ea5a1a4
+13 -3
View File
@@ -177,10 +177,19 @@ const WidgetManager = {
const entry = this._widgets.get(id); const entry = this._widgets.get(id);
if (!entry) return; if (!entry) return;
entry.state.open = false; entry.state.open = false;
entry._minimizing = true;
entry.el.classList.add('widget-minimized'); entry.el.classList.add('widget-minimized');
setTimeout(() => {
entry.el.addEventListener('transitionend', function onEnd(e) {
if (e.target !== entry.el) return;
entry.el.removeEventListener('transitionend', onEnd);
if (entry._minimizing) {
entry.el.style.display = 'none'; entry.el.style.display = 'none';
}, 250); }
entry._minimizing = false;
});
this._emitter.dispatchEvent(new CustomEvent('widget:minimize', { detail: { id } }));
await this.save(); await this.save();
}, },
@@ -191,13 +200,14 @@ const WidgetManager = {
async openWidget(id) { async openWidget(id) {
const entry = this._widgets.get(id); const entry = this._widgets.get(id);
if (!entry) return; if (!entry) return;
entry._minimizing = false;
entry.state.open = true; entry.state.open = true;
entry.el.style.display = 'flex'; entry.el.style.display = 'flex';
// Naechster Frame fuer Animation
requestAnimationFrame(() => { requestAnimationFrame(() => {
entry.el.classList.remove('widget-minimized'); entry.el.classList.remove('widget-minimized');
}); });
this.bringToFront(id); this.bringToFront(id);
this._emitter.dispatchEvent(new CustomEvent('widget:open', { detail: { id } }));
await this.save(); await this.save();
}, },