diff options
| author | Adam <[email protected]> | 2025-12-29 08:47:27 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2025-12-29 08:47:38 -0600 |
| commit | c4930eb6b219a2011cddc70a9b76f41809418114 (patch) | |
| tree | ce90fdd5b21622fcb8b1a3b851e0842d771ac112 /packages/app/src | |
| parent | a24549fce77b12f025f0583063df2c7f23ad3ffc (diff) | |
| download | opencode-c4930eb6b219a2011cddc70a9b76f41809418114.tar.gz opencode-c4930eb6b219a2011cddc70a9b76f41809418114.zip | |
fix(desktop): more fine-grained state updates for permissions
Diffstat (limited to 'packages/app/src')
| -rw-r--r-- | packages/app/src/context/global-sync.tsx | 65 |
1 files changed, 44 insertions, 21 deletions
diff --git a/packages/app/src/context/global-sync.tsx b/packages/app/src/context/global-sync.tsx index 0296dfad3..e1dcf15fc 100644 --- a/packages/app/src/context/global-sync.tsx +++ b/packages/app/src/context/global-sync.tsx @@ -23,7 +23,7 @@ import { Binary } from "@opencode-ai/util/binary" import { retry } from "@opencode-ai/util/retry" import { useGlobalSDK } from "./global-sdk" import { ErrorPage, type InitError } from "../pages/error" -import { createContext, useContext, onMount, type ParentProps, Switch, Match } from "solid-js" +import { batch, createContext, useContext, onMount, type ParentProps, Switch, Match } from "solid-js" import { showToast } from "@opencode-ai/ui/toast" import { getFilename } from "@opencode-ai/util/path" @@ -135,7 +135,7 @@ function createGlobalSync() { async function bootstrapInstance(directory: string) { if (!directory) return - const [, setStore] = child(directory) + const [store, setStore] = child(directory) const sdk = createOpencodeClient({ baseUrl: globalSDK.url, directory, @@ -167,12 +167,32 @@ function createGlobalSync() { vcs: () => sdk.vcs.get().then((x) => setStore("vcs", x.data)), permission: () => sdk.permission.list().then((x) => { - const grouped: Record<string, typeof x.data> = {} + const grouped: Record<string, Permission[]> = {} for (const perm of x.data ?? []) { - grouped[perm.sessionID] = grouped[perm.sessionID] ?? [] - grouped[perm.sessionID]!.push(perm) + const existing = grouped[perm.sessionID] + if (existing) { + existing.push(perm) + continue + } + grouped[perm.sessionID] = [perm] } - setStore("permission", grouped) + + batch(() => { + for (const sessionID of Object.keys(store.permission)) { + if (grouped[sessionID]) continue + setStore("permission", sessionID, []) + } + for (const [sessionID, permissions] of Object.entries(grouped)) { + setStore( + "permission", + sessionID, + reconcile( + permissions.slice().sort((a, b) => a.id.localeCompare(b.id)), + { key: "id" }, + ), + ) + } + }) }), } await Promise.all(Object.values(load).map((p) => retry(p).catch((e) => setGlobalStore("error", e)))) @@ -325,23 +345,26 @@ function createGlobalSync() { break } case "permission.updated": { - const permissions = store.permission[event.properties.sessionID] + const sessionID = event.properties.sessionID + const permissions = store.permission[sessionID] if (!permissions) { - setStore("permission", event.properties.sessionID, [event.properties]) - } else { - const result = Binary.search(permissions, event.properties.id, (p) => p.id) - setStore( - "permission", - event.properties.sessionID, - produce((draft) => { - if (result.found) { - draft[result.index] = event.properties - return - } - draft.push(event.properties) - }), - ) + setStore("permission", sessionID, [event.properties]) + break } + + const result = Binary.search(permissions, event.properties.id, (p) => p.id) + if (result.found) { + setStore("permission", sessionID, result.index, reconcile(event.properties)) + break + } + + setStore( + "permission", + sessionID, + produce((draft) => { + draft.splice(result.index, 0, event.properties) + }), + ) break } case "permission.replied": { |
