Skip to content

Commit c02a4bc

Browse files
committed
Prevent Sendspin toast spam
1 parent 3554e25 commit c02a4bc

2 files changed

Lines changed: 38 additions & 34 deletions

File tree

dist/homeii-music-flow.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
this._localSendspinDesired = false;
4444
this._localSendspinLifecycleListening = false;
4545
this._localSendspinSuppressClose = false;
46+
this._toastHistory = new Map();
4647
this._directMaPlayers = [];
4748
this._directMaPlayersRefreshPromise = null;
4849

@@ -2964,9 +2965,10 @@
29642965
this._localSendspinPlayerId = session.playerId || this._localSendspinPlayerId || "";
29652966
this._localSendspinState = session.state || this._localSendspinState || null;
29662967
this._localSendspinDesired = !!session.desired || this._localSendspinDesired;
2967-
if (session.desired || this._isLocalSendspinDesired()) {
2968-
this._state.awaitingThisDevicePlayer = true;
2968+
const desired = session.desired || this._isLocalSendspinDesired();
2969+
if (desired) {
29692970
this._state.localSendspinStatus = session.connected ? "connected" : (session.connecting ? "connecting" : "reconnecting");
2971+
if (session.connected) this._state.awaitingThisDevicePlayer = false;
29702972
}
29712973
return session;
29722974
}
@@ -3319,12 +3321,6 @@
33193321
if (this._state.menuOpen && typeof this._renderMobileMenu === "function") {
33203322
this._renderMobileMenu().catch(() => {});
33213323
}
3322-
if (delay === 10000 && this._state.awaitingThisDevicePlayer) {
3323-
this._toast(this._localText(
3324-
"Local player is connected; waiting for Home Assistant to publish it.",
3325-
"הנגן המקומי מחובר; ממתין ש-Home Assistant יציג אותו ברשימה."
3326-
));
3327-
}
33283324
}, delay));
33293325
}
33303326

@@ -3416,12 +3412,6 @@
34163412
? session.controller
34173413
: this;
34183414
if (desired) {
3419-
if (controller.isConnected) {
3420-
controller._toast(controller._localText(
3421-
"This device player paused in the background; reconnecting when the dashboard is active.",
3422-
"נגן המכשיר הושהה ברקע; יתחבר מחדש כשהדשבורד פעיל."
3423-
));
3424-
}
34253415
controller._scheduleLocalSendspinReconnect(event?.type || "socket_close", 1200);
34263416
}
34273417
}
@@ -7640,7 +7630,6 @@
76407630
this._state.knownBrowserPlayerIds = [];
76417631
this._state.selectedPlayer = newcomer.entity_id;
76427632
this._state.hasAutoSelectedPlayer = true;
7643-
this._toast(this._t("This device player connected"));
76447633
}
76457634
}
76467635
const selectedPlayer = this._playerByEntityId(this._state.selectedPlayer);
@@ -8643,11 +8632,24 @@
86438632
_toast(message, variant = "info") {
86448633
const wrap = this.$("toastWrap");
86458634
if (!wrap) return;
8646-
const el = document.createElement("div");
8635+
const text = String(message ?? "").trim();
8636+
if (!text) return;
86478637
const safeVariant = ["success", "error", "info"].includes(variant) ? variant : "info";
8638+
const now = Date.now();
8639+
const key = `${safeVariant}:${text}`;
8640+
const lastShown = this._toastHistory?.get(key) || 0;
8641+
if (now - lastShown < 2500) return;
8642+
if (!this._toastHistory) this._toastHistory = new Map();
8643+
this._toastHistory.set(key, now);
8644+
for (const [toastKey, at] of this._toastHistory.entries()) {
8645+
if (now - at > 12000) this._toastHistory.delete(toastKey);
8646+
}
8647+
const activeToasts = Array.from(wrap.querySelectorAll(".toast"));
8648+
while (activeToasts.length >= 3) activeToasts.shift()?.remove();
8649+
const el = document.createElement("div");
86488650
el.className = `toast ${safeVariant}`;
86498651
const icon = safeVariant === "success" ? "✓" : safeVariant === "error" ? "×" : "i";
8650-
el.innerHTML = `<span class="toast-icon">${icon}</span><span class="toast-text">${this._esc(message)}</span>`;
8652+
el.innerHTML = `<span class="toast-icon">${icon}</span><span class="toast-text">${this._esc(text)}</span>`;
86518653
wrap.appendChild(el);
86528654
setTimeout(() => el.remove(), 3300);
86538655
}

src/homeii-music-flow.js

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
this._localSendspinDesired = false;
4444
this._localSendspinLifecycleListening = false;
4545
this._localSendspinSuppressClose = false;
46+
this._toastHistory = new Map();
4647
this._directMaPlayers = [];
4748
this._directMaPlayersRefreshPromise = null;
4849

@@ -2964,9 +2965,10 @@
29642965
this._localSendspinPlayerId = session.playerId || this._localSendspinPlayerId || "";
29652966
this._localSendspinState = session.state || this._localSendspinState || null;
29662967
this._localSendspinDesired = !!session.desired || this._localSendspinDesired;
2967-
if (session.desired || this._isLocalSendspinDesired()) {
2968-
this._state.awaitingThisDevicePlayer = true;
2968+
const desired = session.desired || this._isLocalSendspinDesired();
2969+
if (desired) {
29692970
this._state.localSendspinStatus = session.connected ? "connected" : (session.connecting ? "connecting" : "reconnecting");
2971+
if (session.connected) this._state.awaitingThisDevicePlayer = false;
29702972
}
29712973
return session;
29722974
}
@@ -3319,12 +3321,6 @@
33193321
if (this._state.menuOpen && typeof this._renderMobileMenu === "function") {
33203322
this._renderMobileMenu().catch(() => {});
33213323
}
3322-
if (delay === 10000 && this._state.awaitingThisDevicePlayer) {
3323-
this._toast(this._localText(
3324-
"Local player is connected; waiting for Home Assistant to publish it.",
3325-
"הנגן המקומי מחובר; ממתין ש-Home Assistant יציג אותו ברשימה."
3326-
));
3327-
}
33283324
}, delay));
33293325
}
33303326

@@ -3416,12 +3412,6 @@
34163412
? session.controller
34173413
: this;
34183414
if (desired) {
3419-
if (controller.isConnected) {
3420-
controller._toast(controller._localText(
3421-
"This device player paused in the background; reconnecting when the dashboard is active.",
3422-
"נגן המכשיר הושהה ברקע; יתחבר מחדש כשהדשבורד פעיל."
3423-
));
3424-
}
34253415
controller._scheduleLocalSendspinReconnect(event?.type || "socket_close", 1200);
34263416
}
34273417
}
@@ -7640,7 +7630,6 @@
76407630
this._state.knownBrowserPlayerIds = [];
76417631
this._state.selectedPlayer = newcomer.entity_id;
76427632
this._state.hasAutoSelectedPlayer = true;
7643-
this._toast(this._t("This device player connected"));
76447633
}
76457634
}
76467635
const selectedPlayer = this._playerByEntityId(this._state.selectedPlayer);
@@ -8643,11 +8632,24 @@
86438632
_toast(message, variant = "info") {
86448633
const wrap = this.$("toastWrap");
86458634
if (!wrap) return;
8646-
const el = document.createElement("div");
8635+
const text = String(message ?? "").trim();
8636+
if (!text) return;
86478637
const safeVariant = ["success", "error", "info"].includes(variant) ? variant : "info";
8638+
const now = Date.now();
8639+
const key = `${safeVariant}:${text}`;
8640+
const lastShown = this._toastHistory?.get(key) || 0;
8641+
if (now - lastShown < 2500) return;
8642+
if (!this._toastHistory) this._toastHistory = new Map();
8643+
this._toastHistory.set(key, now);
8644+
for (const [toastKey, at] of this._toastHistory.entries()) {
8645+
if (now - at > 12000) this._toastHistory.delete(toastKey);
8646+
}
8647+
const activeToasts = Array.from(wrap.querySelectorAll(".toast"));
8648+
while (activeToasts.length >= 3) activeToasts.shift()?.remove();
8649+
const el = document.createElement("div");
86488650
el.className = `toast ${safeVariant}`;
86498651
const icon = safeVariant === "success" ? "✓" : safeVariant === "error" ? "×" : "i";
8650-
el.innerHTML = `<span class="toast-icon">${icon}</span><span class="toast-text">${this._esc(message)}</span>`;
8652+
el.innerHTML = `<span class="toast-icon">${icon}</span><span class="toast-text">${this._esc(text)}</span>`;
86518653
wrap.appendChild(el);
86528654
setTimeout(() => el.remove(), 3300);
86538655
}

0 commit comments

Comments
 (0)