import { Component, createSignal, Show, For, onMount, onCleanup, createEffect } from "solid-js" import { Folder, Clock, Trash2, FolderPlus, Settings, ChevronDown, ChevronUp } from "lucide-solid" import { recentFolders, removeRecentFolder, preferences, updateLastUsedBinary } from "../stores/preferences" import OpenCodeBinarySelector from "./opencode-binary-selector" import EnvironmentVariablesEditor from "./environment-variables-editor" interface FolderSelectionViewProps { onSelectFolder: (folder?: string, binaryPath?: string) => void isLoading?: boolean } const FolderSelectionView: Component = (props) => { const [selectedIndex, setSelectedIndex] = createSignal(0) const [focusMode, setFocusMode] = createSignal<"recent" | "new" | null>("recent") const [showAdvanced, setShowAdvanced] = createSignal(false) const [selectedBinary, setSelectedBinary] = createSignal(preferences().lastUsedBinary || "opencode") const folders = () => recentFolders() // Update selected binary when preferences change createEffect(() => { const lastUsed = preferences().lastUsedBinary if (lastUsed && lastUsed !== selectedBinary()) { setSelectedBinary(lastUsed) } }) function scrollToIndex(index: number) { const element = document.querySelector(`[data-folder-index="${index}"]`) if (element) { element.scrollIntoView({ block: "nearest", behavior: "auto" }) } } function handleKeyDown(e: KeyboardEvent) { const folderList = folders() if (e.key === "Enter" && (e.metaKey || e.ctrlKey)) { e.preventDefault() handleBrowse() return } if (folderList.length === 0) return if (e.key === "ArrowDown") { e.preventDefault() const newIndex = Math.min(selectedIndex() + 1, folderList.length - 1) setSelectedIndex(newIndex) setFocusMode("recent") scrollToIndex(newIndex) } else if (e.key === "ArrowUp") { e.preventDefault() const newIndex = Math.max(selectedIndex() - 1, 0) setSelectedIndex(newIndex) setFocusMode("recent") scrollToIndex(newIndex) } else if (e.key === "PageDown") { e.preventDefault() const pageSize = 5 const newIndex = Math.min(selectedIndex() + pageSize, folderList.length - 1) setSelectedIndex(newIndex) setFocusMode("recent") scrollToIndex(newIndex) } else if (e.key === "PageUp") { e.preventDefault() const pageSize = 5 const newIndex = Math.max(selectedIndex() - pageSize, 0) setSelectedIndex(newIndex) setFocusMode("recent") scrollToIndex(newIndex) } else if (e.key === "Home") { e.preventDefault() setSelectedIndex(0) setFocusMode("recent") scrollToIndex(0) } else if (e.key === "End") { e.preventDefault() const newIndex = folderList.length - 1 setSelectedIndex(newIndex) setFocusMode("recent") scrollToIndex(newIndex) } else if (e.key === "Enter") { e.preventDefault() handleEnterKey() } else if (e.key === "Backspace" || e.key === "Delete") { e.preventDefault() if (folderList.length > 0 && focusMode() === "recent") { const folder = folderList[selectedIndex()] if (folder) { handleRemove(folder.path) } } } } function handleEnterKey() { const folderList = folders() const index = selectedIndex() if (index < folderList.length) { props.onSelectFolder(folderList[index].path) } } onMount(() => { window.addEventListener("keydown", handleKeyDown) onCleanup(() => { window.removeEventListener("keydown", handleKeyDown) }) }) function formatRelativeTime(timestamp: number): string { const seconds = Math.floor((Date.now() - timestamp) / 1000) const minutes = Math.floor(seconds / 60) const hours = Math.floor(minutes / 60) const days = Math.floor(hours / 24) if (days > 0) return `${days}d ago` if (hours > 0) return `${hours}h ago` if (minutes > 0) return `${minutes}m ago` return "just now" } function handleFolderSelect(path: string) { updateLastUsedBinary(selectedBinary()) props.onSelectFolder(path, selectedBinary()) } function handleBrowse() { updateLastUsedBinary(selectedBinary()) props.onSelectFolder(undefined, selectedBinary()) } function handleBinaryChange(binary: string) { setSelectedBinary(binary) } function handleRemove(path: string, e?: Event) { e?.stopPropagation() removeRecentFolder(path) const folderList = folders() if (selectedIndex() >= folderList.length && folderList.length > 0) { setSelectedIndex(folderList.length - 1) } } function getDisplayPath(path: string): string { if (path.startsWith("/Users/")) { return path.replace(/^\/Users\/[^/]+/, "~") } return path } return (

Welcome to OpenCode

Select a folder to start coding with AI

0} fallback={

No Recent Folders

Browse for a folder to get started

} >

Recent Folders

{folders().length} {folders().length === 1 ? "folder" : "folders"} available

{(folder, index) => (
)}

Browse for Folder

Select any folder on your computer

{/* Advanced settings section */}
OpenCode Binary
) } export default FolderSelectionView