import React, { useEffect, useState } from "react"; import { Button, Form } from "react-bootstrap"; import { useIntl } from "react-intl"; import { DurationInput, LoadingIndicator } from "src/components/Shared"; import { useConfiguration, useConfigureDefaults, useConfigureInterface, } from "src/core/StashService"; import { useToast } from "src/hooks"; import * as GQL from "src/core/generated-graphql"; import { CheckboxGroup } from "./CheckboxGroup"; import { withoutTypename } from "src/utils"; const allMenuItems = [ { id: "scenes", label: "Scenes" }, { id: "images", label: "Images" }, { id: "movies", label: "Movies" }, { id: "markers", label: "Markers" }, { id: "galleries", label: "Galleries" }, { id: "performers", label: "Performers" }, { id: "studios", label: "Studios" }, { id: "tags", label: "Tags" }, ]; const SECONDS_TO_MS = 1000; export const SettingsInterfacePanel: React.FC = () => { const intl = useIntl(); const Toast = useToast(); const { data: config, error, loading } = useConfiguration(); const [menuItemIds, setMenuItemIds] = useState( allMenuItems.map((item) => item.id) ); const [noBrowser, setNoBrowserFlag] = useState(false); const [soundOnPreview, setSoundOnPreview] = useState(true); const [wallShowTitle, setWallShowTitle] = useState(true); const [wallPlayback, setWallPlayback] = useState("video"); const [maximumLoopDuration, setMaximumLoopDuration] = useState(0); const [autostartVideo, setAutostartVideo] = useState(false); const [ autostartVideoOnPlaySelected, setAutostartVideoOnPlaySelected, ] = useState(true); const [continuePlaylistDefault, setContinuePlaylistDefault] = useState(false); const [slideshowDelay, setSlideshowDelay] = useState(0); const [showStudioAsText, setShowStudioAsText] = useState(false); const [css, setCSS] = useState(); const [cssEnabled, setCSSEnabled] = useState(false); const [language, setLanguage] = useState("en"); const [handyKey, setHandyKey] = useState(); const [funscriptOffset, setFunscriptOffset] = useState(0); const [deleteFileDefault, setDeleteFileDefault] = useState(false); const [deleteGeneratedDefault, setDeleteGeneratedDefault] = useState( true ); const [ disableDropdownCreate, setDisableDropdownCreate, ] = useState({}); const [updateInterfaceConfig] = useConfigureInterface({ menuItems: menuItemIds, soundOnPreview, wallShowTitle, wallPlayback, maximumLoopDuration, noBrowser, autostartVideo, autostartVideoOnPlaySelected, continuePlaylistDefault, showStudioAsText, css, cssEnabled, language, slideshowDelay, handyKey, funscriptOffset, disableDropdownCreate, }); const [updateDefaultsConfig] = useConfigureDefaults(); useEffect(() => { if (config) { const { interface: iCfg, defaults } = config.configuration; setMenuItemIds(iCfg.menuItems ?? allMenuItems.map((item) => item.id)); setSoundOnPreview(iCfg.soundOnPreview ?? true); setWallShowTitle(iCfg.wallShowTitle ?? true); setWallPlayback(iCfg.wallPlayback ?? "video"); setMaximumLoopDuration(iCfg.maximumLoopDuration ?? 0); setNoBrowserFlag(iCfg?.noBrowser ?? false); setAutostartVideo(iCfg.autostartVideo ?? false); setAutostartVideoOnPlaySelected( iCfg.autostartVideoOnPlaySelected ?? true ); setContinuePlaylistDefault(iCfg.continuePlaylistDefault ?? false); setShowStudioAsText(iCfg.showStudioAsText ?? false); setCSS(iCfg.css ?? ""); setCSSEnabled(iCfg.cssEnabled ?? false); setLanguage(iCfg.language ?? "en-US"); setSlideshowDelay(iCfg.slideshowDelay ?? 5000); setHandyKey(iCfg.handyKey ?? ""); setFunscriptOffset(iCfg.funscriptOffset ?? 0); setDisableDropdownCreate({ performer: iCfg.disabledDropdownCreate.performer, studio: iCfg.disabledDropdownCreate.studio, tag: iCfg.disabledDropdownCreate.tag, }); setDeleteFileDefault(defaults.deleteFile ?? false); setDeleteGeneratedDefault(defaults.deleteGenerated ?? true); } }, [config]); async function onSave() { const prevCSS = config?.configuration.interface.css; const prevCSSenabled = config?.configuration.interface.cssEnabled; try { if (config?.configuration.defaults) { await updateDefaultsConfig({ variables: { input: { ...withoutTypename(config?.configuration.defaults), deleteFile: deleteFileDefault, deleteGenerated: deleteGeneratedDefault, }, }, }); } const result = await updateInterfaceConfig(); // Force refetch of custom css if it was changed if ( prevCSS !== result.data?.configureInterface.css || prevCSSenabled !== result.data?.configureInterface.cssEnabled ) { await fetch("/css", { cache: "reload" }); window.location.reload(); } Toast.success({ content: intl.formatMessage( { id: "toast.updated_entity" }, { entity: intl .formatMessage({ id: "configuration" }) .toLocaleLowerCase(), } ), }); } catch (e) { Toast.error(e); } } if (error) return

{error.message}

; if (loading) return ; return ( <>

{intl.formatMessage({ id: "config.ui.title" })}

{intl.formatMessage({ id: "config.ui.language.heading" })}
) => setLanguage(e.currentTarget.value) } >
{intl.formatMessage({ id: "config.ui.menu_items.heading" })}
{intl.formatMessage({ id: "config.ui.menu_items.description" })}

{intl.formatMessage({ id: "config.ui.desktop_integration.desktop_integration", })}

setNoBrowserFlag(!noBrowser)} /> {intl.formatMessage({ id: "config.ui.desktop_integration.skip_opening_browser_on_startup", })}
{intl.formatMessage({ id: "config.ui.scene_wall.heading" })}
setWallShowTitle(!wallShowTitle)} /> setSoundOnPreview(!soundOnPreview)} />
{intl.formatMessage({ id: "config.ui.preview_type.heading" })}
) => setWallPlayback(e.currentTarget.value) } > {intl.formatMessage({ id: "config.ui.preview_type.description" })}
{intl.formatMessage({ id: "config.ui.scene_list.heading" })}
{ setShowStudioAsText(!showStudioAsText); }} />
{intl.formatMessage({ id: "config.ui.scene_player.heading" })}
{ setAutostartVideo(!autostartVideo); }} /> { setAutostartVideoOnPlaySelected(!autostartVideoOnPlaySelected); }} /> {intl.formatMessage({ id: "config.ui.scene_player.options.auto_start_video_on_play_selected.description", })} { setContinuePlaylistDefault(!continuePlaylistDefault); }} /> {intl.formatMessage({ id: "config.ui.scene_player.options.continue_playlist_default.description", })}
{intl.formatMessage({ id: "config.ui.max_loop_duration.heading" })}
setMaximumLoopDuration(duration ?? 0)} /> {intl.formatMessage({ id: "config.ui.max_loop_duration.description", })}
{intl.formatMessage({ id: "config.ui.slideshow_delay.heading" })}
) => { setSlideshowDelay( Number.parseInt(e.currentTarget.value, 10) * SECONDS_TO_MS ); }} /> {intl.formatMessage({ id: "config.ui.slideshow_delay.description" })}
{intl.formatMessage({ id: "config.ui.editing.heading" })}
{intl.formatMessage({ id: "config.ui.editing.disable_dropdown_create.heading", })}
{ setDisableDropdownCreate({ ...disableDropdownCreate, performer: !disableDropdownCreate.performer ?? true, }); }} /> { setDisableDropdownCreate({ ...disableDropdownCreate, studio: !disableDropdownCreate.studio ?? true, }); }} /> { setDisableDropdownCreate({ ...disableDropdownCreate, tag: !disableDropdownCreate.tag ?? true, }); }} /> {intl.formatMessage({ id: "config.ui.editing.disable_dropdown_create.description", })}
{intl.formatMessage({ id: "config.ui.custom_css.heading" })}
{ setCSSEnabled(!cssEnabled); }} /> ) => setCSS(e.currentTarget.value) } rows={16} className="col col-sm-6 text-input code" /> {intl.formatMessage({ id: "config.ui.custom_css.description" })}
{intl.formatMessage({ id: "config.ui.handy_connection_key.heading" })}
) => { setHandyKey(e.currentTarget.value); }} /> {intl.formatMessage({ id: "config.ui.handy_connection_key.description", })}
{intl.formatMessage({ id: "config.ui.funscript_offset.heading" })}
) => { setFunscriptOffset(Number.parseInt(e.currentTarget.value, 10)); }} /> {intl.formatMessage({ id: "config.ui.funscript_offset.description" })}
{intl.formatMessage({ id: "config.ui.delete_options.heading" })}
{ setDeleteFileDefault(!deleteFileDefault); }} /> { setDeleteGeneratedDefault(!deleteGeneratedDefault); }} /> {intl.formatMessage({ id: "config.ui.delete_options.description", })}

); };