From a2417e043e37a772d0627edccab32c55678b8e52 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Wed, 20 May 2026 19:30:04 +0300 Subject: [PATCH] [Chat] Add embeds to the optimistic message (#10564) --- .../Messages/components/MessagesList.tsx | 20 ++++++++++++++----- src/state/messages/convo/agent.ts | 16 ++++++++++++--- src/state/messages/convo/types.ts | 3 +++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/screens/Messages/components/MessagesList.tsx b/src/screens/Messages/components/MessagesList.tsx index c0ea298ba5..69182c082b 100644 --- a/src/screens/Messages/components/MessagesList.tsx +++ b/src/screens/Messages/components/MessagesList.tsx @@ -45,6 +45,7 @@ import { } from '#/state/messages/convo' import {type ConvoState, ConvoStatus} from '#/state/messages/convo/types' import {useGetPost} from '#/state/queries/post' +import {createEmbedViewRecordFromPost} from '#/state/queries/postgate/util' import {useAgent} from '#/state/session' import {List, type ListMethods} from '#/view/com/util/List' import {MessageComposer} from '#/screens/Messages/components/MessageComposer' @@ -331,6 +332,7 @@ export function MessagesList({ rt.detectFacetsWithoutResolution() let embed: $Typed | undefined + let embedView: $Typed | undefined if (embedUri) { try { @@ -344,6 +346,11 @@ export function MessagesList({ }, } + embedView = { + $type: 'app.bsky.embed.record#view', + record: createEmbedViewRecordFromPost(post), + } + // look for the embed uri in the facets, so we can remove it from the text const postLinkFacet = rt.facets?.find(facet => { return facet.features.find(feature => { @@ -391,11 +398,14 @@ export function MessagesList({ setHasScrolled(true) } - convoState.sendMessage({ - text: rt.text, - facets: rt.facets, - embed, - }) + convoState.sendMessage( + { + text: rt.text, + facets: rt.facets, + embed, + }, + embedView, + ) }, [agent, convoState, embedUri, getPost, hasScrolled, setHasScrolled], ) diff --git a/src/state/messages/convo/agent.ts b/src/state/messages/convo/agent.ts index 6220d5faac..08b609f71a 100644 --- a/src/state/messages/convo/agent.ts +++ b/src/state/messages/convo/agent.ts @@ -1,4 +1,6 @@ import { + type $Typed, + type AppBskyEmbedRecord, type AtpAgent, type ChatBskyActorDefs, ChatBskyConvoDefs, @@ -104,7 +106,11 @@ export class Convo { > = new Map() private pendingMessages: Map< string, - {id: string; message: ChatBskyConvoSendMessage.InputSchema['message']} + { + id: string + message: ChatBskyConvoSendMessage.InputSchema['message'] + optimisticEmbedView?: $Typed + } > = new Map() private deletedMessages: Set = new Set() private relatedProfiles: Map = @@ -934,7 +940,10 @@ export class Convo { private pendingMessageFailure: 'recoverable' | 'unrecoverable' | null = null - sendMessage(message: ChatBskyConvoSendMessage.InputSchema['message']) { + sendMessage( + message: ChatBskyConvoSendMessage.InputSchema['message'], + optimisticEmbedView?: $Typed, + ) { // Ignore empty messages for now since they have no other purpose atm if (!message.text.trim() && !message.embed) return @@ -946,6 +955,7 @@ export class Convo { this.pendingMessages.set(tempId, { id: tempId, message, + optimisticEmbedView, }) if (this.convo?.view.status === 'request') { this.updateConvo({ @@ -1292,7 +1302,7 @@ export class Convo { key: m.id, message: { ...m.message, - embed: undefined, + embed: m.optimisticEmbedView, $type: 'chat.bsky.convo.defs#messageView', id: nanoid(), rev: '__fake__', diff --git a/src/state/messages/convo/types.ts b/src/state/messages/convo/types.ts index 363c8291b5..51d111356a 100644 --- a/src/state/messages/convo/types.ts +++ b/src/state/messages/convo/types.ts @@ -1,4 +1,6 @@ import { + type $Typed, + type AppBskyEmbedRecord, type BskyAgent, type ChatBskyActorDefs, type ChatBskyConvoDefs, @@ -106,6 +108,7 @@ export type ConvoItem = type DeleteMessage = (messageId: string) => Promise type SendMessage = ( message: ChatBskyConvoSendMessage.InputSchema['message'], + optimisticEmbedView: $Typed | undefined, ) => void type FetchMessageHistory = () => Promise type MarkConvoAccepted = () => void