port over astra desktop tag algos

This commit is contained in:
Boof2015
2026-06-14 14:57:25 -04:00
parent 51b733a293
commit be740c2d60
9 changed files with 415 additions and 20 deletions
+20 -3
View File
@@ -1,7 +1,8 @@
import { create } from 'zustand';
import type { Album, Artist, DbTrack, LibraryFolder } from '@/types/library';
import { openLibraryDb } from '@/db/database';
import { getAlbums, getAllTracks, getArtists, getTrackCount } from '@/db/queries';
import { getAlbums, getAllTracks, getTrackCount } from '@/db/queries';
import { buildArtistList } from '@/library/artistGrouping';
import {
addFolderViaPicker,
loadFolders,
@@ -12,6 +13,7 @@ import {
} from '@/library/scanner';
import type { TrackSort } from '@/lib/trackSort';
import { usePlaylistStore } from './playlistStore';
import { useSettingsStore } from './settingsStore';
/**
* Library state — SQLite is the source of truth (no persist middleware);
@@ -45,6 +47,7 @@ interface LibraryStore {
initialize: () => Promise<void>;
refresh: () => Promise<void>;
recomputeArtists: () => void;
setViewMode: (mode: ViewMode) => void;
setTrackSort: (sort: TrackSort) => void;
addFolder: () => Promise<void>;
@@ -88,6 +91,12 @@ export const useLibraryStore = create<LibraryStore>((set, get) => {
if (!initPromise) {
initPromise = (async () => {
const db = await openLibraryDb();
// Load the persisted grouping mode before the first refresh so the artist
// list is built correctly; recompute it whenever the mode changes later.
await useSettingsStore.getState().load();
useSettingsStore.subscribe((state, prev) => {
if (state.artistGroupingMode !== prev.artistGroupingMode) get().recomputeArtists();
});
await get().refresh();
set({ initialized: true });
// One-time recovery: the v3 migration marks tracks stale (mtime = -1)
@@ -108,18 +117,26 @@ export const useLibraryStore = create<LibraryStore>((set, get) => {
refresh: async () => {
const db = await openLibraryDb();
const [tracks, albums, artists, folders, totalTrackCount] = await Promise.all([
const [tracks, albums, folders, totalTrackCount] = await Promise.all([
getAllTracks(db),
getAlbums(db),
getArtists(db),
loadFolders(),
getTrackCount(db),
]);
// The artist list is derived in JS so it can honor the grouping mode.
const artists = buildArtistList(tracks, useSettingsStore.getState().artistGroupingMode);
set({ tracks, albums, artists, folders, totalTrackCount });
// Playlist counts/missing states depend on tracks — keep them in step.
await usePlaylistStore.getState().refresh();
},
// Rebuild the artist list from in-memory tracks (e.g. on grouping-mode change),
// without re-querying SQLite.
recomputeArtists: () =>
set((state) => ({
artists: buildArtistList(state.tracks, useSettingsStore.getState().artistGroupingMode),
})),
setViewMode: (viewMode) => set({ viewMode }),
setTrackSort: (trackSort) => set({ trackSort }),
+41
View File
@@ -0,0 +1,41 @@
import { create } from 'zustand';
import { openLibraryDb } from '@/db/database';
import { getSetting, setSetting } from '@/db/queries';
import type { ArtistGroupingMode } from '@/library/artistGrouping';
/**
* Persisted app preferences. SQLite (settings table) is the source of truth — this
* store mirrors it in memory. Kept free of cross-store imports; libraryStore
* subscribes here to recompute the artist list when the grouping mode changes.
*/
const ARTIST_GROUPING_KEY = 'artist_grouping_mode';
function parseGroupingMode(value: string | null): ArtistGroupingMode {
return value === 'fileTags' ? 'fileTags' : 'astra';
}
interface SettingsStore {
artistGroupingMode: ArtistGroupingMode;
loaded: boolean;
load: () => Promise<void>;
setArtistGroupingMode: (mode: ArtistGroupingMode) => Promise<void>;
}
export const useSettingsStore = create<SettingsStore>((set, get) => ({
artistGroupingMode: 'astra',
loaded: false,
load: async () => {
if (get().loaded) return;
const db = await openLibraryDb();
const stored = await getSetting(db, ARTIST_GROUPING_KEY);
set({ artistGroupingMode: parseGroupingMode(stored), loaded: true });
},
setArtistGroupingMode: async (mode) => {
if (get().artistGroupingMode === mode) return;
set({ artistGroupingMode: mode });
const db = await openLibraryDb();
await setSetting(db, ARTIST_GROUPING_KEY, mode);
},
}));