From f5a6b919aaf842fd26de5eed8b40afd898df28b6 Mon Sep 17 00:00:00 2001 From: Senko-san Date: Sun, 14 Jun 2026 14:09:47 +0300 Subject: [PATCH] fix(library): poll track list while enrichment is pending MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The library tracks query wasn't refetching, so a track stayed on "Identifying metadata…" until an unrelated Track-tag invalidation. Poll every 4s while any listed track is metadata_status=pending, then stop (and never while offline). Co-Authored-By: Claude Opus 4.8 --- src/features/library/LibraryPage.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/features/library/LibraryPage.tsx b/src/features/library/LibraryPage.tsx index 79e6ec4..a4eeec8 100644 --- a/src/features/library/LibraryPage.tsx +++ b/src/features/library/LibraryPage.tsx @@ -1,4 +1,4 @@ -import { useState } from 'react'; +import { useEffect, useState } from 'react'; import { useNavigate } from 'react-router'; import { useTranslation } from 'react-i18next'; import { @@ -54,8 +54,14 @@ export function LibraryPage() { const [search, setSearch] = useState(''); const [debouncedSearch] = useDebounce(search, 300); + // Poll while any listed track is still being enriched, then stop. Enrichment + // runs asynchronously in a worker after import/upload; without this the row + // stays stuck on "Identifying metadata…" until something else invalidates the + // Track tag. Cleared to 0 once nothing is pending (and while offline). + const [tracksPollMs, setTracksPollMs] = useState(0); const tracksQuery = useGetTracksQuery( debouncedSearch ? { search } : undefined, + { pollingInterval: tracksPollMs }, ); const albumsQuery = useGetAlbumsQuery( debouncedSearch ? { search } : undefined, @@ -73,6 +79,14 @@ export function LibraryPage() { const localArtists = useAppSelector(selectLocalArtists); const q = debouncedSearch.trim().toLowerCase(); + const anyPending = + !offline && + (tracksQuery.data?.items.some((tr) => tr.metadataStatus === 'pending') ?? + false); + useEffect(() => { + setTracksPollMs(anyPending ? 4000 : 0); + }, [anyPending]); + // Live server data wins; offline we fall back to the locally-composed list. const tracksToShow = tracksQuery.data?.items ??