Add chips input for the provider builder

This commit is contained in:
LASER-Yi 2022-06-27 11:24:06 +08:00
parent 2b88c9f60c
commit c45b172415
3 changed files with 270 additions and 168 deletions

View File

@ -1,6 +1,7 @@
import { Selector } from "@/components";
import { useModals, withModal } from "@/modules/modals";
import { BuildKey, isReactText, useSelectorOptions } from "@/utilities";
import { BuildKey, useSelectorOptions } from "@/utilities";
import { ASSERT } from "@/utilities/console";
import {
Button,
Divider,
@ -10,7 +11,7 @@ import {
Text as MantineText,
} from "@mantine/core";
import { useForm } from "@mantine/hooks";
import { capitalize, isBoolean } from "lodash";
import { capitalize } from "lodash";
import {
forwardRef,
FunctionComponent,
@ -22,6 +23,7 @@ import {
import {
Card,
Check,
Chips,
Message,
Password,
Text,
@ -192,42 +194,21 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
(v) => v.name ?? capitalize(v.key)
);
const modification = useMemo(() => {
if (info === null) {
return null;
}
const defaultKey = info.defaultKey;
const override = info.keyNameOverride ?? {};
if (defaultKey === undefined) {
const inputs = useMemo(() => {
if (info === null || info.inputs === undefined) {
return null;
}
const itemKey = info.key;
const elements: JSX.Element[] = [];
const checks: JSX.Element[] = [];
for (const key in defaultKey) {
const value = defaultKey[key];
let label = key;
info.inputs?.forEach((value) => {
const key = value.key;
const label = value.name ?? capitalize(value.key);
if (label in override) {
label = override[label];
} else {
label = capitalize(key);
}
if (isReactText(value)) {
if (key === "password") {
elements.push(
<Password
key={BuildKey(itemKey, key)}
label={label}
settingKey={`settings-${itemKey}-${key}`}
></Password>
);
} else {
switch (value.type) {
case "text":
elements.push(
<Text
key={BuildKey(itemKey, key)}
@ -235,25 +216,41 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
settingKey={`settings-${itemKey}-${key}`}
></Text>
);
}
} else if (isBoolean(value)) {
checks.push(
<Check
key={key}
inline
label={label}
settingKey={`settings-${itemKey}-${key}`}
></Check>
);
return;
case "password":
elements.push(
<Password
key={BuildKey(itemKey, key)}
label={label}
settingKey={`settings-${itemKey}-${key}`}
></Password>
);
return;
case "switch":
elements.push(
<Check
key={key}
inline
label={label}
settingKey={`settings-${itemKey}-${key}`}
></Check>
);
return;
case "chips":
elements.push(
<Chips
key={key}
label={label}
settingKey={`settings-${itemKey}-${key}`}
></Chips>
);
return;
default:
ASSERT(false, "Implement your new input here");
}
}
});
return (
<Stack spacing="xs">
{elements}
<Group hidden={checks.length === 0}>{checks}</Group>
</Stack>
);
return <Stack spacing="xs">{elements}</Stack>;
}, [info]);
return (
@ -271,7 +268,7 @@ const ProviderTool: FunctionComponent<ProviderToolProps> = ({
onChange={onSelect}
></Selector>
<Message>{info?.description}</Message>
{modification}
{inputs}
<div hidden={info?.message === undefined}>
<Message>{info?.message}</Message>
</div>

View File

@ -1,56 +1,79 @@
import { ReactText } from "react";
type AvailableType = ReactText | boolean;
type Input<T, N> = {
type: N;
key: string;
defaultValue?: T;
name?: string;
description?: string;
};
type AvailableInput =
| Input<ReactText, "text">
| Input<string, "password">
| Input<boolean, "switch">
| Input<ReactText[], "chips">;
export interface ProviderInfo {
key: string;
name?: string;
description?: string;
message?: string;
defaultKey?: {
[key: string]: AvailableType;
};
keyNameOverride?: {
[key: string]: string;
};
inputs?: AvailableInput[];
}
export const ProviderList: Readonly<ProviderInfo[]> = [
{
key: "addic7ed",
description: "Requires Anti-Captcha Provider or cookies",
defaultKey: {
username: "",
password: "",
cookies: "",
user_agent: "",
vip: false,
},
keyNameOverride: {
vip: "VIP",
cookies:
"Cookies, e.g., PHPSESSID=abc; wikisubtitlesuser=xyz; wikisubtitlespass=efg",
user_agent:
"User-Agent, e.g., Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
{
type: "text",
key: "cookies",
name: "Cookies, e.g., PHPSESSID=abc; wikisubtitlesuser=xyz; wikisubtitlespass=efg",
},
{
type: "text",
key: "user_agent",
name: "User-Agent, e.g., Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:95.0) Gecko/20100101 Firefox/95.0",
},
{
type: "switch",
key: "vip",
name: "VIP",
},
],
},
{ key: "argenteam", description: "LATAM Spanish Subtitles Provider" },
{
key: "assrt",
description: "Chinese Subtitles Provider",
defaultKey: {
token: "",
},
inputs: [
{
type: "text",
key: "token",
},
],
},
{
key: "betaseries",
name: "BetaSeries",
description: "French / English Provider for TV Shows Only",
defaultKey: {
token: "",
},
keyNameOverride: {
token: "API KEY",
},
inputs: [
{
type: "text",
key: "token",
name: "API KEY",
},
],
},
{
key: "bsplayer",
@ -62,24 +85,38 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
key: "embeddedsubtitles",
name: "Embedded Subtitles",
description: "Embedded Subtitles from your Media Files",
defaultKey: {
include_srt: true,
include_ass: true,
hi_fallback: false,
mergerfs_mode: false,
timeout: 600,
},
inputs: [
{
type: "switch",
key: "include_srt",
name: "Include SRT",
defaultValue: true,
},
{
type: "switch",
key: "include_ass",
name: "Include ASS (will be converted to SRT)",
defaultValue: true,
},
{
type: "switch",
key: "hi_fallback",
name: "Use HI subtitles as a fallback (don't enable it if you have a HI language profile)",
},
{
type: "switch",
key: "mergerfs_mode",
name: "[EXPERIMENTAL] Ignore cloud video files from rclone/mergerfs",
},
{
type: "text",
key: "timeout",
defaultValue: 600,
name: "Extraction timeout in seconds",
},
],
message:
"Warning for cloud users: this provider needs to read the entire file in order to extract subtitles.",
keyNameOverride: {
include_srt: "Include SRT",
include_ass: "Include ASS (will be converted to SRT)",
hi_fallback:
"Use HI subtitles as a fallback (don't enable it if you have a HI language profile)",
mergerfs_mode:
"[EXPERIMENTAL] Ignore cloud video files from rclone/mergerfs",
timeout: "Extraction timeout in seconds",
},
},
{
key: "gestdown",
@ -101,39 +138,53 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
key: "legendasdivx",
name: "LegendasDivx",
description: "Brazilian / Portuguese Subtitles Provider",
defaultKey: {
username: "",
password: "",
skip_wrong_fps: false,
},
keyNameOverride: {
skip_wrong_fps: "Skip Wrong FPS",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
{ type: "switch", key: "skip_wrong_fps", name: "Skip Wrong FPS" },
],
},
{
key: "ktuvit",
name: "Ktuvit",
description: "Hebrew Subtitles Provider",
defaultKey: {
email: "",
hashed_password: "",
},
keyNameOverride: {
hashed_password: "Hashed Password",
},
inputs: [
{
type: "text",
key: "email",
},
{
type: "text",
key: "hashed_password",
name: "Hashed Password",
},
],
},
{
key: "legendastv",
name: "LegendasTV",
description: "Brazilian / Portuguese Subtitles Provider",
defaultKey: {
username: "",
password: "",
featured_only: false,
},
keyNameOverride: {
featured_only: "Only Download Featured",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
{
type: "switch",
key: "featured_only",
name: "Only Download Featured",
},
],
},
{ key: "napiprojekt", description: "Polish Subtitles Provider" },
{
@ -141,50 +192,77 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
description: "Polish Subtitles Provider",
message:
"The provided credentials must have API access. Leave empty to use the defaults.",
defaultKey: {
username: "",
password: "",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
],
},
{ key: "nekur", description: "Latvian Subtitles Provider" },
{
key: "opensubtitles",
name: "OpenSubtitles.org",
defaultKey: {
username: "",
password: "",
vip: false,
ssl: false,
skip_wrong_fps: false,
},
keyNameOverride: {
vip: "VIP",
ssl: "Use SSL",
skip_wrong_fps: "Skip Wrong FPS",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
{
type: "switch",
key: "vip",
name: "VIP",
},
{
type: "switch",
key: "ssl",
name: "Use SSL",
},
{
type: "switch",
key: "skip_wrong_fps",
name: "Skip Wrong FPS",
},
],
},
{
key: "opensubtitlescom",
name: "OpenSubtitles.com",
defaultKey: {
username: "",
password: "",
use_hash: false,
},
keyNameOverride: {
use_hash: "Use Hash",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
{
type: "switch",
key: "use_hash",
name: "Use Hash",
},
],
},
{
key: "podnapisi",
name: "Podnapisi",
defaultKey: {
verify_ssl: true,
},
keyNameOverride: {
verify_ssl:
"Verify SSL certificate (disabling introduce a MitM attack risk)",
},
inputs: [
{
type: "switch",
key: "verify_ssl",
name: "Verify SSL certificate (disabling introduce a MitM attack risk)",
defaultValue: true,
},
],
},
{
key: "regielive",
@ -220,10 +298,16 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
},
{
key: "subscene",
defaultKey: {
username: "",
password: "",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
],
},
{ key: "subscenter" },
{
@ -251,10 +335,16 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
{ key: "supersubtitles" },
{
key: "titlovi",
defaultKey: {
username: "",
password: "",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
],
},
{
key: "titrari",
@ -272,14 +362,21 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
key: "titulky",
name: "Titulky.com",
description: "CZ/SK Subtitles Provider. Available only with VIP",
defaultKey: {
username: "",
password: "",
approved_only: false,
},
keyNameOverride: {
approved_only: "Skip unapproved subtitles",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
{
type: "switch",
key: "approved_only",
name: "Skip unapproved subtitles",
},
],
},
{ key: "tvsubtitles", name: "TVSubtitles" },
{ key: "wizdom", description: "Wizdom.xyz Subtitles Provider." },
@ -287,10 +384,16 @@ export const ProviderList: Readonly<ProviderInfo[]> = [
key: "xsubs",
name: "XSubs",
description: "Greek Subtitles Provider",
defaultKey: {
username: "",
password: "",
},
inputs: [
{
type: "text",
key: "username",
},
{
type: "password",
key: "password",
},
],
},
{
key: "yavkanet",

View File

@ -22,3 +22,5 @@ export function ENSURE(condition: boolean, msg: string, ...payload: any[]) {
LOG("error", msg, payload);
}
}
export const ASSERT = console.assert;