diff --git a/ui/v2.5/src/components/Dialogs/GenerateDialog.tsx b/ui/v2.5/src/components/Dialogs/GenerateDialog.tsx index 71be7affe..186d64e2e 100644 --- a/ui/v2.5/src/components/Dialogs/GenerateDialog.tsx +++ b/ui/v2.5/src/components/Dialogs/GenerateDialog.tsx @@ -12,6 +12,7 @@ import { withoutTypename } from "src/utils/data"; import { GenerateOptions } from "../Settings/Tasks/GenerateOptions"; import { SettingSection } from "../Settings/SettingSection"; import { faCogs, faQuestionCircle } from "@fortawesome/free-solid-svg-icons"; +import { SettingsContext } from "../Settings/context"; interface ISceneGenerateDialog { selectedIds?: string[]; @@ -196,13 +197,15 @@ export const GenerateDialog: React.FC = ({ >
{selectionStatus} - - - + + + + +
); diff --git a/ui/v2.5/src/components/Settings/Inputs.tsx b/ui/v2.5/src/components/Settings/Inputs.tsx index dd7afc2f9..6094ba5ce 100644 --- a/ui/v2.5/src/components/Settings/Inputs.tsx +++ b/ui/v2.5/src/components/Settings/Inputs.tsx @@ -5,9 +5,11 @@ import { FormattedMessage, useIntl } from "react-intl"; import { Icon } from "../Shared/Icon"; import { StringListInput } from "../Shared/StringListInput"; import { PatchComponent } from "src/pluginApi"; +import { useSettings } from "./context"; interface ISetting { id?: string; + advanced?: boolean; className?: string; heading?: React.ReactNode; headingID?: string; @@ -32,8 +34,11 @@ export const Setting: React.FC> = PatchComponent( tooltipID, onClick, disabled, + advanced, } = props; + const { advancedMode } = useSettings(); + const intl = useIntl(); function renderHeading() { @@ -61,6 +66,8 @@ export const Setting: React.FC> = PatchComponent( : undefined; const disabledClassName = disabled ? "disabled" : ""; + if (advanced && !advancedMode) return null; + return (
> = ({ value, children, onChange, + advanced, }) => { return ( - + (props: IModalSetting) => { buttonTextID, modalProps, disabled, + advanced, } = props; const [showModal, setShowModal] = useState(false); + const { advancedMode } = useSettings(); + + if (advanced && !advancedMode) return null; return ( <> diff --git a/ui/v2.5/src/components/Settings/SettingSection.tsx b/ui/v2.5/src/components/Settings/SettingSection.tsx index 41d365088..ad2c9ebae 100644 --- a/ui/v2.5/src/components/Settings/SettingSection.tsx +++ b/ui/v2.5/src/components/Settings/SettingSection.tsx @@ -1,11 +1,13 @@ import React, { PropsWithChildren } from "react"; import { Card } from "react-bootstrap"; import { useIntl } from "react-intl"; +import { useSettings } from "./context"; interface ISettingGroup { id?: string; headingID?: string; subHeadingID?: string; + advanced?: boolean; } export const SettingSection: React.FC> = ({ @@ -13,8 +15,12 @@ export const SettingSection: React.FC> = ({ children, headingID, subHeadingID, + advanced, }) => { const intl = useIntl(); + const { advancedMode } = useSettings(); + + if (advanced && !advancedMode) return null; return (
diff --git a/ui/v2.5/src/components/Settings/Settings.tsx b/ui/v2.5/src/components/Settings/Settings.tsx index 324f8afd5..182de71c7 100644 --- a/ui/v2.5/src/components/Settings/Settings.tsx +++ b/ui/v2.5/src/components/Settings/Settings.tsx @@ -1,6 +1,6 @@ import React from "react"; -import { Tab, Nav, Row, Col } from "react-bootstrap"; -import { Redirect, RouteComponentProps } from "react-router-dom"; +import { Tab, Nav, Row, Col, Form } from "react-bootstrap"; +import { Redirect } from "react-router-dom"; import { LinkContainer } from "react-router-bootstrap"; import { FormattedMessage } from "react-intl"; import { Helmet } from "react-helmet"; @@ -14,7 +14,7 @@ import { SettingsPluginsPanel } from "./SettingsPluginsPanel"; import { SettingsScrapingPanel } from "./SettingsScrapingPanel"; import { SettingsToolsPanel } from "./SettingsToolsPanel"; import { SettingsServicesPanel } from "./SettingsServicesPanel"; -import { SettingsContext } from "./context"; +import { SettingsContext, useSettings } from "./context"; import { SettingsLibraryPanel } from "./SettingsLibraryPanel"; import { SettingsSecurityPanel } from "./SettingsSecurityPanel"; import Changelog from "../Changelog/Changelog"; @@ -41,9 +41,11 @@ function isTabKey(tab: string | null): tab is TabKey { return validTabs.includes(tab as TabKey); } -const Settings: React.FC = ({ location }) => { +const SettingTabs: React.FC = () => { const tab = new URLSearchParams(location.search).get("tab"); + const { advancedMode, setAdvancedMode } = useSettings(); + const titleProps = useTitleProps({ id: "settings" }); if (!isTabKey(tab)) { @@ -147,6 +149,18 @@ const Settings: React.FC = ({ location }) => { + +
+ + + + setAdvancedMode(!advancedMode)} + /> +
+

@@ -156,50 +170,56 @@ const Settings: React.FC = ({ location }) => { md={{ offset: 3 }} xl={{ offset: 2 }} > - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ); }; +export const Settings: React.FC = () => { + return ( + + + + ); +}; + export default Settings; diff --git a/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx b/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx index 78155f61a..07f8868a3 100644 --- a/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx +++ b/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx @@ -240,6 +240,7 @@ export const SettingsInterfacePanel: React.FC = () => { /> { /> - + { { /> { value={general.transcodeInputArgs ?? []} /> { /> { value={general.liveTranscodeInputArgs ?? []} /> = ({ diff --git a/ui/v2.5/src/components/Settings/Tasks/GenerateOptions.tsx b/ui/v2.5/src/components/Settings/Tasks/GenerateOptions.tsx index 23e5f21db..77020e3b3 100644 --- a/ui/v2.5/src/components/Settings/Tasks/GenerateOptions.tsx +++ b/ui/v2.5/src/components/Settings/Tasks/GenerateOptions.tsx @@ -40,6 +40,7 @@ export const GenerateOptions: React.FC = ({ onChange={(v) => setOptions({ previews: v })} /> = ({ onChange={(v) => setOptions({ markers: v })} /> = ({ } /> = ({ /> = ({ /> {selection ? ( { - + @@ -349,7 +349,7 @@ export const LibraryTasks: React.FC = () => { - + = ({ onChange={(v) => setOptions({ scanGeneratePreviews: v })} /> ) => void; saveUI: (input: Partial) => void; savePluginSettings: (pluginID: string, input: {}) => void; + setAdvancedMode: (value: boolean) => void; refetch: () => void; } @@ -91,7 +94,7 @@ export const SettingsContext: React.FC = ({ children }) => { const [pendingDLNA, setPendingDLNA] = useState(); const [updateDLNAConfig] = useConfigureDLNA(); - const [ui, setUI] = useState({}); + const [ui, setUI] = useState({}); const [pendingUI, setPendingUI] = useState<{}>(); const [updateUIConfig] = useConfigureUI(); @@ -430,6 +433,12 @@ export const SettingsContext: React.FC = ({ children }) => { }); } + function setAdvancedMode(value: boolean) { + saveUI({ + advancedMode: value, + }); + } + // saves the configuration if no further changes are made after a half second const savePluginConfig = useDebounce(async (input: PluginSettings) => { try { @@ -536,6 +545,7 @@ export const SettingsContext: React.FC = ({ children }) => { dlna, ui, plugins, + advancedMode: ui.advancedMode ?? false, saveGeneral, saveInterface, saveDefaults, @@ -544,6 +554,7 @@ export const SettingsContext: React.FC = ({ children }) => { saveUI, refetch, savePluginSettings, + setAdvancedMode, }} > {maybeRenderLoadingIndicator()} diff --git a/ui/v2.5/src/components/Settings/styles.scss b/ui/v2.5/src/components/Settings/styles.scss index 02caf99ee..965c9dcfc 100644 --- a/ui/v2.5/src/components/Settings/styles.scss +++ b/ui/v2.5/src/components/Settings/styles.scss @@ -410,3 +410,18 @@ .empty-queue-message { color: $text-muted; } + +.advanced-switch { + display: flex; + justify-content: space-between; + padding: 0.5rem 1rem; + + .form-label { + color: $text-muted; + margin-right: 0.5rem; + } + + .custom-switch { + display: inline-block; + } +} diff --git a/ui/v2.5/src/core/config.ts b/ui/v2.5/src/core/config.ts index 41023de81..c7a196f18 100644 --- a/ui/v2.5/src/core/config.ts +++ b/ui/v2.5/src/core/config.ts @@ -83,6 +83,8 @@ export interface IUIConfig { vrTag?: string; pinnedFilters?: PinnedFilters; + + advancedMode?: boolean; } interface ISavedFilterRowBroken extends ISavedFilterRow { diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json index 0b3823d78..4744acfeb 100644 --- a/ui/v2.5/src/locales/en-GB.json +++ b/ui/v2.5/src/locales/en-GB.json @@ -215,6 +215,7 @@ "stash_wiki": "Stash {url} page", "version": "Version" }, + "advanced_mode": "Advanced Mode", "application_paths": { "heading": "Application Paths" },