mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 20:34:37 +03:00
Advanced settings (#4378)
* Add advanced settings mode toggle * Add advanced settings
This commit is contained in:
@@ -12,6 +12,7 @@ import { withoutTypename } from "src/utils/data";
|
|||||||
import { GenerateOptions } from "../Settings/Tasks/GenerateOptions";
|
import { GenerateOptions } from "../Settings/Tasks/GenerateOptions";
|
||||||
import { SettingSection } from "../Settings/SettingSection";
|
import { SettingSection } from "../Settings/SettingSection";
|
||||||
import { faCogs, faQuestionCircle } from "@fortawesome/free-solid-svg-icons";
|
import { faCogs, faQuestionCircle } from "@fortawesome/free-solid-svg-icons";
|
||||||
|
import { SettingsContext } from "../Settings/context";
|
||||||
|
|
||||||
interface ISceneGenerateDialog {
|
interface ISceneGenerateDialog {
|
||||||
selectedIds?: string[];
|
selectedIds?: string[];
|
||||||
@@ -196,6 +197,7 @@ export const GenerateDialog: React.FC<ISceneGenerateDialog> = ({
|
|||||||
>
|
>
|
||||||
<Form>
|
<Form>
|
||||||
{selectionStatus}
|
{selectionStatus}
|
||||||
|
<SettingsContext>
|
||||||
<SettingSection>
|
<SettingSection>
|
||||||
<GenerateOptions
|
<GenerateOptions
|
||||||
options={options}
|
options={options}
|
||||||
@@ -203,6 +205,7 @@ export const GenerateDialog: React.FC<ISceneGenerateDialog> = ({
|
|||||||
selection
|
selection
|
||||||
/>
|
/>
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
|
</SettingsContext>
|
||||||
</Form>
|
</Form>
|
||||||
</ModalComponent>
|
</ModalComponent>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -5,9 +5,11 @@ import { FormattedMessage, useIntl } from "react-intl";
|
|||||||
import { Icon } from "../Shared/Icon";
|
import { Icon } from "../Shared/Icon";
|
||||||
import { StringListInput } from "../Shared/StringListInput";
|
import { StringListInput } from "../Shared/StringListInput";
|
||||||
import { PatchComponent } from "src/pluginApi";
|
import { PatchComponent } from "src/pluginApi";
|
||||||
|
import { useSettings } from "./context";
|
||||||
|
|
||||||
interface ISetting {
|
interface ISetting {
|
||||||
id?: string;
|
id?: string;
|
||||||
|
advanced?: boolean;
|
||||||
className?: string;
|
className?: string;
|
||||||
heading?: React.ReactNode;
|
heading?: React.ReactNode;
|
||||||
headingID?: string;
|
headingID?: string;
|
||||||
@@ -32,8 +34,11 @@ export const Setting: React.FC<PropsWithChildren<ISetting>> = PatchComponent(
|
|||||||
tooltipID,
|
tooltipID,
|
||||||
onClick,
|
onClick,
|
||||||
disabled,
|
disabled,
|
||||||
|
advanced,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
|
const { advancedMode } = useSettings();
|
||||||
|
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
|
||||||
function renderHeading() {
|
function renderHeading() {
|
||||||
@@ -61,6 +66,8 @@ export const Setting: React.FC<PropsWithChildren<ISetting>> = PatchComponent(
|
|||||||
: undefined;
|
: undefined;
|
||||||
const disabledClassName = disabled ? "disabled" : "";
|
const disabledClassName = disabled ? "disabled" : "";
|
||||||
|
|
||||||
|
if (advanced && !advancedMode) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={`setting ${className ?? ""} ${disabledClassName}`}
|
className={`setting ${className ?? ""} ${disabledClassName}`}
|
||||||
@@ -172,9 +179,15 @@ export const SelectSetting: React.FC<PropsWithChildren<ISelectSetting>> = ({
|
|||||||
value,
|
value,
|
||||||
children,
|
children,
|
||||||
onChange,
|
onChange,
|
||||||
|
advanced,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<Setting headingID={headingID} subHeadingID={subHeadingID} id={id}>
|
<Setting
|
||||||
|
advanced={advanced}
|
||||||
|
headingID={headingID}
|
||||||
|
subHeadingID={subHeadingID}
|
||||||
|
id={id}
|
||||||
|
>
|
||||||
<Form.Control
|
<Form.Control
|
||||||
className="input-control"
|
className="input-control"
|
||||||
as="select"
|
as="select"
|
||||||
@@ -346,8 +359,12 @@ export const ModalSetting = <T extends {}>(props: IModalSetting<T>) => {
|
|||||||
buttonTextID,
|
buttonTextID,
|
||||||
modalProps,
|
modalProps,
|
||||||
disabled,
|
disabled,
|
||||||
|
advanced,
|
||||||
} = props;
|
} = props;
|
||||||
const [showModal, setShowModal] = useState(false);
|
const [showModal, setShowModal] = useState(false);
|
||||||
|
const { advancedMode } = useSettings();
|
||||||
|
|
||||||
|
if (advanced && !advancedMode) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
import React, { PropsWithChildren } from "react";
|
import React, { PropsWithChildren } from "react";
|
||||||
import { Card } from "react-bootstrap";
|
import { Card } from "react-bootstrap";
|
||||||
import { useIntl } from "react-intl";
|
import { useIntl } from "react-intl";
|
||||||
|
import { useSettings } from "./context";
|
||||||
|
|
||||||
interface ISettingGroup {
|
interface ISettingGroup {
|
||||||
id?: string;
|
id?: string;
|
||||||
headingID?: string;
|
headingID?: string;
|
||||||
subHeadingID?: string;
|
subHeadingID?: string;
|
||||||
|
advanced?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SettingSection: React.FC<PropsWithChildren<ISettingGroup>> = ({
|
export const SettingSection: React.FC<PropsWithChildren<ISettingGroup>> = ({
|
||||||
@@ -13,8 +15,12 @@ export const SettingSection: React.FC<PropsWithChildren<ISettingGroup>> = ({
|
|||||||
children,
|
children,
|
||||||
headingID,
|
headingID,
|
||||||
subHeadingID,
|
subHeadingID,
|
||||||
|
advanced,
|
||||||
}) => {
|
}) => {
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
|
const { advancedMode } = useSettings();
|
||||||
|
|
||||||
|
if (advanced && !advancedMode) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="setting-section" id={id}>
|
<div className="setting-section" id={id}>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Tab, Nav, Row, Col } from "react-bootstrap";
|
import { Tab, Nav, Row, Col, Form } from "react-bootstrap";
|
||||||
import { Redirect, RouteComponentProps } from "react-router-dom";
|
import { Redirect } from "react-router-dom";
|
||||||
import { LinkContainer } from "react-router-bootstrap";
|
import { LinkContainer } from "react-router-bootstrap";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { Helmet } from "react-helmet";
|
import { Helmet } from "react-helmet";
|
||||||
@@ -14,7 +14,7 @@ import { SettingsPluginsPanel } from "./SettingsPluginsPanel";
|
|||||||
import { SettingsScrapingPanel } from "./SettingsScrapingPanel";
|
import { SettingsScrapingPanel } from "./SettingsScrapingPanel";
|
||||||
import { SettingsToolsPanel } from "./SettingsToolsPanel";
|
import { SettingsToolsPanel } from "./SettingsToolsPanel";
|
||||||
import { SettingsServicesPanel } from "./SettingsServicesPanel";
|
import { SettingsServicesPanel } from "./SettingsServicesPanel";
|
||||||
import { SettingsContext } from "./context";
|
import { SettingsContext, useSettings } from "./context";
|
||||||
import { SettingsLibraryPanel } from "./SettingsLibraryPanel";
|
import { SettingsLibraryPanel } from "./SettingsLibraryPanel";
|
||||||
import { SettingsSecurityPanel } from "./SettingsSecurityPanel";
|
import { SettingsSecurityPanel } from "./SettingsSecurityPanel";
|
||||||
import Changelog from "../Changelog/Changelog";
|
import Changelog from "../Changelog/Changelog";
|
||||||
@@ -41,9 +41,11 @@ function isTabKey(tab: string | null): tab is TabKey {
|
|||||||
return validTabs.includes(tab as TabKey);
|
return validTabs.includes(tab as TabKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
const Settings: React.FC<RouteComponentProps> = ({ location }) => {
|
const SettingTabs: React.FC = () => {
|
||||||
const tab = new URLSearchParams(location.search).get("tab");
|
const tab = new URLSearchParams(location.search).get("tab");
|
||||||
|
|
||||||
|
const { advancedMode, setAdvancedMode } = useSettings();
|
||||||
|
|
||||||
const titleProps = useTitleProps({ id: "settings" });
|
const titleProps = useTitleProps({ id: "settings" });
|
||||||
|
|
||||||
if (!isTabKey(tab)) {
|
if (!isTabKey(tab)) {
|
||||||
@@ -147,6 +149,18 @@ const Settings: React.FC<RouteComponentProps> = ({ location }) => {
|
|||||||
</Nav.Link>
|
</Nav.Link>
|
||||||
</LinkContainer>
|
</LinkContainer>
|
||||||
</Nav.Item>
|
</Nav.Item>
|
||||||
|
<Nav.Item>
|
||||||
|
<div className="advanced-switch">
|
||||||
|
<Form.Label htmlFor="advanced-settings">
|
||||||
|
<FormattedMessage id="config.advanced_mode" />
|
||||||
|
</Form.Label>
|
||||||
|
<Form.Switch
|
||||||
|
id="advanced-settings"
|
||||||
|
checked={advancedMode}
|
||||||
|
onChange={() => setAdvancedMode(!advancedMode)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Nav.Item>
|
||||||
<hr className="d-sm-none" />
|
<hr className="d-sm-none" />
|
||||||
</Nav>
|
</Nav>
|
||||||
</Col>
|
</Col>
|
||||||
@@ -156,7 +170,6 @@ const Settings: React.FC<RouteComponentProps> = ({ location }) => {
|
|||||||
md={{ offset: 3 }}
|
md={{ offset: 3 }}
|
||||||
xl={{ offset: 2 }}
|
xl={{ offset: 2 }}
|
||||||
>
|
>
|
||||||
<SettingsContext>
|
|
||||||
<Tab.Content className="mx-auto">
|
<Tab.Content className="mx-auto">
|
||||||
<Tab.Pane eventKey="library">
|
<Tab.Pane eventKey="library">
|
||||||
<SettingsLibraryPanel />
|
<SettingsLibraryPanel />
|
||||||
@@ -195,11 +208,18 @@ const Settings: React.FC<RouteComponentProps> = ({ location }) => {
|
|||||||
<SettingsAboutPanel />
|
<SettingsAboutPanel />
|
||||||
</Tab.Pane>
|
</Tab.Pane>
|
||||||
</Tab.Content>
|
</Tab.Content>
|
||||||
</SettingsContext>
|
|
||||||
</Col>
|
</Col>
|
||||||
</Row>
|
</Row>
|
||||||
</Tab.Container>
|
</Tab.Container>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const Settings: React.FC = () => {
|
||||||
|
return (
|
||||||
|
<SettingsContext>
|
||||||
|
<SettingTabs />
|
||||||
|
</SettingsContext>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export default Settings;
|
export default Settings;
|
||||||
|
|||||||
@@ -240,6 +240,7 @@ export const SettingsInterfacePanel: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<SelectSetting
|
<SelectSetting
|
||||||
|
advanced
|
||||||
id="wall-preview"
|
id="wall-preview"
|
||||||
headingID="config.ui.preview_type.heading"
|
headingID="config.ui.preview_type.heading"
|
||||||
subHeadingID="config.ui.preview_type.description"
|
subHeadingID="config.ui.preview_type.description"
|
||||||
|
|||||||
@@ -210,7 +210,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
|
|
||||||
<SettingSection headingID="config.general.hashing">
|
<SettingSection advanced headingID="config.general.hashing">
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
id="calculate-md5-and-ohash"
|
id="calculate-md5-and-ohash"
|
||||||
headingID="config.general.calculate_md5_and_ohash_label"
|
headingID="config.general.calculate_md5_and_ohash_label"
|
||||||
@@ -240,6 +240,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||||||
|
|
||||||
<SettingSection headingID="config.system.transcoding">
|
<SettingSection headingID="config.system.transcoding">
|
||||||
<SelectSetting
|
<SelectSetting
|
||||||
|
advanced
|
||||||
id="transcode-size"
|
id="transcode-size"
|
||||||
headingID="config.general.maximum_transcode_size_head"
|
headingID="config.general.maximum_transcode_size_head"
|
||||||
subHeadingID="config.general.maximum_transcode_size_desc"
|
subHeadingID="config.general.maximum_transcode_size_desc"
|
||||||
@@ -282,6 +283,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<StringListSetting
|
<StringListSetting
|
||||||
|
advanced
|
||||||
id="transcode-input-args"
|
id="transcode-input-args"
|
||||||
headingID="config.general.ffmpeg.transcode.input_args.heading"
|
headingID="config.general.ffmpeg.transcode.input_args.heading"
|
||||||
subHeadingID="config.general.ffmpeg.transcode.input_args.desc"
|
subHeadingID="config.general.ffmpeg.transcode.input_args.desc"
|
||||||
@@ -289,6 +291,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||||||
value={general.transcodeInputArgs ?? []}
|
value={general.transcodeInputArgs ?? []}
|
||||||
/>
|
/>
|
||||||
<StringListSetting
|
<StringListSetting
|
||||||
|
advanced
|
||||||
id="transcode-output-args"
|
id="transcode-output-args"
|
||||||
headingID="config.general.ffmpeg.transcode.output_args.heading"
|
headingID="config.general.ffmpeg.transcode.output_args.heading"
|
||||||
subHeadingID="config.general.ffmpeg.transcode.output_args.desc"
|
subHeadingID="config.general.ffmpeg.transcode.output_args.desc"
|
||||||
@@ -297,6 +300,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<StringListSetting
|
<StringListSetting
|
||||||
|
advanced
|
||||||
id="live-transcode-input-args"
|
id="live-transcode-input-args"
|
||||||
headingID="config.general.ffmpeg.live_transcode.input_args.heading"
|
headingID="config.general.ffmpeg.live_transcode.input_args.heading"
|
||||||
subHeadingID="config.general.ffmpeg.live_transcode.input_args.desc"
|
subHeadingID="config.general.ffmpeg.live_transcode.input_args.desc"
|
||||||
@@ -304,6 +308,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
|
|||||||
value={general.liveTranscodeInputArgs ?? []}
|
value={general.liveTranscodeInputArgs ?? []}
|
||||||
/>
|
/>
|
||||||
<StringListSetting
|
<StringListSetting
|
||||||
|
advanced
|
||||||
id="live-transcode-output-args"
|
id="live-transcode-output-args"
|
||||||
headingID="config.general.ffmpeg.live_transcode.output_args.heading"
|
headingID="config.general.ffmpeg.live_transcode.output_args.heading"
|
||||||
subHeadingID="config.general.ffmpeg.live_transcode.output_args.desc"
|
subHeadingID="config.general.ffmpeg.live_transcode.output_args.desc"
|
||||||
|
|||||||
@@ -583,6 +583,7 @@ export const DataManagementTasks: React.FC<IDataManagementTasks> = ({
|
|||||||
|
|
||||||
<SettingSection headingID="config.tasks.migrations">
|
<SettingSection headingID="config.tasks.migrations">
|
||||||
<Setting
|
<Setting
|
||||||
|
advanced
|
||||||
headingID="actions.rename_gen_files"
|
headingID="actions.rename_gen_files"
|
||||||
subHeadingID="config.tasks.migrate_hash_files"
|
subHeadingID="config.tasks.migrate_hash_files"
|
||||||
>
|
>
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ export const GenerateOptions: React.FC<IGenerateOptions> = ({
|
|||||||
onChange={(v) => setOptions({ previews: v })}
|
onChange={(v) => setOptions({ previews: v })}
|
||||||
/>
|
/>
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
|
advanced
|
||||||
className="sub-setting"
|
className="sub-setting"
|
||||||
id="image-preview-task"
|
id="image-preview-task"
|
||||||
checked={options.imagePreviews ?? false}
|
checked={options.imagePreviews ?? false}
|
||||||
@@ -88,6 +89,7 @@ export const GenerateOptions: React.FC<IGenerateOptions> = ({
|
|||||||
onChange={(v) => setOptions({ markers: v })}
|
onChange={(v) => setOptions({ markers: v })}
|
||||||
/>
|
/>
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
|
advanced
|
||||||
id="marker-image-preview-task"
|
id="marker-image-preview-task"
|
||||||
className="sub-setting"
|
className="sub-setting"
|
||||||
checked={options.markerImagePreviews ?? false}
|
checked={options.markerImagePreviews ?? false}
|
||||||
@@ -101,6 +103,7 @@ export const GenerateOptions: React.FC<IGenerateOptions> = ({
|
|||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
|
advanced
|
||||||
id="marker-screenshot-task"
|
id="marker-screenshot-task"
|
||||||
className="sub-setting"
|
className="sub-setting"
|
||||||
checked={options.markerScreenshots ?? false}
|
checked={options.markerScreenshots ?? false}
|
||||||
@@ -111,6 +114,7 @@ export const GenerateOptions: React.FC<IGenerateOptions> = ({
|
|||||||
/>
|
/>
|
||||||
|
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
|
advanced
|
||||||
id="transcode-task"
|
id="transcode-task"
|
||||||
checked={options.transcodes ?? false}
|
checked={options.transcodes ?? false}
|
||||||
headingID="dialogs.scene_gen.transcodes"
|
headingID="dialogs.scene_gen.transcodes"
|
||||||
@@ -119,6 +123,7 @@ export const GenerateOptions: React.FC<IGenerateOptions> = ({
|
|||||||
/>
|
/>
|
||||||
{selection ? (
|
{selection ? (
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
|
advanced
|
||||||
id="force-transcode"
|
id="force-transcode"
|
||||||
className="sub-setting"
|
className="sub-setting"
|
||||||
checked={options.forceTranscodes ?? false}
|
checked={options.forceTranscodes ?? false}
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ export const LibraryTasks: React.FC = () => {
|
|||||||
</SettingGroup>
|
</SettingGroup>
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
|
|
||||||
<SettingSection>
|
<SettingSection advanced>
|
||||||
<Setting
|
<Setting
|
||||||
heading={
|
heading={
|
||||||
<>
|
<>
|
||||||
@@ -349,7 +349,7 @@ export const LibraryTasks: React.FC = () => {
|
|||||||
</Setting>
|
</Setting>
|
||||||
</SettingSection>
|
</SettingSection>
|
||||||
|
|
||||||
<SettingSection>
|
<SettingSection advanced>
|
||||||
<SettingGroup
|
<SettingGroup
|
||||||
settingProps={{
|
settingProps={{
|
||||||
heading: (
|
heading: (
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ export const ScanOptions: React.FC<IScanOptions> = ({
|
|||||||
onChange={(v) => setOptions({ scanGeneratePreviews: v })}
|
onChange={(v) => setOptions({ scanGeneratePreviews: v })}
|
||||||
/>
|
/>
|
||||||
<BooleanSetting
|
<BooleanSetting
|
||||||
|
advanced
|
||||||
id="scan-generate-image-previews"
|
id="scan-generate-image-previews"
|
||||||
className="sub-setting"
|
className="sub-setting"
|
||||||
headingID="config.tasks.generate_previews_during_scan"
|
headingID="config.tasks.generate_previews_during_scan"
|
||||||
|
|||||||
@@ -34,6 +34,8 @@ export interface ISettingsContextState {
|
|||||||
ui: IUIConfig;
|
ui: IUIConfig;
|
||||||
plugins: PluginSettings;
|
plugins: PluginSettings;
|
||||||
|
|
||||||
|
advancedMode: boolean;
|
||||||
|
|
||||||
// apikey isn't directly settable, so expose it here
|
// apikey isn't directly settable, so expose it here
|
||||||
apiKey: string;
|
apiKey: string;
|
||||||
|
|
||||||
@@ -44,6 +46,7 @@ export interface ISettingsContextState {
|
|||||||
saveDLNA: (input: Partial<GQL.ConfigDlnaInput>) => void;
|
saveDLNA: (input: Partial<GQL.ConfigDlnaInput>) => void;
|
||||||
saveUI: (input: Partial<IUIConfig>) => void;
|
saveUI: (input: Partial<IUIConfig>) => void;
|
||||||
savePluginSettings: (pluginID: string, input: {}) => void;
|
savePluginSettings: (pluginID: string, input: {}) => void;
|
||||||
|
setAdvancedMode: (value: boolean) => void;
|
||||||
|
|
||||||
refetch: () => void;
|
refetch: () => void;
|
||||||
}
|
}
|
||||||
@@ -91,7 +94,7 @@ export const SettingsContext: React.FC = ({ children }) => {
|
|||||||
const [pendingDLNA, setPendingDLNA] = useState<GQL.ConfigDlnaInput>();
|
const [pendingDLNA, setPendingDLNA] = useState<GQL.ConfigDlnaInput>();
|
||||||
const [updateDLNAConfig] = useConfigureDLNA();
|
const [updateDLNAConfig] = useConfigureDLNA();
|
||||||
|
|
||||||
const [ui, setUI] = useState({});
|
const [ui, setUI] = useState<IUIConfig>({});
|
||||||
const [pendingUI, setPendingUI] = useState<{}>();
|
const [pendingUI, setPendingUI] = useState<{}>();
|
||||||
const [updateUIConfig] = useConfigureUI();
|
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
|
// saves the configuration if no further changes are made after a half second
|
||||||
const savePluginConfig = useDebounce(async (input: PluginSettings) => {
|
const savePluginConfig = useDebounce(async (input: PluginSettings) => {
|
||||||
try {
|
try {
|
||||||
@@ -536,6 +545,7 @@ export const SettingsContext: React.FC = ({ children }) => {
|
|||||||
dlna,
|
dlna,
|
||||||
ui,
|
ui,
|
||||||
plugins,
|
plugins,
|
||||||
|
advancedMode: ui.advancedMode ?? false,
|
||||||
saveGeneral,
|
saveGeneral,
|
||||||
saveInterface,
|
saveInterface,
|
||||||
saveDefaults,
|
saveDefaults,
|
||||||
@@ -544,6 +554,7 @@ export const SettingsContext: React.FC = ({ children }) => {
|
|||||||
saveUI,
|
saveUI,
|
||||||
refetch,
|
refetch,
|
||||||
savePluginSettings,
|
savePluginSettings,
|
||||||
|
setAdvancedMode,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{maybeRenderLoadingIndicator()}
|
{maybeRenderLoadingIndicator()}
|
||||||
|
|||||||
@@ -410,3 +410,18 @@
|
|||||||
.empty-queue-message {
|
.empty-queue-message {
|
||||||
color: $text-muted;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -83,6 +83,8 @@ export interface IUIConfig {
|
|||||||
|
|
||||||
vrTag?: string;
|
vrTag?: string;
|
||||||
pinnedFilters?: PinnedFilters;
|
pinnedFilters?: PinnedFilters;
|
||||||
|
|
||||||
|
advancedMode?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ISavedFilterRowBroken extends ISavedFilterRow {
|
interface ISavedFilterRowBroken extends ISavedFilterRow {
|
||||||
|
|||||||
@@ -215,6 +215,7 @@
|
|||||||
"stash_wiki": "Stash {url} page",
|
"stash_wiki": "Stash {url} page",
|
||||||
"version": "Version"
|
"version": "Version"
|
||||||
},
|
},
|
||||||
|
"advanced_mode": "Advanced Mode",
|
||||||
"application_paths": {
|
"application_paths": {
|
||||||
"heading": "Application Paths"
|
"heading": "Application Paths"
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user