diff --git a/src/client/components/ComicDetail/ComicDetail.tsx b/src/client/components/ComicDetail/ComicDetail.tsx index 85c6e41..2e76dca 100644 --- a/src/client/components/ComicDetail/ComicDetail.tsx +++ b/src/client/components/ComicDetail/ComicDetail.tsx @@ -96,7 +96,8 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => { const hasAnyMetadata = isComicBookMetadataAvailable || !isEmpty(comicInfo) || - !isNil(locg); + !isNil(locg) || + areRawFileDetailsAvailable; const areRawFileDetailsAvailable = !isUndefined(rawFileDetails) && !isEmpty(rawFileDetails); diff --git a/src/client/components/ComicDetail/Tabs/VolumeInformation.tsx b/src/client/components/ComicDetail/Tabs/VolumeInformation.tsx index d4c912f..0cfd461 100644 --- a/src/client/components/ComicDetail/Tabs/VolumeInformation.tsx +++ b/src/client/components/ComicDetail/Tabs/VolumeInformation.tsx @@ -6,6 +6,7 @@ import { ReconcilerDrawer } from "./ReconcilerDrawer"; import { fetcher } from "../../../graphql/fetcher"; import { useGetComicByIdQuery } from "../../../graphql/generated"; import type { CanonicalRecord } from "./useReconciler"; +import type { RawFileDetails as RawFileDetailsType } from "../../../graphql/generated"; interface ComicVineMetadata { volumeInformation?: Record; @@ -28,6 +29,8 @@ interface VolumeInformationData { id?: string; sourcedMetadata?: SourcedMetadata; inferredMetadata?: { issue?: unknown }; + rawFileDetails?: RawFileDetailsType; + createdAt?: string; updatedAt?: string; } @@ -166,34 +169,37 @@ export const VolumeInformation = ( ); return true; }); - if ( - !isNil(data?.inferredMetadata?.issue) && - !isEmpty(data?.inferredMetadata?.issue) - ) { + const hasLocalFile = + (!isNil(data?.rawFileDetails) && !isEmpty(data?.rawFileDetails)) || + (!isNil(data?.inferredMetadata?.issue) && !isEmpty(data?.inferredMetadata?.issue)); + if (hasLocalFile) { sources.push("inferredMetadata"); } return sources; - }, [data?.sourcedMetadata, data?.inferredMetadata]); + }, [data?.sourcedMetadata, data?.inferredMetadata, data?.rawFileDetails]); + + const onlyComicvine = + presentSources.length === 1 && + !!data.sourcedMetadata?.comicvine?.volumeInformation; return (
- {presentSources.length > 1 && ( + {(presentSources.length > 1 || (presentSources.length === 1 && !onlyComicvine)) && ( setReconcilerOpen(true)} /> )} - {presentSources.length === 1 && - data.sourcedMetadata?.comicvine?.volumeInformation && ( - - )} + {onlyComicvine && ( + + )} diff --git a/src/client/components/Import/Import.tsx b/src/client/components/Import/Import.tsx index 41e5d9e..bf7cdbd 100644 --- a/src/client/components/Import/Import.tsx +++ b/src/client/components/Import/Import.tsx @@ -145,7 +145,14 @@ export const Import = (): ReactElement => { }, [getSocket, queryClient]); /** - * Handles force re-import - re-imports all files to fix indexing issues + * Initiates a force re-import of all library files. + * + * When the queue is already drained, disconnects and reconnects the socket + * before triggering the import — ensures the backend receives a fresh session + * rather than reusing a stale one that would be ignored. + * + * Validates directory availability and active session state before proceeding + * to prevent duplicate or broken imports. */ const handleForceReImport = async () => { setImportError(null); @@ -194,6 +201,7 @@ export const Import = (): ReactElement => { } }; + // `undefined` covers the initial state before any import has ever run in this session const canStartImport = !hasActiveSession && (importJobQueue.status === "drained" || importJobQueue.status === undefined); diff --git a/src/client/components/PullList/PullList.tsx b/src/client/components/PullList/PullList.tsx index e1ae777..1214a86 100644 --- a/src/client/components/PullList/PullList.tsx +++ b/src/client/components/PullList/PullList.tsx @@ -1,3 +1,9 @@ +/** + * @fileoverview Weekly Pull List page — displays comics releasing this week + * that the user has marked to follow. + * @module components/PullList/PullList + */ + import React, { ReactElement, useEffect, useMemo, useState } from "react"; import T2Table from "../shared/T2Table"; import Card from "../shared/Carda"; @@ -16,6 +22,15 @@ interface PullListComic { }; } +/** + * Weekly Pull List page component. + * + * Displays comics releasing this week that the user tracks. + * Fetching is not yet implemented — state is initialised to `null` + * so the table renders only when data is available, avoiding an empty-table flash. + * + * @returns {ReactElement} The pull list page UI + */ export const PullList = (): ReactElement => { // Placeholder for pull list comics - would come from API/store const [pullListComics, setPullListComics] = useState(null); @@ -32,6 +47,7 @@ export const PullList = (): ReactElement => { }, []); const nextPageHandler = () => {}; const previousPageHandler = () => {}; + // Column def memoised — shape is static, no deps needed const columnData = useMemo( () => [ {