fix(queue): improve Up Next counter with total, remaining, and infinite modes

- Show format: (20 of 139, 135 left) for normal playback
- Show format: (20 of ∞) for infinite play or radio mode
- Remove Load More from Queue section (not needed)
- Add Load More to History section for tracks > 20
- Add isRadioMode prop to detect radio context
- Pass both queueTotalTracks and queueRemainingTracks
This commit is contained in:
vicrodh committed 2026-01-23 11:01:08 -06:00
1 parent e200dfd3eb
commit 9501a4b909
4 files changed
+23 -9

No files matched your search

+18 -8
View File
@@ -18,8 +18,10 @@
onClose: () => void;
currentTrack?: QueueTrack;
upcomingTracks: QueueTrack[];
queueTotalTracks?: number; // Real total from backend (excluding current track)
queueTotalTracks?: number; // Total tracks in the entire queue
queueRemainingTracks?: number; // Remaining tracks after current (total - played - 1)
historyTracks?: QueueTrack[];
isRadioMode?: boolean; // Is radio/similar tracks mode active
onPlayTrack?: (trackId: string) => void;
onPlayHistoryTrack?: (trackId: string) => void;
onClearQueue?: () => void;
@@ -36,7 +38,9 @@
currentTrack,
upcomingTracks,
queueTotalTracks = 0,
queueRemainingTracks = 0,
historyTracks = [],
isRadioMode = false,
onPlayTrack,
onPlayHistoryTrack,
onClearQueue,
@@ -67,6 +71,7 @@
// Display limit
const DISPLAY_LIMIT = 20;
let displayCount = $state(DISPLAY_LIMIT);
let historyDisplayCount = $state(DISPLAY_LIMIT);
// Infinite play banner dismissal
let infiniteBannerDismissed = $state(false);
@@ -97,6 +102,7 @@
searchOpen = false;
searchQuery = '';
displayCount = DISPLAY_LIMIT;
historyDisplayCount = DISPLAY_LIMIT;
}
});
@@ -280,7 +286,11 @@
{#if upcomingTracks.length > 0}
<div class="section up-next-section">
<div class="section-label">
{$t('player.upNext').toUpperCase()} ({displayedTracks} {$t('player.ofTotal')} {infinitePlayEnabled ? '∞' : queueTotalTracks})
{#if infinitePlayEnabled || isRadioMode}
{$t('player.upNext').toUpperCase()} ({displayedTracks} {$t('player.ofTotal')} ∞)
{:else}
{$t('player.upNext').toUpperCase()} ({displayedTracks} {$t('player.ofTotal')} {queueTotalTracks}, {queueRemainingTracks} {$t('player.remaining')})
{/if}
</div>
<div class="tracks-list">
{#each filteredTracks as track, index}
@@ -309,11 +319,6 @@
<span class="track-duration">{track.duration}</span>
</div>
{/each}
{#if hasMoreTracks}
<button class="load-more" onclick={loadMore}>
{$t('actions.loadMore')} ({upcomingTracks.length - displayCount} more)
</button>
{/if}
{#if searchQuery && filteredTracks.length === 0}
<div class="no-results">{$t('player.noTracksMatch', { values: { query: searchQuery } })}</div>
{/if}
@@ -333,7 +338,7 @@
<div class="section-label">{$t('player.recentlyPlayed').toUpperCase()}</div>
{#if historyTracks.length > 0}
<div class="history-list">
{#each historyTracks.slice(0, DISPLAY_LIMIT) as track}
{#each historyTracks.slice(0, historyDisplayCount) as track}
<div
class="history-track"
onclick={() => handleHistoryTrackClick(track)}
@@ -355,6 +360,11 @@
{/if}
</div>
{/each}
{#if historyTracks.length > historyDisplayCount}
<button class="load-more" onclick={() => historyDisplayCount += DISPLAY_LIMIT}>
{$t('actions.loadMore')} ({historyTracks.length - historyDisplayCount} more)
</button>
{/if}
</div>
{:else}
<div class="empty-state">
+1
View File
@@ -221,6 +221,7 @@
"queue": "Queue",
"upNext": "Up Next",
"ofTotal": "of",
"remaining": "left",
"history": "History",
"recentlyPlayed": "Recently Played",
"noHistoryYet": "No tracks played yet",
+1
View File
@@ -221,6 +221,7 @@
"queue": "Cola",
"upNext": "Siguiente",
"ofTotal": "de",
"remaining": "restantes",
"history": "Historial",
"recentlyPlayed": "Reproducido Recientemente",
"noHistoryYet": "Sin pistas reproducidas aún",
+3 -1
View File
@@ -2532,8 +2532,10 @@
onClose={closeQueue}
currentTrack={currentQueueTrack ?? undefined}
upcomingTracks={queue}
queueTotalTracks={queueRemainingTracks}
{queueTotalTracks}
{queueRemainingTracks}
{historyTracks}
isRadioMode={getCurrentContext()?.type === 'radio'}
onPlayTrack={handleQueueTrackPlay}
onPlayHistoryTrack={handlePlayHistoryTrack}
onClearQueue={handleClearQueue}