import React, { useState, useEffect, useMemo } from "react"; import { Form, Button, Collapse } from "react-bootstrap"; import { mutateMetadataGenerate, useConfigureDefaults, } from "src/core/StashService"; import { Modal, Icon, OperationButton } from "src/components/Shared"; import { useToast } from "src/hooks"; import * as GQL from "src/core/generated-graphql"; import { FormattedMessage, useIntl } from "react-intl"; import { ConfigurationContext } from "src/hooks/Config"; // import { DirectorySelectionDialog } from "../Settings/SettingsTasksPanel/DirectorySelectionDialog"; import { Manual } from "../Help/Manual"; import { withoutTypename } from "src/utils"; interface IGenerateOptions { options: GQL.GenerateMetadataInput; setOptions: (s: GQL.GenerateMetadataInput) => void; } const GenerateOptions: React.FC = ({ options, setOptions: setOptionsState, }) => { const intl = useIntl(); const [previewOptionsOpen, setPreviewOptionsOpen] = useState(false); const previewOptions: GQL.GeneratePreviewOptionsInput = options.previewOptions ?? {}; function setOptions(input: Partial) { setOptionsState({ ...options, ...input }); } function setPreviewOptions(input: Partial) { setOptions({ previewOptions: { ...previewOptions, ...input, }, }); } return ( setOptions({ previews: !options.previews })} />
setOptions({ imagePreviews: !options.imagePreviews }) } className="ml-2 flex-grow" />
{intl.formatMessage({ id: "dialogs.scene_gen.preview_preset_head", })}
setPreviewOptions({ previewPreset: e.currentTarget.value as GQL.PreviewPreset, }) } > {Object.keys(GQL.PreviewPreset).map((p) => ( ))} {intl.formatMessage({ id: "dialogs.scene_gen.preview_preset_desc", })}
{intl.formatMessage({ id: "dialogs.scene_gen.preview_seg_count_head", })}
setPreviewOptions({ previewSegments: Number.parseInt( e.currentTarget.value, 10 ), }) } /> {intl.formatMessage({ id: "dialogs.scene_gen.preview_seg_count_desc", })}
{intl.formatMessage({ id: "dialogs.scene_gen.preview_seg_duration_head", })}
setPreviewOptions({ previewSegmentDuration: Number.parseFloat( e.currentTarget.value ), }) } /> {intl.formatMessage({ id: "dialogs.scene_gen.preview_seg_duration_desc", })}
{intl.formatMessage({ id: "dialogs.scene_gen.preview_exclude_start_time_head", })}
setPreviewOptions({ previewExcludeStart: e.currentTarget.value, }) } /> {intl.formatMessage({ id: "dialogs.scene_gen.preview_exclude_start_time_desc", })}
{intl.formatMessage({ id: "dialogs.scene_gen.preview_exclude_end_time_head", })}
setPreviewOptions({ previewExcludeEnd: e.currentTarget.value, }) } /> {intl.formatMessage({ id: "dialogs.scene_gen.preview_exclude_end_time_desc", })}
setOptions({ sprites: !options.sprites })} /> setOptions({ markers: !options.markers })} />
setOptions({ markerImagePreviews: !options.markerImagePreviews, }) } className="ml-2 flex-grow" /> setOptions({ markerScreenshots: !options.markerScreenshots }) } className="ml-2 flex-grow" />
setOptions({ transcodes: !options.transcodes })} /> setOptions({ phashes: !options.phashes })} />
setOptions({ overwrite: !options.overwrite })} />
); }; interface ISceneGenerateDialog { selectedIds?: string[]; onClose: () => void; } export const GenerateDialog: React.FC = ({ selectedIds, onClose, }) => { const { configuration } = React.useContext(ConfigurationContext); const [configureDefaults] = useConfigureDefaults(); function getDefaultOptions(): GQL.GenerateMetadataInput { return { sprites: true, phashes: true, previews: true, markers: true, previewOptions: { previewSegments: 0, previewSegmentDuration: 0, previewPreset: GQL.PreviewPreset.Slow, }, }; } const [options, setOptions] = useState( getDefaultOptions() ); const [configRead, setConfigRead] = useState(false); const [paths /* , setPaths */] = useState([]); const [showManual, setShowManual] = useState(false); // const [settingPaths, setSettingPaths] = useState(false); const [savingDefaults, setSavingDefaults] = useState(false); const [animation, setAnimation] = useState(true); const intl = useIntl(); const Toast = useToast(); useEffect(() => { if (configRead) { return; } if (configuration?.defaults.generate) { const { generate } = configuration.defaults; setOptions(withoutTypename(generate)); setConfigRead(true); } else if (configuration?.general) { // backwards compatibility const { general } = configuration; setOptions((existing) => ({ ...existing, previewOptions: { ...existing.previewOptions, previewSegments: general.previewSegments ?? existing.previewOptions?.previewSegments, previewSegmentDuration: general.previewSegmentDuration ?? existing.previewOptions?.previewSegmentDuration, previewExcludeStart: general.previewExcludeStart ?? existing.previewOptions?.previewExcludeStart, previewExcludeEnd: general.previewExcludeEnd ?? existing.previewOptions?.previewExcludeEnd, previewPreset: general.previewPreset ?? existing.previewOptions?.previewPreset, }, })); setConfigRead(true); } }, [configuration, configRead]); const selectionStatus = useMemo(() => { if (selectedIds) { return ( . ); } const message = paths.length ? (
:
    {paths.map((p) => (
  • {p}
  • ))}
) : ( . ); // function onClick() { // setAnimation(false); // setSettingPaths(true); // } return (
{message} {/*
*/}
); }, [selectedIds, intl, paths]); async function onGenerate() { try { await mutateMetadataGenerate(options); Toast.success({ content: intl.formatMessage( { id: "config.tasks.added_job_to_queue" }, { operation_name: intl.formatMessage({ id: "actions.generate" }) } ), }); } catch (e) { Toast.error(e); } finally { onClose(); } } function makeDefaultGenerateInput() { const ret = options; // const { paths: _paths, ...withoutSpecifics } = ret; const { overwrite: _overwrite, ...withoutSpecifics } = ret; return withoutSpecifics; } function onShowManual() { setAnimation(false); setShowManual(true); } async function setAsDefault() { try { setSavingDefaults(true); await configureDefaults({ variables: { input: { generate: makeDefaultGenerateInput(), }, }, }); Toast.success({ content: intl.formatMessage( { id: "config.tasks.defaults_set" }, { action: intl.formatMessage({ id: "actions.generate" }) } ), }); } catch (e) { Toast.error(e); } finally { setSavingDefaults(false); } } // if (settingPaths) { // return ( // { // if (p) { // setPaths(p); // } // setSettingPaths(false); // }} // /> // ); // } if (showManual) { return ( setShowManual(false)} defaultActiveTab="Tasks.md" /> ); } return ( onClose(), text: intl.formatMessage({ id: "actions.cancel" }), variant: "secondary", }} disabled={savingDefaults} footerButtons={ } leftFooterButtons={ } >
{selectionStatus}
); };