diff --git a/internal/api/resolver_query_configuration.go b/internal/api/resolver_query_configuration.go
index adc136206..64a6f0364 100644
--- a/internal/api/resolver_query_configuration.go
+++ b/internal/api/resolver_query_configuration.go
@@ -148,7 +148,6 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult {
handyKey := config.GetHandyKey()
scriptOffset := config.GetFunscriptOffset()
imageLightboxOptions := config.GetImageLightboxOptions()
-
// FIXME - misnamed output field means we have redundant fields
disableDropdownCreate := config.GetDisableDropdownCreate()
diff --git a/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx b/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx
index f90121b1e..07e090a2f 100644
--- a/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx
+++ b/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx
@@ -39,9 +39,14 @@ const allMenuItems = [
export const SettingsInterfacePanel: React.FC = () => {
const intl = useIntl();
- const { interface: iface, saveInterface, loading, error } = React.useContext(
- SettingStateContext
- );
+ const {
+ interface: iface,
+ saveInterface,
+ ui,
+ saveUI,
+ loading,
+ error,
+ } = React.useContext(SettingStateContext);
const {
interactive,
@@ -241,6 +246,24 @@ export const SettingsInterfacePanel: React.FC = () => {
}}
/>
+
+ saveUI({ showChildTagContent: v })}
+ />
+
+
+ saveUI({ showChildStudioContent: v })}
+ />
+
) => void;
saveScraping: (input: Partial) => void;
saveDLNA: (input: Partial) => void;
- saveUI: (input: IUIConfig) => void;
+ saveUI: (input: Partial) => void;
}
export const SettingStateContext = React.createContext({
@@ -443,7 +443,11 @@ export const SettingsContext: React.FC = ({ children }) => {
setPendingUI((current) => {
if (!current) {
- return input;
+ // use full UI object to ensure nothing is wiped
+ return {
+ ...ui,
+ ...input,
+ };
}
return {
...current,
diff --git a/ui/v2.5/src/core/config.ts b/ui/v2.5/src/core/config.ts
index 7d0840f60..bdca294e4 100644
--- a/ui/v2.5/src/core/config.ts
+++ b/ui/v2.5/src/core/config.ts
@@ -28,6 +28,8 @@ export type FrontPageContent = ISavedFilterRow | ICustomFilter;
export interface IUIConfig {
frontPageContent?: FrontPageContent[];
lastNoteSeen?: number;
+ showChildTagContent?: boolean;
+ showChildStudioContent?: boolean;
}
function recentlyReleased(
diff --git a/ui/v2.5/src/core/studios.ts b/ui/v2.5/src/core/studios.ts
index 1be512ede..c34145025 100644
--- a/ui/v2.5/src/core/studios.ts
+++ b/ui/v2.5/src/core/studios.ts
@@ -1,10 +1,14 @@
import * as GQL from "src/core/generated-graphql";
import { StudiosCriterion } from "src/models/list-filter/criteria/studios";
import { ListFilterModel } from "src/models/list-filter/filter";
+import React from "react";
+import { ConfigurationContext } from "src/hooks/Config";
+import { IUIConfig } from "./config";
export const studioFilterHook = (studio: GQL.StudioDataFragment) => {
return (filter: ListFilterModel) => {
const studioValue = { id: studio.id, label: studio.name };
+ const config = React.useContext(ConfigurationContext);
// if studio is already present, then we modify it, otherwise add
let studioCriterion = filter.criteria.find((c) => {
return c.criterionOption.type === "studios";
@@ -28,7 +32,9 @@ export const studioFilterHook = (studio: GQL.StudioDataFragment) => {
studioCriterion = new StudiosCriterion();
studioCriterion.value = {
items: [studioValue],
- depth: 0,
+ depth: (config?.configuration?.ui as IUIConfig)?.showChildStudioContent
+ ? -1
+ : 0,
};
filter.criteria.push(studioCriterion);
}
diff --git a/ui/v2.5/src/core/tags.ts b/ui/v2.5/src/core/tags.ts
index d7365b8ac..9a93e5716 100644
--- a/ui/v2.5/src/core/tags.ts
+++ b/ui/v2.5/src/core/tags.ts
@@ -6,9 +6,13 @@ import {
TagsCriterionOption,
} from "src/models/list-filter/criteria/tags";
import { ListFilterModel } from "src/models/list-filter/filter";
+import React from "react";
+import { ConfigurationContext } from "src/hooks/Config";
+import { IUIConfig } from "./config";
export const tagFilterHook = (tag: GQL.TagDataFragment) => {
return (filter: ListFilterModel) => {
+ const config = React.useContext(ConfigurationContext);
const tagValue = { id: tag.id, label: tag.name };
// if tag is already present, then we modify it, otherwise add
let tagCriterion = filter.criteria.find((c) => {
@@ -35,7 +39,9 @@ export const tagFilterHook = (tag: GQL.TagDataFragment) => {
tagCriterion = new TagsCriterion(TagsCriterionOption);
tagCriterion.value = {
items: [tagValue],
- depth: 0,
+ depth: (config?.configuration?.ui as IUIConfig)?.showChildTagContent
+ ? -1
+ : 0,
};
filter.criteria.push(tagCriterion);
}
diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json
index c8ea82e12..d0f2b7247 100644
--- a/ui/v2.5/src/locales/en-GB.json
+++ b/ui/v2.5/src/locales/en-GB.json
@@ -553,6 +553,24 @@
"description": "Slideshow is available in galleries when in wall view mode",
"heading": "Slideshow Delay (seconds)"
},
+ "tag_panel": {
+ "heading": "Tag view",
+ "options": {
+ "show_child_tagged_content": {
+ "description": "In the tag view, display content from the subtags as well",
+ "heading": "Display subtag content"
+ }
+ }
+ },
+ "studio_panel": {
+ "heading": "Studio view",
+ "options": {
+ "show_child_studio_content": {
+ "description": "In the studio view, display content from the sub-studios as well",
+ "heading": "Display sub-studios content"
+ }
+ }
+ },
"title": "User Interface"
}
},