fix: freeze equalizer animation when player is paused

Separate isActiveTrack (current track) from isPlaying (actively playing)
so the equalizer bars freeze via animation-play-state when paused instead
of always animating. Show Play icon on hover when paused, Pause when playing.
Also fix AlbumDetailView which was missing the isPlaybackActive check.
This commit is contained in:
vicrodh committed 2026-03-08 13:24:12 -06:00
1 parent 8c626c0e6a
commit a2eabf08f1
10 files changed
+33 -11

No files matched your search

+21 -8
View File
@@ -24,6 +24,7 @@
duration: string; duration: string;
quality?: string; quality?: string;
isPlaying?: boolean; isPlaying?: boolean;
isActiveTrack?: boolean;
isLocal?: boolean; // Whether this is a local library track isLocal?: boolean; // Whether this is a local library track
localSource?: 'local' | 'plex'; localSource?: 'local' | 'plex';
isUnavailable?: boolean; // Track removed from Qobuz or otherwise unavailable isUnavailable?: boolean; // Track removed from Qobuz or otherwise unavailable
@@ -80,6 +81,7 @@
duration, duration,
quality, quality,
isPlaying = false, isPlaying = false,
isActiveTrack = false,
isLocal = false, isLocal = false,
localSource = 'local', localSource = 'local',
isUnavailable = false, isUnavailable = false,
@@ -155,8 +157,8 @@
<div <div
class="track-row" class="track-row"
class:playing={isPlaying} class:playing={isActiveTrack || isPlaying}
class:hovered={isHovered && !isPlaying && !isBlacklisted} class:hovered={isHovered && !isActiveTrack && !isPlaying && !isBlacklisted}
class:compact class:compact
class:blacklisted={isBlacklisted} class:blacklisted={isBlacklisted}
class:selected class:selected
@@ -196,13 +198,19 @@
<span class="unavailable-icon" title={unavailableTooltip}> <span class="unavailable-icon" title={unavailableTooltip}>
<AlertCircle size={16} /> <AlertCircle size={16} />
</span> </span>
{:else if isPlaying} {:else if isActiveTrack || isPlaying}
{#if isHovered} {#if isHovered}
<button class="pause-btn" type="button" onclick={handlePauseClick} aria-label="Pause"> {#if isPlaying}
<Pause size={16} class="pause-icon" /> <button class="pause-btn" type="button" onclick={handlePauseClick} aria-label="Pause">
</button> <Pause size={16} class="pause-icon" />
</button>
{:else}
<button class="pause-btn" type="button" onclick={handlePauseClick} aria-label="Resume">
<Play size={16} class="play-icon" fill="white" />
</button>
{/if}
{:else} {:else}
<div class="playing-indicator"> <div class="playing-indicator" class:paused={!isPlaying}>
<div class="bar"></div> <div class="bar"></div>
<div class="bar"></div> <div class="bar"></div>
<div class="bar"></div> <div class="bar"></div>
@@ -230,7 +238,7 @@
<!-- Track Info --> <!-- Track Info -->
<div class="track-info"> <div class="track-info">
<div class="track-title-row"> <div class="track-title-row">
<span class="track-title" class:active={isPlaying}>{title}</span> <span class="track-title" class:active={isActiveTrack || isPlaying}>{title}</span>
{#if explicit} {#if explicit}
<span class="explicit-badge" title="Explicit"></span> <span class="explicit-badge" title="Explicit"></span>
{/if} {/if}
@@ -491,6 +499,11 @@
border-radius: 9999px; border-radius: 9999px;
transform-origin: bottom; transform-origin: bottom;
animation: equalize 1s ease-in-out infinite; animation: equalize 1s ease-in-out infinite;
animation-play-state: running;
}
.playing-indicator.paused .bar {
animation-play-state: paused;
} }
.playing-indicator .bar:nth-child(1) { .playing-indicator .bar:nth-child(1) {
@@ -345,6 +345,7 @@
duration={formatDuration(getTrackDuration(item.track))} duration={formatDuration(getTrackDuration(item.track))}
quality={getQualityBadge(item.track)} quality={getQualityBadge(item.track)}
isPlaying={isPlaybackActive && activeTrackId === trackId} isPlaying={isPlaybackActive && activeTrackId === trackId}
isActiveTrack={activeTrackId === trackId}
isBlacklisted={trackBlacklisted} isBlacklisted={trackBlacklisted}
selectable={selectable} selectable={selectable}
selected={selectedIds?.has(trackId) ?? false} selected={selectedIds?.has(trackId) ?? false}
@@ -643,7 +643,8 @@
duration={track.duration} duration={track.duration}
quality={track.quality} quality={track.quality}
explicit={track.parental_warning === true} explicit={track.parental_warning === true}
isPlaying={activeTrackId === track.id} isPlaying={isPlaybackActive && activeTrackId === track.id}
isActiveTrack={activeTrackId === track.id}
isBlacklisted={trackBlacklisted} isBlacklisted={trackBlacklisted}
selectable={multiSelectMode} selectable={multiSelectMode}
selected={multiSelectedIds.has(track.id)} selected={multiSelectedIds.has(track.id)}
@@ -546,6 +546,7 @@
showArtwork={true} showArtwork={true}
artworkUrl={getQobuzImage(track.album?.image)} artworkUrl={getQobuzImage(track.album?.image)}
isPlaying={isPlaybackActive && activeTrackId === track.id} isPlaying={isPlaybackActive && activeTrackId === track.id}
isActiveTrack={activeTrackId === track.id}
isBlacklisted={trackBlacklisted} isBlacklisted={trackBlacklisted}
selectable={multiSelectMode} selectable={multiSelectMode}
selected={multiSelectedIds.has(track.id)} selected={multiSelectedIds.has(track.id)}
+1
View File
@@ -498,6 +498,7 @@
showArtwork={true} showArtwork={true}
artworkUrl={getQobuzImage(track.album?.image)} artworkUrl={getQobuzImage(track.album?.image)}
isPlaying={isPlaybackActive && activeTrackId === track.id} isPlaying={isPlaybackActive && activeTrackId === track.id}
isActiveTrack={activeTrackId === track.id}
isBlacklisted={trackBlacklisted} isBlacklisted={trackBlacklisted}
selectable={multiSelectMode} selectable={multiSelectMode}
selected={multiSelectedIds.has(track.id)} selected={multiSelectedIds.has(track.id)}
+3 -2
View File
@@ -1327,7 +1327,7 @@
</div> </div>
<div class="track-list compact"> <div class="track-list compact">
{#each continueTracks as track, index (track.id)} {#each continueTracks as track, index (track.id)}
{@const isActiveTrack = isPlaybackActive && activeTrackId === track.id} {@const isThisActiveTrack = activeTrackId === track.id}
{@const cacheStatus = getTrackOfflineCacheStatus?.(track.id) ?? { status: 'none' as const, progress: 0 }} {@const cacheStatus = getTrackOfflineCacheStatus?.(track.id) ?? { status: 'none' as const, progress: 0 }}
{@const isTrackDownloaded = cacheStatus.status === 'ready'} {@const isTrackDownloaded = cacheStatus.status === 'ready'}
{@const trackBlacklisted = track.artistId ? isArtistBlacklisted(track.artistId) : false} {@const trackBlacklisted = track.artistId ? isArtistBlacklisted(track.artistId) : false}
@@ -1339,7 +1339,8 @@
album={track.album} album={track.album}
duration={track.duration} duration={track.duration}
quality={getTrackQuality(track)} quality={getTrackQuality(track)}
isPlaying={isActiveTrack} isPlaying={isPlaybackActive && isThisActiveTrack}
isActiveTrack={isThisActiveTrack}
isBlacklisted={trackBlacklisted} isBlacklisted={trackBlacklisted}
compact={true} compact={true}
hideDownload={trackBlacklisted} hideDownload={trackBlacklisted}
@@ -3256,6 +3256,7 @@
duration={formatDuration(track.duration_secs)} duration={formatDuration(track.duration_secs)}
quality={getQualityBadge(track)} quality={getQualityBadge(track)}
isPlaying={isPlaybackActive && activeTrackId === track.id} isPlaying={isPlaybackActive && activeTrackId === track.id}
isActiveTrack={activeTrackId === track.id}
isLocal={true} isLocal={true}
localSource={track.source === 'plex' ? 'plex' : 'local'} localSource={track.source === 'plex' ? 'plex' : 'local'}
hideDownload={true} hideDownload={true}
@@ -2347,6 +2347,7 @@
? 'Hi-Res' ? 'Hi-Res'
: '-'} : '-'}
isPlaying={isTrackPlaying} isPlaying={isTrackPlaying}
isActiveTrack={isActiveTrack}
isLocal={track.isLocal} isLocal={track.isLocal}
isUnavailable={removedFromQobuz && isOwnPlaylist} isUnavailable={removedFromQobuz && isOwnPlaylist}
unavailableTooltip={removedFromQobuz ? $t('player.trackUnavailable') : undefined} unavailableTooltip={removedFromQobuz ? $t('player.trackUnavailable') : undefined}
+1
View File
@@ -611,6 +611,7 @@
showArtwork={true} showArtwork={true}
artworkUrl={getQobuzImage(track.album?.image)} artworkUrl={getQobuzImage(track.album?.image)}
isPlaying={isPlaybackActive && activeTrackId === track.id} isPlaying={isPlaybackActive && activeTrackId === track.id}
isActiveTrack={activeTrackId === track.id}
isBlacklisted={trackBlacklisted} isBlacklisted={trackBlacklisted}
selectable={multiSelectMode} selectable={multiSelectMode}
selected={multiSelectedIds.has(track.id)} selected={multiSelectedIds.has(track.id)}
@@ -541,6 +541,7 @@
showArtwork={true} showArtwork={true}
artworkUrl={getQobuzImage(track.album?.image)} artworkUrl={getQobuzImage(track.album?.image)}
isPlaying={isPlaybackActive && activeTrackId === track.id} isPlaying={isPlaybackActive && activeTrackId === track.id}
isActiveTrack={activeTrackId === track.id}
isBlacklisted={trackBlacklisted} isBlacklisted={trackBlacklisted}
selectable={multiSelectMode} selectable={multiSelectMode}
selected={multiSelectedIds.has(track.id)} selected={multiSelectedIds.has(track.id)}