import React, { ReactElement, useCallback, useEffect, useState } from "react";
import { format } from "date-fns";
import Loader from "react-loader-spinner";
import { isEmpty, isNil, isUndefined } from "lodash";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import { useStore } from "../../store";
import { useShallow } from "zustand/react/shallow";
import axios from "axios";
interface IProps {
matches?: unknown;
fetchComicMetadata?: any;
path: string;
covers?: any;
}
/**
* Component to facilitate the import of comics to the ThreeTwo library
*
* @param x - The first input number
* @param y - The second input number
* @returns The arithmetic mean of `x` and `y`
*
* @beta
*/
export const Import = (props: IProps): ReactElement => {
const queryClient = useQueryClient();
const [socketReconnectTrigger, setSocketReconnectTrigger] = useState(0);
const { importJobQueue, getSocket, disconnectSocket } = useStore(
useShallow((state) => ({
importJobQueue: state.importJobQueue,
getSocket: state.getSocket,
disconnectSocket: state.disconnectSocket,
})),
);
const { mutate: initiateImport } = useMutation({
mutationFn: async () => {
const sessionId = localStorage.getItem("sessionId");
return await axios.request({
url: `http://localhost:3000/api/library/newImport`,
method: "POST",
data: { sessionId },
});
},
});
const { data, isError, isLoading, refetch } = useQuery({
queryKey: ["allImportJobResults"],
queryFn: async () => {
const response = await axios({
method: "GET",
url: "http://localhost:3000/api/jobqueue/getJobResultStatistics",
params: { _t: Date.now() }, // Cache busting
});
return response;
},
refetchOnWindowFocus: false,
staleTime: 0, // Always consider data stale
gcTime: 0, // Don't cache the data (formerly cacheTime)
});
// Ensure socket connection is established and listen for import completion
useEffect(() => {
const socket = getSocket("/");
// Listen for import queue drained event to refresh the table
const handleQueueDrained = () => {
refetch();
};
// Listen for individual import completions to refresh the table
const handleCoverExtracted = () => {
refetch();
};
socket.on("LS_IMPORT_QUEUE_DRAINED", handleQueueDrained);
socket.on("LS_COVER_EXTRACTED", handleCoverExtracted);
return () => {
socket.off("LS_IMPORT_QUEUE_DRAINED", handleQueueDrained);
socket.off("LS_COVER_EXTRACTED", handleCoverExtracted);
};
}, [getSocket, refetch, socketReconnectTrigger]);
const toggleQueue = (queueAction: string, queueStatus: string) => {
const socket = getSocket("/");
socket.emit(
"call",
"socket.setQueueStatus",
{
queueAction,
queueStatus,
},
);
};
/**
* Method to render import job queue pause/resume controls on the UI
*
* @param status The `string` status (either `"pause"` or `"resume"`)
* @returns ReactElement A `` that toggles queue status
* @remarks Sets the global `importJobQueue.status` state upon toggling
*/
const renderQueueControls = (status: string): ReactElement | null => {
switch (status) {
case "running":
return (
);
case "paused":
return (
);
case "drained":
return null;
default:
return null;
}
};
return (
Import
Import comics into the ThreeTwo library.
Importing will add comics identified from the mapped folder into
ThreeTwo's database.
Metadata from ComicInfo.xml, if present, will also be extracted.
This process could take a while, if you have a lot of comics, or
are importing over a network connection.
{(importJobQueue.status === "drained" ||
importJobQueue.status === undefined) && (
)}
{/* Activity */}
{(importJobQueue.status === "running" ||
importJobQueue.status === "paused") && (
<>
Import Activity
{/* Successful import counts */}
-
{importJobQueue.successfulJobCount}
-
imported
{/* Failed job counts */}
-
{importJobQueue.failedJobCount}
-
failed
- {renderQueueControls(importJobQueue.status)}
Imported: {importJobQueue.mostRecentImport}
>
)}
{/* Past imports */}
{!isLoading && !isEmpty(data?.data) && (
Past Imports
|
#
|
Time Started
|
Session Id
|
Imported
|
Failed
|
{data?.data.map((jobResult: any, index: number) => {
return (
|
{index + 1}
|
{format(
new Date(jobResult.earliestTimestamp),
"EEEE, hh:mma, do LLLL Y",
)}
|
{jobResult.sessionId}
|
{jobResult.completedJobs}
|
{jobResult.failedJobs}
|
);
})}
)}
);
};
export default Import;