cover-grid album dropdown behavior fixes
This commit is contained in:
@@ -78,4 +78,16 @@ export class LibraryController implements ReactiveController {
|
||||
setScrollPosition(view: ViewName, offset: number): void {
|
||||
libraryStore.setScrollPosition(view, offset);
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// COVER SIZE
|
||||
// ===================================================================
|
||||
|
||||
get coverSize(): number {
|
||||
return libraryStore.getCoverSize();
|
||||
}
|
||||
|
||||
set coverSize(size: number) {
|
||||
libraryStore.setCoverSize(size);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,18 @@ type ViewName = 'tracks' | 'albums';
|
||||
|
||||
type Subscriber = () => void;
|
||||
|
||||
/** Minimum album card width in CSS pixels. */
|
||||
const COVER_SIZE_MIN = 100;
|
||||
|
||||
/** Maximum album card width in CSS pixels. */
|
||||
const COVER_SIZE_MAX = 350;
|
||||
|
||||
/** Default album card width in CSS pixels. */
|
||||
const COVER_SIZE_DEFAULT = 176;
|
||||
|
||||
/** localStorage key for persisted cover size. */
|
||||
const COVER_SIZE_KEY = 'cover-grid-size';
|
||||
|
||||
class LibraryStore {
|
||||
private tracks: library.Track[] | null = null;
|
||||
private albums: library.Album[] | null = null;
|
||||
@@ -14,6 +26,8 @@ class LibraryStore {
|
||||
private tracksLoading = false;
|
||||
private albumsLoading = false;
|
||||
|
||||
private coverSizeValue: number = COVER_SIZE_DEFAULT;
|
||||
|
||||
private scrollPositions: Record<ViewName, number> = {
|
||||
tracks: 0,
|
||||
albums: 0,
|
||||
@@ -25,6 +39,8 @@ class LibraryStore {
|
||||
EventsOn(Events.LibraryScanComplete, () => {
|
||||
this.invalidate();
|
||||
});
|
||||
|
||||
this.loadCoverSize();
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
@@ -111,6 +127,56 @@ class LibraryStore {
|
||||
this.scrollPositions[view] = offset;
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// COVER SIZE
|
||||
// ===================================================================
|
||||
|
||||
getCoverSize(): number {
|
||||
return this.coverSizeValue;
|
||||
}
|
||||
|
||||
setCoverSize(size: number): void {
|
||||
const clamped = Math.round(
|
||||
Math.max(COVER_SIZE_MIN, Math.min(COVER_SIZE_MAX, size)),
|
||||
);
|
||||
|
||||
if (clamped === this.coverSizeValue) return;
|
||||
|
||||
this.coverSizeValue = clamped;
|
||||
this.saveCoverSize();
|
||||
this.notify();
|
||||
}
|
||||
|
||||
private loadCoverSize(): void {
|
||||
try {
|
||||
const stored = localStorage.getItem(COVER_SIZE_KEY);
|
||||
|
||||
if (stored !== null) {
|
||||
const parsed = parseInt(stored, 10);
|
||||
|
||||
if (!Number.isNaN(parsed)) {
|
||||
this.coverSizeValue = Math.max(
|
||||
COVER_SIZE_MIN,
|
||||
Math.min(COVER_SIZE_MAX, parsed),
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// localStorage may be unavailable.
|
||||
}
|
||||
}
|
||||
|
||||
private saveCoverSize(): void {
|
||||
try {
|
||||
localStorage.setItem(
|
||||
COVER_SIZE_KEY,
|
||||
String(this.coverSizeValue),
|
||||
);
|
||||
} catch {
|
||||
// localStorage may be unavailable.
|
||||
}
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// INVALIDATION
|
||||
// ===================================================================
|
||||
|
||||
@@ -11,8 +11,10 @@ export interface TrackInfo {
|
||||
title: string; // track title (falls back to fileName)
|
||||
artist: string; // artist name
|
||||
album: string; // album name
|
||||
coverArt: string; // URL path to cover art (e.g., "/covers/abc.jpg") or empty string
|
||||
coverArtThumbnail: string; // URL path to thumbnail (e.g., "/covers/abc_thumb.jpg") or empty string
|
||||
coverArt: string; // URL path to full-size cover art or empty string
|
||||
coverArtSmall: string; // URL path to small variant (100px max) or empty string
|
||||
coverArtMedium: string; // URL path to medium variant (200px max) or empty string
|
||||
coverArtLarge: string; // URL path to large variant (400px max) or empty string
|
||||
trackChangeId: number; // monotonic counter to detect track changes even when the same file plays consecutively
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user