diff --git a/ui/v2.5/src/components/Changelog/versions/v070.md b/ui/v2.5/src/components/Changelog/versions/v070.md index f79e9775c..404202b85 100644 --- a/ui/v2.5/src/components/Changelog/versions/v070.md +++ b/ui/v2.5/src/components/Changelog/versions/v070.md @@ -31,6 +31,7 @@ * Change performer text query to search by name and alias only. ### 🐛 Bug fixes +* Fix performer/studio being cleared when skipped in scene tagger. * Fixed error when auto-tagging for performers/studios/tags with regex characters in the name. * Fix scraped performer image not updating after clearing the current image when creating a new performer. * Fix error preventing adding a new library path when an existing library path is missing. diff --git a/ui/v2.5/src/components/Tagger/Config.tsx b/ui/v2.5/src/components/Tagger/Config.tsx index f320567af..cce04bbde 100644 --- a/ui/v2.5/src/components/Tagger/Config.tsx +++ b/ui/v2.5/src/components/Tagger/Config.tsx @@ -44,6 +44,8 @@ const Config: React.FC = ({ show, config, setConfig }) => { if (!blacklistRef.current) return; const input = blacklistRef.current.value; + if (input.length === 0) return; + setConfig({ ...config, blacklist: [...config.blacklist, input], diff --git a/ui/v2.5/src/components/Tagger/StashSearchResult.tsx b/ui/v2.5/src/components/Tagger/StashSearchResult.tsx index bb121e612..a8a06e6bf 100755 --- a/ui/v2.5/src/components/Tagger/StashSearchResult.tsx +++ b/ui/v2.5/src/components/Tagger/StashSearchResult.tsx @@ -25,28 +25,38 @@ const getDurationStatus = ( scene: IStashBoxScene, stashDuration: number | undefined | null ) => { - const fingerprintDuration = - scene.fingerprints.map((f) => f.duration)?.[0] ?? null; - const sceneDuration = scene.duration || fingerprintDuration; - if (!sceneDuration || !stashDuration) return ""; - const diff = Math.abs(sceneDuration - stashDuration); - if (diff < 5) { + if (!stashDuration) return ""; + + const durations = scene.fingerprints + .map((f) => f.duration) + .map((d) => Math.abs(d - stashDuration)); + const matchCount = durations.filter((duration) => duration <= 5).length; + + let match; + if (matchCount > 0) + match = `Duration matches ${matchCount}/${durations.length} fingerprints`; + else if (Math.abs(scene.duration - stashDuration) < 5) + match = "Duration is a match"; + + if (match) return (
- Duration is a match + {match}
); - } - return
Duration off by {Math.floor(diff)}s
; + + const minDiff = Math.min(scene.duration, ...durations); + return
Duration off by at least {Math.floor(minDiff)}s
; }; const getFingerprintStatus = ( scene: IStashBoxScene, stashScene: GQL.SlimSceneDataFragment ) => { - const checksum = stashScene.checksum ?? stashScene.oshash ?? undefined; - const checksumMatch = scene.fingerprints.some((f) => f.hash === checksum); + const checksumMatch = scene.fingerprints.some( + (f) => f.hash === stashScene.checksum || f.hash === stashScene.oshash + ); const phashMatch = scene.fingerprints.some( (f) => f.hash === stashScene.phash ); @@ -176,6 +186,8 @@ const StashSearchResult: React.FC = ({ studioID = res.data.studioUpdate.id; } else if (studio.type === "existing") { studioID = studio.data.id; + } else if (studio.type === "skip") { + studioID = stashScene.studio?.id; } setSaveState("Saving performers"); @@ -296,6 +308,10 @@ const StashSearchResult: React.FC = ({ updatedTags = uniq(newTagIDs); } + const performer_ids = performerIDs.filter( + (id) => id !== "Skip" + ) as string[]; + const sceneUpdateResult = await updateScene({ variables: { input: { @@ -303,9 +319,10 @@ const StashSearchResult: React.FC = ({ title: scene.title, details: scene.details, date: scene.date, - performer_ids: performerIDs.filter( - (id) => id !== "Skip" - ) as string[], + performer_ids: + performer_ids.length === 0 + ? stashScene.performers.map((p) => p.id) + : performer_ids, studio_id: studioID, cover_image: imgData, url: scene.url, diff --git a/ui/v2.5/src/components/Tagger/Tagger.tsx b/ui/v2.5/src/components/Tagger/Tagger.tsx index ed9aa0a17..35bbb4a58 100755 --- a/ui/v2.5/src/components/Tagger/Tagger.tsx +++ b/ui/v2.5/src/components/Tagger/Tagger.tsx @@ -171,12 +171,15 @@ const TaggerList: React.FC = ({ const [selectedResult, setSelectedResult] = useState< Record >(); + const [selectedFingerprintResult, setSelectedFingerprintResult] = useState< + Record + >(); const [taggedScenes, setTaggedScenes] = useState< Record> >({}); const [loadingFingerprints, setLoadingFingerprints] = useState(false); const [fingerprints, setFingerprints] = useState< - Record + Record >({}); const [hideUnmatched, setHideUnmatched] = useState(false); const fingerprintQueue = @@ -269,7 +272,9 @@ const TaggerList: React.FC = ({ selectScenes(results.data?.queryStashBoxScene).forEach((scene) => { scene.fingerprints?.forEach((f) => { - newFingerprints[f.hash] = scene; + newFingerprints[f.hash] = newFingerprints[f.hash] + ? [...newFingerprints[f.hash], scene] + : [scene]; }); }); @@ -428,21 +433,30 @@ const TaggerList: React.FC = ({ let searchResult; if (fingerprintMatch && !isTagged && !hasStashIDs) { - searchResult = ( + searchResult = sortScenesByDuration( + fingerprintMatch, + scene.file.duration ?? 0 + ).map((match, i) => ( {}} + isActive={(selectedFingerprintResult?.[scene.id] ?? 0) === i} + setActive={() => + setSelectedFingerprintResult({ + ...selectedFingerprintResult, + [scene.id]: i, + }) + } setScene={handleTaggedScene} - scene={fingerprintMatch} + scene={match} setCoverImage={config.setCoverImage} setTags={config.setTags} tagOperation={config.tagOperation} endpoint={selectedEndpoint.endpoint} queueFingerprintSubmission={queueFingerprintSubmission} + key={match.stash_id} /> - ); + )); } else if ( searchResults[scene.id]?.length > 0 && !isTagged && diff --git a/ui/v2.5/src/components/Tagger/utils.ts b/ui/v2.5/src/components/Tagger/utils.ts index b5666bcf0..6222cde6d 100644 --- a/ui/v2.5/src/components/Tagger/utils.ts +++ b/ui/v2.5/src/components/Tagger/utils.ts @@ -165,18 +165,22 @@ export const sortScenesByDuration = ( targetDuration?: number ) => scenes.sort((a, b) => { - const adur = - a?.duration || (a?.fingerprints.map((f) => f.duration)?.[0] ?? null); - const bdur = - b?.duration || (b?.fingerprints.map((f) => f.duration)?.[0] ?? null); - if (!adur && !bdur) return 0; - if (adur && !bdur) return -1; - if (!adur && bdur) return 1; - if (!targetDuration) return 0; - const aDiff = Math.abs((adur ?? 0) - targetDuration); - const bDiff = Math.abs((bdur ?? 0) - targetDuration); + const aDur = [ + a.duration, + ...a.fingerprints.map((f) => f.duration), + ].map((d) => Math.abs(d - targetDuration)); + const bDur = [ + b.duration, + ...b.fingerprints.map((f) => f.duration), + ].map((d) => Math.abs(d - targetDuration)); + + if (aDur.length > 0 && bDur.length === 0) return -1; + if (aDur.length === 0 && bDur.length > 0) return 1; + + const aDiff = Math.min(...aDur); + const bDiff = Math.min(...bDur); if (aDiff < bDiff) return -1; if (aDiff > bDiff) return 1;