feat(web+android): Warteschlange bearbeiten — ziehen und entfernen
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
77a3bb33f0
commit
d5b5c8cf84
9 files changed
+330
-7
No files matched your search
+43
-2
@@ -3,8 +3,10 @@ import { esc, formatDur, toast } from '../utils.js';
|
||||
import { api, streamUrl, coverUrl, downloadUrl, dispTitle, dispArtist, dispArtistParts, dispAlbum } from '../api.js';
|
||||
// views.js/ui.js circular imports — safe (only used inside function bodies)
|
||||
import { loadRecommendations } from '../views/views.js';
|
||||
import { updateLyricsHighlight, onNpSongChange, syncNowPlaying } from './nowplaying.js';
|
||||
import { updateLyricsHighlight, onNpSongChange, syncNowPlaying, renderNpQueue } from './nowplaying.js';
|
||||
import { logPlay } from './scrobbleLog.js';
|
||||
import { macheQueueBearbeitbar, QUEUE_WERKZEUGE } from './queueEdit.js';
|
||||
import { queueNachEntfernen, queueNachVerschieben } from './queueMath.js';
|
||||
|
||||
// ─── NATIVE BRIDGE DETECTION ───────────────────────────────────────────────
|
||||
// True when running inside the NovaSonic Android wrapper (NSBridge injected before loadUrl).
|
||||
@@ -1187,14 +1189,53 @@ export function renderQueue() {
|
||||
S.queue.forEach((s, i) => {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'queue-item' + (i === S.qIdx ? ' active' : '');
|
||||
item.dataset.qidx = i;
|
||||
const cv = coverUrl(s.coverArt, 128);
|
||||
item.innerHTML = `<div class="qi-idx">${i+1}</div><div class="qi-art">${cv ? `<img src="${cv}">` : '♪'}</div><div class="qi-info"><div class="qi-title">${esc(dispTitle(s))}</div><div class="qi-artist">${esc(dispArtist(s))}</div></div>`;
|
||||
item.innerHTML = `<div class="qi-idx">${i+1}</div><div class="qi-art">${cv ? `<img src="${cv}">` : '♪'}</div><div class="qi-info"><div class="qi-title">${esc(dispTitle(s))}</div><div class="qi-artist">${esc(dispArtist(s))}</div></div>` + QUEUE_WERKZEUGE;
|
||||
item.onclick = () => { S.qIdx = i; playCurrent(); };
|
||||
el.appendChild(item);
|
||||
});
|
||||
macheQueueBearbeitbar('queue-list');
|
||||
el.querySelector('.active')?.scrollIntoView({ block: 'nearest' });
|
||||
}
|
||||
|
||||
// ─── WARTESCHLANGE BEARBEITEN ─────────────────────────────────────────────
|
||||
// S.queue ist eine einfache Liste, S.qIdx zeigt auf den laufenden Titel. Beim Aendern muss der
|
||||
// Zeiger mitwandern — sonst spielt nach dem Entfernen eines Titels weiter oben ploetzlich der
|
||||
// falsche. Gemerkt wird deshalb die ID des laufenden Titels, nicht seine Position.
|
||||
|
||||
/** Entfernt den Titel an Position i. Traf es den laufenden, laeuft der naechste an. */
|
||||
export function queueEntfernen(i) {
|
||||
if (i < 0 || i >= S.queue.length) return;
|
||||
const { qIdx, warAktuell } = queueNachEntfernen(S.queue.length, S.qIdx, i);
|
||||
S.queue.splice(i, 1);
|
||||
S.qIdx = qIdx;
|
||||
_renderedQueueKey = '';
|
||||
|
||||
if (!S.queue.length) {
|
||||
S.qIdx = -1;
|
||||
try { S._audioEls?.forEach(a => { a.pause(); }); } catch {}
|
||||
setPlayIcon(false);
|
||||
renderQueue(); renderNpQueue();
|
||||
toast('Warteschlange geleert');
|
||||
return;
|
||||
}
|
||||
if (warAktuell) playCurrent();
|
||||
renderQueue(); renderNpQueue();
|
||||
}
|
||||
|
||||
/** Verschiebt den Titel von Position `von` auf Position `nach`. */
|
||||
export function queueVerschieben(von, nach) {
|
||||
const n = S.queue.length;
|
||||
if (von === nach || von < 0 || von >= n || nach < 0 || nach >= n) return;
|
||||
const { qIdx } = queueNachVerschieben(S.queue.map(x => x.id), S.qIdx, von, nach);
|
||||
const [titel] = S.queue.splice(von, 1);
|
||||
S.queue.splice(nach, 0, titel);
|
||||
S.qIdx = qIdx;
|
||||
_renderedQueueKey = '';
|
||||
renderQueue(); renderNpQueue();
|
||||
}
|
||||
|
||||
export function toggleQueue() {
|
||||
S.queueOpen = !S.queueOpen;
|
||||
document.getElementById('queue-panel').classList.toggle('open', S.queueOpen);
|
||||
|
||||
Reference in new issue
Block a user