mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
Merge 833e858394 into 39fd8a6550
This commit is contained in:
commit
c602de5b78
10 changed files with 66 additions and 11 deletions
|
|
@ -394,6 +394,9 @@ input ConfigInterfaceInput {
|
|||
customLocales: String
|
||||
customLocalesEnabled: Boolean
|
||||
|
||||
"When true, disables all customizations (plugins, CSS, JavaScript, locales) for troubleshooting"
|
||||
disableCustomizations: Boolean
|
||||
|
||||
"Interface language"
|
||||
language: String
|
||||
|
||||
|
|
@ -467,6 +470,9 @@ type ConfigInterfaceResult {
|
|||
customLocales: String
|
||||
customLocalesEnabled: Boolean
|
||||
|
||||
"When true, disables all customizations (plugins, CSS, JavaScript, locales) for troubleshooting"
|
||||
disableCustomizations: Boolean
|
||||
|
||||
"Interface language"
|
||||
language: String
|
||||
|
||||
|
|
|
|||
|
|
@ -515,6 +515,8 @@ func (r *mutationResolver) ConfigureInterface(ctx context.Context, input ConfigI
|
|||
|
||||
r.setConfigBool(config.CustomLocalesEnabled, input.CustomLocalesEnabled)
|
||||
|
||||
r.setConfigBool(config.DisableCustomizations, input.DisableCustomizations)
|
||||
|
||||
if input.DisableDropdownCreate != nil {
|
||||
ddc := input.DisableDropdownCreate
|
||||
r.setConfigBool(config.DisableDropdownCreatePerformer, ddc.Performer)
|
||||
|
|
|
|||
|
|
@ -156,6 +156,7 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult {
|
|||
javascriptEnabled := config.GetJavascriptEnabled()
|
||||
customLocales := config.GetCustomLocales()
|
||||
customLocalesEnabled := config.GetCustomLocalesEnabled()
|
||||
disableCustomizations := config.GetDisableCustomizations()
|
||||
language := config.GetLanguage()
|
||||
handyKey := config.GetHandyKey()
|
||||
scriptOffset := config.GetFunscriptOffset()
|
||||
|
|
@ -183,6 +184,7 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult {
|
|||
JavascriptEnabled: &javascriptEnabled,
|
||||
CustomLocales: &customLocales,
|
||||
CustomLocalesEnabled: &customLocalesEnabled,
|
||||
DisableCustomizations: &disableCustomizations,
|
||||
Language: &language,
|
||||
|
||||
ImageLightbox: &imageLightboxOptions,
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ func cssHandler(c *config.Config) func(w http.ResponseWriter, r *http.Request) {
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var paths []string
|
||||
|
||||
if c.GetCSSEnabled() {
|
||||
if c.GetCSSEnabled() && !c.GetDisableCustomizations() {
|
||||
// search for custom.css in current directory, then $HOME/.stash
|
||||
fn := c.GetCSSPath()
|
||||
exists, _ := fsutil.FileExists(fn)
|
||||
|
|
@ -439,7 +439,7 @@ func javascriptHandler(c *config.Config) func(w http.ResponseWriter, r *http.Req
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
var paths []string
|
||||
|
||||
if c.GetJavascriptEnabled() {
|
||||
if c.GetJavascriptEnabled() && !c.GetDisableCustomizations() {
|
||||
// search for custom.js in current directory, then $HOME/.stash
|
||||
fn := c.GetJavascriptPath()
|
||||
exists, _ := fsutil.FileExists(fn)
|
||||
|
|
@ -457,7 +457,7 @@ func customLocalesHandler(c *config.Config) func(w http.ResponseWriter, r *http.
|
|||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
buffer := bytes.Buffer{}
|
||||
|
||||
if c.GetCustomLocalesEnabled() {
|
||||
if c.GetCustomLocalesEnabled() && !c.GetDisableCustomizations() {
|
||||
// search for custom-locales.json in current directory, then $HOME/.stash
|
||||
path := c.GetCustomLocalesPath()
|
||||
exists, _ := fsutil.FileExists(path)
|
||||
|
|
|
|||
|
|
@ -194,6 +194,7 @@ const (
|
|||
CSSEnabled = "cssenabled"
|
||||
JavascriptEnabled = "javascriptenabled"
|
||||
CustomLocalesEnabled = "customlocalesenabled"
|
||||
DisableCustomizations = "disable_customizations"
|
||||
|
||||
ShowScrubber = "show_scrubber"
|
||||
showScrubberDefault = true
|
||||
|
|
@ -1457,6 +1458,13 @@ func (i *Config) GetCustomLocalesEnabled() bool {
|
|||
return i.getBool(CustomLocalesEnabled)
|
||||
}
|
||||
|
||||
// GetDisableCustomizations returns true if all customizations (plugins, custom CSS,
|
||||
// custom JavaScript, and custom locales) should be disabled. This is useful for
|
||||
// troubleshooting issues without permanently disabling individual customizations.
|
||||
func (i *Config) GetDisableCustomizations() bool {
|
||||
return i.getBool(DisableCustomizations)
|
||||
}
|
||||
|
||||
func (i *Config) GetHandyKey() string {
|
||||
return i.getString(HandyKey)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -92,6 +92,7 @@ fragment ConfigInterfaceData on ConfigInterfaceResult {
|
|||
javascriptEnabled
|
||||
customLocales
|
||||
customLocalesEnabled
|
||||
disableCustomizations
|
||||
language
|
||||
imageLightbox {
|
||||
slideshowDelay
|
||||
|
|
|
|||
|
|
@ -351,7 +351,12 @@ export const App: React.FC = () => {
|
|||
formats={intlFormats}
|
||||
>
|
||||
<ToastProvider>
|
||||
<PluginsLoader>
|
||||
<PluginsLoader
|
||||
disableCustomizations={
|
||||
config.data?.configuration?.interface?.disableCustomizations ??
|
||||
false
|
||||
}
|
||||
>
|
||||
<AppContainer>
|
||||
<ConfigurationProvider configuration={config.data!.configuration}>
|
||||
{maybeRenderReleaseNotes()}
|
||||
|
|
|
|||
|
|
@ -300,6 +300,16 @@ export const SettingsInterfacePanel: React.FC = PatchComponent(
|
|||
/>
|
||||
</SettingSection>
|
||||
|
||||
<SettingSection headingID="config.ui.troubleshooting.heading">
|
||||
<BooleanSetting
|
||||
id="disable-customizations"
|
||||
headingID="config.ui.troubleshooting.disable_customizations.heading"
|
||||
subHeadingID="config.ui.troubleshooting.disable_customizations.description"
|
||||
checked={iface.disableCustomizations ?? undefined}
|
||||
onChange={(v) => saveInterface({ disableCustomizations: v })}
|
||||
/>
|
||||
</SettingSection>
|
||||
|
||||
<SettingSection headingID="config.ui.scene_wall.heading">
|
||||
<BooleanSetting
|
||||
id="wall-show-title"
|
||||
|
|
|
|||
|
|
@ -611,6 +611,13 @@
|
|||
"heading": "Custom CSS",
|
||||
"option_label": "Custom CSS enabled"
|
||||
},
|
||||
"troubleshooting": {
|
||||
"heading": "Troubleshooting",
|
||||
"disable_customizations": {
|
||||
"heading": "Disable customizations",
|
||||
"description": "Temporarily disables all plugins, custom CSS, custom JavaScript, and custom locales. Use this to troubleshoot issues without permanently disabling individual customizations. A page reload is required for changes to take effect."
|
||||
}
|
||||
},
|
||||
"custom_javascript": {
|
||||
"description": "Page must be reloaded for changes to take effect. There is no guarantee of compatibility between custom Javascript and future releases of Stash.",
|
||||
"heading": "Custom Javascript",
|
||||
|
|
|
|||
|
|
@ -59,7 +59,8 @@ function sortPlugins(plugins: PluginList) {
|
|||
|
||||
// load all plugins and their dependencies
|
||||
// returns true when all plugins are loaded, regardess of success or failure
|
||||
function useLoadPlugins() {
|
||||
// if disableCustomizations is true, skip loading plugins entirely
|
||||
function useLoadPlugins(disableCustomizations?: boolean) {
|
||||
const {
|
||||
data: plugins,
|
||||
loading: pluginsLoading,
|
||||
|
|
@ -74,6 +75,12 @@ function useLoadPlugins() {
|
|||
}, [plugins?.plugins, pluginsLoading, pluginsError]);
|
||||
|
||||
const pluginJavascripts = useMemoOnce(() => {
|
||||
// Skip loading plugin JS if customizations are disabled.
|
||||
// Note: We check inside useMemoOnce rather than early-returning from useLoadPlugins
|
||||
// to comply with React's rules of hooks - hooks must be called unconditionally.
|
||||
if (disableCustomizations) {
|
||||
return [[], true];
|
||||
}
|
||||
return [
|
||||
uniq(
|
||||
sortedPlugins
|
||||
|
|
@ -83,9 +90,12 @@ function useLoadPlugins() {
|
|||
),
|
||||
!!sortedPlugins && !pluginsLoading && !pluginsError,
|
||||
];
|
||||
}, [sortedPlugins, pluginsLoading, pluginsError]);
|
||||
}, [sortedPlugins, pluginsLoading, pluginsError, disableCustomizations]);
|
||||
|
||||
const pluginCSS = useMemoOnce(() => {
|
||||
if (disableCustomizations) {
|
||||
return [[], true];
|
||||
}
|
||||
return [
|
||||
uniq(
|
||||
sortedPlugins
|
||||
|
|
@ -95,7 +105,7 @@ function useLoadPlugins() {
|
|||
),
|
||||
!!sortedPlugins && !pluginsLoading && !pluginsError,
|
||||
];
|
||||
}, [sortedPlugins, pluginsLoading, pluginsError]);
|
||||
}, [sortedPlugins, pluginsLoading, pluginsError, disableCustomizations]);
|
||||
|
||||
const pluginJavascriptLoaded = useScript(
|
||||
pluginJavascripts ?? [],
|
||||
|
|
@ -109,11 +119,15 @@ function useLoadPlugins() {
|
|||
};
|
||||
}
|
||||
|
||||
export const PluginsLoader: React.FC<React.PropsWithChildren<{}>> = ({
|
||||
children,
|
||||
}) => {
|
||||
interface IPluginsLoaderProps {
|
||||
disableCustomizations?: boolean;
|
||||
}
|
||||
|
||||
export const PluginsLoader: React.FC<
|
||||
React.PropsWithChildren<IPluginsLoaderProps>
|
||||
> = ({ disableCustomizations, children }) => {
|
||||
const Toast = useToast();
|
||||
const { loading: loaded, error } = useLoadPlugins();
|
||||
const { loading: loaded, error } = useLoadPlugins(disableCustomizations);
|
||||
|
||||
useEffect(() => {
|
||||
if (error) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue