import { useSubtitleAction } from "@/apis/hooks"; import { ColorToolModal } from "@/components/forms/ColorToolForm"; import { FrameRateModal } from "@/components/forms/FrameRateForm"; import { TimeOffsetModal } from "@/components/forms/TimeOffsetForm"; import { TranslationModal } from "@/components/forms/TranslationForm"; import { useModals } from "@/modules/modals"; import { ModalComponent } from "@/modules/modals/WithModal"; import { task } from "@/modules/task"; import { faClock, faCode, faDeaf, faExchangeAlt, faFilm, faImage, faLanguage, faMagic, faPaintBrush, faPlay, faSearch, faTextHeight, faTrash, IconDefinition, } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Divider, List, Menu, MenuProps, ScrollArea } from "@mantine/core"; import { FunctionComponent, ReactElement, useCallback, useMemo } from "react"; import { SyncSubtitleModal } from "./forms/SyncSubtitleForm"; export interface ToolOptions { key: string; icon: IconDefinition; name: string; modal?: ModalComponent<{ selections: FormType.ModifySubtitle[]; }>; } export function useTools() { return useMemo( () => [ { key: "sync", icon: faPlay, name: "Sync...", modal: SyncSubtitleModal, }, { key: "remove_HI", icon: faDeaf, name: "Remove HI Tags", }, { key: "remove_tags", icon: faCode, name: "Remove Style Tags", }, { key: "OCR_fixes", icon: faImage, name: "OCR Fixes", }, { key: "common", icon: faMagic, name: "Common Fixes", }, { key: "fix_uppercase", icon: faTextHeight, name: "Fix Uppercase", }, { key: "reverse_rtl", icon: faExchangeAlt, name: "Reverse RTL", }, { key: "add_color", icon: faPaintBrush, name: "Add Color...", modal: ColorToolModal, }, { key: "change_frame_rate", icon: faFilm, name: "Change Frame Rate...", modal: FrameRateModal, }, { key: "adjust_time", icon: faClock, name: "Adjust Times...", modal: TimeOffsetModal, }, { key: "translation", icon: faLanguage, name: "Translate...", modal: TranslationModal, }, ], [], ); } interface Props { selections: FormType.ModifySubtitle[]; children?: ReactElement; menu?: Omit; onAction?: (action: "delete" | "search") => void; } const SubtitleToolsMenu: FunctionComponent = ({ selections, children, menu, onAction, }) => { const { mutateAsync } = useSubtitleAction(); const process = useCallback( (action: string, name: string) => { selections.forEach((s) => { const form: FormType.ModifySubtitle = { id: s.id, type: s.type, language: s.language, path: s.path, }; task.create(s.path, name, mutateAsync, { action, form }); }); }, [mutateAsync, selections], ); const tools = useTools(); const modals = useModals(); const disabledTools = selections.length === 0; return ( {children} Tools {tools.map((tool) => ( } onClick={() => { if (tool.modal) { modals.openContextModal(tool.modal, { selections }); } else { process(tool.key, tool.name); } }} > {tool.name} ))} Actions } onClick={() => { onAction?.("search"); }} > Search } onClick={() => { modals.openConfirmModal({ title: "The following subtitles will be deleted", size: "lg", children: ( {selections.map((s) => ( {s.path} ))} ), onConfirm: () => { onAction?.("delete"); }, labels: { confirm: "Delete", cancel: "Cancel" }, confirmProps: { color: "red" }, }); }} > Delete... ); }; export default SubtitleToolsMenu;