mirror of
https://github.com/stablyai/orca.git
synced 2026-11-02 10:08:13 +00:00
56 lines
2.3 KiB
TypeScript
56 lines
2.3 KiB
TypeScript
import { useEffect, useRef } from 'react'
|
|
import { useWorkspaceExecutionHost } from '../navigation/workspace-execution-host'
|
|
|
|
export type SessionDiffOpenHandlers = {
|
|
onFileOpenStart: () => void
|
|
onOpenedFileDiff: (relativePath: string) => void
|
|
}
|
|
|
|
// The session keeps its own tab pick over host snapshots, so a Source Control screen pushed over it must hand opened diffs to it like the dock does.
|
|
// A stack per key: the same worktree's session can be pushed twice (e.g. resume from Agent History); the top one owns Changes.
|
|
const handlersBySession = new Map<string, SessionDiffOpenHandlers[]>()
|
|
|
|
function sessionKey(hostId: string, executionHost: string | undefined, worktreeId: string): string {
|
|
return JSON.stringify([hostId, executionHost ?? null, worktreeId])
|
|
}
|
|
|
|
export function useProvideSessionDiffOpenHandlers(
|
|
hostId: string,
|
|
worktreeId: string,
|
|
onFileOpenStart: () => void,
|
|
onOpenedFileDiff: (relativePath: string) => void
|
|
): void {
|
|
const executionHost = useWorkspaceExecutionHost()
|
|
const latestRef = useRef({ onFileOpenStart, onOpenedFileDiff })
|
|
useEffect(() => {
|
|
latestRef.current = { onFileOpenStart, onOpenedFileDiff }
|
|
}, [onFileOpenStart, onOpenedFileDiff])
|
|
// Register once per mount so a lower session's new callbacks cannot jump it above the visible one.
|
|
useEffect(() => {
|
|
const key = sessionKey(hostId, executionHost, worktreeId)
|
|
const handlers: SessionDiffOpenHandlers = {
|
|
onFileOpenStart: () => latestRef.current.onFileOpenStart(),
|
|
onOpenedFileDiff: (relativePath) => latestRef.current.onOpenedFileDiff(relativePath)
|
|
}
|
|
handlersBySession.set(key, [...(handlersBySession.get(key) ?? []), handlers])
|
|
return () => {
|
|
const remaining = (handlersBySession.get(key) ?? []).filter((entry) => entry !== handlers)
|
|
if (remaining.length > 0) {
|
|
handlersBySession.set(key, remaining)
|
|
} else {
|
|
handlersBySession.delete(key)
|
|
}
|
|
}
|
|
}, [executionHost, hostId, worktreeId])
|
|
}
|
|
|
|
export function useSessionDiffOpenHandlers(
|
|
hostId: string | undefined,
|
|
worktreeId: string | undefined
|
|
): SessionDiffOpenHandlers | undefined {
|
|
const executionHost = useWorkspaceExecutionHost()
|
|
return hostId && worktreeId
|
|
? handlersBySession.get(sessionKey(hostId, executionHost, worktreeId))?.at(-1)
|
|
: undefined
|
|
}
|