diff --git a/ui/v2.5/src/components/Settings/Tasks/LibraryTasks.tsx b/ui/v2.5/src/components/Settings/Tasks/LibraryTasks.tsx
index eace4b7dc..cd89ed953 100644
--- a/ui/v2.5/src/components/Settings/Tasks/LibraryTasks.tsx
+++ b/ui/v2.5/src/components/Settings/Tasks/LibraryTasks.tsx
@@ -8,6 +8,7 @@ import {
} from "src/core/StashService";
import { withoutTypename } from "src/utils/data";
import { useConfigurationContext } from "src/hooks/Config";
+import { useAutoTagTrigger } from "src/hooks/useAutoTagTrigger";
import { IdentifyDialog } from "../../Dialogs/IdentifyDialog/IdentifyDialog";
import * as GQL from "src/core/generated-graphql";
import { DirectorySelectionDialog } from "./DirectorySelectionDialog";
@@ -195,6 +196,12 @@ export const LibraryTasks: React.FC = () => {
});
}
+ const onAutoTagClick = useAutoTagTrigger(
+ () => runAutoTag(),
+ () => setDialogOpen({ autoTagAlert: true }),
+ ui.disableAutoTagWarning
+ );
+
function renderScanDialog() {
if (!dialogOpen.scan) {
return;
@@ -449,7 +456,7 @@ export const LibraryTasks: React.FC = () => {
variant="secondary"
type="submit"
className="mr-2"
- onClick={() => setDialogOpen({ autoTagAlert: true })}
+ onClick={onAutoTagClick}
>
…
@@ -468,6 +475,13 @@ export const LibraryTasks: React.FC = () => {
options={autoTagOptions}
setOptions={onSetAutoTagOptions}
/>
+ saveUI({ disableAutoTagWarning: v })}
+ />
diff --git a/ui/v2.5/src/components/Shared/AutoTagConfirmDialog.tsx b/ui/v2.5/src/components/Shared/AutoTagConfirmDialog.tsx
index 0290c7e07..b4fcd21bd 100644
--- a/ui/v2.5/src/components/Shared/AutoTagConfirmDialog.tsx
+++ b/ui/v2.5/src/components/Shared/AutoTagConfirmDialog.tsx
@@ -1,6 +1,10 @@
-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 { useConfigureUISetting } from "src/core/StashService";
+import { SettingStateContext } from "src/components/Settings/context";
+import { useToast } from "src/hooks/Toast";
import { ModalComponent } from "./Modal";
import { Icon } from "./Icon";
@@ -31,6 +35,29 @@ export const AutoTagConfirmDialog: React.FC = ({
onCancel,
}) => {
const intl = useIntl();
+ const Toast = useToast();
+ const [dontShowAgain, setDontShowAgain] = useState(false);
+ const [saveUISetting] = useConfigureUISetting();
+ const settingsContext = useContext(SettingStateContext);
+
+ useEffect(() => {
+ if (show) {
+ setDontShowAgain(false);
+ }
+ }, [show]);
+
+ function handleConfirm() {
+ if (dontShowAgain) {
+ if (settingsContext) {
+ settingsContext.saveUI({ disableAutoTagWarning: true });
+ } else {
+ saveUISetting({
+ variables: { key: "disableAutoTagWarning", value: true },
+ }).catch((e: unknown) => Toast.error(e));
+ }
+ }
+ onConfirm();
+ }
return (
= ({
accept={{
text: intl.formatMessage({ id: "actions.confirm" }),
variant: "danger",
- onClick: onConfirm,
+ onClick: handleConfirm,
}}
cancel={{
onClick: onCancel,
}}
>
+ setDontShowAgain(e.currentTarget.checked)}
+ label={intl.formatMessage({
+ id: "dialogs.dont_show_again",
+ })}
+ />
);
};
diff --git a/ui/v2.5/src/components/Shared/DetailsEditNavbar.tsx b/ui/v2.5/src/components/Shared/DetailsEditNavbar.tsx
index 159bb9f09..d4b0c9114 100644
--- a/ui/v2.5/src/components/Shared/DetailsEditNavbar.tsx
+++ b/ui/v2.5/src/components/Shared/DetailsEditNavbar.tsx
@@ -1,6 +1,7 @@
import { Button, Dropdown, Modal, SplitButton } from "react-bootstrap";
import React, { useState } from "react";
import { FormattedMessage, useIntl } from "react-intl";
+import { useAutoTagTrigger } from "src/hooks/useAutoTagTrigger";
import { ImageInput } from "./ImageInput";
import { AutoTagConfirmDialog } from "./AutoTagConfirmDialog";
import cx from "classnames";
@@ -33,6 +34,11 @@ export const DetailsEditNavbar: React.FC = (props: IProps) => {
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState(false);
const [isAutoTagAlertOpen, setIsAutoTagAlertOpen] = useState(false);
+ const onAutoTagClick = useAutoTagTrigger(
+ () => props.onAutoTag?.(),
+ () => setIsAutoTagAlertOpen(true)
+ );
+
function renderEditButton() {
if (props.isNew) return;
return (
@@ -116,7 +122,7 @@ export const DetailsEditNavbar: React.FC = (props: IProps) => {
diff --git a/ui/v2.5/src/core/config.ts b/ui/v2.5/src/core/config.ts
index e0cf008b5..3978d1887 100644
--- a/ui/v2.5/src/core/config.ts
+++ b/ui/v2.5/src/core/config.ts
@@ -105,6 +105,9 @@ export interface IUIConfig {
taskDefaults?: Record;
+ // if true the auto tag confirmation warning is skipped
+ disableAutoTagWarning?: boolean;
+
defaultFilters?: DefaultFilters;
taggerConfig?: ITaggerConfig;
diff --git a/ui/v2.5/src/docs/en/Manual/AutoTagging.md b/ui/v2.5/src/docs/en/Manual/AutoTagging.md
index 4725020d1..540a4b508 100644
--- a/ui/v2.5/src/docs/en/Manual/AutoTagging.md
+++ b/ui/v2.5/src/docs/en/Manual/AutoTagging.md
@@ -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.
+
+### Disable the confirmation warning
+
+A confirmation warning is shown before the auto tag task runs. If you use auto tag frequently, you can disable this warning by ticking the **Don't show this warning again** checkbox on the warning dialog, or by enabling **Settings** > **Tasks** > **Auto tag** > **Disable auto-tag warning**.
diff --git a/ui/v2.5/src/hooks/useAutoTagTrigger.ts b/ui/v2.5/src/hooks/useAutoTagTrigger.ts
new file mode 100644
index 000000000..4cb3ca38c
--- /dev/null
+++ b/ui/v2.5/src/hooks/useAutoTagTrigger.ts
@@ -0,0 +1,20 @@
+import { useCallback } from "react";
+import { IUIConfig } from "src/core/config";
+import { useConfigurationContext } from "./Config";
+
+export function useAutoTagTrigger(
+ onRun: () => void,
+ onOpenConfirm: () => void,
+ override?: boolean | null
+) {
+ const { configuration } = useConfigurationContext();
+ const ui = configuration?.ui as IUIConfig | undefined;
+ const disabled = override ?? ui?.disableAutoTagWarning ?? false;
+ return useCallback(() => {
+ if (disabled) {
+ onRun();
+ return;
+ }
+ onOpenConfirm();
+ }, [disabled, onRun, onOpenConfirm]);
+}
diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json
index 4974c06ca..b3d05fed7 100644
--- a/ui/v2.5/src/locales/en-GB.json
+++ b/ui/v2.5/src/locales/en-GB.json
@@ -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",
+ "disable_warning": {
+ "description": "Disable the confirmation warning shown before running auto tag.",
+ "heading": "Disable 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}}}",