Fix account swaping
Deploy HEOS panel / deploy (push) Successful in 26s

This commit is contained in:
2026-09-18 02:05:48 +02:00
parent 053be20b9c
commit 5ca504c680
10 changed files with 885 additions and 21 deletions
+44 -2
View File
@@ -204,8 +204,14 @@ function paintRoom(room) {
// them, because the row also holds the host toggle, which stays put and
// merely disables.
els('.spotify', room.spotify).forEach((button) => {
const holding = button.dataset.account === room.spotifyAccount;
button.hidden = !room.available || room.grouped;
button.setAttribute('aria-pressed', String(button.dataset.account === room.spotifyAccount));
button.setAttribute('aria-pressed', String(holding));
// Bordered, the button is the way back out of the room rather than into
// it, so its label has to say that and not "Resume".
button.setAttribute(
'aria-label',
`${holding ? 'Disconnect' : 'Resume'} ${button.querySelector('span').textContent}'s Spotify`);
});
room.toggle.disabled = !room.available;
@@ -592,7 +598,14 @@ function applyJoined(joined) {
receiver to resume that account, instead of always connecting to it
from the Spotify app -------------------------------------------------- */
els('.spotify').forEach((button) => {
button.addEventListener('click', () => resumeSpotify(button));
button.addEventListener('click', () => {
// The bordered button is the account already playing here, and resuming
// it again would do nothing, so that tap is the opposite request: let
// the room go, so another account can have it.
const room = rooms[button.dataset.target];
if (room && room.spotifyAccount === button.dataset.account) disconnectSpotify(button);
else resumeSpotify(button);
});
});
async function resumeSpotify(button) {
@@ -615,6 +628,35 @@ async function resumeSpotify(button) {
}
}
async function disconnectSpotify(button) {
const { target, account } = button.dataset;
const who = button.querySelector('span').textContent;
const room = rooms[target];
button.disabled = true;
try {
const data = await api('/api/spotify/disconnect', { target, account });
// The speaker not answering on the LAN is not a failure -- the room
// still stops -- but it does leave the account signed in to it, and
// that is the difference between "let go of" and "stopped".
toast(data.signed_out
? `${data.device} let go of ${who}'s Spotify`
: `Stopped ${who}'s Spotify on ${data.device} — the speaker did not answer, so it stays signed in`,
'ok');
// The room stops with it, so drop the border, the transport row and the
// song now rather than leaving a card that still claims to be playing;
// the refresh below confirms it.
room.spotifyAccount = null;
room.playState = 'stop';
room.track = null;
paintRoom(room);
setTimeout(refresh, 1500);
} catch (error) {
toast(error.message);
} finally {
button.disabled = false;
}
}
/* --- the input picker -------------------------------------------------- */
ui.inputButton.addEventListener('click', openSheet);
el('[data-role="scrim"]').addEventListener('click', closeSheet);