import React from "react"; import { Button, Form } from "react-bootstrap"; import { FormattedMessage, useIntl } from "react-intl"; import { DurationInput, PercentInput, LoadingIndicator, } from "src/components/Shared"; import { CheckboxGroup } from "./CheckboxGroup"; import { SettingSection } from "../SettingSection"; import { BooleanSetting, ModalSetting, NumberSetting, SelectSetting, StringSetting, } from "../Inputs"; import { SettingStateContext } from "../context"; import { DurationUtils } from "src/utils"; import * as GQL from "src/core/generated-graphql"; import { imageLightboxDisplayModeIntlMap, imageLightboxScrollModeIntlMap, } from "src/core/enums"; import { useInterfaceLocalForage } from "src/hooks"; import { ConnectionState, connectionStateLabel, InteractiveContext, } from "src/hooks/Interactive/context"; import { defaultRatingStarPrecision, defaultRatingSystemOptions, defaultRatingSystemType, RatingStarPrecision, ratingStarPrecisionIntlMap, ratingSystemIntlMap, RatingSystemType, } from "src/utils/rating"; const allMenuItems = [ { id: "scenes", headingID: "scenes" }, { id: "images", headingID: "images" }, { id: "movies", headingID: "movies" }, { id: "markers", headingID: "markers" }, { id: "galleries", headingID: "galleries" }, { id: "performers", headingID: "performers" }, { id: "studios", headingID: "studios" }, { id: "tags", headingID: "tags" }, ]; export const SettingsInterfacePanel: React.FC = () => { const intl = useIntl(); const { interface: iface, saveInterface, ui, saveUI, loading, error, } = React.useContext(SettingStateContext); const { interactive, state: interactiveState, error: interactiveError, serverOffset: interactiveServerOffset, initialised: interactiveInitialised, initialise: initialiseInteractive, sync: interactiveSync, } = React.useContext(InteractiveContext); const [, setInterfaceLocalForage] = useInterfaceLocalForage(); function saveLightboxSettings(v: Partial) { // save in local forage as well for consistency setInterfaceLocalForage((prev) => { return { ...prev, imageLightbox: { ...prev.imageLightbox, ...v, }, }; }); saveInterface({ imageLightbox: { ...iface.imageLightbox, ...v, }, }); } function saveRatingSystemType(t: RatingSystemType) { saveUI({ ratingSystemOptions: { ...ui.ratingSystemOptions, type: t, }, }); } function saveRatingSystemStarPrecision(p: RatingStarPrecision) { saveUI({ ratingSystemOptions: { ...(ui.ratingSystemOptions ?? defaultRatingSystemOptions), starPrecision: p, }, }); } if (error) return

{error.message}

; if (loading) return ; // https://en.wikipedia.org/wiki/List_of_language_names return ( <> saveInterface({ language: v })} >

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

{intl.formatMessage({ id: "config.ui.menu_items.description" })}
saveInterface({ menuItems: v })} />
saveUI({ abbreviateCounters: v })} /> saveInterface({ noBrowser: v })} /> saveInterface({ notificationsEnabled: v })} /> saveInterface({ wallShowTitle: v })} /> saveInterface({ soundOnPreview: v })} /> saveInterface({ wallPlayback: v })} > saveInterface({ showStudioAsText: v })} /> saveInterface({ showScrubber: v })} /> saveUI({ alwaysStartFromBeginning: v })} /> saveUI({ trackActivity: v })} /> id="ignore-interval" headingID="config.ui.minimum_play_percent.heading" subHeadingID="config.ui.minimum_play_percent.description" value={ui.minimumPlayPercent ?? 0} onChange={(v) => saveUI({ minimumPlayPercent: v })} disabled={!ui.trackActivity} renderField={(value, setValue) => ( setValue(interval ?? 0)} /> )} renderValue={(v) => { return {v}%; }} /> saveLightboxSettings({ slideshowDelay: v })} /> saveInterface({ autostartVideo: v })} /> saveInterface({ autostartVideoOnPlaySelected: v })} /> saveInterface({ continuePlaylistDefault: v })} /> id="max-loop-duration" headingID="config.ui.max_loop_duration.heading" subHeadingID="config.ui.max_loop_duration.description" value={iface.maximumLoopDuration ?? undefined} onChange={(v) => saveInterface({ maximumLoopDuration: v })} renderField={(value, setValue) => ( setValue(duration ?? 0)} /> )} renderValue={(v) => { return {DurationUtils.secondsToString(v ?? 0)}; }} /> saveUI({ showTagCardOnHover: v })} /> saveUI({ showChildTagContent: v })} /> saveUI({ showChildStudioContent: v })} /> saveLightboxSettings({ slideshowDelay: v })} /> saveLightboxSettings({ displayMode: v as GQL.ImageLightboxDisplayMode, }) } > {Array.from(imageLightboxDisplayModeIntlMap.entries()).map((v) => ( ))} saveLightboxSettings({ scaleUp: v })} /> saveLightboxSettings({ resetZoomOnNav: v })} /> saveLightboxSettings({ scrollMode: v as GQL.ImageLightboxScrollMode, }) } > {Array.from(imageLightboxScrollModeIntlMap.entries()).map((v) => ( ))} saveLightboxSettings({ scrollAttemptsBeforeChange: v }) } />

{intl.formatMessage({ id: "config.ui.editing.disable_dropdown_create.heading", })}

{intl.formatMessage({ id: "config.ui.editing.disable_dropdown_create.description", })}
saveInterface({ disableDropdownCreate: { ...iface.disableDropdownCreate, performer: v, }, }) } /> saveInterface({ disableDropdownCreate: { ...iface.disableDropdownCreate, studio: v, }, }) } /> saveInterface({ disableDropdownCreate: { ...iface.disableDropdownCreate, tag: v, }, }) } />
saveRatingSystemType(v as RatingSystemType)} > {Array.from(ratingSystemIntlMap.entries()).map((v) => ( ))} {(ui.ratingSystemOptions?.type ?? defaultRatingSystemType) === RatingSystemType.Stars && ( saveRatingSystemStarPrecision(v as RatingStarPrecision) } > {Array.from(ratingStarPrecisionIntlMap.entries()).map((v) => ( ))} )} saveInterface({ cssEnabled: v })} /> id="custom-css" headingID="config.ui.custom_css.heading" subHeadingID="config.ui.custom_css.description" value={iface.css ?? undefined} onChange={(v) => saveInterface({ css: v })} renderField={(value, setValue) => ( ) => setValue(e.currentTarget.value) } rows={16} className="text-input code" /> )} renderValue={() => { return <>; }} /> saveInterface({ javascriptEnabled: v })} /> id="custom-javascript" headingID="config.ui.custom_javascript.heading" subHeadingID="config.ui.custom_javascript.description" value={iface.javascript ?? undefined} onChange={(v) => saveInterface({ javascript: v })} renderField={(value, setValue) => ( ) => setValue(e.currentTarget.value) } rows={16} className="text-input code" /> )} renderValue={() => { return <>; }} /> saveInterface({ customLocalesEnabled: v })} /> id="custom-locales" headingID="config.ui.custom_locales.heading" subHeadingID="config.ui.custom_locales.description" value={iface.customLocales ?? undefined} onChange={(v) => saveInterface({ customLocales: v })} renderField={(value, setValue) => ( ) => setValue(e.currentTarget.value) } rows={16} className="text-input code" /> )} renderValue={() => { return <>; }} /> saveInterface({ handyKey: v })} /> {interactive.handyKey && ( <>

{intl.formatMessage({ id: "config.ui.handy_connection.status.heading", })}

{interactiveError && : {interactiveError}}
{!interactiveInitialised && ( )}

{intl.formatMessage({ id: "config.ui.handy_connection.server_offset.heading", })}

{interactiveServerOffset.toFixed()}ms
{interactiveInitialised && ( )}
)} saveInterface({ funscriptOffset: v })} />
); };