2021-03-25 14:22:43 +00:00
|
|
|
import {
|
|
|
|
faAdjust,
|
|
|
|
faBriefcase,
|
|
|
|
faCloudUploadAlt,
|
|
|
|
faHdd,
|
|
|
|
faSearch,
|
|
|
|
faSync,
|
|
|
|
faWrench,
|
|
|
|
} from "@fortawesome/free-solid-svg-icons";
|
2021-08-14 12:59:08 +00:00
|
|
|
import React, { FunctionComponent, useMemo, useState } from "react";
|
2021-08-22 04:30:03 +00:00
|
|
|
import { Alert, Container, Row } from "react-bootstrap";
|
2021-03-25 14:22:43 +00:00
|
|
|
import { Helmet } from "react-helmet";
|
|
|
|
import { Redirect, RouteComponentProps, withRouter } from "react-router-dom";
|
2021-08-22 08:35:55 +00:00
|
|
|
import { dispatchTask } from "../../@modules/task";
|
2021-08-22 04:30:03 +00:00
|
|
|
import { useIsAnyTaskRunningWithId } from "../../@modules/task/hooks";
|
2021-08-22 08:35:55 +00:00
|
|
|
import { createTask } from "../../@modules/task/utilites";
|
2021-05-08 14:25:29 +00:00
|
|
|
import { useEpisodesBy, useProfileBy, useSerieBy } from "../../@redux/hooks";
|
2021-03-25 14:22:43 +00:00
|
|
|
import { SeriesApi } from "../../apis";
|
|
|
|
import {
|
|
|
|
ContentHeader,
|
|
|
|
ItemEditorModal,
|
|
|
|
LoadingIndicator,
|
|
|
|
SeriesUploadModal,
|
|
|
|
useShowModal,
|
|
|
|
} from "../../components";
|
2021-04-23 16:18:09 +00:00
|
|
|
import { RouterEmptyPath } from "../../special-pages/404";
|
2021-08-14 12:59:08 +00:00
|
|
|
import { useOnLoadedOnce } from "../../utilites";
|
2021-08-22 10:32:11 +00:00
|
|
|
import ItemOverview from "../generic/ItemOverview";
|
2021-03-25 14:22:43 +00:00
|
|
|
import Table from "./table";
|
|
|
|
|
|
|
|
interface Params {
|
|
|
|
id: string;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface Props extends RouteComponentProps<Params> {}
|
|
|
|
|
|
|
|
const SeriesEpisodesView: FunctionComponent<Props> = (props) => {
|
|
|
|
const { match } = props;
|
|
|
|
const id = Number.parseInt(match.params.id);
|
2021-08-14 12:59:08 +00:00
|
|
|
const series = useSerieBy(id);
|
|
|
|
const episodes = useEpisodesBy(id);
|
|
|
|
const serie = series.content;
|
2021-03-25 14:22:43 +00:00
|
|
|
|
2021-08-14 12:59:08 +00:00
|
|
|
const available = episodes.content.length !== 0;
|
2021-03-25 14:22:43 +00:00
|
|
|
|
|
|
|
const details = useMemo(
|
|
|
|
() => [
|
|
|
|
{
|
|
|
|
icon: faHdd,
|
2021-08-14 12:59:08 +00:00
|
|
|
text: `${serie?.episodeFileCount} files`,
|
2021-03-25 14:22:43 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
icon: faAdjust,
|
2021-08-14 12:59:08 +00:00
|
|
|
text: serie?.seriesType ?? "",
|
2021-03-25 14:22:43 +00:00
|
|
|
},
|
|
|
|
],
|
2021-08-14 12:59:08 +00:00
|
|
|
[serie]
|
2021-03-25 14:22:43 +00:00
|
|
|
);
|
|
|
|
|
|
|
|
const showModal = useShowModal();
|
|
|
|
|
|
|
|
const [valid, setValid] = useState(true);
|
|
|
|
|
2021-08-14 12:59:08 +00:00
|
|
|
useOnLoadedOnce(() => {
|
|
|
|
if (series.content === null) {
|
2021-03-25 14:22:43 +00:00
|
|
|
setValid(false);
|
|
|
|
}
|
2021-08-14 12:59:08 +00:00
|
|
|
}, series);
|
2021-03-25 14:22:43 +00:00
|
|
|
|
2021-08-14 12:59:08 +00:00
|
|
|
const profile = useProfileBy(series.content?.profileId);
|
2021-05-08 14:25:29 +00:00
|
|
|
|
2021-08-22 05:20:08 +00:00
|
|
|
const hasTask = useIsAnyTaskRunningWithId(
|
|
|
|
episodes.content.map((v) => v.sonarrEpisodeId)
|
|
|
|
);
|
2021-08-22 04:30:03 +00:00
|
|
|
|
2021-03-25 14:22:43 +00:00
|
|
|
if (isNaN(id) || !valid) {
|
|
|
|
return <Redirect to={RouterEmptyPath}></Redirect>;
|
|
|
|
}
|
|
|
|
|
2021-08-14 12:59:08 +00:00
|
|
|
if (!serie) {
|
2021-03-25 14:22:43 +00:00
|
|
|
return <LoadingIndicator></LoadingIndicator>;
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<Container fluid>
|
|
|
|
<Helmet>
|
2021-08-14 12:59:08 +00:00
|
|
|
<title>{serie.title} - Bazarr (Series)</title>
|
2021-03-25 14:22:43 +00:00
|
|
|
</Helmet>
|
|
|
|
<ContentHeader>
|
|
|
|
<ContentHeader.Group pos="start">
|
2021-08-22 08:35:55 +00:00
|
|
|
<ContentHeader.Button
|
2021-03-25 14:22:43 +00:00
|
|
|
icon={faSync}
|
2021-08-22 04:30:03 +00:00
|
|
|
disabled={!available || hasTask}
|
2021-08-22 08:35:55 +00:00
|
|
|
onClick={() => {
|
|
|
|
const task = createTask(
|
|
|
|
serie.title,
|
|
|
|
id,
|
|
|
|
SeriesApi.action.bind(SeriesApi),
|
|
|
|
{
|
|
|
|
action: "scan-disk",
|
|
|
|
seriesid: id,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
dispatchTask("Scaning disk...", [task], "Scaning...");
|
|
|
|
}}
|
2021-03-25 14:22:43 +00:00
|
|
|
>
|
|
|
|
Scan Disk
|
2021-08-22 08:35:55 +00:00
|
|
|
</ContentHeader.Button>
|
|
|
|
<ContentHeader.Button
|
2021-03-25 14:22:43 +00:00
|
|
|
icon={faSearch}
|
2021-08-22 08:35:55 +00:00
|
|
|
onClick={() => {
|
|
|
|
const task = createTask(
|
|
|
|
serie.title,
|
|
|
|
id,
|
|
|
|
SeriesApi.action.bind(SeriesApi),
|
|
|
|
{
|
|
|
|
action: "search-missing",
|
|
|
|
seriesid: id,
|
|
|
|
}
|
|
|
|
);
|
|
|
|
dispatchTask("Searching subtitles...", [task], "Searching...");
|
|
|
|
}}
|
2021-03-25 14:22:43 +00:00
|
|
|
disabled={
|
2021-08-14 12:59:08 +00:00
|
|
|
serie.episodeFileCount === 0 ||
|
|
|
|
serie.profileId === null ||
|
2021-08-22 04:30:03 +00:00
|
|
|
!available ||
|
|
|
|
hasTask
|
2021-03-25 14:22:43 +00:00
|
|
|
}
|
|
|
|
>
|
|
|
|
Search
|
2021-08-22 08:35:55 +00:00
|
|
|
</ContentHeader.Button>
|
2021-03-25 14:22:43 +00:00
|
|
|
</ContentHeader.Group>
|
|
|
|
<ContentHeader.Group pos="end">
|
|
|
|
<ContentHeader.Button
|
2021-08-22 04:30:03 +00:00
|
|
|
disabled={serie.episodeFileCount === 0 || !available || hasTask}
|
2021-03-25 14:22:43 +00:00
|
|
|
icon={faBriefcase}
|
2021-08-14 12:59:08 +00:00
|
|
|
onClick={() => showModal("tools", episodes.content)}
|
2021-03-25 14:22:43 +00:00
|
|
|
>
|
|
|
|
Tools
|
|
|
|
</ContentHeader.Button>
|
|
|
|
<ContentHeader.Button
|
|
|
|
disabled={
|
2021-08-14 12:59:08 +00:00
|
|
|
serie.episodeFileCount === 0 ||
|
|
|
|
serie.profileId === null ||
|
2021-03-25 14:22:43 +00:00
|
|
|
!available
|
|
|
|
}
|
|
|
|
icon={faCloudUploadAlt}
|
2021-08-14 12:59:08 +00:00
|
|
|
onClick={() => showModal("upload", serie)}
|
2021-03-25 14:22:43 +00:00
|
|
|
>
|
|
|
|
Upload
|
|
|
|
</ContentHeader.Button>
|
|
|
|
<ContentHeader.Button
|
|
|
|
icon={faWrench}
|
2021-08-22 04:30:03 +00:00
|
|
|
disabled={hasTask}
|
2021-08-14 12:59:08 +00:00
|
|
|
onClick={() => showModal("edit", serie)}
|
2021-03-25 14:22:43 +00:00
|
|
|
>
|
|
|
|
Edit Series
|
|
|
|
</ContentHeader.Button>
|
|
|
|
</ContentHeader.Group>
|
|
|
|
</ContentHeader>
|
2021-08-22 04:30:03 +00:00
|
|
|
<Row>
|
|
|
|
<Alert
|
|
|
|
className="w-100 m-0 py-2"
|
|
|
|
show={hasTask}
|
|
|
|
style={{ borderRadius: 0 }}
|
|
|
|
variant="light"
|
|
|
|
>
|
|
|
|
A background task is running for this show, actions are unavailable
|
|
|
|
</Alert>
|
|
|
|
</Row>
|
2021-03-25 14:22:43 +00:00
|
|
|
<Row>
|
2021-08-14 12:59:08 +00:00
|
|
|
<ItemOverview item={serie} details={details}></ItemOverview>
|
2021-03-25 14:22:43 +00:00
|
|
|
</Row>
|
|
|
|
<Row>
|
2021-08-22 05:20:08 +00:00
|
|
|
<Table
|
|
|
|
serie={series}
|
|
|
|
episodes={episodes}
|
|
|
|
profile={profile}
|
|
|
|
disabled={hasTask}
|
|
|
|
></Table>
|
2021-03-25 14:22:43 +00:00
|
|
|
</Row>
|
|
|
|
<ItemEditorModal
|
|
|
|
modalKey="edit"
|
|
|
|
submit={(form) => SeriesApi.modify(form)}
|
|
|
|
></ItemEditorModal>
|
2021-05-08 14:25:29 +00:00
|
|
|
<SeriesUploadModal
|
|
|
|
modalKey="upload"
|
2021-08-14 12:59:08 +00:00
|
|
|
episodes={episodes.content}
|
2021-05-08 14:25:29 +00:00
|
|
|
></SeriesUploadModal>
|
2021-03-25 14:22:43 +00:00
|
|
|
</Container>
|
|
|
|
);
|
|
|
|
};
|
|
|
|
|
|
|
|
export default withRouter(SeriesEpisodesView);
|