fix(ui): improve recent folders path display (#147)
This commit is contained in:
@@ -254,12 +254,63 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
|
|||||||
|
|
||||||
|
|
||||||
function getDisplayPath(path: string): string {
|
function getDisplayPath(path: string): string {
|
||||||
|
if (!path) return path
|
||||||
|
|
||||||
|
// macOS: /Users/<name>/...
|
||||||
if (path.startsWith("/Users/")) {
|
if (path.startsWith("/Users/")) {
|
||||||
return path.replace(/^\/Users\/[^/]+/, "~")
|
return path.replace(/^\/Users\/[^/]+/, "~")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Linux: /home/<name>/...
|
||||||
|
if (path.startsWith("/home/")) {
|
||||||
|
return path.replace(/^\/home\/[^/]+/, "~")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Windows: C:\Users\<name>\... (and the forward-slash variant)
|
||||||
|
if (/^[A-Za-z]:\\Users\\/.test(path)) {
|
||||||
|
return path.replace(/^[A-Za-z]:\\Users\\[^\\]+/, "~")
|
||||||
|
}
|
||||||
|
if (/^[A-Za-z]:\/Users\//.test(path)) {
|
||||||
|
return path.replace(/^[A-Za-z]:\/Users\/[^/]+/, "~")
|
||||||
|
}
|
||||||
|
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function looksLikeWindowsPath(value: string): boolean {
|
||||||
|
if (!value) return false
|
||||||
|
// Drive letter (C:\...) or UNC (\\server\share\...)
|
||||||
|
return /^[A-Za-z]:[\\/]/.test(value) || /^\\\\[^\\]+\\[^\\]+/.test(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitFolderPath(rawPath: string): { baseName: string; dirName: string } {
|
||||||
|
if (!rawPath) return { baseName: "", dirName: "" }
|
||||||
|
|
||||||
|
const isWindows = looksLikeWindowsPath(rawPath)
|
||||||
|
const trimmed = rawPath.replace(/[\\/]+$/, "")
|
||||||
|
|
||||||
|
// Root edge-cases ("/", "C:\\", "\\\\server\\share\\")
|
||||||
|
if (!trimmed) {
|
||||||
|
return { baseName: rawPath, dirName: "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isWindows && /^[A-Za-z]:$/.test(trimmed)) {
|
||||||
|
return { baseName: `${trimmed}\\`, dirName: "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastSlash = trimmed.lastIndexOf("/")
|
||||||
|
const lastBackslash = isWindows ? trimmed.lastIndexOf("\\") : -1
|
||||||
|
const lastSep = Math.max(lastSlash, lastBackslash)
|
||||||
|
|
||||||
|
if (lastSep < 0) {
|
||||||
|
return { baseName: trimmed, dirName: "" }
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseName = trimmed.slice(lastSep + 1) || trimmed
|
||||||
|
const dirName = trimmed.slice(0, lastSep)
|
||||||
|
return { baseName, dirName }
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div
|
<div
|
||||||
@@ -441,14 +492,14 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
|
|||||||
<div class="flex items-center gap-2 mb-1">
|
<div class="flex items-center gap-2 mb-1">
|
||||||
<Folder class="w-4 h-4 flex-shrink-0 icon-muted" />
|
<Folder class="w-4 h-4 flex-shrink-0 icon-muted" />
|
||||||
<span class="text-sm font-medium truncate text-primary">
|
<span class="text-sm font-medium truncate text-primary">
|
||||||
{folder.path.split("/").pop()}
|
{splitFolderPath(folder.path).baseName}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="text-xs font-mono truncate pl-6 text-muted">
|
<div class="flex items-center gap-2 pl-6 text-xs text-muted min-w-0">
|
||||||
{getDisplayPath(folder.path)}
|
<span class="font-mono truncate-start flex-1 min-w-0">
|
||||||
</div>
|
{getDisplayPath(folder.path)}
|
||||||
<div class="text-xs mt-1 pl-6 text-muted">
|
</span>
|
||||||
{formatRelativeTime(folder.lastAccessed)}
|
<span class="flex-shrink-0">{formatRelativeTime(folder.lastAccessed)}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Show when={focusMode() === "recent" && selectedIndex() === index()}>
|
<Show when={focusMode() === "recent" && selectedIndex() === index()}>
|
||||||
|
|||||||
@@ -153,6 +153,16 @@
|
|||||||
@apply opacity-50;
|
@apply opacity-50;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Truncate from the start (keeps end visible; good for paths) */
|
||||||
|
.truncate-start {
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
direction: rtl;
|
||||||
|
text-align: left;
|
||||||
|
unicode-bidi: plaintext;
|
||||||
|
}
|
||||||
|
|
||||||
/* Prevent iOS Safari auto-zoom on text input focus */
|
/* Prevent iOS Safari auto-zoom on text input focus */
|
||||||
@media (pointer: coarse) {
|
@media (pointer: coarse) {
|
||||||
input[type="text"],
|
input[type="text"],
|
||||||
|
|||||||
Reference in New Issue
Block a user