feat(filters): add music filters (#91)

* feat(filters): add music filters

* feat: improve parsing and filtering

* feat: add red api support
This commit is contained in:
Ludvig Lundgren 2022-01-19 18:50:04 +01:00 committed by GitHub
parent 30c11d4ef1
commit 00bc8298ac
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 1053 additions and 52 deletions

View file

@ -14,4 +14,30 @@ const ErrorField: React.FC<ErrorFieldProps> = ({ name, classNames }) => (
}
</Field>
);
export { ErrorField }
interface CheckboxFieldProps {
name: string;
label: string;
sublabel?: string;
}
const CheckboxField: React.FC<CheckboxFieldProps> = ({ name, label, sublabel }) => (
<div className="relative flex items-start">
<div className="flex items-center h-5">
<Field
id={name}
name={name}
type="checkbox"
className="focus:ring-bkue-500 h-4 w-4 text-blue-600 border-gray-300 rounded"
/>
</div>
<div className="ml-3 text-sm">
<label htmlFor={name} className="font-medium text-gray-900 dark:text-gray-100">
{label}
</label>
<p className="text-gray-500">{sublabel}</p>
</div>
</div>
)
export { ErrorField, CheckboxField }

View file

@ -1,4 +1,4 @@
export { ErrorField } from "./common";
export { ErrorField, CheckboxField } from "./common";
export { TextField, NumberField, PasswordField } from "./input";
export { NumberFieldWide, PasswordFieldWide, SwitchGroupWide, TextFieldWide } from "./input_wide";
export { RadioFieldsetWide } from "./radio";

View file

@ -53,7 +53,16 @@ export const sources = [
"HDTV",
"Mixed",
"SiteRip",
"Webrip"
"Webrip",
"CD",
"WEB",
"DVD",
"Vinyl",
"Soundboard",
"DAT",
"Cassette",
"Blu-Ray",
"SACD",
];
export const SOURCES_OPTIONS = sources.map(v => ({ value: v, label: v, key: v}));
@ -80,6 +89,68 @@ export const hdr = [
export const HDR_OPTIONS = hdr.map(v => ({ value: v, label: v, key: v}));
export const formatMusic = [
"MP3",
"FLAC",
"Ogg Vorbis",
"Ogg",
"AAC",
"AC3",
"DTS",
];
export const FORMATS_OPTIONS = formatMusic.map(r => ({ value: r, label: r, key: r}));
export const sourcesMusic = [
"CD",
"WEB",
"DVD",
"Vinyl",
"Soundboard",
"DAT",
"Cassette",
"Blu-Ray",
"SACD",
];
export const SOURCES_MUSIC_OPTIONS = sourcesMusic.map(v => ({ value: v, label: v, key: v}));
export const qualityMusic = [
"192",
"256",
"320",
"APS (VBR)",
"APX (VBR)",
"V2 (VBR)",
"V1 (VBR)",
"V0 (VBR)",
"Lossless",
"24bit Lossless",
];
export const QUALITY_MUSIC_OPTIONS = qualityMusic.map(v => ({ value: v, label: v, key: v}));
export const releaseTypeMusic = [
"Album",
"Single",
"EP",
"Soundtrack",
"Anthology",
"Compilation",
"Live album",
"Remix",
"Bootleg",
"Interview",
"Mixtape",
"Demo",
"Concert Recording",
"DJ Mix",
"Unkown",
];
export const RELEASE_TYPE_MUSIC_OPTIONS = releaseTypeMusic.map(v => ({ value: v, label: v, key: v}));
export interface radioFieldsetOption {
label: string;
description: string;

View file

@ -83,8 +83,17 @@ export interface Filter {
sources: string[];
codecs: string[];
containers: string[];
match_release_types: string[];
quality: string[];
formats: string[];
match_hdr: string[];
except_hdr: string[];
log_score: number;
log: boolean;
cue: boolean;
perfect_flac: boolean;
artists: string;
albums: string;
seasons: string;
episodes: string;
match_releases: string;

View file

@ -16,7 +16,7 @@ import { Action, ActionType, DownloadClient, Filter, Indexer } from "../../domai
import { useToggle } from "../../hooks/hooks";
import { useMutation, useQuery } from "react-query";
import { queryClient } from "../../App";
import { CONTAINER_OPTIONS, CODECS_OPTIONS, RESOLUTION_OPTIONS, SOURCES_OPTIONS, ActionTypeNameMap, ActionTypeOptions, HDR_OPTIONS } from "../../domain/constants";
import { CONTAINER_OPTIONS, CODECS_OPTIONS, RESOLUTION_OPTIONS, SOURCES_OPTIONS, ActionTypeNameMap, ActionTypeOptions, HDR_OPTIONS, FORMATS_OPTIONS, SOURCES_MUSIC_OPTIONS, QUALITY_MUSIC_OPTIONS, RELEASE_TYPE_MUSIC_OPTIONS } from "../../domain/constants";
import DEBUG from "../../components/debug";
import { TitleSubtitle } from "../../components/headings";
@ -30,11 +30,12 @@ import Toast from '../../components/notifications/Toast';
import { Field, FieldArray, Form, Formik } from "formik";
import { AlertWarning } from "../../components/alerts";
import { DeleteModal } from "../../components/modals";
import { NumberField, TextField, SwitchGroup, Select, MultiSelect, DownloadClientSelect } from "../../components/inputs";
import { NumberField, TextField, SwitchGroup, Select, MultiSelect, DownloadClientSelect, CheckboxField } from "../../components/inputs";
const tabs = [
{ name: 'General', href: '', current: true },
{ name: 'Movies and TV', href: 'movies-tv', current: false },
{ name: 'Music', href: 'music', current: false },
// { name: 'P2P', href: 'p2p', current: false },
{ name: 'Advanced', href: 'advanced', current: false },
{ name: 'Actions', href: 'actions', current: false },
@ -251,7 +252,16 @@ export default function FilterDetails() {
freeleech_percent: data.freeleech_percent,
indexers: data.indexers || [],
actions: data.actions || [],
}}
formats: data.formats || [],
quality: data.quality || [],
match_release_types: data.match_release_types || [],
log_score: data.log_score,
log: data.log,
cue: data.cue,
perfect_flac: data.perfect_flac,
artists: data.artists,
albums: data.albums,
} as Filter}
onSubmit={handleSubmit}
>
{({ values, dirty, resetForm }) => (
@ -265,6 +275,10 @@ export default function FilterDetails() {
<MoviesTv />
</Route>
<Route path={`${url}/music`}>
<Music />
</Route>
<Route path={`${url}/advanced`}>
<Advanced />
</Route>
@ -405,6 +419,58 @@ function MoviesTv() {
)
}
function Music() {
return (
<div>
<div className="mt-6 grid grid-cols-12 gap-6">
<TextField name="artists" label="Artists" columns={4} placeholder="eg. Aritst One" />
<TextField name="albums" label="Albums" columns={4} placeholder="eg. That Album" />
<TextField name="years" label="Years" columns={4} placeholder="eg. 2018,2019-2021" />
</div>
<div className="mt-6 lg:pb-8">
<TitleSubtitle title="Quality" subtitle="Format, source, log etc." />
<div className="mt-6 grid grid-cols-12 gap-6">
<MultiSelect name="formats" options={FORMATS_OPTIONS} label="Format" columns={6} />
<MultiSelect name="quality" options={QUALITY_MUSIC_OPTIONS} label="Quality" columns={6} />
</div>
<div className="mt-6 grid grid-cols-12 gap-6">
<MultiSelect name="sources" options={SOURCES_MUSIC_OPTIONS} label="sources" columns={6} />
<MultiSelect name="match_release_types" options={RELEASE_TYPE_MUSIC_OPTIONS} label="Type" columns={6} />
</div>
<div className="mt-6 grid grid-cols-12 gap-6">
<NumberField name="log_score" label="Log score" placeholder="eg. 100" />
</div>
</div>
<div className="space-y-6 sm:space-y-5 divide-y divide-gray-200">
<div className="pt-6 sm:pt-5">
<div role="group" aria-labelledby="label-email">
<div className="sm:grid sm:grid-cols-3 sm:gap-4 sm:items-baseline">
{/* <div>
<div className="text-base font-medium text-gray-900 sm:text-sm sm:text-gray-700" id="label-email">
Extra
</div>
</div> */}
<div className="mt-4 sm:mt-0 sm:col-span-2">
<div className="max-w-lg space-y-4">
<CheckboxField name="log" label="Log" sublabel="Must include Log" />
<CheckboxField name="cue" label="Cue" sublabel="Must include Cue"/>
<CheckboxField name="perfect_flac" label="Perfect FLAC" sublabel="Override all options about quality, source, format, and cue/log/log score"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
)
}
function Advanced() {
const [releasesIsOpen, toggleReleases] = useToggle(false)
const [groupsIsOpen, toggleGroups] = useToggle(false)