initial work for autotag skip warning

This commit is contained in:
Gykes 2026-04-22 23:25:01 -07:00
parent a33cca6033
commit 35488c706f
10 changed files with 108 additions and 6 deletions

View file

@ -428,6 +428,9 @@ input ConfigInterfaceInput {
"Set to true to disable creating new objects via the dropdown menus"
disableDropdownCreate: ConfigDisableDropdownCreateInput
"Set to true to skip the auto tag confirmation warning"
disableAutoTagWarning: Boolean
"Handy Connection Key"
handyKey: String
"Funscript Time Offset"
@ -505,6 +508,9 @@ type ConfigInterfaceResult {
"Fields are true if creating via dropdown menus are disabled"
disableDropdownCreate: ConfigDisableDropdownCreate!
"True if the auto tag confirmation warning should be skipped"
disableAutoTagWarning: Boolean
"Handy Connection Key"
handyKey: String
"Funscript Time Offset"

View file

@ -538,6 +538,8 @@ func (r *mutationResolver) ConfigureInterface(ctx context.Context, input ConfigI
r.setConfigBool(config.DisableDropdownCreateGallery, ddc.Gallery)
}
r.setConfigBool(config.DisableAutoTagWarning, input.DisableAutoTagWarning)
r.setConfigString(config.HandyKey, input.HandyKey)
r.setConfigInt(config.FunscriptOffset, input.FunscriptOffset)
r.setConfigBool(config.UseStashHostedFunscript, input.UseStashHostedFunscript)

View file

@ -168,6 +168,7 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult {
useStashHostedFunscript := config.GetUseStashHostedFunscript()
imageLightboxOptions := config.GetImageLightboxOptions()
disableDropdownCreate := config.GetDisableDropdownCreate()
disableAutoTagWarning := config.GetDisableAutoTagWarning()
return &ConfigInterfaceResult{
SfwContentMode: config.GetSFWContentMode(),
@ -196,6 +197,8 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult {
DisableDropdownCreate: disableDropdownCreate,
DisableAutoTagWarning: &disableAutoTagWarning,
HandyKey: &handyKey,
FunscriptOffset: &scriptOffset,
UseStashHostedFunscript: &useStashHostedFunscript,

View file

@ -237,6 +237,8 @@ const (
DisableDropdownCreateMovie = "disable_dropdown_create.movie"
DisableDropdownCreateGallery = "disable_dropdown_create.gallery"
DisableAutoTagWarning = "disable_auto_tag_warning"
HandyKey = "handy_key"
FunscriptOffset = "funscript_offset"
UseStashHostedFunscript = "use_stash_hosted_funscript"
@ -1311,6 +1313,10 @@ func (i *Config) GetShowStudioAsText() bool {
return i.getBool(ShowStudioAsText)
}
func (i *Config) GetDisableAutoTagWarning() bool {
return i.getBool(DisableAutoTagWarning)
}
func (i *Config) getSlideshowDelay() int {
// assume have lock

View file

@ -115,6 +115,7 @@ fragment ConfigInterfaceData on ConfigInterfaceResult {
movie
gallery
}
disableAutoTagWarning
handyKey
funscriptOffset
useStashHostedFunscript

View file

@ -75,7 +75,13 @@ const AutoTagOptions: React.FC<IAutoTagOptions> = ({
export const LibraryTasks: React.FC = () => {
const intl = useIntl();
const Toast = useToast();
const { ui, saveUI, loading } = useSettings();
const {
ui,
saveUI,
interface: iface,
saveInterface,
loading,
} = useSettings();
const { taskDefaults } = ui;
@ -195,6 +201,14 @@ export const LibraryTasks: React.FC = () => {
});
}
function onAutoTagClick() {
if (configuration?.interface.disableAutoTagWarning) {
runAutoTag();
return;
}
setDialogOpen({ autoTagAlert: true });
}
function renderScanDialog() {
if (!dialogOpen.scan) {
return;
@ -449,7 +463,7 @@ export const LibraryTasks: React.FC = () => {
variant="secondary"
type="submit"
className="mr-2"
onClick={() => setDialogOpen({ autoTagAlert: true })}
onClick={onAutoTagClick}
>
<FormattedMessage id="actions.auto_tag" />
</Button>
@ -468,6 +482,13 @@ export const LibraryTasks: React.FC = () => {
options={autoTagOptions}
setOptions={onSetAutoTagOptions}
/>
<BooleanSetting
id="disable_auto_tag_warning"
headingID="config.tasks.auto_tag.skip_warning.heading"
subHeadingID="config.tasks.auto_tag.skip_warning.description"
checked={iface.disableAutoTagWarning ?? undefined}
onChange={(v) => saveInterface({ disableAutoTagWarning: v })}
/>
</SettingGroup>
</SettingSection>

View file

@ -1,6 +1,9 @@
import React from "react";
import React, { useContext, useEffect, useState } from "react";
import { Form } from "react-bootstrap";
import { FormattedMessage, useIntl } from "react-intl";
import { faExclamationTriangle } from "@fortawesome/free-solid-svg-icons";
import { useConfigureInterface } from "src/core/StashService";
import { SettingStateContext } from "src/components/Settings/context";
import { ModalComponent } from "./Modal";
import { Icon } from "./Icon";
@ -31,6 +34,34 @@ export const AutoTagConfirmDialog: React.FC<IAutoTagConfirmDialog> = ({
onCancel,
}) => {
const intl = useIntl();
const [dontShowAgain, setDontShowAgain] = useState(false);
const [configureInterface] = useConfigureInterface();
useEffect(() => {
if (show) {
setDontShowAgain(false);
}
}, [show]);
// route through SettingsContext when available so the Settings panel's
// local state reflects the change without a page refresh
const settingsContext = useContext(SettingStateContext);
async function handleConfirm() {
if (dontShowAgain) {
try {
if (settingsContext) {
settingsContext.saveInterface({ disableAutoTagWarning: true });
} else {
await configureInterface({
variables: { input: { disableAutoTagWarning: true } },
});
}
} catch (e) {
// preference persistence failure must not block the confirmed action
}
}
onConfirm();
}
return (
<ModalComponent
@ -40,13 +71,21 @@ export const AutoTagConfirmDialog: React.FC<IAutoTagConfirmDialog> = ({
accept={{
text: intl.formatMessage({ id: "actions.confirm" }),
variant: "danger",
onClick: onConfirm,
onClick: handleConfirm,
}}
cancel={{
onClick: onCancel,
}}
>
<AutoTagWarning />
<Form.Check
id="auto-tag-dont-show-again"
checked={dontShowAgain}
onChange={(e) => setDontShowAgain(e.currentTarget.checked)}
label={intl.formatMessage({
id: "dialogs.dont_show_again",
})}
/>
</ModalComponent>
);
};

View file

@ -1,6 +1,7 @@
import { Button, Dropdown, Modal, SplitButton } from "react-bootstrap";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
import { useConfigurationContext } from "src/hooks/Config";
import { ImageInput } from "./ImageInput";
import { AutoTagConfirmDialog } from "./AutoTagConfirmDialog";
import cx from "classnames";
@ -30,9 +31,23 @@ interface IProps {
export const DetailsEditNavbar: React.FC<IProps> = (props: IProps) => {
const intl = useIntl();
const { configuration } = useConfigurationContext();
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
const [isAutoTagAlertOpen, setIsAutoTagAlertOpen] = useState<boolean>(false);
const skipAutoTagWarning =
configuration?.interface.disableAutoTagWarning ?? false;
function onAutoTagClick() {
if (skipAutoTagWarning) {
if (props.onAutoTag) {
props.onAutoTag();
}
return;
}
setIsAutoTagAlertOpen(true);
}
function renderEditButton() {
if (props.isNew) return;
return (
@ -116,7 +131,7 @@ export const DetailsEditNavbar: React.FC<IProps> = (props: IProps) => {
<Button
variant="secondary"
disabled={props.autoTagDisabled}
onClick={() => setIsAutoTagAlertOpen(true)}
onClick={onAutoTagClick}
>
<FormattedMessage id="actions.auto_tag" />
</Button>

View file

@ -48,3 +48,7 @@ Performers or Tags that have Ignore Auto tag flag added to them will be skipped
- **Auto tag:** You can run the Auto tag task on your entire library from the Tasks page.
- **Selective auto tag:** You can run the Auto tag task on specific directories from the Tasks page.
- **Individual pages:** You can run Auto tag tasks for specific Performers, Studios, and Tags from their respective pages.
### Skip the confirmation warning
A confirmation warning is shown before Auto tag runs. If you use Auto tag frequently you can bypass this warning by ticking the **Don't show this warning again** checkbox on the warning dialog, or by enabling **Settings → Tasks → Auto Tag → Skip auto tag warning**.

View file

@ -509,7 +509,11 @@
"anonymising_database": "Anonymising database",
"auto_tag": {
"auto_tagging_all_paths": "Auto tagging all paths",
"auto_tagging_paths": "Auto tagging the following paths"
"auto_tagging_paths": "Auto tagging the following paths",
"skip_warning": {
"description": "Skip the confirmation warning shown before running auto tag.",
"heading": "Skip auto tag warning"
}
},
"auto_tag_based_on_filenames": "Auto tag content based on file paths.",
"auto_tag_confirm": "This will attempt to match your content against existing metadata.",
@ -1002,6 +1006,7 @@
"delete_object_desc": "Are you sure you want to delete {count, plural, one {this {singularEntity}} other {these {pluralEntity}}}?",
"delete_object_overflow": "…and {count} other {count, plural, one {{singularEntity}} other {{pluralEntity}}}.",
"delete_object_title": "Delete {count, plural, one {{singularEntity}} other {{pluralEntity}}}",
"dont_show_again": "Don't show this warning again",
"dont_show_until_updated": "Don't show until next update",
"edit_entity_title": "Edit {count, plural, one {{singularEntity}} other {{pluralEntity}}}",
"edit_entity_count_title": "Edit {count} {count, plural, one {{singularEntity}} other {{pluralEntity}}}",