aboutsummaryrefslogtreecommitdiffhomepage
path: root/frontend/src/components/forms
diff options
context:
space:
mode:
Diffstat (limited to 'frontend/src/components/forms')
-rw-r--r--frontend/src/components/forms/MovieUploadForm.tsx92
-rw-r--r--frontend/src/components/forms/ProfileEditForm.module.scss8
-rw-r--r--frontend/src/components/forms/ProfileEditForm.tsx31
-rw-r--r--frontend/src/components/forms/SeriesUploadForm.tsx103
-rw-r--r--frontend/src/components/forms/uploadFormSelectorTypes.tsx16
5 files changed, 173 insertions, 77 deletions
diff --git a/frontend/src/components/forms/MovieUploadForm.tsx b/frontend/src/components/forms/MovieUploadForm.tsx
index 8e318d7ad..f7f8f47c5 100644
--- a/frontend/src/components/forms/MovieUploadForm.tsx
+++ b/frontend/src/components/forms/MovieUploadForm.tsx
@@ -1,9 +1,9 @@
-import { FunctionComponent, useEffect, useMemo } from "react";
+import React, { FunctionComponent, useEffect, useMemo } from "react";
import {
Button,
- Checkbox,
Divider,
MantineColor,
+ Select,
Stack,
Text,
} from "@mantine/core";
@@ -17,8 +17,9 @@ import {
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ColumnDef } from "@tanstack/react-table";
-import { isString } from "lodash";
+import { isString, uniqBy } from "lodash";
import { useMovieSubtitleModification } from "@/apis/hooks";
+import { subtitlesTypeOptions } from "@/components/forms/uploadFormSelectorTypes";
import { Action, Selector } from "@/components/inputs";
import SimpleTable from "@/components/tables/SimpleTable";
import TextPopover from "@/components/TextPopover";
@@ -88,7 +89,7 @@ const MovieUploadForm: FunctionComponent<Props> = ({
const languages = useProfileItemsToLanguages(profile);
const languageOptions = useSelectorOptions(
- languages,
+ uniqBy(languages, "code2"),
(v) => v.name,
(v) => v.code2,
);
@@ -208,34 +209,6 @@ const MovieUploadForm: FunctionComponent<Props> = ({
},
},
{
- header: "Forced",
- accessorKey: "forced",
- cell: ({ row: { original, index } }) => {
- return (
- <Checkbox
- checked={original.forced}
- onChange={({ currentTarget: { checked } }) => {
- action.mutate(index, { ...original, forced: checked });
- }}
- ></Checkbox>
- );
- },
- },
- {
- header: "HI",
- accessorKey: "hi",
- cell: ({ row: { original, index } }) => {
- return (
- <Checkbox
- checked={original.hi}
- onChange={({ currentTarget: { checked } }) => {
- action.mutate(index, { ...original, hi: checked });
- }}
- ></Checkbox>
- );
- },
- },
- {
header: "Language",
accessorKey: "language",
cell: ({ row: { original, index } }) => {
@@ -252,6 +225,61 @@ const MovieUploadForm: FunctionComponent<Props> = ({
},
},
{
+ header: () => (
+ <Selector
+ options={subtitlesTypeOptions}
+ value={null}
+ placeholder="Type"
+ onChange={(value) => {
+ if (value) {
+ action.update((item) => {
+ switch (value) {
+ case "hi":
+ return { ...item, hi: true, forced: false };
+ case "forced":
+ return { ...item, hi: false, forced: true };
+ case "normal":
+ return { ...item, hi: false, forced: false };
+ default:
+ return item;
+ }
+ });
+ }
+ }}
+ ></Selector>
+ ),
+ accessorKey: "type",
+ cell: ({ row: { original, index } }) => {
+ return (
+ <Select
+ value={
+ subtitlesTypeOptions.find((s) => {
+ if (original.hi) {
+ return s.value === "hi";
+ }
+
+ if (original.forced) {
+ return s.value === "forced";
+ }
+
+ return s.value === "normal";
+ })?.value
+ }
+ data={subtitlesTypeOptions}
+ onChange={(value) => {
+ if (value) {
+ action.mutate(index, {
+ ...original,
+ hi: value === "hi",
+ forced: value === "forced",
+ });
+ }
+ }}
+ ></Select>
+ );
+ },
+ },
+ {
id: "action",
cell: ({ row: { index } }) => {
return (
diff --git a/frontend/src/components/forms/ProfileEditForm.module.scss b/frontend/src/components/forms/ProfileEditForm.module.scss
index d98b850ff..3d4a8e177 100644
--- a/frontend/src/components/forms/ProfileEditForm.module.scss
+++ b/frontend/src/components/forms/ProfileEditForm.module.scss
@@ -3,3 +3,11 @@
padding: 0;
}
}
+
+.evenly {
+ flex-wrap: wrap;
+
+ & > div {
+ flex: 1;
+ }
+}
diff --git a/frontend/src/components/forms/ProfileEditForm.tsx b/frontend/src/components/forms/ProfileEditForm.tsx
index 75e2f9df7..267951fcb 100644
--- a/frontend/src/components/forms/ProfileEditForm.tsx
+++ b/frontend/src/components/forms/ProfileEditForm.tsx
@@ -3,6 +3,7 @@ import {
Accordion,
Button,
Checkbox,
+ Flex,
Select,
Stack,
Switch,
@@ -72,9 +73,16 @@ const ProfileEditForm: FunctionComponent<Props> = ({
(value) => value.length > 0,
"Must have a name",
),
+ tag: FormUtils.validation((value) => {
+ if (!value) {
+ return true;
+ }
+
+ return /^[a-z_0-9-]+$/.test(value);
+ }, "Only lowercase alphanumeric characters, underscores (_) and hyphens (-) are allowed"),
items: FormUtils.validation(
(value) => value.length > 0,
- "Must contain at lease 1 language",
+ "Must contain at least 1 language",
),
},
});
@@ -265,7 +273,24 @@ const ProfileEditForm: FunctionComponent<Props> = ({
})}
>
<Stack>
- <TextInput label="Name" {...form.getInputProps("name")}></TextInput>
+ <Flex
+ direction={{ base: "column", sm: "row" }}
+ gap="sm"
+ className={styles.evenly}
+ >
+ <TextInput label="Name" {...form.getInputProps("name")}></TextInput>
+ <TextInput
+ label="Tag"
+ {...form.getInputProps("tag")}
+ onBlur={() =>
+ form.setFieldValue(
+ "tag",
+ (prev) =>
+ prev?.toLowerCase().trim().replace(/\s+/g, "_") ?? undefined,
+ )
+ }
+ ></TextInput>
+ </Flex>
<Accordion
multiple
chevronPosition="right"
@@ -274,7 +299,6 @@ const ProfileEditForm: FunctionComponent<Props> = ({
>
<Accordion.Item value="Languages">
<Stack>
- {form.errors.items}
<SimpleTable
columns={columns}
data={form.values.items}
@@ -282,6 +306,7 @@ const ProfileEditForm: FunctionComponent<Props> = ({
<Button fullWidth onClick={addItem}>
Add Language
</Button>
+ <Text c="var(--mantine-color-error)">{form.errors.items}</Text>
<Selector
clearable
label="Cutoff"
diff --git a/frontend/src/components/forms/SeriesUploadForm.tsx b/frontend/src/components/forms/SeriesUploadForm.tsx
index e4482cab4..9ae6308c9 100644
--- a/frontend/src/components/forms/SeriesUploadForm.tsx
+++ b/frontend/src/components/forms/SeriesUploadForm.tsx
@@ -1,9 +1,9 @@
-import { FunctionComponent, useEffect, useMemo } from "react";
+import React, { FunctionComponent, useEffect, useMemo } from "react";
import {
Button,
- Checkbox,
Divider,
MantineColor,
+ Select,
Stack,
Text,
} from "@mantine/core";
@@ -17,12 +17,13 @@ import {
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { ColumnDef } from "@tanstack/react-table";
-import { isString } from "lodash";
+import { isString, uniqBy } from "lodash";
import {
useEpisodesBySeriesId,
useEpisodeSubtitleModification,
useSubtitleInfos,
} from "@/apis/hooks";
+import { subtitlesTypeOptions } from "@/components/forms/uploadFormSelectorTypes";
import { Action, Selector } from "@/components/inputs";
import SimpleTable from "@/components/tables/SimpleTable";
import TextPopover from "@/components/TextPopover";
@@ -100,7 +101,7 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
const profile = useLanguageProfileBy(series.profileId);
const languages = useProfileItemsToLanguages(profile);
const languageOptions = useSelectorOptions(
- languages,
+ uniqBy(languages, "code2"),
(v) => v.name,
(v) => v.code2,
);
@@ -236,42 +237,6 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
},
},
{
- header: "Forced",
- accessorKey: "forced",
- cell: ({ row: { original, index } }) => {
- return (
- <Checkbox
- checked={original.forced}
- onChange={({ currentTarget: { checked } }) => {
- action.mutate(index, {
- ...original,
- forced: checked,
- hi: checked ? false : original.hi,
- });
- }}
- ></Checkbox>
- );
- },
- },
- {
- header: "HI",
- accessorKey: "hi",
- cell: ({ row: { original, index } }) => {
- return (
- <Checkbox
- checked={original.hi}
- onChange={({ currentTarget: { checked } }) => {
- action.mutate(index, {
- ...original,
- hi: checked,
- forced: checked ? false : original.forced,
- });
- }}
- ></Checkbox>
- );
- },
- },
- {
header: () => (
<Selector
{...languageOptions}
@@ -280,8 +245,7 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
onChange={(value) => {
if (value) {
action.update((item) => {
- item.language = value;
- return item;
+ return { ...item, language: value };
});
}
}}
@@ -302,6 +266,61 @@ const SeriesUploadForm: FunctionComponent<Props> = ({
},
},
{
+ header: () => (
+ <Selector
+ options={subtitlesTypeOptions}
+ value={null}
+ placeholder="Type"
+ onChange={(value) => {
+ if (value) {
+ action.update((item) => {
+ switch (value) {
+ case "hi":
+ return { ...item, hi: true, forced: false };
+ case "forced":
+ return { ...item, hi: false, forced: true };
+ case "normal":
+ return { ...item, hi: false, forced: false };
+ default:
+ return item;
+ }
+ });
+ }
+ }}
+ ></Selector>
+ ),
+ accessorKey: "type",
+ cell: ({ row: { original, index } }) => {
+ return (
+ <Select
+ value={
+ subtitlesTypeOptions.find((s) => {
+ if (original.hi) {
+ return s.value === "hi";
+ }
+
+ if (original.forced) {
+ return s.value === "forced";
+ }
+
+ return s.value === "normal";
+ })?.value
+ }
+ data={subtitlesTypeOptions}
+ onChange={(value) => {
+ if (value) {
+ action.mutate(index, {
+ ...original,
+ hi: value === "hi",
+ forced: value === "forced",
+ });
+ }
+ }}
+ ></Select>
+ );
+ },
+ },
+ {
id: "episode",
header: "Episode",
accessorKey: "episode",
diff --git a/frontend/src/components/forms/uploadFormSelectorTypes.tsx b/frontend/src/components/forms/uploadFormSelectorTypes.tsx
new file mode 100644
index 000000000..168cdddb1
--- /dev/null
+++ b/frontend/src/components/forms/uploadFormSelectorTypes.tsx
@@ -0,0 +1,16 @@
+import { SelectorOption } from "@/components";
+
+export const subtitlesTypeOptions: SelectorOption<string>[] = [
+ {
+ label: "Normal",
+ value: "normal",
+ },
+ {
+ label: "Hearing-Impaired",
+ value: "hi",
+ },
+ {
+ label: "Forced",
+ value: "forced",
+ },
+];