polish folder picker list and instance focus

This commit is contained in:
Shantur Rathore
2025-11-08 22:47:29 +00:00
parent 03ff2779b0
commit 0a77feac7a
2 changed files with 69 additions and 45 deletions

View File

@@ -28,9 +28,18 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
}) })
function scrollToIndex(index: number) { function scrollToIndex(index: number) {
const element = recentListRef?.querySelector(`[data-folder-index="${index}"]`) const container = recentListRef
if (element) { if (!container) return
element.scrollIntoView({ block: "nearest", behavior: "auto" }) const element = container.querySelector(`[data-folder-index="${index}"]`) as HTMLElement | null
if (!element) return
const containerRect = container.getBoundingClientRect()
const elementRect = element.getBoundingClientRect()
if (elementRect.top < containerRect.top) {
container.scrollTop -= containerRect.top - elementRect.top
} else if (elementRect.bottom > containerRect.bottom) {
container.scrollTop += elementRect.bottom - containerRect.bottom
} }
} }
@@ -182,59 +191,55 @@ const FolderSelectionView: Component<FolderSelectionViewProps> = (props) => {
</div> </div>
} }
> >
<div class="panel flex-1 min-h-0 overflow-hidden"> <div class="panel flex flex-col flex-1 min-h-0">
<div class="panel-header"> <div class="panel-header">
<h2 class="panel-title">Recent Folders</h2> <h2 class="panel-title">Recent Folders</h2>
<p class="panel-subtitle"> <p class="panel-subtitle">
{folders().length} {folders().length === 1 ? "folder" : "folders"} available {folders().length} {folders().length === 1 ? "folder" : "folders"} available
</p> </p>
</div> </div>
<div <div class="panel-list panel-list--fill flex-1 min-h-0 overflow-auto" ref={(el) => (recentListRef = el)}>
class="panel-list max-h-[50vh] overflow-y-auto pr-1" <For each={folders()}>
ref={(el) => (recentListRef = el)} {(folder, index) => (
> <div
<For each={folders()}> class="panel-list-item"
{(folder, index) => ( classList={{
<div "panel-list-item-highlight": focusMode() === "recent" && selectedIndex() === index(),
data-folder-index={index()} }}
class="panel-list-item" >
classList={{ <div class="flex items-center gap-2 w-full px-1">
"panel-list-item-highlight": focusMode() === "recent" && selectedIndex() === index(),
}}
>
<div class="flex items-center w-full">
<button <button
class="panel-list-item-content w-full" data-folder-index={index()}
class="panel-list-item-content flex-1"
onClick={() => handleFolderSelect(folder.path)} onClick={() => handleFolderSelect(folder.path)}
onMouseEnter={() => { onMouseEnter={() => {
setFocusMode("recent") setFocusMode("recent")
setSelectedIndex(index()) setSelectedIndex(index())
}} }}
> >
<div class="flex-1 min-w-0"> <div class="flex items-center justify-between gap-3 w-full">
<div class="flex items-center gap-2 mb-1"> <div class="flex-1 min-w-0">
<Folder class="w-4 h-4 flex-shrink-0 icon-muted" /> <div class="flex items-center gap-2 mb-1">
<span class="text-sm font-medium truncate text-primary"> <Folder class="w-4 h-4 flex-shrink-0 icon-muted" />
{folder.path.split("/").pop()} <span class="text-sm font-medium truncate text-primary">
</span> {folder.path.split("/").pop()}
</div> </span>
<div class="text-xs font-mono truncate pl-6 text-muted"> </div>
{getDisplayPath(folder.path)} <div class="text-xs font-mono truncate pl-6 text-muted">
</div> {getDisplayPath(folder.path)}
<div class="text-xs mt-1 pl-6 text-muted"> </div>
{formatRelativeTime(folder.lastAccessed)} <div class="text-xs mt-1 pl-6 text-muted">
{formatRelativeTime(folder.lastAccessed)}
</div>
</div> </div>
<Show when={focusMode() === "recent" && selectedIndex() === index()}>
<kbd class="kbd"></kbd>
</Show>
</div> </div>
<Show when={focusMode() === "recent" && selectedIndex() === index()}>
<kbd class="kbd">
</kbd>
</Show>
</button> </button>
<button <button
onClick={(e) => handleRemove(folder.path, e)} onClick={(e) => handleRemove(folder.path, e)}
class="p-2.5 transition-all mr-2 hover:bg-red-100 dark:hover:bg-red-900/30 opacity-70 hover:opacity-100" class="p-2 transition-all hover:bg-red-100 dark:hover:bg-red-900/30 opacity-70 hover:opacity-100 rounded"
title="Remove from recent" title="Remove from recent"
> >
<Trash2 class="w-3.5 h-3.5 transition-colors icon-muted hover:text-red-600 dark:hover:text-red-400" /> <Trash2 class="w-3.5 h-3.5 transition-colors icon-muted hover:text-red-600 dark:hover:text-red-400" />

View File

@@ -64,15 +64,34 @@ function updateInstance(id: string, updates: Partial<Instance>) {
} }
function removeInstance(id: string) { function removeInstance(id: string) {
let nextActiveId: string | null = null
setInstances((prev) => { setInstances((prev) => {
if (!prev.has(id)) {
return prev
}
const keys = Array.from(prev.keys())
const index = keys.indexOf(id)
const next = new Map(prev) const next = new Map(prev)
next.delete(id) next.delete(id)
if (activeInstanceId() === id) {
if (index > 0) {
nextActiveId = keys[index - 1]
} else {
const remainingKeys = Array.from(next.keys())
nextActiveId = remainingKeys.length > 0 ? remainingKeys[0] : null
}
}
return next return next
}) })
removeLogContainer(id) removeLogContainer(id)
if (activeInstanceId() === id) { if (activeInstanceId() === id) {
setActiveInstanceId(null) setActiveInstanceId(nextActiveId)
} }
// Clean up session indexes and drafts for removed instance // Clean up session indexes and drafts for removed instance