feat(wiring): complete playback context integration in AlbumDetailView

EXAMPLE IMPLEMENTATION showing how to wire context system:

Context Creation:
- createAlbumContext(startIndex) helper creates context with track list
- handlePlayAll() creates context from first track
- handlePlayFromHere() creates context from selected track (explicit)

Autoplay Logic:
- handleTrackPlay() checks user preference (implicit action)
  - If 'continue': creates context (play within album)
  - If 'track_only': clears context (isolated playback)

Menu Actions (Explicit - Override Setting):
- onPlayTrackOnly: always clears context
- onPlayFromHere: always creates context from track
- onPlayNow: respects autoplay setting

Precedence Rule Enforced:
- Menu actions (explicit) override global autoplay setting
- Simple clicks (implicit) respect autoplay setting

Stack Icon Integration:
- Context automatically tracked by backend
- Stack icon appears when context active
- Tooltip shows 'Playing from: Album · {album.title}'

This pattern should be replicated in:
- PlaylistDetailView
- ArtistDetailView (Top Tracks)
- FavoritesView
- HomeView (curated lists)

cp
This commit is contained in:
vicrodh committed 2026-01-18 01:01:32 -06:00
1 parent 9d4a269d36
commit b6001b0203
1 file changed
+62 -4
@@ -10,6 +10,8 @@
loadAlbumFavorites,
toggleAlbumFavorite
} from '$lib/stores/albumFavoritesStore';
import { setPlaybackContext, clearPlaybackContext } from '$lib/stores/playbackContextStore';
import { getCachedPreferences } from '$lib/stores/playbackPreferencesStore';
interface Track {
id: number;
@@ -142,6 +144,56 @@
isFavoriteLoading = false;
}
}
// Helper: Create playback context for this album
async function createAlbumContext(startTrackIndex: number) {
const trackIds = album.tracks.map(t => t.id);
await setPlaybackContext(
'album',
album.id,
album.title,
'qobuz',
trackIds,
startTrackIndex
);
}
// Helper: Handle track play with autoplay logic
function handleTrackPlay(track: Track, trackIndex: number) {
const prefs = getCachedPreferences();
// Check autoplay preference (implicit action)
if (prefs.autoplay_mode === 'continue') {
// Create context and play from here
createAlbumContext(trackIndex);
} else {
// Play only this track (clear context)
clearPlaybackContext();
}
// Trigger actual playback
onTrackPlay?.(track);
}
// Explicit action: Play track only (overrides setting)
function handlePlayTrackOnly(track: Track) {
clearPlaybackContext();
onTrackPlay?.(track);
}
// Explicit action: Play from here (overrides setting)
function handlePlayFromHere(track: Track, trackIndex: number) {
createAlbumContext(trackIndex);
onTrackPlay?.(track);
}
// Handle Play All button - always creates context
function handlePlayAll() {
if (album.tracks.length > 0) {
createAlbumContext(0); // Start from first track
}
onPlayAll?.();
}
</script>
<div class="album-detail">
@@ -179,7 +231,7 @@
style="background-color: {playBtnHovered ? 'var(--accent-hover)' : 'var(--accent-primary)'}"
onmouseenter={() => (playBtnHovered = true)}
onmouseleave={() => (playBtnHovered = false)}
onclick={onPlayAll}
onclick={handlePlayAll}
>
<Play size={18} fill="white" color="white" />
<span>Play</span>
@@ -224,7 +276,7 @@
<!-- Track Rows -->
<div class="tracks">
{#each album.tracks as track (`${track.id}-${downloadStateVersion}`)}
{#each album.tracks as track, trackIndex (`${track.id}-${downloadStateVersion}`)}
{@const downloadInfo = getTrackDownloadStatus?.(track.id) ?? { status: 'none' as const, progress: 0 }}
<TrackRow
trackId={track.id}
@@ -237,13 +289,19 @@
downloadStatus={downloadInfo.status}
downloadProgress={downloadInfo.progress}
onPlay={() => {
onTrackPlay?.(track);
handleTrackPlay(track, trackIndex);
}}
onDownload={onTrackDownload ? () => onTrackDownload(track) : undefined}
onRemoveDownload={onTrackRemoveDownload ? () => onTrackRemoveDownload(track.id) : undefined}
menuActions={{
onPlayNow: () => {
onTrackPlay?.(track);
handleTrackPlay(track, trackIndex);
},
onPlayTrackOnly: () => {
handlePlayTrackOnly(track);
},
onPlayFromHere: () => {
handlePlayFromHere(track, trackIndex);
},
onPlayNext: onTrackPlayNext ? () => onTrackPlayNext(track) : undefined,
onPlayLater: onTrackPlayLater ? () => onTrackPlayLater(track) : undefined,