feat(inbox): exibir transcrição de áudio/descrição de imagem na conversa
Mostra o texto gerado pelo motor (messages.transcription, Gemini) abaixo do player de áudio (🎤) e abaixo da imagem (👁). Propaga o campo transcription por inboxTypes.Message, chatStore.Message e o bridge messagesToLegacy, e atualiza em tempo real via novo listener socket message:transcription. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -150,6 +150,11 @@ const AudioBubble: React.FC<AudioBubbleProps> = ({ msg, fullMediaUrl, isOut, Tim
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{msg.transcription && (
|
||||||
|
<p className="mt-1.5 text-[12.5px] italic text-[#54656f] whitespace-pre-wrap leading-snug max-w-[260px]">
|
||||||
|
🎤 {msg.transcription}
|
||||||
|
</p>
|
||||||
|
)}
|
||||||
{TimestampRow}
|
{TimestampRow}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
@@ -652,6 +657,13 @@ const MessageBubble: React.FC<MessageBubbleProps> = ({
|
|||||||
<div className="absolute bottom-0.5 right-1">{TimestampEl}</div>
|
<div className="absolute bottom-0.5 right-1">{TimestampEl}</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
{msg.transcription && (
|
||||||
|
<div className="px-1 pb-1 pt-0.5">
|
||||||
|
<p className="text-[12.5px] italic text-[#54656f] whitespace-pre-wrap leading-snug">
|
||||||
|
👁 {msg.transcription}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ function messagesToLegacy(msgs: ReturnType<typeof useChatStore.getState>['messag
|
|||||||
status: m.status.toLowerCase(),
|
status: m.status.toLowerCase(),
|
||||||
type: m.type.toLowerCase(),
|
type: m.type.toLowerCase(),
|
||||||
media_url: m.mediaUrl,
|
media_url: m.mediaUrl,
|
||||||
|
transcription: (m as any).transcription ?? null,
|
||||||
mime_type: m.mimeType,
|
mime_type: m.mimeType,
|
||||||
reply_to_id: m.replyToId,
|
reply_to_id: m.replyToId,
|
||||||
// Quoted message — mapeia replyTo do Prisma para o formato do MessageBubble
|
// Quoted message — mapeia replyTo do Prisma para o formato do MessageBubble
|
||||||
|
|||||||
@@ -81,6 +81,7 @@ export interface Message {
|
|||||||
type: string
|
type: string
|
||||||
body: string | null
|
body: string | null
|
||||||
mediaUrl: string | null
|
mediaUrl: string | null
|
||||||
|
transcription?: string | null
|
||||||
mimeType: string | null
|
mimeType: string | null
|
||||||
fileName: string | null
|
fileName: string | null
|
||||||
replyToId: string | null
|
replyToId: string | null
|
||||||
@@ -411,6 +412,10 @@ export const useChatStore = create<ChatState>()(
|
|||||||
get().updateMediaReady(messageId, mediaUrl)
|
get().updateMediaReady(messageId, mediaUrl)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
socketService.on('message:transcription', ({ messageId, transcription }: { messageId: string; transcription: string }) => {
|
||||||
|
get().patchMessage(messageId, { transcription })
|
||||||
|
})
|
||||||
|
|
||||||
socketService.on('message:status', ({ messageId, status }: { messageId: string; status: Message['status'] }) => {
|
socketService.on('message:status', ({ messageId, status }: { messageId: string; status: Message['status'] }) => {
|
||||||
get().patchMessage(messageId, { status })
|
get().patchMessage(messageId, { status })
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ export interface Message {
|
|||||||
instance_name?: string;
|
instance_name?: string;
|
||||||
sender_jid?: string;
|
sender_jid?: string;
|
||||||
rich_payload?: RichPayload | null;
|
rich_payload?: RichPayload | null;
|
||||||
|
transcription?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WhatsAppInstance {
|
export interface WhatsAppInstance {
|
||||||
|
|||||||
Reference in New Issue
Block a user