mirror of
https://github.com/stablyai/orca.git
synced 2026-10-28 00:02:54 +00:00
fix(mobile): recheck queued tap delivery context
This commit is contained in:
@@ -2999,12 +2999,16 @@ export default function SessionScreen() {
|
||||
|
||||
async function handleAccessoryKey(
|
||||
input: ReturnType<typeof createTerminalLiveAccessoryInput>,
|
||||
targetHandle = activeHandleRef.current
|
||||
targetHandle = activeHandleRef.current,
|
||||
isDeliveryTargetCurrent: () => boolean = () => targetHandle === activeHandleRef.current
|
||||
) {
|
||||
if (!client || !targetHandle || targetHandle !== activeHandleRef.current || !canSend) {
|
||||
if (!client || !targetHandle || !isDeliveryTargetCurrent() || !canSend) {
|
||||
return false
|
||||
}
|
||||
const accessoryCommit = await handleLiveInputAccessoryBytes(input)
|
||||
if (!isDeliveryTargetCurrent()) {
|
||||
return false
|
||||
}
|
||||
if (accessoryCommit.kind !== 'allow-raw') {
|
||||
return accessoryCommit.kind === 'handled'
|
||||
}
|
||||
@@ -3419,17 +3423,19 @@ export default function SessionScreen() {
|
||||
// Why: the controller queue sits outside RPC, so fence pre-outage taps from a later connection.
|
||||
const targetClient = clientRef.current
|
||||
const targetConnectedAt = targetClient?.getLastConnectedAt() ?? null
|
||||
const isDeliveryTargetCurrent = (targetHandle: string) =>
|
||||
activeHandleRef.current === targetHandle &&
|
||||
targetClient !== null &&
|
||||
clientRef.current === targetClient &&
|
||||
connStateRef.current === 'connected' &&
|
||||
targetClient.getLastConnectedAt() === targetConnectedAt
|
||||
accessoryRepeatRef.current.start(
|
||||
input,
|
||||
createTerminalAccessoryRepeatSender(
|
||||
activeHandleRef.current,
|
||||
(targetHandle) =>
|
||||
activeHandleRef.current === targetHandle &&
|
||||
targetClient !== null &&
|
||||
clientRef.current === targetClient &&
|
||||
connStateRef.current === 'connected' &&
|
||||
targetClient.getLastConnectedAt() === targetConnectedAt,
|
||||
(nextInput, targetHandle) => handleAccessoryKeyRef.current(nextInput, targetHandle)
|
||||
isDeliveryTargetCurrent,
|
||||
(nextInput, targetHandle, isTargetCurrent) =>
|
||||
handleAccessoryKeyRef.current(nextInput, targetHandle, isTargetCurrent)
|
||||
)
|
||||
)
|
||||
},
|
||||
|
||||
@@ -164,7 +164,26 @@ describe('terminal accessory repeat', () => {
|
||||
await expect(send('down')).resolves.toBe(false)
|
||||
|
||||
expect(sendToTerminal).toHaveBeenCalledTimes(1)
|
||||
expect(sendToTerminal).toHaveBeenCalledWith('down', 'terminal-a')
|
||||
expect(sendToTerminal).toHaveBeenCalledWith('down', 'terminal-a', expect.any(Function))
|
||||
})
|
||||
|
||||
it('provides a live target guard for async send preflight', async () => {
|
||||
let targetCurrent = true
|
||||
const preflight = deferred()
|
||||
const send = createTerminalAccessoryRepeatSender(
|
||||
'terminal-a',
|
||||
() => targetCurrent,
|
||||
async (_input, _targetHandle, isDeliveryTargetCurrent) => {
|
||||
await preflight.promise
|
||||
return isDeliveryTargetCurrent()
|
||||
}
|
||||
)
|
||||
|
||||
const result = send('down')
|
||||
targetCurrent = false
|
||||
preflight.resolve()
|
||||
|
||||
await expect(result).resolves.toBe(false)
|
||||
})
|
||||
|
||||
it('drops a queued send when its press-time connection is no longer current', async () => {
|
||||
|
||||
@@ -2,17 +2,22 @@ export const TERMINAL_ACCESSORY_REPEAT_DELAY_MS = 400
|
||||
export const TERMINAL_ACCESSORY_REPEAT_INTERVAL_MS = 45
|
||||
|
||||
type TerminalAccessoryRepeatSender<TInput> = (input: TInput) => Promise<boolean>
|
||||
type TerminalAccessoryRepeatSendToTerminal<TInput> = (
|
||||
input: TInput,
|
||||
targetHandle: string,
|
||||
isDeliveryTargetCurrent: () => boolean
|
||||
) => Promise<boolean>
|
||||
|
||||
export function createTerminalAccessoryRepeatSender<TInput>(
|
||||
targetHandle: string | null,
|
||||
isDeliveryTargetCurrent: (targetHandle: string) => boolean,
|
||||
sendToTerminal: (input: TInput, targetHandle: string) => Promise<boolean>
|
||||
sendToTerminal: TerminalAccessoryRepeatSendToTerminal<TInput>
|
||||
): TerminalAccessoryRepeatSender<TInput> {
|
||||
return (input) => {
|
||||
if (!targetHandle || !isDeliveryTargetCurrent(targetHandle)) {
|
||||
return Promise.resolve(false)
|
||||
}
|
||||
return sendToTerminal(input, targetHandle)
|
||||
return sendToTerminal(input, targetHandle, () => isDeliveryTargetCurrent(targetHandle))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user