feat: 'In Library' badges, artist images on local pages, MBID-based Tier 3
Three features wired together: 1. 'In Library' badges on explore search results: CheckLibraryMBIDs Wails binding batch-checks which search result MBIDs exist in the local library. Green badges render on matching artist cards and album cards. 2. Artist images on local artist-details page: Local artist pages now call GetArtistMBID(name) to resolve the MBID from tags, then GetArtistImageURL(mbid) to fetch the cached Wikimedia photo. Falls back to initial-letter avatar. 3. Tier 3 search index uses direct MBIDs from tags: buildTier3Library now reads artists.mbid column (from audio tags) for direct MBID matching, falling back to name matching for untagged artists. Eliminates false matches and catches artists that name matching misses.
This commit is contained in:
@@ -6,6 +6,7 @@ import {
|
||||
} from 'lit/decorators.js';
|
||||
import { library } from '@go/models';
|
||||
import { LibraryController } from '@store/controllers/library-controller';
|
||||
import { GetArtistImageURL, GetArtistMBID } from '@go/explore/Service';
|
||||
import '@awesome.me/webawesome/dist/components/icon/icon.js';
|
||||
import '@components/cover-grid/cover-grid.js';
|
||||
import { designTokens } from '../../styles/tokens.css';
|
||||
@@ -18,12 +19,18 @@ export class ArtistDetails extends LitElement {
|
||||
@property({ type: String, attribute: 'artist-name' })
|
||||
artistName = '';
|
||||
|
||||
@property({ type: String, attribute: 'artist-mbid' })
|
||||
artistMBID = '';
|
||||
|
||||
@state()
|
||||
private albums: library.Album[] = [];
|
||||
|
||||
@state()
|
||||
private loading = true;
|
||||
|
||||
@state()
|
||||
private artistImageURL = '';
|
||||
|
||||
private libraryCtrl = new LibraryController(this);
|
||||
|
||||
/** Tracks the store's cached array reference to detect refreshes. */
|
||||
@@ -99,6 +106,12 @@ export class ArtistDetails extends LitElement {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.artist-avatar img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.artist-avatar .initial {
|
||||
color: var(
|
||||
--yj-text-secondary,
|
||||
@@ -156,6 +169,7 @@ export class ArtistDetails extends LitElement {
|
||||
override connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.loadAlbums();
|
||||
this.loadArtistImage();
|
||||
}
|
||||
|
||||
override updated() {
|
||||
@@ -174,6 +188,31 @@ export class ArtistDetails extends LitElement {
|
||||
* Data loading
|
||||
* ================================================================ */
|
||||
|
||||
private async loadArtistImage() {
|
||||
// Resolve MBID from tags if not provided via attribute.
|
||||
let mbid = this.artistMBID;
|
||||
|
||||
if (!mbid && this.artistName) {
|
||||
try {
|
||||
mbid = await GetArtistMBID(this.artistName);
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (!mbid) return;
|
||||
|
||||
try {
|
||||
const url = await GetArtistImageURL(mbid);
|
||||
|
||||
if (url) {
|
||||
this.artistImageURL = url;
|
||||
}
|
||||
} catch {
|
||||
// No image — avatar stays as initial letter.
|
||||
}
|
||||
}
|
||||
|
||||
private async loadAlbums() {
|
||||
if (!this.artistId) return;
|
||||
|
||||
@@ -293,11 +332,14 @@ export class ArtistDetails extends LitElement {
|
||||
></wa-icon>
|
||||
</button>
|
||||
<div class="artist-avatar">
|
||||
<span class="initial">
|
||||
${this.getInitial(
|
||||
this.artistName,
|
||||
)}
|
||||
</span>
|
||||
${this.artistImageURL
|
||||
? html`<img
|
||||
src="${this.artistImageURL}"
|
||||
alt="${this.artistName}"
|
||||
/>`
|
||||
: html`<span class="initial">
|
||||
${this.getInitial(this.artistName)}
|
||||
</span>`}
|
||||
</div>
|
||||
<div class="artist-info">
|
||||
<h1
|
||||
|
||||
Reference in New Issue
Block a user