Compare commits
28 Commits
comic-deta
...
zustand-re
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ff53f1e21 | |||
| 063bee98cf | |||
| 70debabb53 | |||
| 96890ad1e4 | |||
| c3573e67e2 | |||
| 4650bedbcf | |||
| 9859dbdeab | |||
| eb399f08e0 | |||
| f9afc5a249 | |||
| 9e5612237b | |||
| 21a5a6028e | |||
| be67348d20 | |||
| 4d2d7da5b4 | |||
| 199ddc2859 | |||
| 3699ca8b2a | |||
| b1d63b02c4 | |||
| 15cba6d56a | |||
| 7e304b2b96 | |||
| 794fd9b3a0 | |||
| be51f9b8f2 | |||
| 8f9bc9dc84 | |||
| 19a1532f06 | |||
| 2dcaca425d | |||
| 214f29f9a8 | |||
| 18d2624d6c | |||
| 936945138f | |||
| 580307a39b | |||
| 74a9c4bdb0 |
22
index.html
22
index.html
@@ -1,14 +1,16 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en" data-theme="dark">
|
<html lang="en">
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8" />
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
|
|
||||||
<title>Three Two!</title>
|
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<title>Three Two!</title>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
<div id="root"></div>
|
<div id="root"></div>
|
||||||
<script type="module" src="/src/client/index.tsx"></script>
|
<script type="module" src="/src/client/index.tsx"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
@@ -31,7 +31,6 @@
|
|||||||
"axios-cache-interceptor": "^1.0.1",
|
"axios-cache-interceptor": "^1.0.1",
|
||||||
"axios-rate-limit": "^1.3.0",
|
"axios-rate-limit": "^1.3.0",
|
||||||
"babel-plugin-styled-components": "^2.1.4",
|
"babel-plugin-styled-components": "^2.1.4",
|
||||||
"bulma-prefers-dark": "^0.1.0-beta.1",
|
|
||||||
"date-fns": "^2.28.0",
|
"date-fns": "^2.28.0",
|
||||||
"dayjs": "^1.10.6",
|
"dayjs": "^1.10.6",
|
||||||
"ellipsize": "^0.5.1",
|
"ellipsize": "^0.5.1",
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
@import "/node_modules/bulma/bulma.sass";
|
@import "/node_modules/bulma/bulma.sass";
|
||||||
@import "/node_modules/bulma-prefers-dark/bulma-prefers-dark.sass";
|
|
||||||
$fa-font-path: "/node_modules/@fortawesome/fontawesome-free/webfonts";
|
$fa-font-path: "/node_modules/@fortawesome/fontawesome-free/webfonts";
|
||||||
@import "/node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss";
|
@import "/node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss";
|
||||||
@import "/node_modules/@fortawesome/fontawesome-free/scss/regular.scss";
|
@import "/node_modules/@fortawesome/fontawesome-free/scss/regular.scss";
|
||||||
@@ -15,9 +14,8 @@ $flexSize: 4em;
|
|||||||
$boxSpacing: 1em;
|
$boxSpacing: 1em;
|
||||||
$colorText: #404646;
|
$colorText: #404646;
|
||||||
body {
|
body {
|
||||||
background: #20292f;
|
background: #fffcc;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-size-8 {
|
.is-size-8 {
|
||||||
font-size: $size-8;
|
font-size: $size-8;
|
||||||
}
|
}
|
||||||
@@ -74,6 +72,10 @@ pre {
|
|||||||
background: #454a59;
|
background: #454a59;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background: #454a59;
|
||||||
|
}
|
||||||
|
|
||||||
.pulsating-circle {
|
.pulsating-circle {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: -120%;
|
left: -120%;
|
||||||
@@ -242,16 +244,12 @@ pre {
|
|||||||
|
|
||||||
.generic-card {
|
.generic-card {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
background-color: hsl(232, 11%, 15%);
|
background-color: #fff;
|
||||||
border-top-left-radius: 0.4rem;
|
border-top-left-radius: 0.4rem;
|
||||||
border-top-right-radius: 0.4rem;
|
border-top-right-radius: 0.4rem;
|
||||||
border-bottom-left-radius: 0.4rem;
|
border-bottom-left-radius: 0.4rem;
|
||||||
border-bottom-right-radius: 0.4rem;
|
border-bottom-right-radius: 0.4rem;
|
||||||
box-shadow: inset 0 0 0.5px 1px hsla(0, 0%, 100%, 0.1),
|
box-shadow: 1px 8px 23px 7px rgba(0, 0, 0, 0.12);
|
||||||
/* 2. shadow ring 👇 */ 0 0 0 1px hsla(230, 13%, 9%, 0.075),
|
|
||||||
/* 3. multiple soft shadows 👇 */ 0 0.3px 0.4px hsla(230, 13%, 9%, 0.02),
|
|
||||||
0 0.9px 1.5px hsla(230, 13%, 9%, 0.045),
|
|
||||||
0 3.5px 6px hsla(230, 13%, 9%, 0.09);
|
|
||||||
|
|
||||||
.green-border {
|
.green-border {
|
||||||
border: 1px dotted #168b64;
|
border: 1px dotted #168b64;
|
||||||
@@ -360,7 +358,7 @@ pre {
|
|||||||
// raw file details
|
// raw file details
|
||||||
.raw-file-details {
|
.raw-file-details {
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
background: #30475e;
|
background-color: beige;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -370,23 +368,23 @@ pre {
|
|||||||
|
|
||||||
// comicvine metadata
|
// comicvine metadata
|
||||||
.comicvine-metadata {
|
.comicvine-metadata {
|
||||||
background-color: #d6cc99;
|
background-color: #f2f1f9;
|
||||||
padding: 0.8rem;
|
padding: 0.8rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.issue-metadata {
|
.issue-metadata {
|
||||||
background-color: #57615c;
|
background-color: #fbffee;
|
||||||
padding: 0.8em;
|
padding: 0.8em;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
.name {
|
.name {
|
||||||
font-size: 0.95rem;
|
font-size: 0.95rem;
|
||||||
|
color: #4a4f50;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.comicInfo-metadata {
|
.comicInfo-metadata {
|
||||||
background-color: #d6cc99;
|
background-color: #f7ebdd;
|
||||||
color: #000;
|
|
||||||
padding: 0.8rem;
|
padding: 0.8rem;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
@@ -423,17 +421,17 @@ pre {
|
|||||||
}
|
}
|
||||||
// Library
|
// Library
|
||||||
.header-area {
|
.header-area {
|
||||||
background: #20292f;
|
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 25px 0 15px 0;
|
padding: 25px 0 15px 0;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
z-index: 9;
|
z-index: 9999;
|
||||||
top: 57px;
|
background: #fffffc;
|
||||||
|
top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.library {
|
.library {
|
||||||
.table-controls {
|
.table-controls {
|
||||||
background: #20292f;
|
background: #fffffc;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 126px;
|
top: 126px;
|
||||||
@@ -441,17 +439,17 @@ pre {
|
|||||||
}
|
}
|
||||||
.pagination {
|
.pagination {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
background: #fffffc;
|
||||||
}
|
}
|
||||||
|
|
||||||
table {
|
table {
|
||||||
background: #20292f;
|
|
||||||
border-collapse: separate;
|
border-collapse: separate;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
thead {
|
thead {
|
||||||
background: #20292f;
|
|
||||||
position: sticky;
|
position: sticky;
|
||||||
top: 250px;
|
top: 250px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
|
background: #fffffc;
|
||||||
min-height: 130px;
|
min-height: 130px;
|
||||||
}
|
}
|
||||||
tr {
|
tr {
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import React, { useCallback, ReactElement, useEffect, useState } from "react";
|
import React, { useCallback, ReactElement, useEffect, useState } from "react";
|
||||||
import { getBundlesForComic, sleep } from "../../actions/airdcpp.actions";
|
import {
|
||||||
|
downloadAirDCPPItem,
|
||||||
|
getBundlesForComic,
|
||||||
|
sleep,
|
||||||
|
} from "../../actions/airdcpp.actions";
|
||||||
import { SearchQuery, PriorityEnum, SearchResponse } from "threetwo-ui-typings";
|
import { SearchQuery, PriorityEnum, SearchResponse } from "threetwo-ui-typings";
|
||||||
import { RootState, SearchInstance } from "threetwo-ui-typings";
|
import { RootState, SearchInstance } from "threetwo-ui-typings";
|
||||||
import ellipsize from "ellipsize";
|
import ellipsize from "ellipsize";
|
||||||
@@ -9,7 +13,6 @@ import { isEmpty, isNil, map } from "lodash";
|
|||||||
import { useStore } from "../../store";
|
import { useStore } from "../../store";
|
||||||
import { useShallow } from "zustand/react/shallow";
|
import { useShallow } from "zustand/react/shallow";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
interface IAcquisitionPanelProps {
|
interface IAcquisitionPanelProps {
|
||||||
query: any;
|
query: any;
|
||||||
@@ -25,22 +28,14 @@ export const AcquisitionPanel = (
|
|||||||
airDCPPSocketInstance,
|
airDCPPSocketInstance,
|
||||||
airDCPPClientConfiguration,
|
airDCPPClientConfiguration,
|
||||||
airDCPPSessionInformation,
|
airDCPPSessionInformation,
|
||||||
airDCPPDownloadTick,
|
|
||||||
} = useStore(
|
} = useStore(
|
||||||
useShallow((state) => ({
|
useShallow((state) => ({
|
||||||
airDCPPSocketInstance: state.airDCPPSocketInstance,
|
airDCPPSocketInstance: state.airDCPPSocketInstance,
|
||||||
airDCPPClientConfiguration: state.airDCPPClientConfiguration,
|
airDCPPClientConfiguration: state.airDCPPClientConfiguration,
|
||||||
airDCPPSessionInformation: state.airDCPPSessionInformation,
|
airDCPPSessionInformation: state.airDCPPSessionInformation,
|
||||||
airDCPPDownloadTick: state.airDCPPDownloadTick,
|
|
||||||
})),
|
})),
|
||||||
);
|
);
|
||||||
|
|
||||||
interface SearchData {
|
|
||||||
query: Pick<SearchQuery, "pattern"> & Partial<Omit<SearchQuery, "pattern">>;
|
|
||||||
hub_urls: string[] | undefined | null;
|
|
||||||
priority: PriorityEnum;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the hubs list from an AirDCPP Socket
|
* Get the hubs list from an AirDCPP Socket
|
||||||
*/
|
*/
|
||||||
@@ -48,15 +43,34 @@ export const AcquisitionPanel = (
|
|||||||
queryKey: ["hubs"],
|
queryKey: ["hubs"],
|
||||||
queryFn: async () => await airDCPPSocketInstance.get(`hubs`),
|
queryFn: async () => await airDCPPSocketInstance.get(`hubs`),
|
||||||
});
|
});
|
||||||
const { comicObjectId } = props;
|
|
||||||
const issueName = props.query.issue.name || "";
|
const issueName = props.query.issue.name || "";
|
||||||
|
// const { settings } = props;
|
||||||
const sanitizedIssueName = issueName.replace(/[^a-zA-Z0-9 ]/g, " ");
|
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 settings = useSelector((state: RootState) => state.settings.data);
|
||||||
|
// const airDCPPConfiguration = useContext(AirDCPPSocketContext);
|
||||||
|
interface SearchData {
|
||||||
|
query: Pick<SearchQuery, "pattern"> & Partial<Omit<SearchQuery, "pattern">>;
|
||||||
|
hub_urls: string[] | undefined | null;
|
||||||
|
priority: PriorityEnum;
|
||||||
|
}
|
||||||
const [dcppQuery, setDcppQuery] = useState({});
|
const [dcppQuery, setDcppQuery] = useState({});
|
||||||
const [airDCPPSearchResults, setAirDCPPSearchResults] = useState([]);
|
const [airDCPPSearchResults, setAirDCPPSearchResults] = useState([]);
|
||||||
const [airDCPPSearchStatus, setAirDCPPSearchStatus] = useState(false);
|
|
||||||
const [airDCPPSearchInstance, setAirDCPPSearchInstance] = useState({});
|
|
||||||
const [airDCPPSearchInfo, setAirDCPPSearchInfo] = useState({});
|
|
||||||
|
|
||||||
// Construct a AirDC++ query based on metadata inferred, upon component mount
|
// Construct a AirDC++ query based on metadata inferred, upon component mount
|
||||||
// Pre-populate the search input with the search string, so that
|
// Pre-populate the search input with the search string, so that
|
||||||
@@ -74,18 +88,15 @@ export const AcquisitionPanel = (
|
|||||||
setDcppQuery(dcppSearchQuery);
|
setDcppQuery(dcppSearchQuery);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to perform a search via an AirDC++ websocket
|
|
||||||
* @param {SearchData} data - a SearchData query
|
|
||||||
* @param {any} ADCPPSocket - an intialized AirDC++ socket instance
|
|
||||||
*/
|
|
||||||
const search = async (data: SearchData, ADCPPSocket: any) => {
|
const search = async (data: SearchData, ADCPPSocket: any) => {
|
||||||
try {
|
try {
|
||||||
if (!ADCPPSocket.isConnected()) {
|
if (!ADCPPSocket.isConnected()) {
|
||||||
await ADCPPSocket();
|
await ADCPPSocket();
|
||||||
}
|
}
|
||||||
const instance: SearchInstance = await ADCPPSocket.post("search");
|
const instance: SearchInstance = await ADCPPSocket.post("search");
|
||||||
setAirDCPPSearchStatus(true);
|
// dispatch({
|
||||||
|
// type: AIRDCPP_SEARCH_IN_PROGRESS,
|
||||||
|
// });
|
||||||
|
|
||||||
// We want to get notified about every new result in order to make the user experience better
|
// We want to get notified about every new result in order to make the user experience better
|
||||||
await ADCPPSocket.addListener(
|
await ADCPPSocket.addListener(
|
||||||
@@ -131,9 +142,6 @@ export const AcquisitionPanel = (
|
|||||||
const currentInstance = await ADCPPSocket.get(
|
const currentInstance = await ADCPPSocket.get(
|
||||||
`search/${instance.id}`,
|
`search/${instance.id}`,
|
||||||
);
|
);
|
||||||
setAirDCPPSearchInstance(currentInstance);
|
|
||||||
setAirDCPPSearchInfo(searchInfo);
|
|
||||||
console.log("Asdas", airDCPPSearchInfo);
|
|
||||||
if (currentInstance.result_count === 0) {
|
if (currentInstance.result_count === 0) {
|
||||||
// ...nothing was received, show an informative message to the user
|
// ...nothing was received, show an informative message to the user
|
||||||
console.log("No more search results.");
|
console.log("No more search results.");
|
||||||
@@ -141,8 +149,11 @@ export const AcquisitionPanel = (
|
|||||||
|
|
||||||
// The search can now be considered to be "complete"
|
// 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
|
// If there's an "in progress" indicator in the UI, that could also be disabled here
|
||||||
setAirDCPPSearchInstance(instance);
|
// dispatch({
|
||||||
setAirDCPPSearchStatus(false);
|
// type: AIRDCPP_HUB_SEARCHES_SENT,
|
||||||
|
// searchInfo,
|
||||||
|
// instance,
|
||||||
|
// });
|
||||||
},
|
},
|
||||||
instance.id,
|
instance.id,
|
||||||
);
|
);
|
||||||
@@ -153,68 +164,6 @@ export const AcquisitionPanel = (
|
|||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Method to download a bundle associated with a search result from AirDC++
|
|
||||||
* @param {Number} searchInstanceId - description
|
|
||||||
* @param {String} resultId - description
|
|
||||||
* @param {String} comicObjectId - description
|
|
||||||
* @param {String} name - description
|
|
||||||
* @param {Number} size - description
|
|
||||||
* @param {any} type - description
|
|
||||||
* @param {any} ADCPPSocket - description
|
|
||||||
* @returns {void} - description
|
|
||||||
*/
|
|
||||||
const download = async (
|
|
||||||
searchInstanceId: Number,
|
|
||||||
resultId: String,
|
|
||||||
comicObjectId: String,
|
|
||||||
name: String,
|
|
||||||
size: Number,
|
|
||||||
type: any,
|
|
||||||
ADCPPSocket: any,
|
|
||||||
): void => {
|
|
||||||
try {
|
|
||||||
if (!ADCPPSocket.isConnected()) {
|
|
||||||
await ADCPPSocket.connect();
|
|
||||||
}
|
|
||||||
let bundleDBImportResult = {};
|
|
||||||
const downloadResult = await ADCPPSocket.post(
|
|
||||||
`search/${searchInstanceId}/results/${resultId}/download`,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!isNil(downloadResult)) {
|
|
||||||
bundleDBImportResult = await axios({
|
|
||||||
method: "POST",
|
|
||||||
url: `http://localhost:3000/api/library/applyAirDCPPDownloadMetadata`,
|
|
||||||
headers: {
|
|
||||||
"Content-Type": "application/json; charset=utf-8",
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
bundleId: downloadResult.bundle_info.id,
|
|
||||||
comicObjectId,
|
|
||||||
name,
|
|
||||||
size,
|
|
||||||
type,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
// dispatch({
|
|
||||||
// type: AIRDCPP_RESULT_DOWNLOAD_INITIATED,
|
|
||||||
// downloadResult,
|
|
||||||
// bundleDBImportResult,
|
|
||||||
// });
|
|
||||||
//
|
|
||||||
// dispatch({
|
|
||||||
// type: IMS_COMIC_BOOK_DB_OBJECT_FETCHED,
|
|
||||||
// comicBookDetail: bundleDBImportResult.data,
|
|
||||||
// IMS_inProgress: false,
|
|
||||||
// });
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
throw error;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const getDCPPSearchResults = async (searchQuery) => {
|
const getDCPPSearchResults = async (searchQuery) => {
|
||||||
const manualQuery = {
|
const manualQuery = {
|
||||||
query: {
|
query: {
|
||||||
@@ -260,6 +209,7 @@ export const AcquisitionPanel = (
|
|||||||
},
|
},
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
console.log("yaman", airDCPPSearchResults);
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="comic-detail columns">
|
<div className="comic-detail columns">
|
||||||
@@ -295,7 +245,7 @@ export const AcquisitionPanel = (
|
|||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
className={
|
className={
|
||||||
airDCPPSearchStatus
|
false
|
||||||
? "button is-loading is-warning"
|
? "button is-loading is-warning"
|
||||||
: "button is-success is-light"
|
: "button is-success is-light"
|
||||||
}
|
}
|
||||||
@@ -323,60 +273,6 @@ export const AcquisitionPanel = (
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* AirDC++ search instance details */}
|
|
||||||
{!isNil(airDCPPSearchInstance) &&
|
|
||||||
!isEmpty(airDCPPSearchInfo) &&
|
|
||||||
!isNil(hubs) && (
|
|
||||||
<div className="columns">
|
|
||||||
<div className="column is-one-quarter is-size-7">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-content">
|
|
||||||
<dl>
|
|
||||||
<dt>
|
|
||||||
<div className="tags mb-1">
|
|
||||||
{hubs.map((value, idx) => (
|
|
||||||
<span className="tag is-warning" key={idx}>
|
|
||||||
{value.identity.name}
|
|
||||||
</span>
|
|
||||||
))}
|
|
||||||
</div>
|
|
||||||
</dt>
|
|
||||||
<dt>
|
|
||||||
Query:
|
|
||||||
<span className="has-text-weight-semibold">
|
|
||||||
{airDCPPSearchInfo.query.pattern}
|
|
||||||
</span>
|
|
||||||
</dt>
|
|
||||||
<dd>
|
|
||||||
Extensions:
|
|
||||||
<span className="has-text-weight-semibold">
|
|
||||||
{airDCPPSearchInfo.query.extensions.join(", ")}
|
|
||||||
</span>
|
|
||||||
</dd>
|
|
||||||
<dd>
|
|
||||||
File type:
|
|
||||||
<span className="has-text-weight-semibold">
|
|
||||||
{airDCPPSearchInfo.query.file_type}
|
|
||||||
</span>
|
|
||||||
</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="column is-one-quarter is-size-7">
|
|
||||||
<div className="card">
|
|
||||||
<div className="card-content">
|
|
||||||
<dl>
|
|
||||||
<dt>Search Instance: {airDCPPSearchInstance.id}</dt>
|
|
||||||
<dt>Owned by {airDCPPSearchInstance.owner}</dt>
|
|
||||||
<dd>Expires in: {airDCPPSearchInstance.expires_in}</dd>
|
|
||||||
</dl>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* AirDC++ results */}
|
{/* AirDC++ results */}
|
||||||
<div className="columns">
|
<div className="columns">
|
||||||
{!isNil(airDCPPSearchResults) && !isEmpty(airDCPPSearchResults) ? (
|
{!isNil(airDCPPSearchResults) && !isEmpty(airDCPPSearchResults) ? (
|
||||||
@@ -446,14 +342,12 @@ export const AcquisitionPanel = (
|
|||||||
<button
|
<button
|
||||||
className="button is-small is-light is-success"
|
className="button is-small is-light is-success"
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
download(
|
downloadDCPPResult(
|
||||||
airDCPPSearchInstance.id,
|
searchInstance.id,
|
||||||
result.id,
|
result.id,
|
||||||
comicObjectId,
|
|
||||||
result.name,
|
result.name,
|
||||||
result.size,
|
result.size,
|
||||||
result.type,
|
result.type,
|
||||||
airDCPPSocketInstance,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -69,29 +69,17 @@ export const Menu = (props): ReactElement => {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const customStyles = {
|
|
||||||
option: (base, { data, isDisabled, isFocused, isSelected }) => {
|
|
||||||
return {
|
|
||||||
...base,
|
|
||||||
backgroundColor: isFocused ? "gray" : "black",
|
|
||||||
};
|
|
||||||
},
|
|
||||||
control: (base) => ({
|
|
||||||
...base,
|
|
||||||
backgroundColor: "black",
|
|
||||||
border: "1px solid #CCC",
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Select
|
<Select
|
||||||
|
className="basic-single"
|
||||||
|
classNamePrefix="select"
|
||||||
components={{ Placeholder }}
|
components={{ Placeholder }}
|
||||||
placeholder={
|
placeholder={
|
||||||
<span>
|
<span>
|
||||||
<i className="fa-solid fa-list"></i> Actions
|
<i className="fa-solid fa-list"></i> Actions
|
||||||
</span>
|
</span>
|
||||||
}
|
}
|
||||||
styles={customStyles}
|
|
||||||
name="actions"
|
name="actions"
|
||||||
isSearchable={false}
|
isSearchable={false}
|
||||||
options={filteredActionOptions}
|
options={filteredActionOptions}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import React, { ReactElement } from "react";
|
|||||||
|
|
||||||
export const DownloadProgressTick = (props): ReactElement => {
|
export const DownloadProgressTick = (props): ReactElement => {
|
||||||
return (
|
return (
|
||||||
<div>
|
<div >
|
||||||
<h4 className="is-size-5">{props.data.name}</h4>
|
<h4 className="is-size-6">{props.data.name}</h4>
|
||||||
<div>
|
<div>
|
||||||
<span className="is-size-4 has-text-weight-semibold">
|
<span className="is-size-3 has-text-weight-semibold">
|
||||||
{prettyBytes(props.data.downloaded_bytes)} of{" "}
|
{prettyBytes(props.data.downloaded_bytes)} of{" "}
|
||||||
{prettyBytes(props.data.size)}{" "}
|
{prettyBytes(props.data.size)}{" "}
|
||||||
</span>
|
</span>
|
||||||
@@ -20,12 +20,13 @@ export const DownloadProgressTick = (props): ReactElement => {
|
|||||||
%
|
%
|
||||||
</progress>
|
</progress>
|
||||||
</div>
|
</div>
|
||||||
<div className="is-size-6 mt-1 mb-2">
|
<div className="is-size-5">
|
||||||
<p>{prettyBytes(props.data.speed)} per second.</p>
|
{prettyBytes(props.data.speed)} per second.
|
||||||
|
</div>
|
||||||
|
<div className="is-size-5">
|
||||||
Time left:
|
Time left:
|
||||||
{Math.round(parseInt(props.data.seconds_left) / 60)}
|
{Math.round(parseInt(props.data.seconds_left) / 60)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>{props.data.target}</div>
|
<div>{props.data.target}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ export const RawFileDetails = (props): ReactElement => {
|
|||||||
const { rawFileDetails, inferredMetadata } = props.data;
|
const { rawFileDetails, inferredMetadata } = props.data;
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="comic-detail raw-file-details column is-three-quarters">
|
<div className="comic-detail raw-file-details column is-three-fifths">
|
||||||
<dl>
|
<dl>
|
||||||
<dt>Raw File Details</dt>
|
<dt>Raw File Details</dt>
|
||||||
<dd className="is-size-7">
|
<dd className="is-size-7">
|
||||||
@@ -103,4 +103,4 @@ RawFileDetails.propTypes = {
|
|||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,13 @@
|
|||||||
import React, { ReactElement, useEffect, useState } from "react";
|
import React, {
|
||||||
|
ReactElement,
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useEffect,
|
||||||
|
useState,
|
||||||
|
} from "react";
|
||||||
import { getTransfers } from "../../actions/airdcpp.actions";
|
import { getTransfers } from "../../actions/airdcpp.actions";
|
||||||
|
import { useDispatch, useSelector } from "react-redux";
|
||||||
|
import { AirDCPPSocketContext } from "../../context/AirDCPPSocket";
|
||||||
import { isEmpty, isNil, isUndefined } from "lodash";
|
import { isEmpty, isNil, isUndefined } from "lodash";
|
||||||
import { determineCoverFile } from "../../shared/utils/metadata.utils";
|
import { determineCoverFile } from "../../shared/utils/metadata.utils";
|
||||||
import MetadataPanel from "../shared/MetadataPanel";
|
import MetadataPanel from "../shared/MetadataPanel";
|
||||||
@@ -9,18 +17,18 @@ interface IDownloadsProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const Downloads = (props: IDownloadsProps): ReactElement => {
|
export const Downloads = (props: IDownloadsProps): ReactElement => {
|
||||||
// const airDCPPConfiguration = useContext(AirDCPPSocketContext);
|
const airDCPPConfiguration = useContext(AirDCPPSocketContext);
|
||||||
const {
|
const {
|
||||||
airDCPPState: { settings, socket },
|
airDCPPState: { settings, socket },
|
||||||
} = airDCPPConfiguration;
|
} = airDCPPConfiguration;
|
||||||
// const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
// const airDCPPTransfers = useSelector(
|
const airDCPPTransfers = useSelector(
|
||||||
// (state: RootState) => state.airdcpp.transfers,
|
(state: RootState) => state.airdcpp.transfers,
|
||||||
// );
|
);
|
||||||
// const issueBundles = useSelector(
|
const issueBundles = useSelector(
|
||||||
// (state: RootState) => state.airdcpp.issue_bundles,
|
(state: RootState) => state.airdcpp.issue_bundles,
|
||||||
// );
|
);
|
||||||
const [bundles, setBundles] = useState([]);
|
const [bundles, setBundles] = useState([]);
|
||||||
// Make the call to get all transfers from AirDC++
|
// Make the call to get all transfers from AirDC++
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ export const Import = (props: IProps): ReactElement => {
|
|||||||
{!isLoading && !isEmpty(data?.data) && (
|
{!isLoading && !isEmpty(data?.data) && (
|
||||||
<>
|
<>
|
||||||
<h3 className="subtitle is-4 mt-5">Past Imports</h3>
|
<h3 className="subtitle is-4 mt-5">Past Imports</h3>
|
||||||
<table className="table is-striped">
|
<table className="table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Time Started</th>
|
<th>Time Started</th>
|
||||||
|
|||||||
@@ -35,16 +35,19 @@ export const AirDCPPHubsForm = (): ReactElement => {
|
|||||||
* Get the hubs list from an AirDCPP Socket
|
* Get the hubs list from an AirDCPP Socket
|
||||||
*/
|
*/
|
||||||
const { data: hubs } = useQuery({
|
const { data: hubs } = useQuery({
|
||||||
queryKey: ["hubs"],
|
queryKey: [],
|
||||||
queryFn: async () => await airDCPPSocketInstance.get(`hubs`),
|
queryFn: async () => await airDCPPSocketInstance.get(`hubs`),
|
||||||
|
enabled: !!settings,
|
||||||
});
|
});
|
||||||
let hubList = {};
|
let hubList = {};
|
||||||
if (!isNil(hubs)) {
|
if (!isEmpty(hubs)) {
|
||||||
|
console.log("hs", hubs);
|
||||||
hubList = hubs.map(({ hub_url, identity }) => ({
|
hubList = hubs.map(({ hub_url, identity }) => ({
|
||||||
value: hub_url,
|
value: hub_url,
|
||||||
label: identity.name,
|
label: identity.name,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
console.log(hubList);
|
||||||
const { mutate } = useMutation({
|
const { mutate } = useMutation({
|
||||||
mutationFn: async (values) =>
|
mutationFn: async (values) =>
|
||||||
await axios({
|
await axios({
|
||||||
|
|||||||
@@ -23,7 +23,6 @@ export const useStore = create((set, get) => ({
|
|||||||
airDCPPSocketConnected: value,
|
airDCPPSocketConnected: value,
|
||||||
})),
|
})),
|
||||||
airDCPPDownloadTick: {},
|
airDCPPDownloadTick: {},
|
||||||
airDCPPTransfers: {},
|
|
||||||
// Socket.io state
|
// Socket.io state
|
||||||
socketIOInstance: {},
|
socketIOInstance: {},
|
||||||
|
|
||||||
|
|||||||
@@ -4310,11 +4310,6 @@ builtin-modules@^3.3.0:
|
|||||||
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.3.0.tgz#cae62812b89801e9656336e46223e030386be7b6"
|
||||||
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
|
integrity sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==
|
||||||
|
|
||||||
bulma-prefers-dark@^0.1.0-beta.1:
|
|
||||||
version "0.1.0-beta.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/bulma-prefers-dark/-/bulma-prefers-dark-0.1.0-beta.1.tgz#074aa71899f389a0137dd3753f0d89e96ab1e59b"
|
|
||||||
integrity sha512-ti4sKxIIrTAvGtsYc9Rk66SUZSH/j63EU1hApQijQVlKFF0qBLGSb8E16HhI83KJaIeYP4aAHQv2tj0ara831A==
|
|
||||||
|
|
||||||
bulma@^0.9.4:
|
bulma@^0.9.4:
|
||||||
version "0.9.4"
|
version "0.9.4"
|
||||||
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.4.tgz#0ca8aeb1847a34264768dba26a064c8be72674a1"
|
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.9.4.tgz#0ca8aeb1847a34264768dba26a064c8be72674a1"
|
||||||
|
|||||||
Reference in New Issue
Block a user