Просмотр исходного кода

fix(app): fix flicker and navigation when collapsing/expanding projects (#6658)

Albin Groen 1 месяц назад
Родитель
Сommit
bbd1c071c4

+ 4 - 2
packages/app/src/components/session/session-header.tsx

@@ -1,4 +1,4 @@
-import { createEffect, createMemo, createResource, Show } from "solid-js"
+import { createMemo, createResource, Show } from "solid-js"
 import { A, useNavigate, useParams } from "@solidjs/router"
 import { useLayout } from "@/context/layout"
 import { useCommand } from "@/context/command"
@@ -20,6 +20,7 @@ import { DialogSelectServer } from "@/components/dialog-select-server"
 import { SessionLspIndicator } from "@/components/session-lsp-indicator"
 import { SessionMcpIndicator } from "@/components/session-mcp-indicator"
 import type { Session } from "@opencode-ai/sdk/v2/client"
+import { same } from "@/utils/same"
 
 export function SessionHeader() {
   const globalSDK = useGlobalSDK()
@@ -36,6 +37,7 @@ export function SessionHeader() {
   const sessions = createMemo(() => (sync.data.session ?? []).filter((s) => !s.parentID))
   const currentSession = createMemo(() => sessions().find((s) => s.id === params.id))
   const shareEnabled = createMemo(() => sync.data.config.share !== "disabled")
+  const worktrees = createMemo(() => layout.projects.list().map((p) => p.worktree), [], { equals: same })
 
   function navigateToProject(directory: string) {
     navigate(`/${base64Encode(directory)}`)
@@ -60,7 +62,7 @@ export function SessionHeader() {
           <div class="flex items-center gap-2 min-w-0">
             <div class="hidden xl:flex items-center gap-2">
               <Select
-                options={layout.projects.list().map((project) => project.worktree)}
+                options={worktrees()}
                 current={sync.project?.worktree ?? projectDirectory()}
                 label={(x) => getFilename(x)}
                 onSelect={(x) => (x ? navigateToProject(x) : undefined)}

+ 1 - 7
packages/app/src/context/layout.tsx

@@ -6,6 +6,7 @@ import { useGlobalSDK } from "./global-sdk"
 import { useServer } from "./server"
 import { Project } from "@opencode-ai/sdk/v2"
 import { persisted } from "@/utils/persist"
+import { same } from "@/utils/same"
 
 const AVATAR_COLOR_KEYS = ["pink", "mint", "orange", "purple", "cyan", "lime"] as const
 export type AvatarColorKey = (typeof AVATAR_COLOR_KEYS)[number]
@@ -23,13 +24,6 @@ export function getAvatarColors(key?: string) {
   }
 }
 
-function same<T>(a: readonly T[] | undefined, b: readonly T[] | undefined) {
-  if (a === b) return true
-  if (!a || !b) return false
-  if (a.length !== b.length) return false
-  return a.every((x, i) => x === b[i])
-}
-
 type SessionTabs = {
   active?: string
   all: string[]

+ 1 - 6
packages/app/src/pages/session.tsx

@@ -48,12 +48,7 @@ import {
   NewSessionView,
 } from "@/components/session"
 import { usePlatform } from "@/context/platform"
-
-function same<T>(a: readonly T[], b: readonly T[]) {
-  if (a === b) return true
-  if (a.length !== b.length) return false
-  return a.every((x, i) => x === b[i])
-}
+import { same } from "@/utils/same"
 
 type DiffStyle = "unified" | "split"
 

+ 6 - 0
packages/app/src/utils/same.ts

@@ -0,0 +1,6 @@
+export function same<T>(a: readonly T[] | undefined, b: readonly T[] | undefined) {
+  if (a === b) return true
+  if (!a || !b) return false
+  if (a.length !== b.length) return false
+  return a.every((x, i) => x === b[i])
+}