Adam 2 месяцев назад
Родитель
Сommit
f736751ab2

+ 25 - 6
packages/desktop/src/context/global-sync.tsx

@@ -22,7 +22,7 @@ type State = {
   ready: boolean
   provider: Provider[]
   agent: Agent[]
-  project: Project
+  project: string
   config: Config
   path: Path
   session: Session[]
@@ -60,11 +60,10 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple
     })
 
     const children: Record<string, ReturnType<typeof createStore<State>>> = {}
-
     function child(directory: string) {
       if (!children[directory]) {
         setGlobalStore("children", directory, {
-          project: { id: "", worktree: "", time: { created: 0, initialized: 0, updated: 0 } },
+          project: "",
           config: {},
           path: { state: "", config: "", worktree: "", directory: "" },
           ready: false,
@@ -88,9 +87,29 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple
     const sdk = useGlobalSDK()
     sdk.event.listen((e) => {
       const directory = e.name
-      const [store, setStore] = child(directory)
-
       const event = e.details
+
+      if (directory === "global") {
+        switch (event.type) {
+          case "project.updated": {
+            const result = Binary.search(globalStore.projects, event.properties.id, (s) => s.id)
+            if (result.found) {
+              setGlobalStore("projects", result.index, reconcile(event.properties))
+              break
+            }
+            setGlobalStore(
+              "projects",
+              produce((draft) => {
+                draft.splice(result.index, 0, event.properties)
+              }),
+            )
+            break
+          }
+        }
+        return
+      }
+
+      const [store, setStore] = child(directory)
       switch (event.type) {
         case "session.updated": {
           const result = Binary.search(store.session, event.properties.info.id, (s) => s.id)
@@ -166,7 +185,7 @@ export const { use: useGlobalSync, provider: GlobalSyncProvider } = createSimple
           "projects",
           x
             .data!.filter((x) => !x.worktree.includes("opencode-test") && x.vcs)
-            .sort((a, b) => b.time.created - a.time.created),
+            .sort((a, b) => a.id.localeCompare(b.id)),
         ),
       ),
     ]).then(() => setGlobalStore("ready", true))

+ 8 - 1
packages/desktop/src/context/sync.tsx

@@ -13,7 +13,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
     const [store, setStore] = globalSync.child(sdk.directory)
 
     const load = {
-      project: () => sdk.client.project.current().then((x) => setStore("project", x.data!)),
+      project: () => sdk.client.project.current().then((x) => setStore("project", x.data!.id)),
       provider: () => sdk.client.config.providers().then((x) => setStore("provider", x.data!.providers)),
       path: () => sdk.client.path.get().then((x) => setStore("path", x.data!)),
       agent: () => sdk.client.app.agents().then((x) => setStore("agent", x.data ?? [])),
@@ -41,6 +41,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
       get ready() {
         return store.ready
       },
+      get project() {
+        console.log("project", store.project)
+        console.log("projects", globalSync.data.projects)
+        const match = Binary.search(globalSync.data.projects, store.project, (p) => p.id)
+        if (match.found) return globalSync.data.projects[match.index]
+        return undefined
+      },
       session: {
         get(sessionID: string) {
           const match = Binary.search(store.session, sessionID, (s) => s.id)

+ 11 - 4
packages/desktop/src/pages/home.tsx

@@ -7,6 +7,7 @@ import { useNavigate } from "@solidjs/router"
 import { base64Encode } from "@opencode-ai/util/encode"
 import { Icon } from "@opencode-ai/ui/icon"
 import { usePlatform } from "@/context/platform"
+import { DateTime } from "luxon"
 
 export default function Home() {
   const sync = useGlobalSync()
@@ -47,8 +48,12 @@ export default function Home() {
                 </Button>
               </Show>
             </div>
-            <ol class="flex flex-col gap-2">
-              <For each={sync.data.projects.slice(0, 5)}>
+            <ul class="flex flex-col gap-2">
+              <For
+                each={sync.data.projects
+                  .sort((a, b) => (b.time.updated ?? b.time.created) - (a.time.updated ?? a.time.created))
+                  .slice(0, 5)}
+              >
                 {(project) => (
                   <Button
                     size="large"
@@ -57,11 +62,13 @@ export default function Home() {
                     onClick={() => openProject(project.worktree)}
                   >
                     {project.worktree}
-                    <div class="text-14-regular text-text-weak">10m ago</div>
+                    <div class="text-14-regular text-text-weak">
+                      {DateTime.fromMillis(project.time.updated ?? project.time.created).toRelative()}
+                    </div>
                   </Button>
                 )}
               </For>
-            </ol>
+            </ul>
           </div>
         </Match>
         <Match when={true}>

+ 13 - 9
packages/desktop/src/pages/session.tsx

@@ -401,15 +401,19 @@ export default function Page() {
                             <span class="text-text-strong">{getFilename(sync.data.path.directory)}</span>
                           </div>
                         </div>
-                        <div class="flex justify-center items-center gap-3">
-                          <Icon name="pencil-line" size="small" />
-                          <div class="text-12-medium text-text-weak">
-                            Last modified&nbsp;
-                            <span class="text-text-strong">
-                              {DateTime.fromMillis(sync.data.project.time.created).toRelative()}
-                            </span>
-                          </div>
-                        </div>
+                        <Show when={sync.project}>
+                          {(project) => (
+                            <div class="flex justify-center items-center gap-3">
+                              <Icon name="pencil-line" size="small" />
+                              <div class="text-12-medium text-text-weak">
+                                Last modified&nbsp;
+                                <span class="text-text-strong">
+                                  {DateTime.fromMillis(project().time.updated ?? project().time.created).toRelative()}
+                                </span>
+                              </div>
+                            </div>
+                          )}
+                        </Show>
                       </div>
                     </Match>
                   </Switch>