From 3eb2db98ed0a9c266e1bf00544e460cb0633b368 Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Thu, 23 Oct 2025 15:27:31 -0500 Subject: wip: desktop work --- packages/desktop/src/components/code.tsx | 4 +- packages/desktop/src/components/editor-pane.tsx | 252 --------------------- packages/desktop/src/components/file-tree.tsx | 3 +- packages/desktop/src/components/markdown.tsx | 2 +- packages/desktop/src/components/prompt-input.tsx | 9 +- .../desktop/src/components/session-timeline.tsx | 7 +- 6 files changed, 12 insertions(+), 265 deletions(-) delete mode 100644 packages/desktop/src/components/editor-pane.tsx (limited to 'packages/desktop/src/components') diff --git a/packages/desktop/src/components/code.tsx b/packages/desktop/src/components/code.tsx index b4dd216e9..11518e73a 100644 --- a/packages/desktop/src/components/code.tsx +++ b/packages/desktop/src/components/code.tsx @@ -1,8 +1,8 @@ import { bundledLanguages, type BundledLanguage, type ShikiTransformer } from "shiki" import { splitProps, type ComponentProps, createEffect, onMount, onCleanup, createMemo, createResource } from "solid-js" -import { useLocal, useShiki } from "@/context" -import type { TextSelection } from "@/context/local" +import { useLocal, type TextSelection } from "@/context/local" import { getFileExtension, getNodeOffsetInLine, getSelectionInContainer } from "@/utils" +import { useShiki } from "@/context/shiki" type DefinedSelection = Exclude diff --git a/packages/desktop/src/components/editor-pane.tsx b/packages/desktop/src/components/editor-pane.tsx deleted file mode 100644 index a97a0ef7f..000000000 --- a/packages/desktop/src/components/editor-pane.tsx +++ /dev/null @@ -1,252 +0,0 @@ -import { For, Match, Show, Switch, createSignal, splitProps } from "solid-js" -import { IconButton, Tabs, Tooltip } from "@opencode-ai/ui" -import { FileIcon } from "@/ui" -import { - DragDropProvider, - DragDropSensors, - DragOverlay, - SortableProvider, - closestCenter, - createSortable, - useDragDropContext, -} from "@thisbeyond/solid-dnd" -import type { DragEvent, Transformer } from "@thisbeyond/solid-dnd" -import type { LocalFile } from "@/context/local" -import { Code } from "@/components/code" -import { useLocal } from "@/context" -import type { JSX } from "solid-js" - -interface EditorPaneProps { - onFileClick: (file: LocalFile) => void -} - -export default function EditorPane(props: EditorPaneProps): JSX.Element { - const [localProps] = splitProps(props, ["onFileClick"]) - const local = useLocal() - const [activeItem, setActiveItem] = createSignal(undefined) - - const navigateChange = (dir: 1 | -1) => { - const active = local.file.active() - if (!active) return - const current = local.file.changeIndex(active.path) - const next = current === undefined ? (dir === 1 ? 0 : -1) : current + dir - local.file.setChangeIndex(active.path, next) - } - - const handleTabChange = (path: string) => { - local.file.open(path) - } - - const handleTabClose = (file: LocalFile) => { - local.file.close(file.path) - } - - const handleDragStart = (event: unknown) => { - const id = getDraggableId(event) - if (!id) return - setActiveItem(id) - } - - const handleDragOver = (event: DragEvent) => { - const { draggable, droppable } = event - if (draggable && droppable) { - const currentFiles = local.file.opened().map((file) => file.path) - const fromIndex = currentFiles.indexOf(draggable.id.toString()) - const toIndex = currentFiles.indexOf(droppable.id.toString()) - if (fromIndex !== toIndex) { - local.file.move(draggable.id.toString(), toIndex) - } - } - } - - const handleDragEnd = () => { - setActiveItem(undefined) - } - - return ( - - - - -
- - file.path)}> - - {(file) => } - - - - -
- - {(file) => ( - - {(() => { - const view = local.file.view(file.path) - const showRaw = view === "raw" || !file.content?.diff - const code = showRaw ? (file.content?.content ?? "") : (file.content?.diff ?? "") - return - })()} - - )} - -
- - {(() => { - const id = activeItem() - if (!id) return null - const draggedFile = local.file.node(id) - if (!draggedFile) return null - return ( -
- -
- ) - })()} -
-
- ) -} - -function TabVisual(props: { file: LocalFile }): JSX.Element { - return ( -
- - - {props.file.name} - - - - - M - - - A - - - D - - - -
- ) -} - -function SortableTab(props: { - file: LocalFile - onTabClick: (file: LocalFile) => void - onTabClose: (file: LocalFile) => void -}): JSX.Element { - const sortable = createSortable(props.file.path) - - return ( - // @ts-ignore -
- -
- props.onTabClick(props.file)}> - - - props.onTabClose(props.file)} - /> -
-
-
- ) -} - -function ConstrainDragYAxis(): JSX.Element { - const context = useDragDropContext() - if (!context) return <> - const [, { onDragStart, onDragEnd, addTransformer, removeTransformer }] = context - const transformer: Transformer = { - id: "constrain-y-axis", - order: 100, - callback: (transform) => ({ ...transform, y: 0 }), - } - onDragStart((event) => { - const id = getDraggableId(event) - if (!id) return - addTransformer("draggables", id, transformer) - }) - onDragEnd((event) => { - const id = getDraggableId(event) - if (!id) return - removeTransformer("draggables", id, transformer.id) - }) - return <> -} - -const getDraggableId = (event: unknown): string | undefined => { - if (typeof event !== "object" || event === null) return undefined - if (!("draggable" in event)) return undefined - const draggable = (event as { draggable?: { id?: unknown } }).draggable - if (!draggable) return undefined - return typeof draggable.id === "string" ? draggable.id : undefined -} diff --git a/packages/desktop/src/components/file-tree.tsx b/packages/desktop/src/components/file-tree.tsx index 7e4b1abcc..d10328136 100644 --- a/packages/desktop/src/components/file-tree.tsx +++ b/packages/desktop/src/components/file-tree.tsx @@ -1,5 +1,4 @@ -import { useLocal } from "@/context" -import type { LocalFile } from "@/context/local" +import { useLocal, type LocalFile } from "@/context/local" import { Tooltip } from "@opencode-ai/ui" import { Collapsible, FileIcon } from "@/ui" import { For, Match, Switch, Show, type ComponentProps, type ParentProps } from "solid-js" diff --git a/packages/desktop/src/components/markdown.tsx b/packages/desktop/src/components/markdown.tsx index 30e3831e3..e0f185f5f 100644 --- a/packages/desktop/src/components/markdown.tsx +++ b/packages/desktop/src/components/markdown.tsx @@ -1,4 +1,4 @@ -import { useMarked } from "@/context" +import { useMarked } from "@/context/marked" import { createResource } from "solid-js" function strip(text: string): string { diff --git a/packages/desktop/src/components/prompt-input.tsx b/packages/desktop/src/components/prompt-input.tsx index 55a410516..47893f44c 100644 --- a/packages/desktop/src/components/prompt-input.tsx +++ b/packages/desktop/src/components/prompt-input.tsx @@ -1,12 +1,11 @@ -import { useLocal } from "@/context" -import { Button, Icon, IconButton, Select, SelectDialog, Tooltip } from "@opencode-ai/ui" +import { Button, Icon, IconButton, Select, SelectDialog } from "@opencode-ai/ui" import { useFilteredList } from "@opencode-ai/ui/hooks" -import { createEffect, on, Component, createMemo, Show, Switch, Match, For } from "solid-js" +import { createEffect, on, Component, createMemo, Show, For } from "solid-js" import { createStore } from "solid-js/store" import { FileIcon } from "@/ui" import { getDirectory, getFilename } from "@/utils" import { createFocusSignal } from "@solid-primitives/active-element" -import { TextSelection } from "@/context/local" +import { TextSelection, useLocal } from "@/context/local" import { DateTime } from "luxon" interface PartBase { @@ -245,7 +244,7 @@ export const PromptInput: Component = (props) => { } return ( -
+
diff --git a/packages/desktop/src/components/session-timeline.tsx b/packages/desktop/src/components/session-timeline.tsx index 0d8a7cd3c..b751f2940 100644 --- a/packages/desktop/src/components/session-timeline.tsx +++ b/packages/desktop/src/components/session-timeline.tsx @@ -1,4 +1,3 @@ -import { useLocal, useSync } from "@/context" import { Icon, Tooltip } from "@opencode-ai/ui" import { Collapsible } from "@/ui" import type { AssistantMessage, Message, Part, ToolPart } from "@opencode-ai/sdk" @@ -22,6 +21,8 @@ import { createElementSize } from "@solid-primitives/resize-observer" import { createScrollPosition } from "@solid-primitives/scroll" import { ProgressCircle } from "./progress-circle" import { pipe, sumBy } from "remeda" +import { useSync } from "@/context/sync" +import { useLocal } from "@/context/local" function Part(props: ParentProps & ComponentProps<"div">) { const [local, others] = splitProps(props, ["class", "classList", "children"]) @@ -394,7 +395,7 @@ export default function SessionTimeline(props: { session: string; class?: string [props.class ?? ""]: !!props.class, }} > -
+
@@ -405,7 +406,7 @@ export default function SessionTimeline(props: { session: string; class?: string
{cost()}
-
    +
      {(message) => (