fix(mobile): preserve queued image preview on WAL adoption

This commit is contained in:
Brennan Benson
2026-08-16 22:14:59 -07:00
parent 0127d5c953
commit 793c323368
2 changed files with 49 additions and 9 deletions
@@ -91,6 +91,30 @@ describe('mobile structured session timeline', () => {
expect(rows[0]).toMatchObject({ key: wal.itemId, outbox: { state: 'unconfirmed' } })
})
it('keeps the device-local thumbnail on the adopted row while delivery is unconfirmed', () => {
const wal: AgentJournalRenderItem = {
itemId: agentJournalSubmissionKey(OUTBOX.clientMessageId),
revision: 1,
sequence: 1,
observedAt: 3,
body: OUTBOX.body
}
const rows = buildMobileStructuredTimeline([wal], [OUTBOX])
expect(rows).toHaveLength(1)
expect(rows[0]).toMatchObject({
key: wal.itemId,
outbox: { state: 'unconfirmed' },
message: {
blocks: [
{ type: 'text', text: 'look' },
{ type: 'image-ref', url: 'file:///preview.png' }
]
}
})
})
it('restores host paths and local previews when a queued send is edited', () => {
expect(restoreMobileStructuredAttachments(OUTBOX)).toEqual([
{
@@ -26,22 +26,29 @@ function isPendingPrompt(item: AgentJournalRenderItem): item is MobileStructured
}
function outboxMessage(entry: MobileStructuredOutboxEntry): NativeChatMessage {
let imageIndex = 0
return {
id: entry.clientMessageId,
role: 'user',
timestamp: entry.queuedAt,
source: 'transcript',
blocks: entry.body.blocks.map((block) => {
if (block.type !== 'image-ref') {
return block
}
const preview = entry.previewUris[imageIndex++]
return preview ? { ...block, url: preview, path: undefined } : block
})
blocks: mobilePreviewBlocks(entry.body.blocks, entry.previewUris)
}
}
function mobilePreviewBlocks(
blocks: NativeChatMessage['blocks'],
previewUris: readonly string[]
): NativeChatMessage['blocks'] {
let imageIndex = 0
return blocks.map((block) => {
if (block.type !== 'image-ref') {
return block
}
const preview = previewUris[imageIndex++]
return preview ? { ...block, url: preview, path: undefined } : block
})
}
export function buildMobileStructuredTimeline(
items: readonly AgentJournalRenderItem[],
outbox: readonly MobileStructuredOutboxEntry[]
@@ -67,7 +74,16 @@ export function buildMobileStructuredTimeline(
if (entry) {
seen.add(entry.clientMessageId)
}
return [{ kind: 'message', key: message.id, message, ...(entry ? { outbox: entry } : {}) }]
return [
{
kind: 'message',
key: message.id,
message: entry
? { ...message, blocks: mobilePreviewBlocks(message.blocks, entry.previewUris) }
: message,
...(entry ? { outbox: entry } : {})
}
]
})
return [
...canonical,