refactor(immersive): clean up controls and improve split view layout

- Remove track info (artwork, title, artist) from ImmersiveControls bottom bar
- Add track title and artist below album artwork in split view mode
- Change Lyrics Focus icon from MessageSquareText to Mic (microphone)
- Remove unused compact mode from ImmersiveControls
- Simplify props and cleanup CSS
This commit is contained in:
vicrodh committed 2026-01-30 23:11:06 -06:00
1 parent 0fc0723804
commit 4d5a78ff24
3 files changed
+63 -103

No files matched your search

@@ -6,10 +6,6 @@
interface Props {
visible?: boolean;
// Track info
artwork: string;
trackTitle: string;
artist: string;
// Playback state
isPlaying: boolean;
currentTime: number;
@@ -32,15 +28,10 @@
onToggleRepeat: () => void;
onToggleFavorite: () => void;
onVolumeChange: (volume: number) => void;
// Compact mode (hide some elements)
compact?: boolean;
}
let {
visible = true,
artwork,
trackTitle,
artist,
isPlaying,
currentTime,
duration,
@@ -58,23 +49,11 @@
onToggleShuffle,
onToggleRepeat,
onToggleFavorite,
onVolumeChange,
compact = false
onVolumeChange
}: Props = $props();
</script>
<div class="immersive-controls" class:visible class:compact>
<!-- Left: Track Info -->
{#if !compact}
<div class="track-info">
<img src={artwork} alt="" class="mini-artwork" />
<div class="track-meta">
<div class="track-title">{trackTitle}</div>
<div class="track-artist">{artist}</div>
</div>
</div>
{/if}
<div class="immersive-controls" class:visible>
<!-- Center: Playback Controls + Progress -->
<div class="playback-section">
<div class="controls">
@@ -136,31 +115,29 @@
</div>
<!-- Right: Volume + Actions -->
{#if !compact}
<div class="right-section">
<button
class="action-btn"
class:active={isFavorite}
onclick={onToggleFavorite}
title={isFavorite ? 'Remove from Favorites' : 'Add to Favorites'}
>
<Heart
size={18}
fill={isFavorite ? 'currentColor' : 'none'}
/>
</button>
<div class="right-section">
<button
class="action-btn"
class:active={isFavorite}
onclick={onToggleFavorite}
title={isFavorite ? 'Remove from Favorites' : 'Add to Favorites'}
>
<Heart
size={18}
fill={isFavorite ? 'currentColor' : 'none'}
/>
</button>
<div class="volume-wrapper">
<VolumeSlider {volume} {onVolumeChange} />
</div>
{#if quality}
<div class="quality-wrapper">
<QualityBadge {quality} {bitDepth} {samplingRate} />
</div>
{/if}
<div class="volume-wrapper">
<VolumeSlider {volume} {onVolumeChange} />
</div>
{/if}
{#if quality}
<div class="quality-wrapper">
<QualityBadge {quality} {bitDepth} {samplingRate} />
</div>
{/if}
</div>
</div>
<style>
@@ -193,46 +170,6 @@
pointer-events: auto;
}
/* Track Info (Left) */
.track-info {
display: flex;
align-items: center;
gap: 12px;
min-width: 200px;
max-width: 280px;
}
.mini-artwork {
width: 48px;
height: 48px;
border-radius: 6px;
object-fit: cover;
flex-shrink: 0;
}
.track-meta {
min-width: 0;
flex: 1;
}
.track-title {
font-size: 14px;
font-weight: 600;
color: var(--text-primary, white);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.track-artist {
font-size: 12px;
color: var(--alpha-60, rgba(255, 255, 255, 0.6));
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-top: 2px;
}
/* Playback Section (Center) */
.playback-section {
flex: 1;
@@ -351,14 +288,8 @@
margin-left: 8px;
}
/* Compact mode */
.immersive-controls.compact .playback-section {
max-width: 100%;
}
/* Responsive */
@media (max-width: 900px) {
.track-info,
.right-section {
display: none;
}
@@ -1,5 +1,5 @@
<script lang="ts">
import { X, Disc3, LayoutGrid, MessageSquareText, ListMusic, Music2, Info, Radio } from 'lucide-svelte';
import { X, Disc3, LayoutGrid, Mic, ListMusic, Music2, Info, Radio } from 'lucide-svelte';
import { t } from '$lib/i18n';
export type ImmersiveTab = 'lyrics' | 'credits' | 'suggestions' | 'queue';
@@ -39,7 +39,7 @@
const displayModes: { id: DisplayMode; icon: typeof Disc3; title: string }[] = [
{ id: 'coverflow', icon: Disc3, title: 'Coverflow (1)' },
{ id: 'split', icon: LayoutGrid, title: 'Split View (2)' },
{ id: 'lyrics-focus', icon: MessageSquareText, title: 'Lyrics Focus (3)' },
{ id: 'lyrics-focus', icon: Mic, title: 'Lyrics Focus (3)' },
{ id: 'queue-focus', icon: ListMusic, title: 'Queue Focus (4)' },
];
@@ -271,10 +271,14 @@
</div>
{:else}
<!-- Split: Artwork + Panel side by side -->
<div class="main-content">
<!-- Left: Artwork -->
<div class="immersive-main">
<!-- Left: Artwork + Track Info -->
<div class="artwork-section">
<ImmersiveArtwork {artwork} {trackTitle} variant="floating" />
<div class="split-track-info">
<h2 class="split-track-title">{trackTitle}</h2>
<p class="split-track-artist">{artist}</p>
</div>
</div>
<!-- Right: Active Panel -->
@@ -307,9 +311,6 @@
<!-- Bottom Controls -->
<ImmersiveControls
visible={showUI}
{artwork}
{trackTitle}
{artist}
{isPlaying}
{currentTime}
{duration}
@@ -354,7 +355,7 @@
}
/* Split mode layout */
.main-content {
.immersive-main {
position: absolute;
top: 0;
left: 50%;
@@ -373,8 +374,36 @@
.artwork-section {
flex: 0 0 auto;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: 20px;
}
.split-track-info {
text-align: center;
max-width: 380px;
}
.split-track-title {
font-size: clamp(18px, 2.5vw, 24px);
font-weight: 700;
color: var(--text-primary, white);
margin: 0 0 6px 0;
text-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
/* Truncate long titles */
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.split-track-artist {
font-size: clamp(14px, 1.8vw, 16px);
color: var(--alpha-70, rgba(255, 255, 255, 0.7));
margin: 0;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.panel-section {
@@ -412,7 +441,7 @@
/* Responsive */
@media (max-width: 1200px) {
.main-content {
.immersive-main {
padding: 70px 32px 130px;
gap: 40px;
}
@@ -427,7 +456,7 @@
}
@media (max-width: 900px) {
.main-content {
.immersive-main {
flex-direction: column;
padding: 70px 24px 140px;
gap: 24px;
@@ -454,7 +483,7 @@
}
@media (max-width: 600px) {
.main-content {
.immersive-main {
padding: 60px 16px 130px;
gap: 20px;
}