faster fetching for artist albums
This commit is contained in:
@@ -150,18 +150,6 @@ export class ArtistDetails extends LitElement {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-message,
|
||||
.empty-message {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
height: 100%;
|
||||
color: var(
|
||||
--yj-text-secondary,
|
||||
#b3b3b3
|
||||
);
|
||||
font-size: 14px;
|
||||
}
|
||||
`;
|
||||
|
||||
override connectedCallback() {
|
||||
@@ -185,26 +173,76 @@ export class ArtistDetails extends LitElement {
|
||||
private async loadAlbums() {
|
||||
if (!this.artistId) return;
|
||||
|
||||
try {
|
||||
this.loading = true;
|
||||
// Try to populate instantly from the
|
||||
// cached all-albums list if available.
|
||||
const cached =
|
||||
this.libraryCtrl.getAlbumsByArtistNameCached(
|
||||
this.artistName,
|
||||
);
|
||||
|
||||
if (cached !== null && cached.length > 0) {
|
||||
this.albums = cached;
|
||||
this.loading = false;
|
||||
}
|
||||
|
||||
// Always run the authoritative backend
|
||||
// query. If we got a cache hit above,
|
||||
// this serves as a correction pass.
|
||||
try {
|
||||
const albums =
|
||||
await this.libraryCtrl.getAlbumsByArtist(
|
||||
this.artistId,
|
||||
);
|
||||
|
||||
this.albums = albums ?? [];
|
||||
const result = albums ?? [];
|
||||
|
||||
// Skip update if the cached result
|
||||
// is identical (same IDs in same
|
||||
// order) to avoid a re-render.
|
||||
if (!this.albumsMatch(result)) {
|
||||
this.albums = result;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error(
|
||||
'Error loading artist albums:',
|
||||
error,
|
||||
);
|
||||
this.albums = [];
|
||||
|
||||
// Only overwrite if we had no cached
|
||||
// result to fall back on.
|
||||
if (cached === null) {
|
||||
this.albums = [];
|
||||
}
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two album lists by ID to avoid
|
||||
* unnecessary re-renders when the backend
|
||||
* result matches the cached approximation.
|
||||
*/
|
||||
private albumsMatch(
|
||||
incoming: library.Album[],
|
||||
): boolean {
|
||||
const current = this.albums;
|
||||
|
||||
if (current.length !== incoming.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < current.length; i++) {
|
||||
if (
|
||||
current[i]!.ID !== incoming[i]!.ID
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ================================================================
|
||||
* Navigation
|
||||
* ================================================================ */
|
||||
@@ -277,20 +315,9 @@ export class ArtistDetails extends LitElement {
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
${this.loading
|
||||
? html`
|
||||
<div
|
||||
class="loading-message"
|
||||
>
|
||||
Loading albums...
|
||||
</div>
|
||||
`
|
||||
: html`
|
||||
<cover-grid
|
||||
.externalAlbums=${this
|
||||
.albums}
|
||||
></cover-grid>
|
||||
`}
|
||||
<cover-grid
|
||||
.externalAlbums=${this.albums}
|
||||
></cover-grid>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -61,6 +61,14 @@ export class LibraryController implements ReactiveController {
|
||||
return libraryStore.getAlbumsByArtist(artistID);
|
||||
}
|
||||
|
||||
getAlbumsByArtistNameCached(
|
||||
artistName: string,
|
||||
): library.Album[] | null {
|
||||
return libraryStore.getAlbumsByArtistNameCached(
|
||||
artistName,
|
||||
);
|
||||
}
|
||||
|
||||
get cachedTracks(): library.Track[] | null {
|
||||
return libraryStore.getCachedTracks();
|
||||
}
|
||||
|
||||
@@ -130,6 +130,24 @@ class LibraryStore {
|
||||
return GetAlbumsByArtist(artistID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns albums filtered by artist name from
|
||||
* the in-memory cache, or null if the cache is
|
||||
* not populated. This provides an instant
|
||||
* result when the all-albums list has already
|
||||
* been loaded (e.g. the user visited the albums
|
||||
* view first).
|
||||
*/
|
||||
getAlbumsByArtistNameCached(
|
||||
artistName: string,
|
||||
): library.Album[] | null {
|
||||
if (this.albums === null) return null;
|
||||
|
||||
return this.albums.filter(
|
||||
(a) => a.ArtistName === artistName,
|
||||
);
|
||||
}
|
||||
|
||||
// ===================================================================
|
||||
// STATE ACCESSORS
|
||||
// Synchronous access for controllers that need current cached values.
|
||||
|
||||
Reference in New Issue
Block a user