diff --git a/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx b/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx index d64d15a1585..1532bf5e82a 100644 --- a/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx +++ b/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx @@ -177,6 +177,22 @@ export const SceneDuplicateChecker: React.FC = () => { }); }; + const findLargestResolutionScene = (group: GQL.SlimSceneDataFragment[]) => { + // Get resolution of a scene + const sceneResolution = (scene: GQL.SlimSceneDataFragment) => { + return scene.files.reduce( + (sum: number, f) => sum + (f.height * f.width || 0), + 0 + ); + }; + // Find scene object with maximum resolution + return group.reduce((largest, scene) => { + const largestSize = sceneResolution(largest); + const currentSize = sceneResolution(scene); + return currentSize > largestSize ? scene : largest; + }); + }; + // Helper to get file date const findFirstFileByAge = ( @@ -216,6 +232,13 @@ export const SceneDuplicateChecker: React.FC = () => { return new Set(codecs).size === 1; } + function checkSameResolution(dataGroup: GQL.SlimSceneDataFragment[]) { + const resolutions = dataGroup.map( + (s) => s.files[0]?.width * s.files[0]?.height + ); + return new Set(resolutions).size === 1; + } + const onSelectLargestClick = () => { setSelectedScenes([]); const checkedArray: Record = {}; @@ -236,6 +259,30 @@ export const SceneDuplicateChecker: React.FC = () => { setCheckedScenes(checkedArray); }; + const onSelectLargestResolutionClick = () => { + setSelectedScenes([]); + const checkedArray: Record = {}; + + filteredScenes.forEach((group) => { + if (chkSafeSelect && !checkSameCodec(group)) { + return; + } + // Don't select scenes where resolution is identical. + if (checkSameResolution(group)) { + return; + } + // Find the highest resolution scene in group. + const highest = findLargestResolutionScene(group); + group.forEach((scene) => { + if (scene !== highest) { + checkedArray[scene.id] = true; + } + }); + }); + + setCheckedScenes(checkedArray); + }; + const onSelectByAge = (oldest: boolean) => { setSelectedScenes([]); @@ -715,6 +762,14 @@ export const SceneDuplicateChecker: React.FC = () => { {intl.formatMessage({ id: "dupe_check.select_none" })} + onSelectLargestResolutionClick()} + > + {intl.formatMessage({ + id: "dupe_check.select_all_but_largest_resolution", + })} + + onSelectLargestClick()}> {intl.formatMessage({ id: "dupe_check.select_all_but_largest_file", diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json index 073ce90432b..52c90603990 100644 --- a/ui/v2.5/src/locales/en-GB.json +++ b/ui/v2.5/src/locales/en-GB.json @@ -932,6 +932,7 @@ "search_accuracy_label": "Search Accuracy", "select_options": "Select Options…", "select_all_but_largest_file": "Select every file in each duplicated group, except the largest file", + "select_all_but_largest_resolution": "Select every file in each duplicated group, except the file with highest resolution", "select_none": "Select None", "select_oldest": "Select the oldest file in the duplicate group", "select_youngest": "Select the youngest file in the duplicate group", @@ -1367,4 +1368,4 @@ "weight_kg": "Weight (kg)", "years_old": "years old", "zip_file_count": "Zip File Count" -} \ No newline at end of file +}