ui(duplicates): show grandparent + parent in path strip
When two duplicates live in folders with the same parent name (e.g. matching '2023' subfolders under different archives), showing only the parent gave both thumbnails the same label. Walk one level up: the path strip now renders '…/<grandparent>/<parent>' so the user can always tell two copies apart at a glance. Filename still surfaces via the title tooltip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -515,20 +515,25 @@ function formatBytes(n: number): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Short label for the bottom path strip on a duplicate thumbnail.
|
/** Short label for the bottom path strip on a duplicate thumbnail.
|
||||||
* Goal: tell two copies-with-the-same-filename apart at a glance, so
|
* Goal: tell two copies-with-the-same-filename apart at a glance.
|
||||||
* we want the parent folder name — that's almost always the
|
* Shows the last two folders ("…/<grandparent>/<parent>") so the
|
||||||
* discriminator (different shoots, different years, different
|
* discriminator is visible even when both copies live under the
|
||||||
* upload sources). When the parent folder is unhelpful (e.g. the
|
* same parent name (e.g. matching `2023` subfolders under different
|
||||||
* filename is itself sitting at the root) we fall back to the file
|
* archives). The leading "…/" is always present when there's any
|
||||||
* basename. Long folder names get text-overflow-ellipsis'd by the
|
* truncated prefix; the enclosing strip's `truncate` handles any
|
||||||
* enclosing strip's `truncate`. */
|
* excess width. */
|
||||||
function duplicatePathLabel(filepath: string): string {
|
function duplicatePathLabel(filepath: string): string {
|
||||||
if (!filepath) return ''
|
if (!filepath) return ''
|
||||||
const parts = filepath.split('/').filter(Boolean)
|
const parts = filepath.split('/').filter(Boolean)
|
||||||
if (parts.length === 0) return filepath
|
if (parts.length === 0) return filepath
|
||||||
if (parts.length === 1) return parts[0]
|
// Strip the filename (last segment); only the directory chain
|
||||||
// The second-to-last segment IS the parent directory.
|
// discriminates between copies with matching basenames.
|
||||||
return parts[parts.length - 2]
|
const folders = parts.slice(0, -1)
|
||||||
|
if (folders.length === 0) return parts[0]
|
||||||
|
if (folders.length === 1) return `…/${folders[0]}`
|
||||||
|
const parent = folders[folders.length - 1]
|
||||||
|
const grandparent = folders[folders.length - 2]
|
||||||
|
return `…/${grandparent}/${parent}`
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Adapt a DuplicateGroupMember (the slim API shape) to a Photo, which
|
/** Adapt a DuplicateGroupMember (the slim API shape) to a Photo, which
|
||||||
|
|||||||
Reference in New Issue
Block a user