summaryrefslogtreecommitdiffhomepage
path: root/packages/app
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app')
-rw-r--r--packages/app/src/pages/session.tsx104
-rw-r--r--packages/app/src/pages/session/composer/session-composer-region.tsx9
-rw-r--r--packages/app/src/pages/session/composer/session-revert-dock.tsx13
3 files changed, 98 insertions, 28 deletions
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx
index 7642ac165..b8d32fed4 100644
--- a/packages/app/src/pages/session.tsx
+++ b/packages/app/src/pages/session.tsx
@@ -1,6 +1,7 @@
import type { Project, UserMessage } from "@opencode-ai/sdk/v2"
import { useDialog } from "@opencode-ai/ui/context/dialog"
import {
+ batch,
onCleanup,
Show,
Match,
@@ -291,6 +292,7 @@ export default function Page() {
git: false,
pendingMessage: undefined as string | undefined,
restoring: undefined as string | undefined,
+ reverting: false,
reviewSnap: false,
scrollGesture: 0,
scroll: {
@@ -1243,6 +1245,24 @@ export default function Page() {
})
}
+ const merge = (next: NonNullable<ReturnType<typeof info>>) =>
+ sync.set("session", (list) => {
+ const idx = list.findIndex((item) => item.id === next.id)
+ if (idx < 0) return list
+ const out = list.slice()
+ out[idx] = next
+ return out
+ })
+
+ const roll = (sessionID: string, next: NonNullable<ReturnType<typeof info>>["revert"]) =>
+ sync.set("session", (list) => {
+ const idx = list.findIndex((item) => item.id === sessionID)
+ if (idx < 0) return list
+ const out = list.slice()
+ out[idx] = { ...out[idx], revert: next }
+ return out
+ })
+
const busy = (sessionID: string) => {
if (sync.data.session_status[sessionID]?.type !== "idle") return true
return (sync.data.message[sessionID] ?? []).some(
@@ -1275,42 +1295,77 @@ export default function Page() {
}
const revert = (input: { sessionID: string; messageID: string }) => {
+ if (ui.reverting || ui.restoring) return
+ const prev = prompt.current().slice()
+ const last = info()?.revert
const value = draft(input.messageID)
+ batch(() => {
+ setUi("reverting", true)
+ roll(input.sessionID, { messageID: input.messageID })
+ prompt.set(value)
+ })
return halt(input.sessionID)
.then(() => sdk.client.session.revert(input))
- .then(() => {
- prompt.set(value)
+ .then((result) => {
+ if (result.data) merge(result.data)
+ })
+ .catch((err) => {
+ batch(() => {
+ roll(input.sessionID, last)
+ prompt.set(prev)
+ })
+ fail(err)
+ })
+ .finally(() => {
+ setUi("reverting", false)
})
- .catch(fail)
}
const restore = (id: string) => {
const sessionID = params.id
- if (!sessionID || ui.restoring) return
+ if (!sessionID || ui.restoring || ui.reverting) return
const next = userMessages().find((item) => item.id > id)
- setUi("restoring", id)
+ const prev = prompt.current().slice()
+ const last = info()?.revert
+
+ batch(() => {
+ setUi("restoring", id)
+ setUi("reverting", true)
+ roll(sessionID, next ? { messageID: next.id } : undefined)
+ if (next) {
+ prompt.set(draft(next.id))
+ return
+ }
+ prompt.reset()
+ })
const task = !next
- ? halt(sessionID)
- .then(() => sdk.client.session.unrevert({ sessionID }))
- .then(() => {
- prompt.reset()
- })
- : halt(sessionID)
- .then(() =>
- sdk.client.session.revert({
- sessionID,
- messageID: next.id,
- }),
- )
- .then(() => {
- prompt.set(draft(next.id))
- })
-
- return task.catch(fail).finally(() => {
- setUi("restoring", (value) => (value === id ? undefined : value))
- })
+ ? halt(sessionID).then(() => sdk.client.session.unrevert({ sessionID }))
+ : halt(sessionID).then(() =>
+ sdk.client.session.revert({
+ sessionID,
+ messageID: next.id,
+ }),
+ )
+
+ return task
+ .then((result) => {
+ if (result.data) merge(result.data)
+ })
+ .catch((err) => {
+ batch(() => {
+ roll(sessionID, last)
+ prompt.set(prev)
+ })
+ fail(err)
+ })
+ .finally(() => {
+ batch(() => {
+ setUi("restoring", (value) => (value === id ? undefined : value))
+ setUi("reverting", false)
+ })
+ })
}
const rolled = createMemo(() => {
@@ -1487,6 +1542,7 @@ export default function Page() {
? {
items: rolled(),
restoring: ui.restoring,
+ disabled: ui.reverting,
onRestore: restore,
}
: undefined
diff --git a/packages/app/src/pages/session/composer/session-composer-region.tsx b/packages/app/src/pages/session/composer/session-composer-region.tsx
index 6d60d81b5..0cca90180 100644
--- a/packages/app/src/pages/session/composer/session-composer-region.tsx
+++ b/packages/app/src/pages/session/composer/session-composer-region.tsx
@@ -24,6 +24,7 @@ export function SessionComposerRegion(props: {
revert?: {
items: { id: string; text: string }[]
restoring?: string
+ disabled?: boolean
onRestore: (id: string) => void
}
setPromptDockRef: (el: HTMLDivElement) => void
@@ -156,6 +157,7 @@ export function SessionComposerRegion(props: {
<SessionRevertDock
items={revert.items}
restoring={revert.restoring}
+ disabled={revert.disabled}
onRestore={revert.onRestore}
/>
</div>
@@ -195,7 +197,12 @@ export function SessionComposerRegion(props: {
"margin-top": `${-36 * value()}px`,
}}
>
- <SessionRevertDock items={revert.items} restoring={revert.restoring} onRestore={revert.onRestore} />
+ <SessionRevertDock
+ items={revert.items}
+ restoring={revert.restoring}
+ disabled={revert.disabled}
+ onRestore={revert.onRestore}
+ />
</div>
)}
</Show>
diff --git a/packages/app/src/pages/session/composer/session-revert-dock.tsx b/packages/app/src/pages/session/composer/session-revert-dock.tsx
index ce7644b67..fd4b39ee7 100644
--- a/packages/app/src/pages/session/composer/session-revert-dock.tsx
+++ b/packages/app/src/pages/session/composer/session-revert-dock.tsx
@@ -1,4 +1,4 @@
-import { For, Show, createMemo } from "solid-js"
+import { For, Show, createEffect, createMemo } from "solid-js"
import { createStore } from "solid-js/store"
import { Button } from "@opencode-ai/ui/button"
import { DockTray } from "@opencode-ai/ui/dock-surface"
@@ -8,11 +8,18 @@ import { useLanguage } from "@/context/language"
export function SessionRevertDock(props: {
items: { id: string; text: string }[]
restoring?: string
+ disabled?: boolean
onRestore: (id: string) => void
}) {
const language = useLanguage()
const [store, setStore] = createStore({
- collapsed: false,
+ collapsed: true,
+ })
+
+ createEffect(() => {
+ props.items.length
+ props.items[0]?.id
+ setStore("collapsed", true)
})
const toggle = () => setStore("collapsed", (value) => !value)
@@ -77,7 +84,7 @@ export function SessionRevertDock(props: {
size="small"
variant="secondary"
class="shrink-0"
- disabled={!!props.restoring}
+ disabled={props.disabled || !!props.restoring}
onClick={() => props.onRestore(item.id)}
>
{language.t("session.revertDock.restore")}