mirror of
https://github.com/aljazceru/opencode.git
synced 2026-01-03 16:05:00 +01:00
feat(desktop): review flow
This commit is contained in:
@@ -464,9 +464,12 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
|
||||
opened: true,
|
||||
width: 240,
|
||||
},
|
||||
review: {
|
||||
state: "closed" as "open" | "closed" | "tab",
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "layout",
|
||||
name: "default-layout",
|
||||
},
|
||||
)
|
||||
|
||||
@@ -487,6 +490,18 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({
|
||||
setStore("sidebar", "width", width)
|
||||
},
|
||||
},
|
||||
review: {
|
||||
state: createMemo(() => store.review?.state ?? "closed"),
|
||||
open() {
|
||||
setStore("review", "state", "open")
|
||||
},
|
||||
close() {
|
||||
setStore("review", "state", "closed")
|
||||
},
|
||||
tab() {
|
||||
setStore("review", "state", "tab")
|
||||
},
|
||||
},
|
||||
}
|
||||
})()
|
||||
|
||||
|
||||
@@ -80,6 +80,7 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
|
||||
const model = createMemo(() =>
|
||||
last() ? sync.data.provider.find((x) => x.id === last().providerID)?.models[last().modelID] : undefined,
|
||||
)
|
||||
const diffs = createMemo(() => (props.sessionId ? (sync.data.session_diff[props.sessionId] ?? []) : []))
|
||||
|
||||
const tokens = createMemo(() => {
|
||||
if (!last()) return
|
||||
@@ -98,6 +99,7 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
|
||||
id: props.sessionId,
|
||||
info,
|
||||
working,
|
||||
diffs,
|
||||
prompt: {
|
||||
current: createMemo(() => store.prompt),
|
||||
cursor: createMemo(() => store.cursorPosition),
|
||||
@@ -139,8 +141,10 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
|
||||
if (tab.startsWith("file://")) {
|
||||
await local.file.open(tab.replace("file://", ""))
|
||||
}
|
||||
if (!store.tabs.opened.includes(tab)) {
|
||||
setStore("tabs", "opened", [...store.tabs.opened, tab])
|
||||
if (tab !== "review") {
|
||||
if (!store.tabs.opened.includes(tab)) {
|
||||
setStore("tabs", "opened", [...store.tabs.opened, tab])
|
||||
}
|
||||
}
|
||||
setStore("tabs", "active", tab)
|
||||
},
|
||||
|
||||
@@ -1,4 +1,17 @@
|
||||
import type { Message, Agent, Provider, Session, Part, Config, Path, File, FileNode, Project } from "@opencode-ai/sdk"
|
||||
import type {
|
||||
Message,
|
||||
Agent,
|
||||
Provider,
|
||||
Session,
|
||||
Part,
|
||||
Config,
|
||||
Path,
|
||||
File,
|
||||
FileNode,
|
||||
Project,
|
||||
FileDiff,
|
||||
Todo,
|
||||
} from "@opencode-ai/sdk"
|
||||
import { createStore, produce, reconcile } from "solid-js/store"
|
||||
import { createMemo } from "solid-js"
|
||||
import { Binary } from "@/utils/binary"
|
||||
@@ -16,8 +29,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
config: Config
|
||||
path: Path
|
||||
session: Session[]
|
||||
session_diff: {
|
||||
[sessionID: string]: FileDiff[]
|
||||
}
|
||||
todo: {
|
||||
[sessionID: string]: Todo[]
|
||||
}
|
||||
limit: number
|
||||
more: boolean
|
||||
message: {
|
||||
[sessionID: string]: Message[]
|
||||
}
|
||||
@@ -34,8 +52,9 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
agent: [],
|
||||
provider: [],
|
||||
session: [],
|
||||
session_diff: {},
|
||||
todo: {},
|
||||
limit: 10,
|
||||
more: false,
|
||||
message: {},
|
||||
part: {},
|
||||
node: [],
|
||||
@@ -60,6 +79,12 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
)
|
||||
break
|
||||
}
|
||||
case "session.diff":
|
||||
setStore("session_diff", event.properties.sessionID, event.properties.diff)
|
||||
break
|
||||
case "todo.updated":
|
||||
setStore("todo", event.properties.sessionID, event.properties.todos)
|
||||
break
|
||||
case "message.updated": {
|
||||
const messages = store.message[event.properties.info.sessionID]
|
||||
if (!messages) {
|
||||
@@ -116,7 +141,6 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
.sort((a, b) => a.id.localeCompare(b.id))
|
||||
.slice(0, store.limit)
|
||||
setStore("session", sessions)
|
||||
setStore("more", sessions.length === store.limit)
|
||||
}),
|
||||
config: () => sdk.client.config.get().then((x) => setStore("config", x.data!)),
|
||||
changes: () => sdk.client.file.status().then((x) => setStore("changes", x.data!)),
|
||||
@@ -161,22 +185,19 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
if (match.found) return store.session[match.index]
|
||||
return undefined
|
||||
},
|
||||
async sync(sessionID: string, isRetry = false) {
|
||||
const [session, messages] = await Promise.all([
|
||||
sdk.client.session.get({ path: { id: sessionID } }),
|
||||
async sync(sessionID: string, _isRetry = false) {
|
||||
const [session, messages, todo, diff] = await Promise.all([
|
||||
sdk.client.session.get({ path: { id: sessionID }, throwOnError: true }),
|
||||
sdk.client.session.messages({ path: { id: sessionID } }),
|
||||
sdk.client.session.todo({ path: { id: sessionID } }),
|
||||
sdk.client.session.diff({ path: { id: sessionID } }),
|
||||
])
|
||||
|
||||
// If no messages and this might be a new session, retry after a delay
|
||||
if (!isRetry && messages.data!.length === 0) {
|
||||
setTimeout(() => this.sync(sessionID, true), 500)
|
||||
return
|
||||
}
|
||||
|
||||
setStore(
|
||||
produce((draft) => {
|
||||
const match = Binary.search(draft.session, sessionID, (s) => s.id)
|
||||
draft.session[match.index] = session.data!
|
||||
if (match.found) draft.session[match.index] = session.data!
|
||||
if (!match.found) draft.session.splice(match.index, 0, session.data!)
|
||||
draft.todo[sessionID] = todo.data ?? []
|
||||
draft.message[sessionID] = messages
|
||||
.data!.map((x) => x.info)
|
||||
.slice()
|
||||
@@ -187,13 +208,21 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
.map(sanitizePart)
|
||||
.sort((a, b) => a.id.localeCompare(b.id))
|
||||
}
|
||||
draft.session_diff[sessionID] = diff.data ?? []
|
||||
}),
|
||||
)
|
||||
|
||||
// If no messages and this might be a new session, retry after a delay
|
||||
// if (!isRetry && messages.data!.length === 0) {
|
||||
// setTimeout(() => this.sync(sessionID, true), 500)
|
||||
// return
|
||||
// }
|
||||
},
|
||||
fetch: async (count = 10) => {
|
||||
setStore("limit", (x) => x + count)
|
||||
await load.session()
|
||||
},
|
||||
more: createMemo(() => store.session.length === store.limit),
|
||||
},
|
||||
load,
|
||||
absolute,
|
||||
|
||||
Reference in New Issue
Block a user