{#snippet externalLinks( info: { musicBrainzId?: string; lastFmUrl?: string }, type: "artist" | "recording" | "release", )} {#if info.musicBrainzId || info.lastFmUrl} {#if info.musicBrainzId} MusicBrainz {/if} {#if info.lastFmUrl} Last.fm {/if} {/if} {/snippet} {#snippet infoNavButton( type: "album" | "artist", id: string, label: string, )} {#if id} {:else} {label} {/if} {/snippet} {#snippet libraryItem( type: StarredType, item: LibraryItem, fetcher: (() => Promise) | undefined, rowKey: string, detail?: string, depth = 0, )} {@const track = type === "song" && isSong(item) ? item : undefined} {@const childFactory = type === "artist" ? (child: LibraryItem) => () => api.getAlbum(child.id) : undefined} {@const node = miniNode(rowKey)} void toggleMiniNode(rowKey, fetcher)} onAdd={(asNext) => void addToQueue(rowKey, type, fetcher, item, childFactory, asNext)} onMenu={(nextMenu) => (menu = nextMenu)} /> {#if node.expanded && node.items} {@const childType = type === "artist" ? "album" : "song"} {#each node.items as child, index (itemKey( rowKey, childType, child.id, index, ))} {@const childFetcher = childType === "album" ? () => api.getAlbum(child.id) : undefined} {@render libraryItem( childType, child, childFetcher, itemKey(rowKey, childType, child.id, index), childType === "album" ? yearDetail(child) : undefined, depth + 1, )} {/each} {/if} {/snippet} {#snippet showMoreItem( keyPrefix: string, onShowAll: () => void, )} {/snippet} {#snippet songListSection( listKey: string, label: string, fetcher: () => Promise, )} {@const node = miniNode(listKey)} {#if node.items?.length} {@const visibleSongs = node.showAll ? node.items : node.items.slice(0, previewCount)} addSongsToQueue(node.items ?? [])} onToggle={() => void toggleMiniNode(listKey, fetcher)} /> {#if node.expanded}
{#each visibleSongs as song, index (itemKey( listKey, "song", song.id, index, ))} {@render libraryItem( "song", song, undefined, itemKey(listKey, "song", song.id, index), )} {/each}
{#if !node.showAll && node.items.length > previewCount} {@render showMoreItem(listKey, () => { ensureMiniNode(listKey).showAll = true; })} {/if} {/if} {/if} {/snippet} {#snippet infoArtwork( coverArtId: string, onload: (event: Event) => void, )} {@const artwork = api.getCoverArt(coverArtId, infoArtworkSize)} {@const artwork2x = api.getCoverArt(coverArtId, infoArtworkSize * 2)} fadeImage(element, coverArtId)} > {/snippet} {#snippet itemActions( item: StarredItem, type: StarredType, )}
void toggleStar(item, type)} /> void setRating(item, value)} />
{/snippet} { ui.infoItem = null; }} class="info-modal" style={modalTheme ? `--info-bg: ${modalTheme.bg}; --info-text: ${modalTheme.text}; color-scheme: ${modalTheme.dark ? "dark" : "light"}` : ""} title={`${t("common.info")}: ${ui.infoItem?.label ?? ""}`} >
{#if artistItem || albumItem || songItem} {@const backgroundId = artistItem?.coverArt || albumItem?.coverArt || (songItem && songArtId(songItem)) || undefined} {@const backgroundSize = settings.coverBackgroundBlur > 0 ? 128 : 512} {@const backgroundImage = backgroundId ? api.getCoverArt(backgroundId, backgroundSize) : undefined} {#if backgroundImage} {/if} {/if}
{#if loading}

{t("common.busy")}

{:else if error}

{error}

{:else if !artistItem && !albumItem && !songItem && details !== null}
{JSON.stringify(details, null, 2)}
{:else}
{#if artistItem}
{#if artistItem.coverArt} {@const coverArt = artistItem.coverArt} {@render infoArtwork(coverArt, (event) => applyModalTheme(event, artistItem), )} {/if}

{artistLabel}

{@render itemActions(artistItem, "artist")} {#if artistInfo} {@render externalLinks(artistInfo, "artist")} {/if}
{#if artistInfo?.biography}

{artistInfo.biography}

{/if}
{/if} {#if songItem} {@const artId = songArtId(songItem)}
{#if artId} {@render infoArtwork(artId, (event) => applyModalTheme(event, songItem), )} {/if}

{songItem.title} {#if songItem.year !== undefined} ({songItem.year}) {/if}

{#if albumLabel || artistLabel}
{#if albumLabel} {@render infoNavButton("album", albumId, albumLabel)} {/if} {#if artistLabel} {@render infoNavButton( "artist", artistId, artistLabel, )} {/if}
{/if} {@render itemActions(songItem, "song")} {@render externalLinks(songItem, "recording")}
{/if} {#if albumItem}
{#if albumItem.coverArt} {@const coverArt = albumItem.coverArt} {@render infoArtwork(coverArt, (event) => applyModalTheme(event, albumItem), )} {/if}

{albumLabel} {#if albumItem.year !== undefined} ({albumItem.year}) {/if}

{#if artistLabel}
{@render infoNavButton("artist", artistId, artistLabel)}
{/if} {@render itemActions(albumItem, "album")} {#if albumInfo} {@render externalLinks(albumInfo, "release")} {/if}
{#if albumInfo?.notes}

{albumInfo.notes}

{/if}
{/if} {#if details !== null}
API
{JSON.stringify({ item: details, artistInfo, albumInfo, artistAlbums }, null, 2)}
{/if}
{#if albumItem || artistItem || songItem} {/if}
{/if}
{#if menu} (menu = null)} /> {/if}