fix(immersive): improve background quality and polish UI

- Increase canvas blur size from 64x64 to 256x256 for smoother background
- Fix lyrics horizontal scroll by adding word-wrap and overflow-x: hidden
- Remove queue button from controls (use header tab instead)
- Add queue sync effect when immersive player is open

Addresses visual quality issues with pixelated background and long
German lyrics causing horizontal overflow.
This commit is contained in:
vicrodh committed 2026-01-30 16:40:20 -06:00
1 parent 07b7228538
commit 223a7f5e1d
5 files changed
+20 -23

No files matched your search

@@ -1,5 +1,5 @@
<script lang="ts">
import { Shuffle, SkipBack, Play, Pause, SkipForward, Repeat, Heart, List } from 'lucide-svelte';
import { Shuffle, SkipBack, Play, Pause, SkipForward, Repeat, Heart } from 'lucide-svelte';
import ProgressBar from './shared/ProgressBar.svelte';
import VolumeSlider from './shared/VolumeSlider.svelte';
import QualityBadge from '../QualityBadge.svelte';
@@ -32,7 +32,6 @@
onToggleRepeat: () => void;
onToggleFavorite: () => void;
onVolumeChange: (volume: number) => void;
onOpenQueue?: () => void;
// Compact mode (hide some elements)
compact?: boolean;
}
@@ -60,7 +59,6 @@
onToggleRepeat,
onToggleFavorite,
onVolumeChange,
onOpenQueue,
compact = false
}: Props = $props();
</script>
@@ -152,12 +150,6 @@
/>
</button>
{#if onOpenQueue}
<button class="action-btn" onclick={onOpenQueue} title="Queue">
<List size={18} />
</button>
{/if}
<div class="volume-wrapper">
<VolumeSlider {volume} {onVolumeChange} />
</div>
@@ -53,7 +53,6 @@
onToggleShuffle: () => void;
onToggleRepeat: () => void;
onToggleFavorite: () => void;
onOpenQueue?: () => void;
// Lyrics
lyricsLines?: LyricsLine[];
lyricsActiveIndex?: number;
@@ -99,7 +98,6 @@
onToggleShuffle,
onToggleRepeat,
onToggleFavorite,
onOpenQueue,
lyricsLines = [],
lyricsActiveIndex = -1,
lyricsActiveProgress = 0,
@@ -289,7 +287,6 @@
{onToggleRepeat}
{onToggleFavorite}
{onVolumeChange}
{onOpenQueue}
/>
</div>
{/if}
@@ -134,6 +134,7 @@
gap: 16px;
padding: 16px 20px;
overflow-y: auto;
overflow-x: hidden;
height: 100%;
scrollbar-width: thin;
scrollbar-color: var(--bg-tertiary) transparent;
@@ -213,6 +214,9 @@
font-size 150ms ease-out,
color 250ms ease-out;
transform-origin: left center;
/* Prevent horizontal overflow with long lyrics */
word-wrap: break-word;
overflow-wrap: break-word;
/* will-change removed from all lines - only active line gets GPU layer */
}
+6 -6
View File
@@ -2,8 +2,8 @@
* Optimized Image Blur Utility
*
* Pre-computes blurred background images for the immersive player.
* Uses a tiny canvas (64x64) which, when scaled up, produces the same
* visual effect as CSS blur(100px) but with near-zero GPU cost.
* Uses a small canvas (256x256) with blur which, when scaled up, produces
* a smooth background effect with minimal GPU cost.
*
* Performance comparison:
* - CSS blur(100px) on 600x600 image: ~15-30% GPU, constant
@@ -19,14 +19,14 @@ const MAX_CACHE_SIZE = 20;
* Returns a data URL that can be used as background-image.
*
* @param artworkUrl - The original artwork URL
* @param size - Output canvas size (default 64, higher = sharper blur edges)
* @param blurRadius - Canvas blur radius (default 8, effective ~100px at fullscreen)
* @param size - Output canvas size (default 256, higher = smoother result)
* @param blurRadius - Canvas blur radius (default 20, effective ~80px at fullscreen)
* @returns Promise<string> - Data URL of blurred image
*/
export async function generateBlurredBackground(
artworkUrl: string,
size: number = 64,
blurRadius: number = 8
size: number = 256,
blurRadius: number = 20
): Promise<string> {
// Check cache first
const cacheKey = `${artworkUrl}-${size}-${blurRadius}`;
+9 -5
View File
@@ -2587,6 +2587,15 @@
}
});
// Sync queue state when immersive player is open and track changes
$effect(() => {
const trackId = currentTrack?.id;
const immersiveOpen = isFullScreenOpen || isFocusModeOpen;
if (immersiveOpen && trackId !== undefined) {
syncQueueState();
}
});
// Helper function to fetch and update queue counts and history
async function updateQueueCounts() {
const state = await getBackendQueueState();
@@ -3095,11 +3104,6 @@
onToggleRepeat={toggleRepeat}
{isFavorite}
onToggleFavorite={toggleFavorite}
onOpenQueue={() => {
closeFullScreen();
closeFocusMode();
toggleQueue();
}}
lyricsLines={lyricsLines.map(l => ({ text: l.text }))}
lyricsActiveIndex={lyricsActiveIndex}
lyricsActiveProgress={lyricsActiveProgress}