2023-12-14 10:37:29 +00:00
|
|
|
import { useCallback, useContext, useEffect, useState } from "react";
|
|
|
|
|
import { AddTorrentResponse, AddTorrentOptions } from "../../api-types";
|
|
|
|
|
import { AppContext, APIContext } from "../../context";
|
|
|
|
|
import { ErrorComponent } from "../ErrorComponent";
|
|
|
|
|
import { formatBytes } from "../../helper/formatBytes";
|
|
|
|
|
import { ErrorWithLabel } from "../../rqbit-web";
|
|
|
|
|
import { Spinner } from "../Spinner";
|
|
|
|
|
import { Modal } from "./Modal";
|
|
|
|
|
import { ModalBody } from "./ModalBody";
|
|
|
|
|
import { ModalFooter } from "./ModalFooter";
|
|
|
|
|
import { Button } from "../buttons/Button";
|
|
|
|
|
import { FormCheckbox } from "../forms/FormCheckbox";
|
|
|
|
|
import { Fieldset } from "../forms/Fieldset";
|
|
|
|
|
import { FormInput } from "../forms/FormInput";
|
|
|
|
|
import { Form } from "../forms/Form";
|
2023-12-07 16:33:37 +00:00
|
|
|
|
|
|
|
|
export const FileSelectionModal = (props: {
|
|
|
|
|
onHide: () => void;
|
|
|
|
|
listTorrentResponse: AddTorrentResponse | null;
|
2023-12-07 22:42:19 +00:00
|
|
|
listTorrentError: ErrorWithLabel | null;
|
2023-12-07 16:33:37 +00:00
|
|
|
listTorrentLoading: boolean;
|
|
|
|
|
data: string | File;
|
|
|
|
|
}) => {
|
|
|
|
|
let {
|
|
|
|
|
onHide,
|
|
|
|
|
listTorrentResponse,
|
|
|
|
|
listTorrentError,
|
|
|
|
|
listTorrentLoading,
|
|
|
|
|
data,
|
|
|
|
|
} = props;
|
|
|
|
|
|
|
|
|
|
const [selectedFiles, setSelectedFiles] = useState<number[]>([]);
|
|
|
|
|
const [uploading, setUploading] = useState(false);
|
2023-12-07 22:42:19 +00:00
|
|
|
const [uploadError, setUploadError] = useState<ErrorWithLabel | null>(null);
|
2023-12-07 16:33:37 +00:00
|
|
|
const [unpopularTorrent, setUnpopularTorrent] = useState(false);
|
|
|
|
|
const [outputFolder, setOutputFolder] = useState<string>("");
|
|
|
|
|
const ctx = useContext(AppContext);
|
|
|
|
|
const API = useContext(APIContext);
|
|
|
|
|
|
2023-12-14 10:37:29 +00:00
|
|
|
const selectAll = () => {
|
2023-12-07 16:33:37 +00:00
|
|
|
setSelectedFiles(
|
|
|
|
|
listTorrentResponse
|
|
|
|
|
? listTorrentResponse.details.files.map((_, id) => id)
|
|
|
|
|
: []
|
|
|
|
|
);
|
2023-12-14 10:37:29 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
console.log(listTorrentResponse);
|
|
|
|
|
selectAll();
|
2023-12-07 16:33:37 +00:00
|
|
|
setOutputFolder(listTorrentResponse?.output_folder || "");
|
|
|
|
|
}, [listTorrentResponse]);
|
|
|
|
|
|
|
|
|
|
const clear = () => {
|
|
|
|
|
onHide();
|
|
|
|
|
setSelectedFiles([]);
|
|
|
|
|
setUploadError(null);
|
|
|
|
|
setUploading(false);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleToggleFile = (toggledId: number) => {
|
|
|
|
|
if (selectedFiles.includes(toggledId)) {
|
|
|
|
|
setSelectedFiles(selectedFiles.filter((i) => i !== toggledId));
|
|
|
|
|
} else {
|
|
|
|
|
setSelectedFiles([...selectedFiles, toggledId]);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleUpload = async () => {
|
|
|
|
|
if (!listTorrentResponse) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
setUploading(true);
|
|
|
|
|
let initialPeers = listTorrentResponse.seen_peers
|
|
|
|
|
? listTorrentResponse.seen_peers.slice(0, 32)
|
|
|
|
|
: null;
|
|
|
|
|
let opts: AddTorrentOptions = {
|
|
|
|
|
overwrite: true,
|
|
|
|
|
only_files: selectedFiles,
|
|
|
|
|
initial_peers: initialPeers,
|
|
|
|
|
output_folder: outputFolder,
|
|
|
|
|
};
|
|
|
|
|
if (unpopularTorrent) {
|
|
|
|
|
opts.peer_opts = {
|
|
|
|
|
connect_timeout: 20,
|
|
|
|
|
read_write_timeout: 60,
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
API.uploadTorrent(data, opts)
|
|
|
|
|
.then(
|
|
|
|
|
() => {
|
|
|
|
|
onHide();
|
|
|
|
|
ctx.refreshTorrents();
|
|
|
|
|
},
|
|
|
|
|
(e) => {
|
|
|
|
|
setUploadError({ text: "Error starting torrent", details: e });
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
.finally(() => setUploading(false));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const getBody = () => {
|
|
|
|
|
if (listTorrentLoading) {
|
|
|
|
|
return <Spinner />;
|
|
|
|
|
} else if (listTorrentError) {
|
|
|
|
|
return <ErrorComponent error={listTorrentError}></ErrorComponent>;
|
|
|
|
|
} else if (listTorrentResponse) {
|
|
|
|
|
return (
|
|
|
|
|
<Form>
|
2023-12-14 12:42:22 +00:00
|
|
|
<FormInput
|
|
|
|
|
label="Output folder"
|
|
|
|
|
name="output_folder"
|
|
|
|
|
inputType="text"
|
|
|
|
|
value={outputFolder}
|
|
|
|
|
onChange={(e) => setOutputFolder(e.target.value)}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<Fieldset>
|
|
|
|
|
<label className="text-sm mb-2 block">Select files</label>
|
2023-12-14 10:37:29 +00:00
|
|
|
<div className="mb-3 flex gap-2">
|
|
|
|
|
<Button onClick={selectAll} className="text-sm">
|
|
|
|
|
Select all
|
|
|
|
|
</Button>
|
|
|
|
|
<Button onClick={() => setSelectedFiles([])} className="text-sm">
|
|
|
|
|
Deselect all
|
|
|
|
|
</Button>
|
|
|
|
|
</div>
|
2023-12-07 16:33:37 +00:00
|
|
|
{listTorrentResponse.details.files.map((file, index) => (
|
2023-12-14 10:37:29 +00:00
|
|
|
<FormCheckbox
|
|
|
|
|
key={index}
|
|
|
|
|
label={`${file.name} (${formatBytes(file.length)})`}
|
|
|
|
|
checked={selectedFiles.includes(index)}
|
|
|
|
|
onChange={() => handleToggleFile(index)}
|
|
|
|
|
name={`check-${index}`}
|
2023-12-07 16:33:37 +00:00
|
|
|
/>
|
2023-12-14 10:37:29 +00:00
|
|
|
))}
|
|
|
|
|
</Fieldset>
|
|
|
|
|
|
2023-12-14 12:42:22 +00:00
|
|
|
{/* <Fieldset label="Options">
|
2023-12-14 10:37:29 +00:00
|
|
|
<FormCheckbox
|
|
|
|
|
label="Increase timeouts"
|
|
|
|
|
checked={unpopularTorrent}
|
|
|
|
|
onChange={() => setUnpopularTorrent(!unpopularTorrent)}
|
|
|
|
|
help="This might be useful for unpopular torrents with few peers. It will slow down fast torrents though."
|
|
|
|
|
name="increase_timeouts"
|
|
|
|
|
/>
|
2023-12-14 12:42:22 +00:00
|
|
|
</Fieldset> */}
|
2023-12-07 16:33:37 +00:00
|
|
|
</Form>
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
return (
|
2023-12-14 10:37:29 +00:00
|
|
|
<Modal isOpen={true} onClose={clear} title="Add Torrent">
|
|
|
|
|
<ModalBody>
|
2023-12-07 16:33:37 +00:00
|
|
|
{getBody()}
|
|
|
|
|
<ErrorComponent error={uploadError} />
|
2023-12-14 10:37:29 +00:00
|
|
|
</ModalBody>
|
|
|
|
|
<ModalFooter>
|
2023-12-07 16:33:37 +00:00
|
|
|
{uploading && <Spinner />}
|
2023-12-14 10:37:29 +00:00
|
|
|
<Button onClick={clear} variant="cancel">
|
|
|
|
|
Cancel
|
|
|
|
|
</Button>
|
2023-12-07 16:33:37 +00:00
|
|
|
<Button
|
|
|
|
|
onClick={handleUpload}
|
2023-12-14 10:37:29 +00:00
|
|
|
variant="primary"
|
2023-12-07 16:33:37 +00:00
|
|
|
disabled={
|
|
|
|
|
listTorrentLoading || uploading || selectedFiles.length == 0
|
|
|
|
|
}
|
|
|
|
|
>
|
|
|
|
|
OK
|
|
|
|
|
</Button>
|
2023-12-14 10:37:29 +00:00
|
|
|
</ModalFooter>
|
2023-12-07 16:33:37 +00:00
|
|
|
</Modal>
|
|
|
|
|
);
|
|
|
|
|
};
|