import React, { useState, ReactElement, useCallback } from "react"; import { useDispatch, useSelector } from "react-redux"; import { useParams } from "react-router-dom"; import Card from "../Carda"; import { ComicVineMatchPanel } from "./ComicVineMatchPanel"; import { RawFileDetails } from "./RawFileDetails"; import TabControls from "./TabControls"; import { EditMetadataPanel } from "./EditMetadataPanel"; import { Menu } from "./ActionMenu/Menu"; import { ArchiveOperations } from "./Tabs/ArchiveOperations"; import { ComicInfoXML } from "./Tabs/ComicInfoXML"; import AcquisitionPanel from "./AcquisitionPanel"; import DownloadsPanel from "./DownloadsPanel"; import { VolumeInformation } from "./Tabs/VolumeInformation"; import { isEmpty, isUndefined, isNil } from "lodash"; import { RootState } from "threetwo-ui-typings"; import "react-sliding-pane/dist/react-sliding-pane.css"; import "react-loader-spinner/dist/loader/css/react-spinner-loader.css"; import Loader from "react-loader-spinner"; import SlidingPane from "react-sliding-pane"; import Modal from "react-modal"; import ComicViewer from "react-comic-viewer"; import { extractComicArchive } from "../../actions/fileops.actions"; import { determineCoverFile } from "../../shared/utils/metadata.utils"; type ComicDetailProps = {}; /** * Component for displaying the metadata for a comic in greater detail. * * @component * @example * return ( * * ) */ export const ComicDetail = (data: ComicDetailProps): ReactElement => { const [page, setPage] = useState(1); const [visible, setVisible] = useState(false); const [slidingPanelContentId, setSlidingPanelContentId] = useState(""); const [modalIsOpen, setIsOpen] = useState(false); const comicVineSearchResults = useSelector( (state: RootState) => state.comicInfo.searchResults, ); const comicVineSearchQueryObject = useSelector( (state: RootState) => state.comicInfo.searchQuery, ); const comicVineAPICallProgress = useSelector( (state: RootState) => state.comicInfo.inProgress, ); const extractedComicBook = useSelector( (state: RootState) => state.fileOps.extractedComicBookArchive, ); const { comicObjectId } = useParams<{ comicObjectId: string }>(); const dispatch = useDispatch(); const openModal = useCallback((filePath) => { setIsOpen(true); dispatch(extractComicArchive(filePath)); }, []); const afterOpenModal = useCallback(() => { // references are now sync'd and can be accessed. // subtitle.style.color = "#f00"; }, []); const closeModal = useCallback(() => { setIsOpen(false); }, []); // sliding panel init const contentForSlidingPanel = { CVMatches: { content: () => { if (!comicVineAPICallProgress) { return ( ); } else { return (
); } }, }, editComicBookMetadata: { content: () => , }, }; const { data: { _id, rawFileDetails, inferredMetadata, sourcedMetadata: { comicvine, locg, comicInfo }, }, userSettings, } = data; // check for the availability of CV metadata const isComicBookMetadataAvailable = !isUndefined(comicvine) && !isUndefined(comicvine.volumeInformation); // check for the availability of rawFileDetails const areRawFileDetailsAvailable = !isUndefined(rawFileDetails) && !isEmpty(rawFileDetails.cover); const { issueName, url } = determineCoverFile({ rawFileDetails, comicvine, locg, }); // query for airdc++ const airDCPPQuery = { issue: { name: issueName, }, }; // Tab content and header details const tabGroup = [ { id: 1, name: "Volume Information", icon: , content: isComicBookMetadataAvailable ? ( ) : null, shouldShow: isComicBookMetadataAvailable, }, { id: 2, name: "ComicInfo.xml", icon: , content: (
{!isNil(comicInfo) && }
), shouldShow: !isEmpty(comicInfo), }, { id: 3, icon: , name: "Archive Operations", content: , shouldShow: areRawFileDetailsAvailable, }, { id: 4, icon: , name: "Acquisition", content: ( ), shouldShow: true, }, { id: 5, icon: null, name: !isEmpty(data.data) ? ( Downloads ) : ( "Downloads" ), content: !isNil(data.data) && !isEmpty(data.data) && ( ), shouldShow: true, }, ]; // filtered Tabs const filteredTabs = tabGroup.filter((tab) => tab.shouldShow); // Determine which cover image to use: // 1. from the locally imported or // 2. from the CV-scraped version return (
{!isNil(data) && !isEmpty(data) && ( <>

{issueName}

{/* action dropdown */}
{/* raw file details */}
{!isUndefined(rawFileDetails) && !isEmpty(rawFileDetails.cover) && ( <> {/* Read comic button */} {extractedComicBook && ( )} )}
{} setVisible(false)} title={"Comic Vine Search Matches"} width={"600px"} > {slidingPanelContentId !== "" && contentForSlidingPanel[slidingPanelContentId].content()} )}
); };