Comicvine integration improvements (#109)

* ️ Refactored VolumeDetail page to use react-query

* 🎨 Added some icons to tabs

* 📚 Wired up story arc fetching

*  Added status checks

* 🍇 Added some integration for issues

* 🔍 Improvements to CV search results

* 🔍 Refining CV search UX

* 🌍 Added i18n lib

* 🔍 CV search metadata wrangling

* 🔧 Refactored Wanted component

Included # of issues in a wanted volume

* 🔧 Refactoring DC++ search/download

* 🔧 Refactored AirDC++ init in store

* 🏗️ Automatic downloads WIP

* 🏗️ Modified the Dockerfile
This commit was merged in pull request #109.
This commit is contained in:
2024-05-11 18:51:28 -04:00
committed by GitHub
parent f57bd35cd4
commit 9ab15df0a8
36 changed files with 1348 additions and 2069 deletions

View File

@@ -3,31 +3,15 @@ import { isNil } from "lodash";
import io from "socket.io-client";
import { SOCKET_BASE_URI } from "../constants/endpoints";
import { produce } from "immer";
import AirDCPPSocket from "../services/DcppSearchService";
import axios from "axios";
import { QueryClient } from "@tanstack/react-query";
/* Broadly, this file sets up:
* 1. The zustand-based global client state
* 2. socket.io client
* 3. AirDC++ websocket connection
*/
export const useStore = create((set, get) => ({
// AirDC++ state
airDCPPSocketInstance: {},
airDCPPSocketConnected: false,
airDCPPDisconnectionInfo: {},
airDCPPClientConfiguration: {},
airDCPPSessionInformation: {},
setAirDCPPSocketConnectionStatus: () =>
set((value) => ({
airDCPPSocketConnected: value,
})),
airDCPPDownloadTick: {},
airDCPPTransfers: {},
// Socket.io state
socketIOInstance: {},
// ComicVine Scraping status
comicvine: {
scrapingStatus: "",
@@ -126,11 +110,12 @@ socketIOInstance.on("RESTORE_JOB_COUNTS_AFTER_SESSION_RESTORATION", (data) => {
// by the LS_COVER_EXTRACTED/LS_COVER_EXTRACTION_FAILED events
socketIOInstance.on("LS_COVER_EXTRACTED", (data) => {
const { completedJobCount, importResult } = data;
console.log(importResult);
setState((state) => ({
importJobQueue: {
...state.importJobQueue,
successfulJobCount: completedJobCount,
mostRecentImport: importResult.rawFileDetails.name,
mostRecentImport: importResult.data.rawFileDetails.name,
},
}));
});
@@ -154,7 +139,6 @@ socketIOInstance.on("LS_IMPORT_QUEUE_DRAINED", (data) => {
status: "drained",
},
}));
console.log("a", queryClient);
queryClient.invalidateQueries({ queryKey: ["allImportJobResults"] });
});
@@ -167,105 +151,3 @@ socketIOInstance.on("CV_SCRAPING_STATUS", (data) => {
},
}));
});
/**
* Method to init AirDC++ Socket with supplied settings
* @param configuration - credentials, and hostname details to init AirDC++ connection
* @returns Initialized AirDC++ connection socket instance
*/
export const initializeAirDCPPSocket = async (configuration): Promise<any> => {
try {
console.log("[AirDCPP]: Initializing socket...");
const initializedAirDCPPSocket = new AirDCPPSocket({
protocol: `${configuration.protocol}`,
hostname: `${configuration.hostname}:${configuration.port}`,
username: `${configuration.username}`,
password: `${configuration.password}`,
});
// Set up connect and disconnect handlers
initializedAirDCPPSocket.onConnected = (sessionInfo) => {
// update global state with socket connection status
setState({
airDCPPSocketConnected: true,
});
};
initializedAirDCPPSocket.onDisconnected = async (
reason,
code,
wasClean,
) => {
// update global state with socket connection status
setState({
disconnectionInfo: { reason, code, wasClean },
airDCPPSocketConnected: false,
});
};
// AirDC++ Socket-related connection and post-connection
// Attempt connection
const airDCPPSessionInformation = await initializedAirDCPPSocket.connect();
setState({
airDCPPSessionInformation,
});
// Set up event listeners
initializedAirDCPPSocket.addListener(
`queue`,
"queue_bundle_tick",
async (downloadProgressData) => {
console.log(downloadProgressData);
setState({
airDCPPDownloadTick: downloadProgressData,
});
},
);
initializedAirDCPPSocket.addListener(
"queue",
"queue_bundle_added",
async (data) => {
console.log("JEMEN:", data);
},
);
initializedAirDCPPSocket.addListener(
`queue`,
"queue_bundle_status",
async (bundleData) => {
let count = 0;
if (bundleData.status.completed && bundleData.status.downloaded) {
// dispatch the action for raw import, with the metadata
if (count < 1) {
console.log(`[AirDCPP]: Download complete.`);
count += 1;
}
}
},
);
return initializedAirDCPPSocket;
} catch (error) {
console.error(error);
}
};
// 1. get settings from mongo
const { data } = await axios({
url: "http://localhost:3000/api/settings/getAllSettings",
method: "GET",
});
const directConnectConfiguration = data?.directConnect?.client.host;
// 2. If available, init AirDC++ Socket with those settings
if (!isNil(directConnectConfiguration)) {
const airDCPPSocketInstance = await initializeAirDCPPSocket(
directConnectConfiguration,
);
setState({
airDCPPSocketInstance,
airDCPPClientConfiguration: directConnectConfiguration,
});
} else {
console.log("problem");
}