فهرست منبع

wip(desktop): progress

Adam 9 ماه پیش
والد
کامیت
20662e2101

+ 0 - 14
packages/desktop/src/PlatformContext.tsx

@@ -1,14 +0,0 @@
-import { createContext } from "solid-js"
-import { useContext } from "solid-js"
-
-export interface Platform {}
-
-const PlatformContext = createContext<Platform>()
-
-export const PlatformProvider = PlatformContext.Provider
-
-export function usePlatform() {
-  const ctx = useContext(PlatformContext)
-  if (!ctx) throw new Error("usePlatform must be used within a PlatformProvider")
-  return ctx
-}

+ 1 - 1
packages/desktop/src/DesktopInterface.tsx → packages/desktop/src/app.tsx

@@ -24,7 +24,7 @@ const url =
     ? `http://${host}:${port}`
     : "/")
 
-export function DesktopInterface() {
+export function App() {
   return (
     <MarkedProvider>
       <DiffComponentProvider component={Diff}>

+ 25 - 0
packages/desktop/src/context/platform.tsx

@@ -0,0 +1,25 @@
+import { createSimpleContext } from "@opencode-ai/ui/context"
+
+export type Platform = {
+  /** Platform discriminator */
+  platform: "web" | "tauri"
+
+  /** Open native directory picker dialog (Tauri only) */
+  openDirectoryPickerDialog?(opts?: { title?: string; multiple?: boolean }): Promise<string | string[] | null>
+
+  /** Open native file picker dialog (Tauri only) */
+  openFilePickerDialog?(opts?: { title?: string; multiple?: boolean }): Promise<string | string[] | null>
+
+  /** Save file picker dialog (Tauri only) */
+  saveFilePickerDialog?(opts?: { title?: string; defaultPath?: string }): Promise<string | null>
+
+  /** Open a URL in the default browser */
+  openLink(url: string): void
+}
+
+export const { use: usePlatform, provider: PlatformProvider } = createSimpleContext({
+  name: "Platform",
+  init: (props: { value: Platform }) => {
+    return props.value
+  },
+})

+ 9 - 4
packages/desktop/src/entry.tsx

@@ -1,7 +1,7 @@
 // @refresh reload
 import { render } from "solid-js/web"
-import { DesktopInterface } from "@/DesktopInterface"
-import { Platform, PlatformProvider } from "@/PlatformContext"
+import { App } from "@/app"
+import { Platform, PlatformProvider } from "@/context/platform"
 
 const root = document.getElementById("root")
 if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
@@ -10,12 +10,17 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
   )
 }
 
-const platform: Platform = {}
+const platform: Platform = {
+  platform: "web",
+  openLink(url: string) {
+    window.open(url, "_blank")
+  },
+}
 
 render(
   () => (
     <PlatformProvider value={platform}>
-      <DesktopInterface />
+      <App />
     </PlatformProvider>
   ),
   root!,

+ 2 - 2
packages/desktop/src/index.ts

@@ -1,2 +1,2 @@
-export { PlatformProvider, type Platform } from "./PlatformContext"
-export { DesktopInterface } from "./DesktopInterface"
+export { PlatformProvider, type Platform } from "./context/platform"
+export { App } from "./app"

+ 1 - 1
packages/desktop/src/pages/layout.tsx

@@ -196,7 +196,7 @@ export default function Layout(props: ParentProps) {
                   return (
                     <Switch>
                       <Match when={layout.sidebar.opened()}>
-                        <Collapsible variant="ghost" defaultOpen class="gap-2">
+                        <Collapsible variant="ghost" defaultOpen>
                           <Button
                             as={"div"}
                             variant="ghost"

+ 37 - 3
packages/tauri/src/index.tsx

@@ -1,8 +1,10 @@
 // @refresh reload
 import { render } from "solid-js/web"
-import { DesktopInterface, PlatformProvider, Platform } from "@opencode-ai/desktop"
+import { App, PlatformProvider, Platform } from "@opencode-ai/desktop"
 import { runUpdater } from "./updater"
 import { onMount } from "solid-js"
+import { open, save } from "@tauri-apps/plugin-dialog"
+import { open as shellOpen } from "@tauri-apps/plugin-shell"
 
 const root = document.getElementById("root")
 if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
@@ -11,7 +13,39 @@ if (import.meta.env.DEV && !(root instanceof HTMLElement)) {
   )
 }
 
-const platform: Platform = {}
+const platform: Platform = {
+  platform: "tauri",
+
+  async openDirectoryPickerDialog(opts) {
+    const result = await open({
+      directory: true,
+      multiple: opts?.multiple ?? false,
+      title: opts?.title ?? "Choose a folder",
+    })
+    return result
+  },
+
+  async openFilePickerDialog(opts) {
+    const result = await open({
+      directory: false,
+      multiple: opts?.multiple ?? false,
+      title: opts?.title ?? "Choose a file",
+    })
+    return result
+  },
+
+  async saveFilePickerDialog(opts) {
+    const result = await save({
+      title: opts?.title ?? "Save file",
+      defaultPath: opts?.defaultPath,
+    })
+    return result
+  },
+
+  openLink(url: string) {
+    shellOpen(url)
+  },
+}
 
 declare global {
   interface Window {
@@ -26,7 +60,7 @@ render(() => {
 
   return (
     <PlatformProvider value={platform}>
-      <DesktopInterface />
+      <App />
     </PlatformProvider>
   )
 }, root!)