From e893b7cc127632225aa9429297f39dbd42ac0843 Mon Sep 17 00:00:00 2001 From: Honey Date: Mon, 18 May 2026 22:25:26 +0200 Subject: [PATCH] fix: radio mode appends songs without restarting; favorites/song row mobile fixes - fillRadioQueue: use addToQueue instead of setQueue so toggling radio mode no longer resets position to 0 on the current song - loadStarred: pass noArtistLink/noAlbumLink to prevent accidental navigation taps on mobile (matches playlist behavior) - styles.css: add pointer:coarse alongside hover:none so song-actions are visible on Android WebView which may report hover:hover - components.js: remove inline download button from song row; keep only star and 3-dots (download stays accessible via context menu) Co-Authored-By: Claude Sonnet 4.6 --- src/components.js | 6 ++---- src/player.js | 7 +++++-- src/views.js | 2 +- styles.css | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/components.js b/src/components.js index 3ffeed2..755cc94 100644 --- a/src/components.js +++ b/src/components.js @@ -2,7 +2,7 @@ import { S } from './state.js'; import { esc, formatDur } from './utils.js'; import { coverUrl } from './api.js'; // Circular imports — safe (only used inside event handlers after module init) -import { playQueue, dlSongLocal, toggleStar, playPreview } from './player.js'; +import { playQueue, toggleStar, playPreview } from './player.js'; import { showCtxMenu, openDlModal } from './ui.js'; import { navigate, quickPlayAlbum, quickPlayArtist } from './views.js'; @@ -54,14 +54,12 @@ export function makeSongItem(s, idx, list, { noArtistLink = false, noAlbumLink = ${formatDur(s.duration)}
-
`; const btns = el.querySelectorAll('.icon-btn'); btns[0].onclick = (e) => { e.stopPropagation(); toggleStar(s, btns[0]); }; - btns[1].onclick = (e) => { e.stopPropagation(); dlSongLocal(s); }; - btns[2].onclick = (e) => { e.stopPropagation(); showCtxMenu(e, s, list, idx); }; + btns[1].onclick = (e) => { e.stopPropagation(); showCtxMenu(e, s, list, idx); }; el.onclick = () => playQueue(list, idx); el.addEventListener('contextmenu', e => { e.preventDefault(); showCtxMenu(e, s, list, idx); }); return el; diff --git a/src/player.js b/src/player.js index 6274762..c208947 100644 --- a/src/player.js +++ b/src/player.js @@ -595,9 +595,12 @@ export async function fillRadioQueue() { if(!S.radioMode) return; try { const r = await api('getRandomSongs', '&size=20'); - S.queue.push(...(r.randomSongs?.song || [])); + const newSongs = r.randomSongs?.song || []; + const prevLen = S.queue.length; + S.queue.push(...newSongs); renderQueue(); - _pushQueueIfBridge(); + // Append-only: never call setQueue here (that resets position to 0). + S.queue.slice(prevLen).forEach(s => _nsBridge('addToQueue', JSON.stringify(_trackToNative(s)), -1)); } catch {} } diff --git a/src/views.js b/src/views.js index b3c58e9..4b2cae8 100644 --- a/src/views.js +++ b/src/views.js @@ -669,7 +669,7 @@ export async function loadStarred(sort = _starredSort) { else if (sort === 'plays') songs.sort((a, b) => (b.playCount||0) - (a.playCount||0)); el.innerHTML = ''; if(!songs.length) { el.innerHTML = '
⭐

Noch keine Favoriten

'; return; } - songs.forEach((s,i) => el.appendChild(makeSongItem(s, i, songs))); + songs.forEach((s,i) => el.appendChild(makeSongItem(s, i, songs, { noArtistLink: true, noAlbumLink: true }))); } catch(e) { el.innerHTML = `

${e.message}

`; } } diff --git a/styles.css b/styles.css index db3204e..7ee05e2 100644 --- a/styles.css +++ b/styles.css @@ -189,7 +189,7 @@ nav{flex:1;overflow-y:auto;padding:4px 10px} .song-dur{font-size:11px;color:var(--text3);font-family:var(--mono)} .song-actions{display:flex;gap:2px;opacity:0;transition:opacity .15s} .song-item:hover .song-actions{opacity:1} -@media (hover:none){.song-actions{opacity:1}} +@media (hover:none),(pointer:coarse){.song-actions{opacity:1}} /* ── PLAYLIST DRAG & DROP ── */ .song-list.pl-draggable .song-item{grid-template-columns:18px 32px 44px 1fr auto} .pl-drag-handle{display:flex;align-items:center;justify-content:center;color:var(--text3);opacity:0;cursor:grab;transition:opacity .15s;touch-action:none}