feat: add originalPath for external library assets in dedupe (#23710)

* Add original path info row to duplicate asset component

View path of images, useful when using external Library

* Make if for not show path in internal images

* Update web/src/lib/components/utilities-page/duplicates/duplicate-asset.svelte

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>

* Refactor original path display logic in duplicate-asset

* Update duplicate-asset.svelte

* Add full path localization string

* Change translated data

* format: fix

---------

Co-authored-by: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com>
Co-authored-by: Alex Tran <alex.tran1502@gmail.com>
This commit is contained in:
Kevin Puertas 2025-11-19 04:24:17 +01:00 committed by GitHub
parent d9fd52ea18
commit 3a694219bf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 29 additions and 0 deletions

View File

@ -1121,6 +1121,7 @@
"folders_feature_description": "Browsing the folder view for the photos and videos on the file system", "folders_feature_description": "Browsing the folder view for the photos and videos on the file system",
"forgot_pin_code_question": "Forgot your PIN?", "forgot_pin_code_question": "Forgot your PIN?",
"forward": "Forward", "forward": "Forward",
"full_path": "Full path: {path}",
"gcast_enabled": "Google Cast", "gcast_enabled": "Google Cast",
"gcast_enabled_description": "This feature loads external resources from Google in order to work.", "gcast_enabled_description": "This feature loads external resources from Google in order to work.",
"general": "General", "general": "General",

View File

@ -12,6 +12,7 @@
mdiClock, mdiClock,
mdiFile, mdiFile,
mdiFitToScreen, mdiFitToScreen,
mdiFolderOutline,
mdiHeart, mdiHeart,
mdiImageMultipleOutline, mdiImageMultipleOutline,
mdiImageOutline, mdiImageOutline,
@ -51,6 +52,7 @@
fileName: isDifferent((a) => a.originalFileName), fileName: isDifferent((a) => a.originalFileName),
fileSize: isDifferent((a) => getFileSize(a)), fileSize: isDifferent((a) => getFileSize(a)),
resolution: isDifferent((a) => getAssetResolution(a)), resolution: isDifferent((a) => getAssetResolution(a)),
originalPath: isDifferent((a) => a.originalPath ?? $t('unknown')),
date: isDifferent((a) => { date: isDifferent((a) => {
const tz = a.exifInfo?.timeZone; const tz = a.exifInfo?.timeZone;
const dt = const dt =
@ -79,6 +81,24 @@
(a) => [a.exifInfo?.city, a.exifInfo?.state, a.exifInfo?.country].filter(Boolean).join(', ') || 'unknown', (a) => [a.exifInfo?.city, a.exifInfo?.state, a.exifInfo?.country].filter(Boolean).join(', ') || 'unknown',
), ),
}); });
const getBasePath = (fullpath: string, fileName: string): string => {
if (fileName && fullpath.endsWith(fileName)) {
return fullpath.slice(0, -(fileName.length + 1));
}
return fullpath;
};
function truncateMiddle(path: string, maxLength: number = 50): string {
if (path.length <= maxLength) {
return path;
}
const start = Math.floor(maxLength / 2) - 2;
const end = Math.floor(maxLength / 2) - 2;
return path.slice(0, Math.max(0, start)) + '...' + path.slice(Math.max(0, path.length - end));
}
</script> </script>
<div class="min-w-60 transition-colors border rounded-lg"> <div class="min-w-60 transition-colors border rounded-lg">
@ -152,6 +172,14 @@
{asset.originalFileName} {asset.originalFileName}
</InfoRow> </InfoRow>
<InfoRow
icon={mdiFolderOutline}
highlight={hasDifferentValues.originalPath}
title={$t('full_path', { values: { path: asset.originalPath } })}
>
{truncateMiddle(getBasePath(asset.originalPath, asset.originalFileName)) || $t('unknown')}
</InfoRow>
<InfoRow icon={mdiFile} highlight={hasDifferentValues.fileSize} title={$t('file_size')}> <InfoRow icon={mdiFile} highlight={hasDifferentValues.fileSize} title={$t('file_size')}>
{getFileSize(asset)} {getFileSize(asset)}
</InfoRow> </InfoRow>