137 lines
3.6 KiB
JavaScript
137 lines
3.6 KiB
JavaScript
import React, { useState } from "react";
|
|
import PropTypes from "prop-types";
|
|
import { useDispatch } from "react-redux";
|
|
|
|
import { prettySize } from "../../utils";
|
|
import { addTorrent } from "../../actions/torrents";
|
|
|
|
import Dropdown from "react-bootstrap/Dropdown";
|
|
|
|
const buildMenuItems = (torrents) => {
|
|
if (!torrents || torrents.length === 0) {
|
|
return [];
|
|
}
|
|
|
|
// Build the array of entries
|
|
let entries = [];
|
|
|
|
let dividerCount = torrents.size - 1;
|
|
torrents.forEach((torrentsBySource, source) => {
|
|
// Push the title
|
|
entries.push({
|
|
type: "header",
|
|
value: source,
|
|
});
|
|
|
|
torrentsBySource.forEach((torrent) => {
|
|
entries.push({
|
|
type: "entry",
|
|
quality: torrent.quality,
|
|
size: torrent.result.size,
|
|
torrent: torrent,
|
|
});
|
|
});
|
|
|
|
// Push the divider
|
|
if (dividerCount > 0) {
|
|
dividerCount--;
|
|
entries.push({ type: "divider" });
|
|
}
|
|
});
|
|
|
|
return entries;
|
|
};
|
|
|
|
const countEntries = (torrents) => {
|
|
if (!torrents || torrents.length === 0) {
|
|
return 0;
|
|
}
|
|
|
|
let count = 0;
|
|
torrents.forEach((source) => {
|
|
count = count + source.size;
|
|
});
|
|
|
|
return count;
|
|
};
|
|
|
|
export const TorrentsButton = ({ torrents, search, searching, url }) => {
|
|
const dispatch = useDispatch();
|
|
|
|
const [show, setShow] = useState(false);
|
|
const entries = buildMenuItems(torrents);
|
|
const count = countEntries(torrents);
|
|
|
|
const onSelect = (eventKey) => {
|
|
// Close the dropdown if the eventkey is not specified
|
|
if (eventKey === null) {
|
|
setShow(false);
|
|
}
|
|
};
|
|
|
|
const onToggle = (isOpen, event, metadata) => {
|
|
// Don't close on select
|
|
if (metadata && metadata.source !== "select") {
|
|
setShow(isOpen);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<span className="mr-1 mb-1">
|
|
<Dropdown drop="up" show={show} onToggle={onToggle} onSelect={onSelect}>
|
|
<Dropdown.Toggle variant="secondary" bsPrefix="btn-sm w-md-100">
|
|
<i className="fa fa-magnet mr-1" />
|
|
Torrents
|
|
<span className="ml-1 badge badge-pill badge-info">{count}</span>
|
|
</Dropdown.Toggle>
|
|
|
|
<Dropdown.Menu>
|
|
<Dropdown.Item eventKey={1} onClick={search}>
|
|
<i className={`fa ${searching ? "fa-spin" : ""} fa-refresh mr-1`} />
|
|
Automatic search
|
|
</Dropdown.Item>
|
|
<Dropdown.Item href={url}>
|
|
<i className="fa fa-search mr-1" />
|
|
Manual search
|
|
</Dropdown.Item>
|
|
{entries.length > 0 && <Dropdown.Divider />}
|
|
{entries.map((e, index) => {
|
|
switch (e.type) {
|
|
case "header":
|
|
return (
|
|
<Dropdown.Header key={index}>
|
|
<span className="text-warning">{e.value}</span>
|
|
</Dropdown.Header>
|
|
);
|
|
case "divider":
|
|
return <Dropdown.Divider key={index} />;
|
|
case "entry":
|
|
return (
|
|
<Dropdown.Item
|
|
key={index}
|
|
href={e.torrent.result.url}
|
|
onClick={(event) => {
|
|
event.preventDefault();
|
|
dispatch(addTorrent(e.torrent));
|
|
}}
|
|
>
|
|
{e.quality}
|
|
{e.size !== 0 && (
|
|
<small className="ml-1">({prettySize(e.size)})</small>
|
|
)}
|
|
</Dropdown.Item>
|
|
);
|
|
}
|
|
})}
|
|
</Dropdown.Menu>
|
|
</Dropdown>
|
|
</span>
|
|
);
|
|
};
|
|
TorrentsButton.propTypes = {
|
|
torrents: PropTypes.object,
|
|
searching: PropTypes.bool,
|
|
search: PropTypes.func.isRequired,
|
|
url: PropTypes.string,
|
|
};
|