Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Fixed

- A media player renamed in Home Assistant (new entity id) no longer disappears
from the sidebar until the page is reloaded.

### Changed

- Now in the HACS default store: install by searching for Sidebar Mini Player in HACS, no custom repository needed. README badge and install steps updated.
Expand Down
7 changes: 4 additions & 3 deletions ha-sidebar-mini-player.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,15 +309,16 @@
/**
* Cached list of candidate media_player ids. A large install has thousands
* of entities; we only re-list hass.states' keys when the states object
* changed AND its key count changed (entity added/removed), or the config
* changed. Otherwise each tick only looks at the cached media players.
* changed AND its key count changed (entity added/removed) or a cached
* player is gone (entity renamed: one id out, one in, same count), or the
* config changed. Otherwise each tick only looks at the cached media players.
*/
const cache = { states: null, count: -1, ids: [] };
function mediaPlayerIds(states) {
if (states !== cache.states) {
cache.states = states;
const keys = Object.keys(states);
if (keys.length !== cache.count) {
if (keys.length !== cache.count || cache.ids.some((id) => !(id in states))) {
cache.count = keys.length;
cache.ids = keys.filter((id) => id.startsWith("media_player.") && allowed(id));
}
Expand Down
7 changes: 7 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,13 @@ function setup(layoutHtml, statesFile = FIXTURE, prep = null, opts = {}) {
// New Speaker is now the most recent playing -> auto focus (no click choice made in this run).
check("V3 newly added entity discovered + auto-focused (5 active)", q3(".spk").textContent === "New Speaker" && R3.querySelectorAll(".mini").length === 4,
`${q3(".spk").textContent}, minis=${R3.querySelectorAll(".mini").length}`);
// Entity renamed (one id out, one in, so the key count stays the same) -> still shown.
const stR = { ...t3.ha.hass.states };
delete stR["media_player.new_speaker"];
stR["media_player.renamed_speaker"] = { entity_id: "media_player.renamed_speaker", state: "playing", last_changed: new Date().toISOString(), attributes: { friendly_name: "Renamed Speaker", media_title: "Hello" } };
t3.ha.hass = { ...t3.hass, states: stR }; await sleep(1200);
check("V3 renamed entity (same entity count) picked up", q3(".spk").textContent === "Renamed Speaker" && R3.querySelectorAll(".mini").length === 4,
`${q3(".spk").textContent}, minis=${R3.querySelectorAll(".mini").length}`);
// Cap: add 3 more -> 8 active, 7 others -> 4 cards + "+3 more" at the top.
const st4 = { ...t3.ha.hass.states };
for (const k of ["a", "b", "c"]) st4["media_player.extra_" + k] = { entity_id: "media_player.extra_" + k, state: "paused", last_changed: new Date(Date.now() - 4 * 60000).toISOString() /* < 5 min */, attributes: { friendly_name: "Extra " + k.toUpperCase(), media_title: "T" + k } };
Expand Down
Loading