From 9e5612237b616bcdd8bfd74ce6d120e65c80999d Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Mon, 20 Nov 2023 14:17:55 -0500 Subject: [PATCH] =?UTF-8?q?=F0=9F=8F=97=EF=B8=8F=20Refactoring=20Acquisiti?= =?UTF-8?q?onPanel?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ComicDetail/AcquisitionPanel.tsx | 40 ++++-- .../AirDCPPSettings/AirDCPPHubsForm.tsx | 92 ++++++++---- .../AirDCPPSettings/AirDCPPSettingsForm.tsx | 34 +++-- src/client/components/Settings/Settings.tsx | 6 +- src/client/components/shared/Navbar.tsx | 15 +- src/client/store/index.ts | 133 ++++++++++-------- 6 files changed, 201 insertions(+), 119 deletions(-) diff --git a/src/client/components/ComicDetail/AcquisitionPanel.tsx b/src/client/components/ComicDetail/AcquisitionPanel.tsx index 27d3d0c..3e1f7f5 100644 --- a/src/client/components/ComicDetail/AcquisitionPanel.tsx +++ b/src/client/components/ComicDetail/AcquisitionPanel.tsx @@ -14,6 +14,8 @@ import { RootState, SearchInstance } from "threetwo-ui-typings"; import ellipsize from "ellipsize"; import { Form, Field } from "react-final-form"; import { isEmpty, isNil, map } from "lodash"; +import { useStore } from "../../store"; +import { useShallow } from "zustand/react/shallow"; interface IAcquisitionPanelProps { query: any; @@ -25,26 +27,38 @@ interface IAcquisitionPanelProps { export const AcquisitionPanel = ( props: IAcquisitionPanelProps, ): ReactElement => { + const { + airDCPPSocketInstance, + airDCPPClientConfiguration, + airDCPPSessionInformation, + } = useStore( + useShallow((state) => ({ + airDCPPSocketInstance: state.airDCPPSocketInstance, + airDCPPClientConfiguration: state.airDCPPClientConfiguration, + airDCPPSessionInformation: state.airDCPPSessionInformation, + })), + ); + console.log("ulhas umlaut", airDCPPSessionInformation); const issueName = props.query.issue.name || ""; // const { settings } = props; const sanitizedIssueName = issueName.replace(/[^a-zA-Z0-9 ]/g, " "); // Selectors for picking state - const airDCPPSearchResults = useSelector((state: RootState) => { - return state.airdcpp.searchResults; - }); - const isAirDCPPSearchInProgress = useSelector( - (state: RootState) => state.airdcpp.isAirDCPPSearchInProgress, - ); - const searchInfo = useSelector( - (state: RootState) => state.airdcpp.searchInfo, - ); - const searchInstance: SearchInstance = useSelector( - (state: RootState) => state.airdcpp.searchInstance, - ); + // const airDCPPSearchResults = useSelector((state: RootState) => { + // return state.airdcpp.searchResults; + // }); + // const isAirDCPPSearchInProgress = useSelector( + // (state: RootState) => state.airdcpp.isAirDCPPSearchInProgress, + // ); + // const searchInfo = useSelector( + // (state: RootState) => state.airdcpp.searchInfo, + // ); + // const searchInstance: SearchInstance = useSelector( + // (state: RootState) => state.airdcpp.searchInstance, + // ); // const settings = useSelector((state: RootState) => state.settings.data); - const airDCPPConfiguration = useContext(AirDCPPSocketContext); + // const airDCPPConfiguration = useContext(AirDCPPSocketContext); const [dcppQuery, setDcppQuery] = useState({}); diff --git a/src/client/components/Settings/AirDCPPSettings/AirDCPPHubsForm.tsx b/src/client/components/Settings/AirDCPPSettings/AirDCPPHubsForm.tsx index c2a88bf..0524f95 100644 --- a/src/client/components/Settings/AirDCPPSettings/AirDCPPHubsForm.tsx +++ b/src/client/components/Settings/AirDCPPSettings/AirDCPPHubsForm.tsx @@ -1,38 +1,67 @@ import React, { ReactElement, useEffect, useState, useContext } from "react"; import { Form, Field } from "react-final-form"; -import { useDispatch } from "react-redux"; import { isEmpty, isNil, isUndefined } from "lodash"; import Select from "react-select"; import { saveSettings } from "../../../actions/settings.actions"; -import { AirDCPPSocketContext } from "../../../context/AirDCPPSocket"; +import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query"; +import { useStore } from "../../../store"; +import { useShallow } from "zustand/react/shallow"; +import axios from "axios"; export const AirDCPPHubsForm = (airDCPPClientUserSettings): ReactElement => { - const dispatch = useDispatch(); - const [hubList, setHubList] = useState([]); - const airDCPPConfiguration = useContext(AirDCPPSocketContext); + const queryClient = useQueryClient(); const { - airDCPPState: { settings, socket }, - } = airDCPPConfiguration; + airDCPPSocketInstance, + airDCPPClientConfiguration, + airDCPPSessionInformation, + } = useStore( + useShallow((state) => ({ + airDCPPSocketInstance: state.airDCPPSocketInstance, + airDCPPClientConfiguration: state.airDCPPClientConfiguration, + airDCPPSessionInformation: state.airDCPPSessionInformation, + })), + ); - useEffect(() => { - (async () => { - if (!isEmpty(settings)) { - const hubs = await socket.get(`hubs`); - const hubSelectionOptions = hubs.map(({ hub_url, identity }) => ({ - value: hub_url, - label: identity.name, - })); + const { data, isLoading, isError } = useQuery({ + queryKey: ["settings"], + queryFn: async () => + await axios({ + url: "http://localhost:3000/api/settings/getAllSettings", + method: "GET", + }), + }); - setHubList(hubSelectionOptions); - } - })(); - }, []); + console.log("Asd", data); + const { + settings: { + data: { directConnect }, + }, + } = data; - const onSubmit = (values) => { - if (!isUndefined(values.hubs)) { - dispatch(saveSettings({ ...settings, hubs: values.hubs }, settings._id)); - } - }; + const { data: hubs } = useQuery({ + queryKey: [], + queryFn: async () => await airDCPPSocketInstance.get(`hubs`), + enabled: !!settings, + }); + let hubList = {}; + if (hubs) { + hubList = hubs.map(({ hub_url, identity }) => ({ + value: hub_url, + label: identity.name, + })); + } + + const { mutate } = useMutation({ + mutationFn: async (values) => + await axios({ + url: `http://localhost:3000/api/settings/saveSettings`, + method: "POST", + data: { settingsPayload: values, settingsKey: "directConnect" }, + }), + onSuccess: () => { + queryClient.invalidateQueries({ queryKey: ["settings"] }); + }, + }); const validate = async () => {}; @@ -43,7 +72,7 @@ export const AirDCPPHubsForm = (airDCPPClientUserSettings): ReactElement => { return ( <>
( @@ -82,12 +111,13 @@ export const AirDCPPHubsForm = (airDCPPClientUserSettings): ReactElement => {
Selected hubs
- {settings.directConnect.client.hubs.map(({ value, label }) => ( -
-
{label}
- {value} -
- ))} + {settings && + settings?.directConnect?.client.hubs.map(({ value, label }) => ( +
+
{label}
+ {value} +
+ ))}
); diff --git a/src/client/components/Settings/AirDCPPSettings/AirDCPPSettingsForm.tsx b/src/client/components/Settings/AirDCPPSettings/AirDCPPSettingsForm.tsx index b6aa8fd..9cd5786 100644 --- a/src/client/components/Settings/AirDCPPSettings/AirDCPPSettingsForm.tsx +++ b/src/client/components/Settings/AirDCPPSettings/AirDCPPSettingsForm.tsx @@ -2,8 +2,10 @@ import React, { ReactElement, useCallback } from "react"; import { AirDCPPSettingsConfirmation } from "./AirDCPPSettingsConfirmation"; import { isUndefined, isEmpty } from "lodash"; import { ConnectionForm } from "../../shared/ConnectionForm/ConnectionForm"; -import { useStore } from "../../../store/index"; +import { initializeAirDCPPSocket, useStore } from "../../../store/index"; import { useShallow } from "zustand/react/shallow"; +import { useMutation } from "@tanstack/react-query"; +import axios from "axios"; export const AirDCPPSettingsForm = (): ReactElement => { // cherry-picking selectors for: @@ -24,13 +26,27 @@ export const AirDCPPSettingsForm = (): ReactElement => { airDCPPSocketInstance: state.airDCPPSocketInstance, })), ); - const onSubmit = useCallback(async (values) => { - try { - // airDCPPSettings.setSettings(values); - } catch (error) { - console.log(error); - } - }, []); + + const { mutate } = useMutation({ + mutationFn: async (values) => + await axios({ + url: `http://localhost:3000/api/settings/saveSettings`, + method: "POST", + data: { settingsPayload: values, settingsKey: "directConnect" }, + }), + onSuccess: (values) => { + const { + data: { + directConnect: { + client: { host }, + }, + }, + } = values; + console.log("asdas", host); + initializeAirDCPPSocket(host); + }, + }); + const removeSettings = useCallback(async () => { // airDCPPSettings.setSettings({}); }, []); @@ -43,7 +59,7 @@ export const AirDCPPSettingsForm = (): ReactElement => { <> diff --git a/src/client/components/Settings/Settings.tsx b/src/client/components/Settings/Settings.tsx index 7821155..d6d19d0 100644 --- a/src/client/components/Settings/Settings.tsx +++ b/src/client/components/Settings/Settings.tsx @@ -14,7 +14,11 @@ export const Settings = (props: ISettingsProps): ReactElement => { const settingsContent = [ { id: "adc-hubs", - content:
{/* */}
, + content: ( +
+ +
+ ), }, { id: "adc-connection", diff --git a/src/client/components/shared/Navbar.tsx b/src/client/components/shared/Navbar.tsx index 0763f1f..f167063 100644 --- a/src/client/components/shared/Navbar.tsx +++ b/src/client/components/shared/Navbar.tsx @@ -2,7 +2,7 @@ import React from "react"; import { SearchBar } from "../GlobalSearchBar/SearchBar"; import { DownloadProgressTick } from "../ComicDetail/DownloadProgressTick"; import { Link } from "react-router-dom"; -import { isEmpty, isUndefined } from "lodash"; +import { isEmpty, isNil, isUndefined } from "lodash"; import { format, fromUnixTime } from "date-fns"; import { useStore } from "../../store/index"; import { useShallow } from "zustand/react/shallow"; @@ -23,6 +23,7 @@ const Navbar: React.FunctionComponent = (props) => { importJobQueue: state.importJobQueue, })), ); + console.log(airDCPPSessionInformation); // const downloadProgressTick = useSelector( // (state: RootState) => state.airdcpp.downloadProgressData, // ); @@ -146,7 +147,7 @@ const Navbar: React.FunctionComponent = (props) => { {/* AirDC++ socket connection status */}
- {airDCPPSocketConnected ? ( + {!isUndefined(airDCPPSessionInformation.user) ? ( <> @@ -158,7 +159,9 @@ const Navbar: React.FunctionComponent = (props) => { Last login was{" "} {format( - fromUnixTime(airDCPPSessionInformation.user.last_login), + fromUnixTime( + airDCPPSessionInformation?.user.last_login, + ), "dd MMMM, yyyy", )} @@ -178,7 +181,11 @@ const Navbar: React.FunctionComponent = (props) => {

- {/*
{JSON.stringify(airDCPPSessionInfo, null, 2)}
*/} + { +
+                      {JSON.stringify(airDCPPSessionInformation, null, 2)}
+                    
+ }
) : ( diff --git a/src/client/store/index.ts b/src/client/store/index.ts index f9b4970..f57ef08 100644 --- a/src/client/store/index.ts +++ b/src/client/store/index.ts @@ -69,7 +69,7 @@ export const useStore = create((set, get) => ({ const { getState, setState } = useStore; -// Socket.IO initialization +/** Socket.IO initialization **/ // 1. Fetch sessionId from localStorage const sessionId = localStorage.getItem("sessionId"); // 2. socket.io instantiation @@ -119,72 +119,81 @@ socketIOInstance.on("RESTORE_JOB_COUNTS_AFTER_SESSION_RESTORATION", (data) => { * @param configuration - credentials, and hostname details to init AirDC++ connection * @returns Initialized AirDC++ connection socket instance */ -const initializeAirDCPPSocket = async (configuration): Promise => { - console.log("[AirDCPP]: Initializing socket..."); +export const initializeAirDCPPSocket = async (configuration): Promise => { + 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, + const initializedAirDCPPSocket = new AirDCPPSocket({ + protocol: `${configuration.protocol}`, + hostname: `${configuration.hostname}:${configuration.port}`, + username: `${configuration.username}`, + password: `${configuration.password}`, }); - }; - 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); + // Set up connect and disconnect handlers + initializedAirDCPPSocket.onConnected = (sessionInfo) => { + // update global state with socket connection status setState({ - airDCPPDownloadTick: downloadProgressData, + airDCPPSocketConnected: true, }); - }, - ); - initializedAirDCPPSocket.addListener( - "queue", - "queue_bundle_added", - async (data) => { - console.log("JEMEN:", data); - }, - ); + }; + 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(); + console.log("zondhale", airDCPPSessionInformation); + setState({ + airDCPPSessionInformation, + }); - 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.`); + // 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); + }, + ); - count += 1; + 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; + }, + ); + return initializedAirDCPPSocket; + } catch (error) { + console.error(error); + } }; // 1. get settings from mongo @@ -193,10 +202,10 @@ const { data } = await axios({ method: "GET", }); -const directConnectConfiguration = data?.directConnect.client.host; +const directConnectConfiguration = data?.directConnect?.client.host; // 2. If available, init AirDC++ Socket with those settings -if (!isEmpty(directConnectConfiguration)) { +if (!isEmpty(data)) { const airDCPPSocketInstance = await initializeAirDCPPSocket( directConnectConfiguration, ); @@ -204,6 +213,8 @@ if (!isEmpty(directConnectConfiguration)) { airDCPPSocketInstance, airDCPPClientConfiguration: directConnectConfiguration, }); +} else { + console.log("problem"); } console.log("connected?", getState());