From f865feeeb2d5ff08108fbb0336e41483f9f8bd47 Mon Sep 17 00:00:00 2001 From: Rishi Ghan Date: Sun, 10 Jul 2022 21:11:56 -0700 Subject: [PATCH] =?UTF-8?q?=E2=A4=B5=EF=B8=8F=20Downloads=20page=20scaffol?= =?UTF-8?q?d?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/client/actions/airdcpp.actions.tsx | 338 +++++++++--------- src/client/components/App.tsx | 11 + src/client/components/Downloads/Downloads.tsx | 6 +- src/client/stories/MetadataPanel.stories.tsx | 4 +- 4 files changed, 183 insertions(+), 176 deletions(-) diff --git a/src/client/actions/airdcpp.actions.tsx b/src/client/actions/airdcpp.actions.tsx index 6c90e3e..fe6e16a 100644 --- a/src/client/actions/airdcpp.actions.tsx +++ b/src/client/actions/airdcpp.actions.tsx @@ -1,4 +1,3 @@ -import SocketService from "../services/DcppSearchService"; import { SearchQuery, SearchInstance, @@ -34,84 +33,84 @@ function sleep(ms: number): Promise { export const search = (data: SearchData, ADCPPSocket: any, credentials: any) => - async (dispatch) => { - try { - if (!ADCPPSocket.isConnected()) { - await ADCPPSocket.connect( - credentials.username, - credentials.password, - true, - ); - } - const instance: SearchInstance = await ADCPPSocket.post("search"); - dispatch({ - type: AIRDCPP_SEARCH_IN_PROGRESS, - }); - - // We want to get notified about every new result in order to make the user experience better - await ADCPPSocket.addListener( - `search`, - "search_result_added", - async (groupedResult) => { - // ...add the received result in the UI - // (it's probably a good idea to have some kind of throttling for the UI updates as there can be thousands of results) - - dispatch({ - type: AIRDCPP_SEARCH_RESULTS_ADDED, - groupedResult, - }); - }, - instance.id, - ); - - // We also want to update the existing items in our list when new hits arrive for the previously listed files/directories - await ADCPPSocket.addListener( - `search`, - "search_result_updated", - async (groupedResult) => { - // ...update properties of the existing result in the UI - dispatch({ - type: AIRDCPP_SEARCH_RESULTS_UPDATED, - groupedResult, - }); - }, - instance.id, - ); - - // We need to show something to the user in case the search won't yield any results so that he won't be waiting forever) - // Wait for 5 seconds for any results to arrive after the searches were sent to the hubs - await ADCPPSocket.addListener( - `search`, - "search_hub_searches_sent", - async (searchInfo) => { - await sleep(5000); - - // Check the number of received results (in real use cases we should know that even without calling the API) - const currentInstance = await ADCPPSocket.get( - `search/${instance.id}`, + async (dispatch) => { + try { + if (!ADCPPSocket.isConnected()) { + await ADCPPSocket.connect( + credentials.username, + credentials.password, + true, ); - if (currentInstance.result_count === 0) { - // ...nothing was received, show an informative message to the user - console.log("No more search results."); - } + } + const instance: SearchInstance = await ADCPPSocket.post("search"); + dispatch({ + type: AIRDCPP_SEARCH_IN_PROGRESS, + }); - // The search can now be considered to be "complete" - // If there's an "in progress" indicator in the UI, that could also be disabled here - dispatch({ - type: AIRDCPP_HUB_SEARCHES_SENT, - searchInfo, - instance, - }); - }, - instance.id, - ); - // Finally, perform the actual search - await ADCPPSocket.post(`search/${instance.id}/hub_search`, data); - } catch (error) { - console.log(error); - throw error; - } - }; + // We want to get notified about every new result in order to make the user experience better + await ADCPPSocket.addListener( + `search`, + "search_result_added", + async (groupedResult) => { + // ...add the received result in the UI + // (it's probably a good idea to have some kind of throttling for the UI updates as there can be thousands of results) + + dispatch({ + type: AIRDCPP_SEARCH_RESULTS_ADDED, + groupedResult, + }); + }, + instance.id, + ); + + // We also want to update the existing items in our list when new hits arrive for the previously listed files/directories + await ADCPPSocket.addListener( + `search`, + "search_result_updated", + async (groupedResult) => { + // ...update properties of the existing result in the UI + dispatch({ + type: AIRDCPP_SEARCH_RESULTS_UPDATED, + groupedResult, + }); + }, + instance.id, + ); + + // We need to show something to the user in case the search won't yield any results so that he won't be waiting forever) + // Wait for 5 seconds for any results to arrive after the searches were sent to the hubs + await ADCPPSocket.addListener( + `search`, + "search_hub_searches_sent", + async (searchInfo) => { + await sleep(5000); + + // Check the number of received results (in real use cases we should know that even without calling the API) + const currentInstance = await ADCPPSocket.get( + `search/${instance.id}`, + ); + if (currentInstance.result_count === 0) { + // ...nothing was received, show an informative message to the user + console.log("No more search results."); + } + + // The search can now be considered to be "complete" + // If there's an "in progress" indicator in the UI, that could also be disabled here + dispatch({ + type: AIRDCPP_HUB_SEARCHES_SENT, + searchInfo, + instance, + }); + }, + instance.id, + ); + // Finally, perform the actual search + await ADCPPSocket.post(`search/${instance.id}/hub_search`, data); + } catch (error) { + console.log(error); + throw error; + } + }; export const downloadAirDCPPItem = ( @@ -122,113 +121,98 @@ export const downloadAirDCPPItem = ADCPPSocket: any, credentials: any, ): void => - async (dispatch) => { - try { - if (!ADCPPSocket.isConnected()) { - await ADCPPSocket.connect( - `${credentials.username}`, - `${credentials.password}`, - true, - ); - } - console.log(comicObject); - let bundleDBImportResult = {}; - const downloadResult = await ADCPPSocket.post( - `search/${instanceId}/results/${resultId}/download`, - ); - let downloadStatus = undefined; - let count = 0; - // download status check - await ADCPPSocket.addListener(`queue`, "queue_file_status", (status) => { - if (status.status.completed) { - downloadStatus = status; - if (count === 0) { - dispatch({ - type: LS_SINGLE_IMPORT, - meta: { remote: true }, - data: { downloadStatus, comicObjectId, comicObject }, - }); - } - count += 1; + async (dispatch) => { + try { + if (!ADCPPSocket.isConnected()) { + await ADCPPSocket.connect( + `${credentials.username}`, + `${credentials.password}`, + true, + ); } - }); - - let bundleId; - let directoryIds; - if (!isNil(downloadResult.bundle_info)) { - bundleId = downloadResult.bundle_info.id; - } - if (!isNil(downloadResult.directory_download_ids)) { - directoryIds = downloadResult.directory_download_ids.map( - (item) => item.id, + console.log(comicObject); + let bundleDBImportResult = {}; + const downloadResult = await ADCPPSocket.post( + `search/${instanceId}/results/${resultId}/download`, ); + + + let bundleId; + let directoryIds; + if (!isNil(downloadResult.bundle_info)) { + bundleId = downloadResult.bundle_info.id; + } + if (!isNil(downloadResult.directory_download_ids)) { + directoryIds = downloadResult.directory_download_ids.map( + (item) => item.id, + ); + } + if (!isNil(downloadResult)) { + bundleDBImportResult = await axios({ + method: "POST", + url: `${LIBRARY_SERVICE_BASE_URI}/applyAirDCPPDownloadMetadata`, + headers: { + "Content-Type": "application/json; charset=utf-8", + }, + data: { + resultId, + comicObjectId, + searchInstanceId: instanceId, + bundleId, + directoryIds, + }, + }); + dispatch({ + type: AIRDCPP_RESULT_DOWNLOAD_INITIATED, + downloadResult: downloadResult, + bundleDBImportResult, + }); + dispatch({ + type: IMS_COMIC_BOOK_DB_OBJECT_FETCHED, + comicBookDetail: bundleDBImportResult.data, + IMS_inProgress: false, + }); + } + } catch (error) { + throw error; } - if (!isNil(downloadResult)) { - bundleDBImportResult = await axios({ + }; + +export const getBundlesForComic = + (comicObjectId: string, ADCPPSocket: any, credentials: any) => + async (dispatch) => { + try { + if (!ADCPPSocket.isConnected()) { + await ADCPPSocket.connect( + `${credentials.username}`, + `${credentials.password}`, + true, + ); + } + const comicObject = await axios({ method: "POST", - url: `${LIBRARY_SERVICE_BASE_URI}/applyAirDCPPDownloadMetadata`, + url: `${LIBRARY_SERVICE_BASE_URI}/getComicBookById`, headers: { "Content-Type": "application/json; charset=utf-8", }, data: { - resultId, - comicObjectId, - searchInstanceId: instanceId, - bundleId, - directoryIds, + id: `${comicObjectId}`, }, }); - dispatch({ - type: AIRDCPP_RESULT_DOWNLOAD_INITIATED, - downloadResult: downloadResult, - bundleDBImportResult, - }); - dispatch({ - type: IMS_COMIC_BOOK_DB_OBJECT_FETCHED, - comicBookDetail: bundleDBImportResult.data, - IMS_inProgress: false, - }); - } - } catch (error) { - throw error; - } - }; - -export const getBundlesForComic = - (comicObjectId: string, ADCPPSocket: any, credentials: any) => - async (dispatch) => { - try { - if (!ADCPPSocket.isConnected()) { - await ADCPPSocket.connect( - `${credentials.username}`, - `${credentials.password}`, - true, + // get only the bundles applicable for the comic + const filteredBundles = comicObject.data.acquisition.directconnect.map( + async ({ bundleId }) => { + return await ADCPPSocket.get(`queue/bundles/${bundleId}`); + }, ); + dispatch({ + type: AIRDCPP_BUNDLES_FETCHED, + bundles: await Promise.all(filteredBundles), + }); + } catch (error) { + throw error; } - const comicObject = await axios({ - method: "POST", - url: `${LIBRARY_SERVICE_BASE_URI}/getComicBookById`, - headers: { - "Content-Type": "application/json; charset=utf-8", - }, - data: { - id: `${comicObjectId}`, - }, - }); - // get only the bundles applicable for the comic - const filteredBundles = comicObject.data.acquisition.directconnect.map( - async ({ bundleId }) => { - return await ADCPPSocket.get(`queue/bundles/${bundleId}`); - }, - ); - dispatch({ - type: AIRDCPP_BUNDLES_FETCHED, - bundles: await Promise.all(filteredBundles), - }); - } catch (error) { - throw error; - } - }; + }; export const getTransfers = (ADCPPSocket: any, credentials: any) => async (dispatch) => { @@ -242,10 +226,20 @@ export const getTransfers = } const bundles = await ADCPPSocket.get("queue/bundles/1/50", {}); if (!isNil(bundles)) { + dispatch({ type: AIRDCPP_TRANSFERS_FETCHED, bundles, }); + const bundleIds = bundles.map((bundle) => bundle.id); + console.log(bundleIds); + // get issues with matching bundleIds + const issues = await axios({ + url: `${LIBRARY_SERVICE_BASE_URI}/groupIssuesByBundles`, + method: "POST", + data: bundleIds, + }); + } } catch (err) { throw err; diff --git a/src/client/components/App.tsx b/src/client/components/App.tsx index 882b2e3..a50df9c 100644 --- a/src/client/components/App.tsx +++ b/src/client/components/App.tsx @@ -51,12 +51,23 @@ const AirDCPPSocketComponent = (): ReactElement => { }); }, ); + // download complete listener + await airDCPPConfiguration.airDCPPState.socket.addListener( + `transfers`, + "transfer_completed", + async (transferData) => { + console.log(transferData) + }, + ); console.log( "[AirDCPP]: Listener registered - listening to queue bundle download ticks", ); console.log( "[AirDCPP]: Listener registered - listening to queue bundle changes", ); + console.log( + "[AirDCPP]: Listener registered - listening to transfer completion", + ); } }; foo(); diff --git a/src/client/components/Downloads/Downloads.tsx b/src/client/components/Downloads/Downloads.tsx index 81ee1bd..f2d986d 100644 --- a/src/client/components/Downloads/Downloads.tsx +++ b/src/client/components/Downloads/Downloads.tsx @@ -16,7 +16,7 @@ export const Downloads = (props: IDownloadsProps): ReactElement => { } = airDCPPConfiguration; const dispatch = useDispatch(); - const AirDCPPTransfers = useSelector( + const airDCPPTransfers = useSelector( (state: RootState) => state.airdcpp.transfers, ); useEffect(() => { @@ -46,8 +46,10 @@ export const Downloads = (props: IDownloadsProps): ReactElement => { ); } }, [socket]); + + // const getAllDownloads = useCallback(() => {}); - return
{JSON.stringify(AirDCPPTransfers, null, 2)}
; + return
{JSON.stringify(airDCPPTransfers, null, 2)}
; }; export default Downloads; diff --git a/src/client/stories/MetadataPanel.stories.tsx b/src/client/stories/MetadataPanel.stories.tsx index b895e68..d7e1f1c 100644 --- a/src/client/stories/MetadataPanel.stories.tsx +++ b/src/client/stories/MetadataPanel.stories.tsx @@ -16,8 +16,8 @@ export default { //👇 We create a “template” of how args map to rendering const Template = (args) => ; //👇 Each story then reuses that template -export const ComicVine = Template.bind({}); -ComicVine.args = { +export const RawFileDetails = Template.bind({}); +RawFileDetails.args = { data: { "_id": { "$oid": "62bb40c82089f1ea67997e0d" }, "__v": 0,