mirror of
https://github.com/stablyai/orca.git
synced 2026-10-13 00:02:54 +00:00
fix mobile terminal replay row mismatch
Co-authored-by: Orca <help@stably.ai>
This commit is contained in:
@@ -69,11 +69,13 @@ const STATUS_LABELS: Record<ConnectionState, string> = {
|
||||
function TerminalPaneView({
|
||||
handle,
|
||||
active,
|
||||
onRef
|
||||
onRef,
|
||||
onWebReady
|
||||
}: {
|
||||
handle: string
|
||||
active: boolean
|
||||
onRef: (handle: string, ref: TerminalWebViewHandle | null) => void
|
||||
onWebReady: (handle: string) => void
|
||||
}) {
|
||||
const setRef = useCallback(
|
||||
(ref: TerminalWebViewHandle | null) => {
|
||||
@@ -87,7 +89,11 @@ function TerminalPaneView({
|
||||
pointerEvents={active ? 'auto' : 'none'}
|
||||
style={[styles.terminalPane, !active && styles.terminalPaneHidden]}
|
||||
>
|
||||
<TerminalWebView ref={setRef} style={styles.terminalWebView} />
|
||||
<TerminalWebView
|
||||
ref={setRef}
|
||||
style={styles.terminalWebView}
|
||||
onWebReady={() => onWebReady(handle)}
|
||||
/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
@@ -541,6 +547,21 @@ export default function SessionScreen() {
|
||||
[subscribeToTerminal]
|
||||
)
|
||||
|
||||
const handleTerminalWebReady = useCallback(
|
||||
(handle: string) => {
|
||||
if (!initializedHandlesRef.current.has(handle)) {
|
||||
return
|
||||
}
|
||||
// Why: the native WebView can reload independently of the session
|
||||
// screen during Metro reloads or Android process churn. The old xterm
|
||||
// buffer is gone, so force a fresh scrollback snapshot for this handle.
|
||||
unsubscribeTerminal(handle)
|
||||
initializedHandlesRef.current.delete(handle)
|
||||
subscribeToTerminal(handle)
|
||||
},
|
||||
[subscribeToTerminal, unsubscribeTerminal]
|
||||
)
|
||||
|
||||
async function handleSend() {
|
||||
if (!client || !activeHandle || !input.trim()) return
|
||||
|
||||
@@ -771,6 +792,7 @@ export default function SessionScreen() {
|
||||
handle={terminal.handle}
|
||||
active={terminal.handle === activeHandle}
|
||||
onRef={setTerminalWebViewRef}
|
||||
onWebReady={handleTerminalWebReady}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
@@ -14,6 +14,7 @@ export type TerminalWebViewHandle = {
|
||||
|
||||
type Props = {
|
||||
style?: StyleProp<ViewStyle>
|
||||
onWebReady?: () => void
|
||||
}
|
||||
|
||||
type TerminalMessage =
|
||||
@@ -138,6 +139,11 @@ const XTERM_HTML = `<!DOCTYPE html>
|
||||
// managed by xterm, not a separate HTML gap. Never shrink below the
|
||||
// original init row count to avoid clipping active terminal content.
|
||||
function adjustRowsForViewport() {
|
||||
// Why: mobile replays a live PTY snapshot and then applies live cursor-
|
||||
// relative chunks from that same PTY. Resizing only the WebView xterm
|
||||
// changes cursor coordinates and makes TUI repaint chunks duplicate or
|
||||
// overlap existing frames. Keep xterm rows identical to the PTY.
|
||||
return;
|
||||
if (!term || !term.element) return;
|
||||
// Why: active alternate-screen TUIs (Claude Code, vim, etc.) are exact
|
||||
// screen snapshots. Locally resizing the mobile xterm after replay can
|
||||
@@ -495,7 +501,7 @@ const XTERM_HTML = `<!DOCTYPE html>
|
||||
</html>`
|
||||
|
||||
export const TerminalWebView = forwardRef<TerminalWebViewHandle, Props>(function TerminalWebView(
|
||||
{ style },
|
||||
{ style, onWebReady },
|
||||
ref
|
||||
) {
|
||||
const webViewRef = useRef<WebView>(null)
|
||||
@@ -541,6 +547,7 @@ export const TerminalWebView = forwardRef<TerminalWebViewHandle, Props>(function
|
||||
|
||||
if (msg.type === 'web-ready') {
|
||||
isWebReadyRef.current = true
|
||||
onWebReady?.()
|
||||
flushPendingMessages()
|
||||
} else if (msg.type === 'measure-result') {
|
||||
const resolve = measureResolveRef.current
|
||||
@@ -552,7 +559,7 @@ export const TerminalWebView = forwardRef<TerminalWebViewHandle, Props>(function
|
||||
}
|
||||
}
|
||||
},
|
||||
[flushPendingMessages]
|
||||
[flushPendingMessages, onWebReady]
|
||||
)
|
||||
|
||||
const handleLoadStart = useCallback(() => {
|
||||
|
||||
Reference in New Issue
Block a user