Skip to content

Commit

Permalink
Add option to disable create from dropdown (#1814)
Browse files Browse the repository at this point in the history
* Convert config hooks to common context
* Add option to disable creating from dropdown
  • Loading branch information
WithoutPants authored Oct 11, 2021
1 parent 46ae458 commit b5381ff
Show file tree
Hide file tree
Showing 24 changed files with 269 additions and 130 deletions.
5 changes: 5 additions & 0 deletions graphql/documents/data/config.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ fragment ConfigInterfaceData on ConfigInterfaceResult {
cssEnabled
language
slideshowDelay
disabledDropdownCreate {
performer
tag
studio
}
handyKey
funscriptOffset
}
Expand Down
16 changes: 16 additions & 0 deletions graphql/schema/types/config.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -188,6 +188,12 @@ type ConfigGeneralResult {
stashBoxes: [StashBox!]!
}

input ConfigDisableDropdownCreateInput {
performer: Boolean
tag: Boolean
studio: Boolean
}

input ConfigInterfaceInput {
"""Ordered list of items that should be shown in the menu"""
menuItems: [String!]
Expand All @@ -210,12 +216,20 @@ input ConfigInterfaceInput {
language: String
"""Slideshow Delay"""
slideshowDelay: Int
"""Set to true to disable creating new objects via the dropdown menus"""
disableDropdownCreate: ConfigDisableDropdownCreateInput
"""Handy Connection Key"""
handyKey: String
"""Funscript Time Offset"""
funscriptOffset: Int
}

type ConfigDisableDropdownCreate {
performer: Boolean!
tag: Boolean!
studio: Boolean!
}

type ConfigInterfaceResult {
"""Ordered list of items that should be shown in the menu"""
menuItems: [String!]
Expand All @@ -238,6 +252,8 @@ type ConfigInterfaceResult {
language: String
"""Slideshow Delay"""
slideshowDelay: Int
"""Fields are true if creating via dropdown menus are disabled"""
disabledDropdownCreate: ConfigDisableDropdownCreate!
"""Handy Connection Key"""
handyKey: String
"""Funscript Time Offset"""
Expand Down
34 changes: 18 additions & 16 deletions pkg/api/resolver_mutation_configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -225,18 +225,20 @@ func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input models.Co

func (r *mutationResolver) ConfigureInterface(ctx context.Context, input models.ConfigInterfaceInput) (*models.ConfigInterfaceResult, error) {
c := config.GetInstance()
if input.MenuItems != nil {
c.Set(config.MenuItems, input.MenuItems)
}

if input.SoundOnPreview != nil {
c.Set(config.SoundOnPreview, *input.SoundOnPreview)
setBool := func(key string, v *bool) {
if v != nil {
c.Set(key, *v)
}
}

if input.WallShowTitle != nil {
c.Set(config.WallShowTitle, *input.WallShowTitle)
if input.MenuItems != nil {
c.Set(config.MenuItems, input.MenuItems)
}

setBool(config.SoundOnPreview, input.SoundOnPreview)
setBool(config.WallShowTitle, input.WallShowTitle)

if input.WallPlayback != nil {
c.Set(config.WallPlayback, *input.WallPlayback)
}
Expand All @@ -245,13 +247,8 @@ func (r *mutationResolver) ConfigureInterface(ctx context.Context, input models.
c.Set(config.MaximumLoopDuration, *input.MaximumLoopDuration)
}

if input.AutostartVideo != nil {
c.Set(config.AutostartVideo, *input.AutostartVideo)
}

if input.ShowStudioAsText != nil {
c.Set(config.ShowStudioAsText, *input.ShowStudioAsText)
}
setBool(config.AutostartVideo, input.AutostartVideo)
setBool(config.ShowStudioAsText, input.ShowStudioAsText)

if input.Language != nil {
c.Set(config.Language, *input.Language)
Expand All @@ -269,8 +266,13 @@ func (r *mutationResolver) ConfigureInterface(ctx context.Context, input models.

c.SetCSS(css)

if input.CSSEnabled != nil {
c.Set(config.CSSEnabled, *input.CSSEnabled)
setBool(config.CSSEnabled, input.CSSEnabled)

if input.DisableDropdownCreate != nil {
ddc := input.DisableDropdownCreate
setBool(config.DisableDropdownCreatePerformer, ddc.Performer)
setBool(config.DisableDropdownCreateStudio, ddc.Studio)
setBool(config.DisableDropdownCreateTag, ddc.Tag)
}

if input.HandyKey != nil {
Expand Down
27 changes: 14 additions & 13 deletions pkg/api/resolver_query_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,19 +115,20 @@ func makeConfigInterfaceResult() *models.ConfigInterfaceResult {
scriptOffset := config.GetFunscriptOffset()

return &models.ConfigInterfaceResult{
MenuItems: menuItems,
SoundOnPreview: &soundOnPreview,
WallShowTitle: &wallShowTitle,
WallPlayback: &wallPlayback,
MaximumLoopDuration: &maximumLoopDuration,
AutostartVideo: &autostartVideo,
ShowStudioAsText: &showStudioAsText,
CSS: &css,
CSSEnabled: &cssEnabled,
Language: &language,
SlideshowDelay: &slideshowDelay,
HandyKey: &handyKey,
FunscriptOffset: &scriptOffset,
MenuItems: menuItems,
SoundOnPreview: &soundOnPreview,
WallShowTitle: &wallShowTitle,
WallPlayback: &wallPlayback,
MaximumLoopDuration: &maximumLoopDuration,
AutostartVideo: &autostartVideo,
ShowStudioAsText: &showStudioAsText,
CSS: &css,
CSSEnabled: &cssEnabled,
Language: &language,
SlideshowDelay: &slideshowDelay,
DisabledDropdownCreate: config.GetDisableDropdownCreate(),
HandyKey: &handyKey,
FunscriptOffset: &scriptOffset,
}
}

Expand Down
18 changes: 18 additions & 0 deletions pkg/manager/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ const ShowStudioAsText = "show_studio_as_text"
const CSSEnabled = "cssEnabled"
const WallPlayback = "wall_playback"
const SlideshowDelay = "slideshow_delay"

const (
DisableDropdownCreatePerformer = "disable_dropdown_create.performer"
DisableDropdownCreateStudio = "disable_dropdown_create.studio"
DisableDropdownCreateTag = "disable_dropdown_create.tag"
)

const HandyKey = "handy_key"
const FunscriptOffset = "funscript_offset"

Expand Down Expand Up @@ -787,6 +794,17 @@ func (i *Instance) GetSlideshowDelay() int {
return viper.GetInt(SlideshowDelay)
}

func (i *Instance) GetDisableDropdownCreate() *models.ConfigDisableDropdownCreate {
i.Lock()
defer i.Unlock()

return &models.ConfigDisableDropdownCreate{
Performer: viper.GetBool(DisableDropdownCreatePerformer),
Studio: viper.GetBool(DisableDropdownCreateStudio),
Tag: viper.GetBool(DisableDropdownCreateTag),
}
}

func (i *Instance) GetCSSPath() string {
i.RLock()
defer i.RUnlock()
Expand Down
18 changes: 12 additions & 6 deletions ui/v2.5/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { Setup } from "./components/Setup/Setup";
import { Migrate } from "./components/Setup/Migrate";
import * as GQL from "./core/generated-graphql";
import { LoadingIndicator } from "./components/Shared";
import ConfigurationProvider from "./hooks/Config";

initPolyfills();

Expand Down Expand Up @@ -138,12 +139,17 @@ export const App: React.FC = () => {
return (
<ErrorBoundary>
<IntlProvider locale={language} messages={messages} formats={intlFormats}>
<ToastProvider>
<LightboxProvider>
{maybeRenderNavbar()}
<div className="main container-fluid">{renderContent()}</div>
</LightboxProvider>
</ToastProvider>
<ConfigurationProvider
configuration={config.data?.configuration}
loading={config.loading}
>
<ToastProvider>
<LightboxProvider>
{maybeRenderNavbar()}
<div className="main container-fluid">{renderContent()}</div>
</LightboxProvider>
</ToastProvider>
</ConfigurationProvider>
</IntlProvider>
</ErrorBoundary>
);
Expand Down
3 changes: 3 additions & 0 deletions ui/v2.5/src/components/Changelog/versions/v0110.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
### ✨ New Features
* Added interface options to disable creating performers/studios/tags from dropdown selectors. ([#1814](https://github.com/stashapp/stash/pull/1814))

### 🐛 Bug fixes
* Fix huge memory usage spike during clean task. ([#1805](https://github.com/stashapp/stash/pull/1805))
7 changes: 3 additions & 4 deletions ui/v2.5/src/components/Galleries/GalleryCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { Button, ButtonGroup } from "react-bootstrap";
import React from "react";
import { Link } from "react-router-dom";
import * as GQL from "src/core/generated-graphql";
import { useConfiguration } from "src/core/StashService";
import {
GridCard,
HoverPopover,
Expand All @@ -12,6 +11,7 @@ import {
} from "src/components/Shared";
import { PopoverCountButton } from "src/components/Shared/PopoverCountButton";
import { NavUtils, TextUtils } from "src/utils";
import { ConfigurationContext } from "src/hooks/Config";
import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton";
import { RatingBanner } from "../Shared/RatingBanner";

Expand All @@ -24,9 +24,8 @@ interface IProps {
}

export const GalleryCard: React.FC<IProps> = (props) => {
const config = useConfiguration();
const showStudioAsText =
config?.data?.configuration.interface.showStudioAsText ?? false;
const { configuration } = React.useContext(ConfigurationContext);
const showStudioAsText = configuration?.interface.showStudioAsText ?? false;

function maybeRenderScenePopoverButton() {
if (props.gallery.scenes.length === 0) return;
Expand Down
8 changes: 4 additions & 4 deletions ui/v2.5/src/components/MainNavbar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import Mousetrap from "mousetrap";

import { SessionUtils } from "src/utils";
import { Icon } from "src/components/Shared";
import { ConfigurationContext } from "src/hooks/Config";
import { Manual } from "./Help/Manual";
import { useConfiguration } from "../core/StashService";

interface IMenuItem {
name: string;
Expand Down Expand Up @@ -120,7 +120,7 @@ const allMenuItems: IMenuItem[] = [
export const MainNavbar: React.FC = () => {
const history = useHistory();
const location = useLocation();
const { data: config, loading } = useConfiguration();
const { configuration, loading } = React.useContext(ConfigurationContext);

// Show all menu items by default, unless config says otherwise
const [menuItems, setMenuItems] = useState<IMenuItem[]>(allMenuItems);
Expand All @@ -129,15 +129,15 @@ export const MainNavbar: React.FC = () => {
const [showManual, setShowManual] = useState(false);

useEffect(() => {
const iCfg = config?.configuration?.interface;
const iCfg = configuration?.interface;
if (iCfg?.menuItems) {
setMenuItems(
allMenuItems.filter((menuItem) =>
iCfg.menuItems!.includes(menuItem.name)
)
);
}
}, [config]);
}, [configuration]);

// react-bootstrap typing bug
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
usePerformerCreate,
useTagCreate,
queryScrapePerformerURL,
useConfiguration,
} from "src/core/StashService";
import {
Icon,
Expand All @@ -41,6 +40,7 @@ import {
genderToString,
stringToGender,
} from "src/utils/gender";
import { ConfigurationContext } from "src/hooks/Config";
import { PerformerScrapeDialog } from "./PerformerScrapeDialog";
import PerformerScrapeModal from "./PerformerScrapeModal";
import PerformerStashBoxModal, { IStashBox } from "./PerformerStashBoxModal";
Expand Down Expand Up @@ -88,7 +88,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
const [scrapedPerformer, setScrapedPerformer] = useState<
GQL.ScrapedPerformer | undefined
>();
const stashConfig = useConfiguration();
const { configuration: stashConfig } = React.useContext(ConfigurationContext);

const imageEncoding = ImageUtils.usePasteImage(onImageLoad, true);

Expand Down Expand Up @@ -601,7 +601,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
if (!performer) {
return;
}
const stashBoxes = stashConfig.data?.configuration.general.stashBoxes ?? [];
const stashBoxes = stashConfig?.general.stashBoxes ?? [];

const popover = (
<Dropdown.Menu id="performer-scraper-popover">
Expand Down
10 changes: 3 additions & 7 deletions ui/v2.5/src/components/ScenePlayer/ScenePlayer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
import React from "react";
import ReactJWPlayer from "react-jw-player";
import * as GQL from "src/core/generated-graphql";
import { useConfiguration } from "src/core/StashService";
import { JWUtils, ScreenUtils } from "src/utils";
import { ConfigurationContext } from "src/hooks/Config";
import { ScenePlayerScrubber } from "./ScenePlayerScrubber";
import { Interactive } from "../../utils/interactive";

Expand Down Expand Up @@ -366,16 +366,12 @@ export class ScenePlayerImpl extends React.Component<
export const ScenePlayer: React.FC<IScenePlayerProps> = (
props: IScenePlayerProps
) => {
const config = useConfiguration();
const { configuration } = React.useContext(ConfigurationContext);

return (
<ScenePlayerImpl
{...props}
config={
config.data && config.data.configuration
? config.data.configuration.interface
: undefined
}
config={configuration ? configuration.interface : undefined}
/>
);
};
11 changes: 4 additions & 7 deletions ui/v2.5/src/components/Scenes/SceneCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Button, ButtonGroup } from "react-bootstrap";
import { Link } from "react-router-dom";
import cx from "classnames";
import * as GQL from "src/core/generated-graphql";
import { useConfiguration } from "src/core/StashService";
import {
Icon,
TagLink,
Expand All @@ -13,6 +12,7 @@ import {
} from "src/components/Shared";
import { TextUtils } from "src/utils";
import { SceneQueue } from "src/models/sceneQueue";
import { ConfigurationContext } from "src/hooks/Config";
import { PerformerPopoverButton } from "../Shared/PerformerPopoverButton";
import { GridCard } from "../Shared/GridCard";
import { RatingBanner } from "../Shared/RatingBanner";
Expand Down Expand Up @@ -80,15 +80,14 @@ interface ISceneCardProps {
export const SceneCard: React.FC<ISceneCardProps> = (
props: ISceneCardProps
) => {
const config = useConfiguration();
const { configuration } = React.useContext(ConfigurationContext);

// studio image is missing if it uses the default
const missingStudioImage = props.scene.studio?.image_path?.endsWith(
"?default=true"
);
const showStudioAsText =
missingStudioImage ||
(config?.data?.configuration.interface.showStudioAsText ?? false);
missingStudioImage || (configuration?.interface.showStudioAsText ?? false);

function maybeRenderSceneSpecsOverlay() {
return (
Expand Down Expand Up @@ -327,9 +326,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
image={props.scene.paths.screenshot ?? undefined}
video={props.scene.paths.preview ?? undefined}
isPortrait={isPortrait()}
soundActive={
config.data?.configuration?.interface?.soundOnPreview ?? false
}
soundActive={configuration?.interface?.soundOnPreview ?? false}
/>
<RatingBanner rating={props.scene.rating} />
{maybeRenderSceneSpecsOverlay()}
Expand Down
Loading

0 comments on commit b5381ff

Please sign in to comment.