(drag = null)} />
(ui.activeContext = "queue")} oncontextmenu={(e) => { if (e.target === e.currentTarget) { e.preventDefault(); clearSel(); showMenu(-1, e.clientX, e.clientY); } }} tabindex="0" >
{#each visibleColumns as column (column.id)}
{column.header}
{/each}
{#if ui.selectionMode} {@const hasSelection = queue.sel.length > 0} {@const selectKey = hasSelection ? "common.deselect_all" : "common.select_all"} {@const groupKey = groupPhase === "from" ? "action.group_from" : groupPhase === "to" ? "action.group_to" : "action.group"} {@const groupIcon = groupPhase === "from" ? "groupFrom" : groupPhase === "to" ? "groupTo" : "group"}
{#if hasSelection}
{/if}
{/if}
e.stopPropagation()} onkeydown={(e) => { if (e.key === "Escape") { if (hasFilter) queueFilter.text = ""; else e.currentTarget.blur(); } }} >
queue.keys[origIdx] ?? -origIdx - 1} bufferSize={600} startMargin={headerHeight} onscroll={handleScroll} onscrollend={handleScrollEnd} > {#snippet children( origIdx, virtIdx, )} {@const track = queue.tracks[origIdx]} {@const trackKey = queue.keys[origIdx] ?? -origIdx - 1} {@const radio = isRadio(track)} {@const entryIndex = pendingEntryAnimations.get(trackKey)}
attachEntry( element, entryIndex, entryGen, trackKey, finishEntryAnimation, )} data-id="queue-row-{origIdx}" data-queue-key={trackKey} class:playing={queue.pos === origIdx} class:stop-after={isStopAfter(origIdx)} class:selected={isSelected(origIdx)} class:odd={virtIdx % 2 !== 0} class:over-above={drag?.index === origIdx && !drag.isAfter} class:over-below={drag?.index === origIdx && drag.isAfter} class:unavailable={!canPlayTrack(track)} draggable={true} ondragstart={(e) => onDragStart(e, origIdx)} ondragover={(e) => onDragOver(e, origIdx)} ondrop={onDrop} onclick={(e) => { e.stopPropagation(); if (groupPhase === "from") { groupFrom = origIdx; groupPhase = "to"; } else if (groupPhase === "to") { toggleSelectionRange(groupFrom, origIdx); groupPhase = null; groupFrom = -1; } else { select( origIdx, ui.selectionMode || e.ctrlKey || e.metaKey, e.shiftKey, ); } }} ondblclick={() => { if (ui.selectionMode) return; goto(origIdx); clearSel(); }} oncontextmenu={(e) => { e.preventDefault(); showMenu(origIdx, e.clientX, e.clientY); }} > {#each visibleColumns as column (column.id)} {#if column.kind === "artwork"} {@const artId = songArtId(track)} {@const coverArtUrl = artId ? api.getCoverArt(artId, settings.artSong) : ""}
{#if coverArtUrl} fadeImage(image, track.id)} > {/if}
{:else if column.kind === "favorite"}
{#if !radio} toggleStar(track, "song"))} /> {/if}
{:else if column.kind === "rating"}
{#if !radio} { event.stopPropagation(); setRating(track, value); }} /> {/if}
{:else if column.kind === "download"}
{#if !radio} {@const isDownloaded = offlineManager.downloadedSongIds.has( track.id, )} {@const isDownloading = !isDownloaded && (offlineManager.activeDownloadIds.has(track.id) || offlineManager.queuedDownloadIds.has(track.id))} {/if}
{:else} {@const value = String(column.value?.(track, origIdx) ?? "")}
{value}
{/if} {/each}
{/snippet}
{#if menu} { menu = null; sortExpanded = false; }} items={getQueueItems(menu.index)} /> {/if}