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 {
|
||||
if (!path) return path
|
||||
|
||||
// macOS: /Users/<name>/...
|
||||
if (path.startsWith("/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
|
||||
}
|
||||
|
||||
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 (
|
||||
<>
|
||||
<div
|
||||
@@ -441,14 +492,14 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
|
||||
<div class="flex items-center gap-2 mb-1">
|
||||
<Folder class="w-4 h-4 flex-shrink-0 icon-muted" />
|
||||
<span class="text-sm font-medium truncate text-primary">
|
||||
{folder.path.split("/").pop()}
|
||||
{splitFolderPath(folder.path).baseName}
|
||||
</span>
|
||||
</div>
|
||||
<div class="text-xs font-mono truncate pl-6 text-muted">
|
||||
{getDisplayPath(folder.path)}
|
||||
</div>
|
||||
<div class="text-xs mt-1 pl-6 text-muted">
|
||||
{formatRelativeTime(folder.lastAccessed)}
|
||||
<div class="flex items-center gap-2 pl-6 text-xs text-muted min-w-0">
|
||||
<span class="font-mono truncate-start flex-1 min-w-0">
|
||||
{getDisplayPath(folder.path)}
|
||||
</span>
|
||||
<span class="flex-shrink-0">{formatRelativeTime(folder.lastAccessed)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<Show when={focusMode() === "recent" && selectedIndex() === index()}>
|
||||
|
||||
@@ -153,6 +153,16 @@
|
||||
@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 */
|
||||
@media (pointer: coarse) {
|
||||
input[type="text"],
|
||||
|
||||
Reference in New Issue
Block a user