feat: Library Only mode — toggle, search, artist page, similar artists
Backend: - Migration 17: similar_artist_map table stores per-artist similar artist relationships (source_mbid → similar_mbid + name + score) - Tier 4 index build now persists similar artists to this table - GetLibrarySimilarArtists(mbid) queries similar artists filtered by JOIN with the artists table (library-only, no API calls) - Added db field to explore.Service for direct queries Frontend: - ExploreSettingsStore with libraryOnly toggle, persisted to localStorage - Top bar toggle button with active/inactive styling - Explore search: skips full MB/LB pipeline when library-only, uses only searchLibraryCache (pure JS, instant) - Artist detail page: in library-only mode, skips all API calls (no top tracks, no top releases, no LB play count, no MB artist lookup). Uses library store for discography, calls GetLibrarySimilarArtists for similar artists. - Similar artists section: changed from horizontal scroll to wrapping flex layout with collapsible toggle (Show all N) - Removed debug artist ranking log
This commit is contained in:
@@ -409,6 +409,14 @@ func runMigrations(
|
||||
}
|
||||
}
|
||||
|
||||
if version < 17 { //nolint:mnd
|
||||
if err := migration17SimilarArtistMap(
|
||||
ctx, db, logger,
|
||||
); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -1833,6 +1841,43 @@ func migration16ArtistImages(
|
||||
return nil
|
||||
}
|
||||
|
||||
func migration17SimilarArtistMap(
|
||||
ctx context.Context,
|
||||
db *sql.DB,
|
||||
logger *slog.Logger,
|
||||
) error {
|
||||
logger.Info("applying migration 17: similar_artist_map table")
|
||||
|
||||
if _, err := db.ExecContext(ctx, `
|
||||
CREATE TABLE IF NOT EXISTS similar_artist_map (
|
||||
source_artist_mbid TEXT NOT NULL,
|
||||
similar_artist_mbid TEXT NOT NULL,
|
||||
similar_artist_name TEXT NOT NULL,
|
||||
score INTEGER NOT NULL DEFAULT 0,
|
||||
PRIMARY KEY (source_artist_mbid, similar_artist_mbid)
|
||||
)
|
||||
`); err != nil {
|
||||
return fmt.Errorf("migration 17: create similar_artist_map: %w", err)
|
||||
}
|
||||
|
||||
if _, err := db.ExecContext(ctx, `
|
||||
CREATE INDEX IF NOT EXISTS idx_similar_artist_map_source
|
||||
ON similar_artist_map(source_artist_mbid)
|
||||
`); err != nil {
|
||||
return fmt.Errorf("migration 17: create source index: %w", err)
|
||||
}
|
||||
|
||||
if _, err := db.ExecContext(ctx,
|
||||
"PRAGMA user_version = 17",
|
||||
); err != nil {
|
||||
return fmt.Errorf("could not set user_version to 17: %w", err)
|
||||
}
|
||||
|
||||
logger.Info("migration 17 complete")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// readLibraryDirFromTOML reads the TOML config file and returns
|
||||
// the Library.DirectoryPath value, or "" if not configured.
|
||||
func readLibraryDirFromTOML(logger *slog.Logger) string {
|
||||
|
||||
Reference in New Issue
Block a user