From 3fa280d21878ae391674a21758199df3d2d8c3b5 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Fri, 3 Oct 2025 09:04:28 -0500 Subject: chore: app -> desktop --- packages/desktop/src/pages/index.tsx | 278 ++++++++++++++++++++++++++++++++++ packages/desktop/src/pages/layout.tsx | 5 + 2 files changed, 283 insertions(+) create mode 100644 packages/desktop/src/pages/index.tsx create mode 100644 packages/desktop/src/pages/layout.tsx (limited to 'packages/desktop/src/pages') diff --git a/packages/desktop/src/pages/index.tsx b/packages/desktop/src/pages/index.tsx new file mode 100644 index 000000000..128c6adfd --- /dev/null +++ b/packages/desktop/src/pages/index.tsx @@ -0,0 +1,278 @@ +import { FileIcon, Icon, IconButton, Tooltip } from "@/ui" +import { Tabs } from "@/ui/tabs" +import FileTree from "@/components/file-tree" +import EditorPane from "@/components/editor-pane" +import { For, Match, onCleanup, onMount, Show, Switch } from "solid-js" +import { SelectDialog } from "@/components/select-dialog" +import { useLocal } from "@/context" +import { ResizeableLayout, ResizeablePane } from "@/components/resizeable-pane" +import type { LocalFile } from "@/context/local" +import SessionList from "@/components/session-list" +import SessionTimeline from "@/components/session-timeline" +import { createStore } from "solid-js/store" +import { getDirectory, getFilename } from "@/utils" + +export default function Page() { + const local = useLocal() + const [store, setStore] = createStore({ + clickTimer: undefined as number | undefined, + modelSelectOpen: false, + fileSelectOpen: false, + }) + + const layoutKey = "workspace" + const timelinePane = "timeline" + + let inputRef: HTMLTextAreaElement | undefined = undefined + + const MOD = typeof navigator === "object" && /(Mac|iPod|iPhone|iPad)/.test(navigator.platform) ? "Meta" : "Control" + + onMount(() => { + document.addEventListener("keydown", handleKeyDown) + }) + + onCleanup(() => { + document.removeEventListener("keydown", handleKeyDown) + }) + + const handleKeyDown = (event: KeyboardEvent) => { + if (event.getModifierState(MOD) && event.shiftKey && event.key.toLowerCase() === "p") { + event.preventDefault() + // TODO: command palette + return + } + if (event.getModifierState(MOD) && event.key.toLowerCase() === "p") { + event.preventDefault() + setStore("fileSelectOpen", true) + return + } + + const focused = document.activeElement === inputRef + if (focused) { + if (event.key === "Escape") { + inputRef?.blur() + } + return + } + + if (local.file.active()) { + const active = local.file.active()! + if (event.key === "Enter" && active.selection) { + local.context.add({ + type: "file", + path: active.path, + selection: { ...active.selection }, + }) + return + } + + if (event.getModifierState(MOD)) { + if (event.key.toLowerCase() === "a") { + return + } + if (event.key.toLowerCase() === "c") { + return + } + } + } + + if (event.key.length === 1 && event.key !== "Unidentified") { + inputRef?.focus() + } + } + + const resetClickTimer = () => { + if (!store.clickTimer) return + clearTimeout(store.clickTimer) + setStore("clickTimer", undefined) + } + + const startClickTimer = () => { + const newClickTimer = setTimeout(() => { + setStore("clickTimer", undefined) + }, 300) + setStore("clickTimer", newClickTimer as unknown as number) + } + + const handleFileClick = async (file: LocalFile) => { + if (store.clickTimer) { + resetClickTimer() + local.file.update(file.path, { ...file, pinned: true }) + } else { + local.file.open(file.path) + startClickTimer() + } + } + + return ( +
+ + + +
+ + + Files + + + Changes + + +
+ + + + + No changes
} + > + + + + + + + setStore("modelSelectOpen", true)} + onInputRefChange={(element: HTMLTextAreaElement | null) => { + inputRef = element ?? undefined + }} + /> + + +
+ }> + {(activeSession) => ( +
+
+
+ local.session.clearActive()} + class="text-text-muted hover:text-text" + > + + +

+ {activeSession().title || "Untitled Session"} +

+
+
+ +
+ )} +
+
+
+ + + `${x.provider.id}:${x.id}`} + items={local.model.list()} + current={local.model.current()} + render={(i) => ( +
+
+ + {i.name} + + {i.id} + +
+
+ + + + + + + + + +
+ {new Intl.NumberFormat("en-US", { + notation: "compact", + compactDisplay: "short", + }).format(i.limit.context)} +
+ +
+ + 10}>$$$ + 1}>$$ + 0.1}>$ + +
+
+
+
+ )} + filter={["provider.name", "name", "id"]} + groupBy={(x) => x.provider.name} + onClose={() => setStore("modelSelectOpen", false)} + onSelect={(x) => local.model.set(x ? { modelID: x.id, providerID: x.provider.id } : undefined)} + /> +
+ + x} + render={(i) => ( +
+
+ + {getFilename(i)} + + {getDirectory(i)} + +
+
+
+ )} + onClose={() => setStore("fileSelectOpen", false)} + onSelect={(x) => (x ? local.file.open(x, { pinned: true }) : undefined)} + /> +
+ + ) +} diff --git a/packages/desktop/src/pages/layout.tsx b/packages/desktop/src/pages/layout.tsx new file mode 100644 index 000000000..d2e33a2ca --- /dev/null +++ b/packages/desktop/src/pages/layout.tsx @@ -0,0 +1,5 @@ +import { type ParentProps } from "solid-js" + +export default function Layout(props: ParentProps) { + return
{props.children}
+} -- cgit v1.2.3