🔧 AirDCPP metadata and download first draft

This commit is contained in:
2021-08-23 14:34:55 -07:00
parent e5870fa1a8
commit 8a1e6fb98a
5 changed files with 162 additions and 84 deletions

View File

@@ -1,7 +1,7 @@
import React, { useState, useEffect, useCallback, ReactElement } from "react";
import { search } from "../actions/airdcpp.actions";
import { search, downloadAirDCPPItem } from "../actions/airdcpp.actions";
import { useDispatch, useSelector } from "react-redux";
import { RootState } from "threetwo-ui-typings";
import { RootState, SearchInstance } from "threetwo-ui-typings";
import { each, isNil, map } from "lodash";
interface IAcquisitionPanelProps {
@@ -17,8 +17,14 @@ export const AcquisitionPanel = (
const airDCPPSearchResults = useSelector(
(state: RootState) => state.airdcpp.results,
);
const searchStatus = useSelector(
(state: RootState) => state.airdcpp.searchStatus,
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 dispatch = useDispatch();
const getDCPPSearchResults = useCallback(
@@ -30,75 +36,133 @@ export const AcquisitionPanel = (
const dcppQuery = {
query: {
pattern: `${volumeName}`,
// file_type: "compressed",
extensions: ["cbz", "cbr"],
},
hub_urls: ["perfection.crabdance.com:777"],
priority: 1,
};
const downloadDCPPResult = useCallback(
(searchInstanceId, resultId) =>
dispatch(downloadAirDCPPItem(searchInstanceId, resultId)),
[dispatch],
);
return (
<div className="comic-detail">
<button
className="button"
onClick={() => getDCPPSearchResults(dcppQuery)}
>
Search on AirDC++
</button>
<p>{searchStatus}</p>
{/* results */}
{!isNil(airDCPPSearchResults) && (
<table className="table is-striped">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Slots</th>
</tr>
</thead>
<tbody>
{map(airDCPPSearchResults, ({ name, type, slots, users }) => {
return (
<tr>
<td>
<p className="mb-2">
{type.id === "directory" ? (
<i className="fas fa-folder"></i>
) : null}{" "}
{name}
</p>
<>
<div className="comic-detail columns">
<div className="column is-one-fifth">
<button
className={
isAirDCPPSearchInProgress
? "button is-loading is-warning"
: "button"
}
onClick={() => getDCPPSearchResults(dcppQuery)}
>
Search on AirDC++
</button>
</div>
{!isNil(searchInfo) && !isNil(searchInstance) && (
<>
<div className="column is-one-quarter is-size-7">
<div className="card">
<div className="card-content">
<div className="content">
<dl>
<dt>Query: {searchInfo.query.pattern}</dt>
<dd>
<div className="tags">
<span className="tag is-light is-info">
{users.user.nicks}
</span>
{users.user.flags.map((flag, idx) => (
<span className="tag is-light" key={idx}>
{flag}
</span>
))}
</div>
Extensions: {searchInfo.query.extensions.join(", ")}
</dd>
<dd>File type: {searchInfo.query.file_type}</dd>
</dl>
</td>
<td>
<span className="tag is-light is-info">
{type.id === "directory" ? "directory" : type.str}
</span>
</td>
<td>
<div className="tags has-addons">
<span className="tag is-success">{slots.free} free</span>
<span className="tag is-light">{slots.total}</span>
</div>
</td>
</tr>
);
})}
</tbody>
</table>
)}
</div>
</div>
</div>
</div>
</div>
<div className="column is-one-quarter is-size-7">
<div className="card">
<div className="card-content">
<div className="content">
<dl>
<dt>Search Instance: {searchInstance.id}</dt>
<dt>Owned by {searchInstance.owner}</dt>
<dd>Expires in: {searchInstance.expires_in}</dd>
</dl>
</div>
</div>
</div>
</div>
</>
)}
</div>
{/* results */}
<div>
{!isNil(airDCPPSearchResults) && (
<table className="table is-striped">
<thead>
<tr>
<th>Name</th>
<th>Type</th>
<th>Slots</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{map(airDCPPSearchResults, ({ name, type, slots, users, id }) => {
return (
<tr>
<td>
<p className="mb-2">
{type.id === "directory" ? (
<i className="fas fa-folder"></i>
) : null}{" "}
{name}
</p>
<dl>
<dd>
<div className="tags">
<span className="tag is-light is-info">
{users.user.nicks}
</span>
{users.user.flags.map((flag, idx) => (
<span className="tag is-light" key={idx}>
{flag}
</span>
))}
</div>
</dd>
</dl>
</td>
<td>
<span className="tag is-light is-info">
{type.id === "directory" ? "directory" : type.str}
</span>
</td>
<td>
<div className="tags has-addons">
<span className="tag is-success">
{slots.free} free
</span>
<span className="tag is-light">{slots.total}</span>
</div>
</td>
<td>
<a
onClick={() =>
downloadDCPPResult(searchInstance.id, id)
}
>
<i className="fas fa-file-download"></i>
</a>
</td>
</tr>
);
})}
</tbody>
</table>
)}
</div>
</>
);
};

View File

@@ -151,6 +151,12 @@ export const ComicDetail = ({}: ComicDetailProps): ReactElement => {
name: "Acquisition",
content: <AcquisitionPanel comicBookMetadata={comicBookDetailData} />,
},
{
id: 4,
icon: <i className="fas fa-cloud-download-alt"></i>,
name: "Downloads",
content: <div>Downloads</div>,
},
];
const MetadataTabGroup = () => {
return (