@crafter/rn-ai-elements 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/commonjs/chatbot/AIImage.js +126 -0
- package/lib/commonjs/chatbot/AIImage.js.map +1 -0
- package/lib/commonjs/chatbot/Attachments.js +317 -0
- package/lib/commonjs/chatbot/Attachments.js.map +1 -0
- package/lib/commonjs/chatbot/ChatErrorBoundary.js +201 -0
- package/lib/commonjs/chatbot/ChatErrorBoundary.js.map +1 -0
- package/lib/commonjs/chatbot/ChatMessageItem.js +169 -0
- package/lib/commonjs/chatbot/ChatMessageItem.js.map +1 -0
- package/lib/commonjs/chatbot/Conversation.js +415 -0
- package/lib/commonjs/chatbot/Conversation.js.map +1 -0
- package/lib/commonjs/chatbot/ConversationScrollButton.js +131 -0
- package/lib/commonjs/chatbot/ConversationScrollButton.js.map +1 -0
- package/lib/commonjs/chatbot/Message.js +203 -0
- package/lib/commonjs/chatbot/Message.js.map +1 -0
- package/lib/commonjs/chatbot/PromptInput.js +352 -0
- package/lib/commonjs/chatbot/PromptInput.js.map +1 -0
- package/lib/commonjs/chatbot/Reasoning.js +184 -0
- package/lib/commonjs/chatbot/Reasoning.js.map +1 -0
- package/lib/commonjs/chatbot/Shimmer.js +116 -0
- package/lib/commonjs/chatbot/Shimmer.js.map +1 -0
- package/lib/commonjs/chatbot/Sources.js +212 -0
- package/lib/commonjs/chatbot/Sources.js.map +1 -0
- package/lib/commonjs/chatbot/Suggestion.js +99 -0
- package/lib/commonjs/chatbot/Suggestion.js.map +1 -0
- package/lib/commonjs/chatbot/Tool.js +307 -0
- package/lib/commonjs/chatbot/Tool.js.map +1 -0
- package/lib/commonjs/chatbot/adapters/uiMessageAdapter.js +141 -0
- package/lib/commonjs/chatbot/adapters/uiMessageAdapter.js.map +1 -0
- package/lib/commonjs/chatbot/index.js +140 -0
- package/lib/commonjs/chatbot/index.js.map +1 -0
- package/lib/commonjs/chatbot/types.js +6 -0
- package/lib/commonjs/chatbot/types.js.map +1 -0
- package/lib/commonjs/hooks/index.js +34 -0
- package/lib/commonjs/hooks/index.js.map +1 -0
- package/lib/commonjs/hooks/useAutoScroll.js +39 -0
- package/lib/commonjs/hooks/useAutoScroll.js.map +1 -0
- package/lib/commonjs/hooks/useClipboard.js +44 -0
- package/lib/commonjs/hooks/useClipboard.js.map +1 -0
- package/lib/commonjs/hooks/useCollapsible.js +35 -0
- package/lib/commonjs/hooks/useCollapsible.js.map +1 -0
- package/lib/commonjs/hooks/useStickToBottom.js +68 -0
- package/lib/commonjs/hooks/useStickToBottom.js.map +1 -0
- package/lib/commonjs/index.js +257 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/primitives/Badge.js +119 -0
- package/lib/commonjs/primitives/Badge.js.map +1 -0
- package/lib/commonjs/primitives/Button.js +185 -0
- package/lib/commonjs/primitives/Button.js.map +1 -0
- package/lib/commonjs/primitives/Card.js +166 -0
- package/lib/commonjs/primitives/Card.js.map +1 -0
- package/lib/commonjs/primitives/Collapsible.js +137 -0
- package/lib/commonjs/primitives/Collapsible.js.map +1 -0
- package/lib/commonjs/primitives/ScrollArea.js +40 -0
- package/lib/commonjs/primitives/ScrollArea.js.map +1 -0
- package/lib/commonjs/primitives/index.js +83 -0
- package/lib/commonjs/primitives/index.js.map +1 -0
- package/lib/commonjs/streaming/StreamingMarkdown.js +252 -0
- package/lib/commonjs/streaming/StreamingMarkdown.js.map +1 -0
- package/lib/commonjs/streaming/index.js +13 -0
- package/lib/commonjs/streaming/index.js.map +1 -0
- package/lib/commonjs/streaming/parser.js +482 -0
- package/lib/commonjs/streaming/parser.js.map +1 -0
- package/lib/commonjs/streaming/renderers/BlockquoteRenderer.js +35 -0
- package/lib/commonjs/streaming/renderers/BlockquoteRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/CodeRenderer.js +128 -0
- package/lib/commonjs/streaming/renderers/CodeRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/HeadingRenderer.js +61 -0
- package/lib/commonjs/streaming/renderers/HeadingRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/ImageRenderer.js +53 -0
- package/lib/commonjs/streaming/renderers/ImageRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/LinkRenderer.js +49 -0
- package/lib/commonjs/streaming/renderers/LinkRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/ListRenderer.js +63 -0
- package/lib/commonjs/streaming/renderers/ListRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/TableRenderer.js +77 -0
- package/lib/commonjs/streaming/renderers/TableRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/TextRenderer.js +41 -0
- package/lib/commonjs/streaming/renderers/TextRenderer.js.map +1 -0
- package/lib/commonjs/streaming/renderers/index.js +76 -0
- package/lib/commonjs/streaming/renderers/index.js.map +1 -0
- package/lib/commonjs/streaming/renderers/renderInlineChildren.js +112 -0
- package/lib/commonjs/streaming/renderers/renderInlineChildren.js.map +1 -0
- package/lib/commonjs/streaming/renderers/renderNode.js +81 -0
- package/lib/commonjs/streaming/renderers/renderNode.js.map +1 -0
- package/lib/commonjs/theme/ThemeProvider.js +68 -0
- package/lib/commonjs/theme/ThemeProvider.js.map +1 -0
- package/lib/commonjs/theme/defaultTheme.js +96 -0
- package/lib/commonjs/theme/defaultTheme.js.map +1 -0
- package/lib/commonjs/theme/index.js +32 -0
- package/lib/commonjs/theme/index.js.map +1 -0
- package/lib/commonjs/theme/tokens.js +2 -0
- package/lib/commonjs/theme/tokens.js.map +1 -0
- package/lib/commonjs/types.d.js +2 -0
- package/lib/commonjs/types.d.js.map +1 -0
- package/lib/commonjs/voice/index.js +13 -0
- package/lib/commonjs/voice/index.js.map +1 -0
- package/lib/commonjs/voice/useSpeechRecognition.js +172 -0
- package/lib/commonjs/voice/useSpeechRecognition.js.map +1 -0
- package/lib/module/chatbot/AIImage.js +121 -0
- package/lib/module/chatbot/AIImage.js.map +1 -0
- package/lib/module/chatbot/Attachments.js +312 -0
- package/lib/module/chatbot/Attachments.js.map +1 -0
- package/lib/module/chatbot/ChatErrorBoundary.js +196 -0
- package/lib/module/chatbot/ChatErrorBoundary.js.map +1 -0
- package/lib/module/chatbot/ChatMessageItem.js +164 -0
- package/lib/module/chatbot/ChatMessageItem.js.map +1 -0
- package/lib/module/chatbot/Conversation.js +412 -0
- package/lib/module/chatbot/Conversation.js.map +1 -0
- package/lib/module/chatbot/ConversationScrollButton.js +126 -0
- package/lib/module/chatbot/ConversationScrollButton.js.map +1 -0
- package/lib/module/chatbot/Message.js +198 -0
- package/lib/module/chatbot/Message.js.map +1 -0
- package/lib/module/chatbot/PromptInput.js +347 -0
- package/lib/module/chatbot/PromptInput.js.map +1 -0
- package/lib/module/chatbot/Reasoning.js +179 -0
- package/lib/module/chatbot/Reasoning.js.map +1 -0
- package/lib/module/chatbot/Shimmer.js +111 -0
- package/lib/module/chatbot/Shimmer.js.map +1 -0
- package/lib/module/chatbot/Sources.js +207 -0
- package/lib/module/chatbot/Sources.js.map +1 -0
- package/lib/module/chatbot/Suggestion.js +94 -0
- package/lib/module/chatbot/Suggestion.js.map +1 -0
- package/lib/module/chatbot/Tool.js +303 -0
- package/lib/module/chatbot/Tool.js.map +1 -0
- package/lib/module/chatbot/adapters/uiMessageAdapter.js +137 -0
- package/lib/module/chatbot/adapters/uiMessageAdapter.js.map +1 -0
- package/lib/module/chatbot/index.js +39 -0
- package/lib/module/chatbot/index.js.map +1 -0
- package/lib/module/chatbot/types.js +4 -0
- package/lib/module/chatbot/types.js.map +1 -0
- package/lib/module/hooks/index.js +7 -0
- package/lib/module/hooks/index.js.map +1 -0
- package/lib/module/hooks/useAutoScroll.js +35 -0
- package/lib/module/hooks/useAutoScroll.js.map +1 -0
- package/lib/module/hooks/useClipboard.js +40 -0
- package/lib/module/hooks/useClipboard.js.map +1 -0
- package/lib/module/hooks/useCollapsible.js +31 -0
- package/lib/module/hooks/useCollapsible.js.map +1 -0
- package/lib/module/hooks/useStickToBottom.js +64 -0
- package/lib/module/hooks/useStickToBottom.js.map +1 -0
- package/lib/module/index.js +19 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/primitives/Badge.js +114 -0
- package/lib/module/primitives/Badge.js.map +1 -0
- package/lib/module/primitives/Button.js +180 -0
- package/lib/module/primitives/Button.js.map +1 -0
- package/lib/module/primitives/Card.js +156 -0
- package/lib/module/primitives/Card.js.map +1 -0
- package/lib/module/primitives/Collapsible.js +130 -0
- package/lib/module/primitives/Collapsible.js.map +1 -0
- package/lib/module/primitives/ScrollArea.js +35 -0
- package/lib/module/primitives/ScrollArea.js.map +1 -0
- package/lib/module/primitives/index.js +8 -0
- package/lib/module/primitives/index.js.map +1 -0
- package/lib/module/streaming/StreamingMarkdown.js +246 -0
- package/lib/module/streaming/StreamingMarkdown.js.map +1 -0
- package/lib/module/streaming/index.js +4 -0
- package/lib/module/streaming/index.js.map +1 -0
- package/lib/module/streaming/parser.js +477 -0
- package/lib/module/streaming/parser.js.map +1 -0
- package/lib/module/streaming/renderers/BlockquoteRenderer.js +30 -0
- package/lib/module/streaming/renderers/BlockquoteRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/CodeRenderer.js +123 -0
- package/lib/module/streaming/renderers/CodeRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/HeadingRenderer.js +56 -0
- package/lib/module/streaming/renderers/HeadingRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/ImageRenderer.js +48 -0
- package/lib/module/streaming/renderers/ImageRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/LinkRenderer.js +44 -0
- package/lib/module/streaming/renderers/LinkRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/ListRenderer.js +58 -0
- package/lib/module/streaming/renderers/ListRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/TableRenderer.js +72 -0
- package/lib/module/streaming/renderers/TableRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/TextRenderer.js +36 -0
- package/lib/module/streaming/renderers/TextRenderer.js.map +1 -0
- package/lib/module/streaming/renderers/index.js +13 -0
- package/lib/module/streaming/renderers/index.js.map +1 -0
- package/lib/module/streaming/renderers/renderInlineChildren.js +107 -0
- package/lib/module/streaming/renderers/renderInlineChildren.js.map +1 -0
- package/lib/module/streaming/renderers/renderNode.js +78 -0
- package/lib/module/streaming/renderers/renderNode.js.map +1 -0
- package/lib/module/theme/ThemeProvider.js +62 -0
- package/lib/module/theme/ThemeProvider.js.map +1 -0
- package/lib/module/theme/defaultTheme.js +92 -0
- package/lib/module/theme/defaultTheme.js.map +1 -0
- package/lib/module/theme/index.js +5 -0
- package/lib/module/theme/index.js.map +1 -0
- package/lib/module/theme/tokens.js +2 -0
- package/lib/module/theme/tokens.js.map +1 -0
- package/lib/module/types.d.js +2 -0
- package/lib/module/types.d.js.map +1 -0
- package/lib/module/voice/index.js +14 -0
- package/lib/module/voice/index.js.map +1 -0
- package/lib/module/voice/useSpeechRecognition.js +169 -0
- package/lib/module/voice/useSpeechRecognition.js.map +1 -0
- package/lib/typescript/src/chatbot/AIImage.d.ts +24 -0
- package/lib/typescript/src/chatbot/AIImage.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Attachments.d.ts +20 -0
- package/lib/typescript/src/chatbot/Attachments.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/ChatErrorBoundary.d.ts +57 -0
- package/lib/typescript/src/chatbot/ChatErrorBoundary.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/ChatMessageItem.d.ts +45 -0
- package/lib/typescript/src/chatbot/ChatMessageItem.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Conversation.d.ts +94 -0
- package/lib/typescript/src/chatbot/Conversation.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/ConversationScrollButton.d.ts +62 -0
- package/lib/typescript/src/chatbot/ConversationScrollButton.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Message.d.ts +39 -0
- package/lib/typescript/src/chatbot/Message.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/PromptInput.d.ts +93 -0
- package/lib/typescript/src/chatbot/PromptInput.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Reasoning.d.ts +14 -0
- package/lib/typescript/src/chatbot/Reasoning.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Shimmer.d.ts +13 -0
- package/lib/typescript/src/chatbot/Shimmer.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Sources.d.ts +17 -0
- package/lib/typescript/src/chatbot/Sources.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Suggestion.d.ts +15 -0
- package/lib/typescript/src/chatbot/Suggestion.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/Tool.d.ts +30 -0
- package/lib/typescript/src/chatbot/Tool.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/adapters/uiMessageAdapter.d.ts +24 -0
- package/lib/typescript/src/chatbot/adapters/uiMessageAdapter.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/index.d.ts +29 -0
- package/lib/typescript/src/chatbot/index.d.ts.map +1 -0
- package/lib/typescript/src/chatbot/types.d.ts +49 -0
- package/lib/typescript/src/chatbot/types.d.ts.map +1 -0
- package/lib/typescript/src/hooks/index.d.ts +9 -0
- package/lib/typescript/src/hooks/index.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useAutoScroll.d.ts +23 -0
- package/lib/typescript/src/hooks/useAutoScroll.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useClipboard.d.ts +22 -0
- package/lib/typescript/src/hooks/useClipboard.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useCollapsible.d.ts +28 -0
- package/lib/typescript/src/hooks/useCollapsible.d.ts.map +1 -0
- package/lib/typescript/src/hooks/useStickToBottom.d.ts +39 -0
- package/lib/typescript/src/hooks/useStickToBottom.d.ts.map +1 -0
- package/lib/typescript/src/index.d.ts +11 -0
- package/lib/typescript/src/index.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Badge.d.ts +10 -0
- package/lib/typescript/src/primitives/Badge.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Button.d.ts +16 -0
- package/lib/typescript/src/primitives/Button.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Card.d.ts +33 -0
- package/lib/typescript/src/primitives/Card.d.ts.map +1 -0
- package/lib/typescript/src/primitives/Collapsible.d.ts +20 -0
- package/lib/typescript/src/primitives/Collapsible.d.ts.map +1 -0
- package/lib/typescript/src/primitives/ScrollArea.d.ts +10 -0
- package/lib/typescript/src/primitives/ScrollArea.d.ts.map +1 -0
- package/lib/typescript/src/primitives/index.d.ts +11 -0
- package/lib/typescript/src/primitives/index.d.ts.map +1 -0
- package/lib/typescript/src/streaming/StreamingMarkdown.d.ts +47 -0
- package/lib/typescript/src/streaming/StreamingMarkdown.d.ts.map +1 -0
- package/lib/typescript/src/streaming/index.d.ts +3 -0
- package/lib/typescript/src/streaming/index.d.ts.map +1 -0
- package/lib/typescript/src/streaming/parser.d.ts +41 -0
- package/lib/typescript/src/streaming/parser.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/BlockquoteRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/BlockquoteRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/CodeRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/CodeRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/HeadingRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/HeadingRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/ImageRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/ImageRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/LinkRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/LinkRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/ListRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/ListRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/TableRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/TableRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/TextRenderer.d.ts +7 -0
- package/lib/typescript/src/streaming/renderers/TextRenderer.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/index.d.ts +19 -0
- package/lib/typescript/src/streaming/renderers/index.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/renderInlineChildren.d.ts +12 -0
- package/lib/typescript/src/streaming/renderers/renderInlineChildren.d.ts.map +1 -0
- package/lib/typescript/src/streaming/renderers/renderNode.d.ts +8 -0
- package/lib/typescript/src/streaming/renderers/renderNode.d.ts.map +1 -0
- package/lib/typescript/src/theme/ThemeProvider.d.ts +14 -0
- package/lib/typescript/src/theme/ThemeProvider.d.ts.map +1 -0
- package/lib/typescript/src/theme/defaultTheme.d.ts +4 -0
- package/lib/typescript/src/theme/defaultTheme.d.ts.map +1 -0
- package/lib/typescript/src/theme/index.d.ts +5 -0
- package/lib/typescript/src/theme/index.d.ts.map +1 -0
- package/lib/typescript/src/theme/tokens.d.ts +66 -0
- package/lib/typescript/src/theme/tokens.d.ts.map +1 -0
- package/lib/typescript/src/voice/index.d.ts +3 -0
- package/lib/typescript/src/voice/index.d.ts.map +1 -0
- package/lib/typescript/src/voice/useSpeechRecognition.d.ts +77 -0
- package/lib/typescript/src/voice/useSpeechRecognition.d.ts.map +1 -0
- package/package.json +132 -0
- package/src/chatbot/AIImage.tsx +166 -0
- package/src/chatbot/Attachments.tsx +382 -0
- package/src/chatbot/ChatErrorBoundary.tsx +230 -0
- package/src/chatbot/ChatMessageItem.tsx +195 -0
- package/src/chatbot/Conversation.tsx +537 -0
- package/src/chatbot/ConversationScrollButton.tsx +149 -0
- package/src/chatbot/Message.tsx +266 -0
- package/src/chatbot/PromptInput.tsx +532 -0
- package/src/chatbot/Reasoning.tsx +198 -0
- package/src/chatbot/Shimmer.tsx +146 -0
- package/src/chatbot/Sources.tsx +263 -0
- package/src/chatbot/Suggestion.tsx +123 -0
- package/src/chatbot/Tool.tsx +340 -0
- package/src/chatbot/adapters/uiMessageAdapter.ts +177 -0
- package/src/chatbot/index.ts +97 -0
- package/src/chatbot/types.ts +66 -0
- package/src/hooks/index.ts +17 -0
- package/src/hooks/useAutoScroll.ts +43 -0
- package/src/hooks/useClipboard.ts +46 -0
- package/src/hooks/useCollapsible.ts +42 -0
- package/src/hooks/useStickToBottom.ts +82 -0
- package/src/index.ts +139 -0
- package/src/primitives/Badge.tsx +119 -0
- package/src/primitives/Button.tsx +213 -0
- package/src/primitives/Card.tsx +221 -0
- package/src/primitives/Collapsible.tsx +168 -0
- package/src/primitives/ScrollArea.tsx +53 -0
- package/src/primitives/index.ts +36 -0
- package/src/streaming/StreamingMarkdown.tsx +282 -0
- package/src/streaming/index.ts +2 -0
- package/src/streaming/parser.ts +506 -0
- package/src/streaming/renderers/BlockquoteRenderer.tsx +42 -0
- package/src/streaming/renderers/CodeRenderer.tsx +158 -0
- package/src/streaming/renderers/HeadingRenderer.tsx +64 -0
- package/src/streaming/renderers/ImageRenderer.tsx +62 -0
- package/src/streaming/renderers/LinkRenderer.tsx +53 -0
- package/src/streaming/renderers/ListRenderer.tsx +65 -0
- package/src/streaming/renderers/TableRenderer.tsx +103 -0
- package/src/streaming/renderers/TextRenderer.tsx +39 -0
- package/src/streaming/renderers/index.ts +26 -0
- package/src/streaming/renderers/renderInlineChildren.tsx +115 -0
- package/src/streaming/renderers/renderNode.tsx +72 -0
- package/src/theme/ThemeProvider.tsx +77 -0
- package/src/theme/defaultTheme.ts +93 -0
- package/src/theme/index.ts +4 -0
- package/src/theme/tokens.ts +69 -0
- package/src/types.d.ts +71 -0
- package/src/voice/index.ts +15 -0
- package/src/voice/useSpeechRecognition.ts +230 -0
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import { StyleSheet, View } from 'react-native';
|
|
5
|
+
import { useAIElementsTheme } from '../theme';
|
|
6
|
+
import { StreamingMarkdown } from '../streaming';
|
|
7
|
+
import { Message, MessageContent } from './Message';
|
|
8
|
+
import { Reasoning } from './Reasoning';
|
|
9
|
+
import { Tool } from './Tool';
|
|
10
|
+
import { Sources } from './Sources';
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Props
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
16
|
+
// ---------------------------------------------------------------------------
|
|
17
|
+
// Component
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Renders a single chat message — either a user bubble (delegated to the
|
|
22
|
+
* library's `Message` compound) or an assistant block composed of optional
|
|
23
|
+
* reasoning, tool call, streaming markdown, and sources.
|
|
24
|
+
*
|
|
25
|
+
* Wrapped in `React.memo` with a custom equality function below: rows only
|
|
26
|
+
* re-render when their own `item` content actually changes, **not** when an
|
|
27
|
+
* unrelated message updates elsewhere in the list. The equality function
|
|
28
|
+
* compares fields directly so callers can safely build a fresh
|
|
29
|
+
* `ChatMessageData` object on every render — identity churn is fine.
|
|
30
|
+
*
|
|
31
|
+
* @example
|
|
32
|
+
* ```tsx
|
|
33
|
+
* const renderMessage = useCallback(
|
|
34
|
+
* (raw: MyMessage) => {
|
|
35
|
+
* const data: ChatMessageData = toChatMessageData(raw);
|
|
36
|
+
* return <ChatMessageItem item={data} />;
|
|
37
|
+
* },
|
|
38
|
+
* [],
|
|
39
|
+
* );
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
function ChatMessageItemImpl({
|
|
43
|
+
item
|
|
44
|
+
}) {
|
|
45
|
+
const theme = useAIElementsTheme();
|
|
46
|
+
const isUser = item.role === 'user';
|
|
47
|
+
if (isUser) {
|
|
48
|
+
// Library's Message compound owns padding + bubble layout for user msgs.
|
|
49
|
+
// We pass the canonical data through — `Message` only reads `id`, `role`
|
|
50
|
+
// and `content`, all of which are present.
|
|
51
|
+
return /*#__PURE__*/_jsx(Message, {
|
|
52
|
+
message: item,
|
|
53
|
+
children: /*#__PURE__*/_jsx(MessageContent, {})
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// Assistant message — composed from optional sub-blocks.
|
|
58
|
+
return /*#__PURE__*/_jsxs(View, {
|
|
59
|
+
style: [styles.assistantBlock, {
|
|
60
|
+
paddingHorizontal: theme.spacing.lg,
|
|
61
|
+
marginBottom: theme.spacing.md
|
|
62
|
+
}],
|
|
63
|
+
children: [item.reasoning && /*#__PURE__*/_jsx(Reasoning, {
|
|
64
|
+
content: item.reasoning.content,
|
|
65
|
+
isStreaming: item.reasoning.isStreaming
|
|
66
|
+
// Collapsed by default — the trigger ("Thinking..." → "Thought
|
|
67
|
+
// for Xs") still shows progress; the user can tap to expand.
|
|
68
|
+
,
|
|
69
|
+
defaultOpen: false,
|
|
70
|
+
style: {
|
|
71
|
+
marginBottom: theme.spacing.sm
|
|
72
|
+
}
|
|
73
|
+
}), item.tool && /*#__PURE__*/_jsx(Tool, {
|
|
74
|
+
name: item.tool.name,
|
|
75
|
+
status: item.tool.status,
|
|
76
|
+
args: item.tool.args,
|
|
77
|
+
result: item.tool.result,
|
|
78
|
+
style: {
|
|
79
|
+
marginBottom: theme.spacing.sm
|
|
80
|
+
}
|
|
81
|
+
}), item.content.length > 0 && /*#__PURE__*/_jsx(StreamingMarkdown, {
|
|
82
|
+
content: item.content
|
|
83
|
+
// Once sources are attached we treat the message as fully
|
|
84
|
+
// delivered and the streaming hint switches off.
|
|
85
|
+
,
|
|
86
|
+
isStreaming: !item.sources
|
|
87
|
+
}), item.sources && item.sources.length > 0 && /*#__PURE__*/_jsx(Sources, {
|
|
88
|
+
sources: item.sources,
|
|
89
|
+
style: {
|
|
90
|
+
marginTop: theme.spacing.sm
|
|
91
|
+
}
|
|
92
|
+
})]
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
ChatMessageItemImpl.displayName = 'ChatMessageItem';
|
|
96
|
+
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Custom equality — only re-render when something we actually display changes
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Returns true when the two prop sets would render identical output. Compares
|
|
103
|
+
* fields directly so a freshly-built `ChatMessageData` object on every render
|
|
104
|
+
* is fine — only real content changes trigger a re-render.
|
|
105
|
+
*/
|
|
106
|
+
function areEqual(prev, next) {
|
|
107
|
+
const a = prev.item;
|
|
108
|
+
const b = next.item;
|
|
109
|
+
if (a === b) return true;
|
|
110
|
+
|
|
111
|
+
// Identity / role
|
|
112
|
+
if (a.id !== b.id) return false;
|
|
113
|
+
if (a.role !== b.role) return false;
|
|
114
|
+
|
|
115
|
+
// Content (the streaming hot path — must be cheap)
|
|
116
|
+
if (a.content !== b.content) return false;
|
|
117
|
+
|
|
118
|
+
// Reasoning (object — compare relevant fields, not identity)
|
|
119
|
+
const ar = a.reasoning;
|
|
120
|
+
const br = b.reasoning;
|
|
121
|
+
if (ar !== br) {
|
|
122
|
+
if (!ar || !br) return false;
|
|
123
|
+
if (ar.content !== br.content) return false;
|
|
124
|
+
if (ar.isStreaming !== br.isStreaming) return false;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Tool — name + status + result are the animating fields. Args are
|
|
128
|
+
// assumed stable per invocation, so we don't deep-compare them.
|
|
129
|
+
const at = a.tool;
|
|
130
|
+
const bt = b.tool;
|
|
131
|
+
if (at !== bt) {
|
|
132
|
+
if (!at || !bt) return false;
|
|
133
|
+
if (at.name !== bt.name) return false;
|
|
134
|
+
if (at.status !== bt.status) return false;
|
|
135
|
+
if (at.result !== bt.result) return false;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Sources — the typical pattern is to attach the array once at the end
|
|
139
|
+
// of the stream and never mutate it, so a length comparison is enough.
|
|
140
|
+
const as = a.sources;
|
|
141
|
+
const bs = b.sources;
|
|
142
|
+
if (as !== bs) {
|
|
143
|
+
if ((as?.length ?? 0) !== (bs?.length ?? 0)) return false;
|
|
144
|
+
}
|
|
145
|
+
return true;
|
|
146
|
+
}
|
|
147
|
+
export const ChatMessageItem = /*#__PURE__*/React.memo(ChatMessageItemImpl, areEqual);
|
|
148
|
+
|
|
149
|
+
// `React.memo` doesn't propagate `displayName` from the inner function, set
|
|
150
|
+
// it on the wrapped export so DevTools shows a meaningful name.
|
|
151
|
+
ChatMessageItem.displayName = 'ChatMessageItem';
|
|
152
|
+
|
|
153
|
+
// ---------------------------------------------------------------------------
|
|
154
|
+
// Styles
|
|
155
|
+
// ---------------------------------------------------------------------------
|
|
156
|
+
|
|
157
|
+
const styles = StyleSheet.create({
|
|
158
|
+
assistantBlock: {
|
|
159
|
+
// Default `alignItems: stretch` so children (Reasoning, Tool,
|
|
160
|
+
// StreamingMarkdown, Sources) span the full available width instead
|
|
161
|
+
// of shrinking to intrinsic content size.
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
//# sourceMappingURL=ChatMessageItem.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","StyleSheet","View","useAIElementsTheme","StreamingMarkdown","Message","MessageContent","Reasoning","Tool","Sources","jsx","_jsx","jsxs","_jsxs","ChatMessageItemImpl","item","theme","isUser","role","message","children","style","styles","assistantBlock","paddingHorizontal","spacing","lg","marginBottom","md","reasoning","content","isStreaming","defaultOpen","sm","tool","name","status","args","result","length","sources","marginTop","displayName","areEqual","prev","next","a","b","id","ar","br","at","bt","as","bs","ChatMessageItem","memo","create"],"sourceRoot":"../../../src","sources":["chatbot/ChatMessageItem.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
import React, { memo, useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { FlatList, StyleSheet, View } from 'react-native';
|
|
5
|
+
import { useAIElementsTheme } from '../theme';
|
|
6
|
+
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
// Constants
|
|
9
|
+
// ---------------------------------------------------------------------------
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Distance in px from the bottom of the content that still counts as "at the
|
|
13
|
+
* bottom" for the purposes of auto-following content growth (e.g. expanding
|
|
14
|
+
* a Sources collapsible).
|
|
15
|
+
*/
|
|
16
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
17
|
+
const STICK_TO_BOTTOM_THRESHOLD = 80;
|
|
18
|
+
|
|
19
|
+
/** Delay before retrying a failed `scrollToIndex` once layout settles. */
|
|
20
|
+
const SCROLL_RETRY_DELAY_MS = 120;
|
|
21
|
+
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
// Types
|
|
24
|
+
// ---------------------------------------------------------------------------
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Minimum shape Conversation requires from a message. Most chat libraries
|
|
28
|
+
* (the Vercel `ai` SDK, OpenAI's `ChatMessage`, Anthropic's `Message`) all
|
|
29
|
+
* satisfy this contract via `id` + `role`.
|
|
30
|
+
*/
|
|
31
|
+
|
|
32
|
+
/** Order in which `messages` is provided. */
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* How `Conversation` reacts to new messages and content growth.
|
|
36
|
+
*
|
|
37
|
+
* - `'anchor-user-message'` *(default)* — When a new user message arrives,
|
|
38
|
+
* scroll it to the top of the viewport and use dynamic bottom padding so
|
|
39
|
+
* the assistant response streams downward beneath it. Auto-scroll on
|
|
40
|
+
* collapsible expansion (e.g. opening a Sources block) when the user is
|
|
41
|
+
* already near the bottom and not currently streaming. This mimics how
|
|
42
|
+
* ChatGPT, Claude, and Vercel ai-elements anchor each new turn.
|
|
43
|
+
* - `'stick-to-bottom'` — Classic chat behavior: always follow the bottom
|
|
44
|
+
* on any content size change, even mid-stream. The list "sticks" to the
|
|
45
|
+
* newest content. Matches what `use-stick-to-bottom` does on the web.
|
|
46
|
+
* - `'none'` — Disable all automatic scrolling and dynamic padding. The
|
|
47
|
+
* consumer is fully responsible for managing scroll position via the
|
|
48
|
+
* imperative `ConversationRef`.
|
|
49
|
+
*/
|
|
50
|
+
|
|
51
|
+
/** Imperative handle exposed via ref. */
|
|
52
|
+
|
|
53
|
+
// ---------------------------------------------------------------------------
|
|
54
|
+
// Helpers
|
|
55
|
+
// ---------------------------------------------------------------------------
|
|
56
|
+
|
|
57
|
+
const defaultIsUserMessage = m => m.role === 'user';
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Find the most-recently-added user message regardless of array order.
|
|
61
|
+
* - For `'newest-first'`: the newest user msg is the *first* match in the
|
|
62
|
+
* forward direction.
|
|
63
|
+
* - For `'oldest-first'`: the newest user msg is the *last* match, so we
|
|
64
|
+
* walk backward.
|
|
65
|
+
*/
|
|
66
|
+
function findNewestUserMessage(messages, isUserMessage, order) {
|
|
67
|
+
if (order === 'newest-first') {
|
|
68
|
+
return messages.find(isUserMessage);
|
|
69
|
+
}
|
|
70
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
71
|
+
if (isUserMessage(messages[i])) return messages[i];
|
|
72
|
+
}
|
|
73
|
+
return undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// ---------------------------------------------------------------------------
|
|
77
|
+
// Component
|
|
78
|
+
// ---------------------------------------------------------------------------
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Chat list, top-to-bottom, with three signature behaviors:
|
|
82
|
+
*
|
|
83
|
+
* 1. **Anchor on send.** When a new user message arrives, the list scrolls
|
|
84
|
+
* that message to the top of the viewport. The assistant response then
|
|
85
|
+
* streams downward beneath it.
|
|
86
|
+
* 2. **Dynamic bottom padding.** When the conversation is shorter than the
|
|
87
|
+
* viewport, padding fills the gap so the user message can still be
|
|
88
|
+
* anchored to the top. Once natural content fills the viewport, the
|
|
89
|
+
* padding collapses to zero so the user can't scroll into empty space.
|
|
90
|
+
* 3. **Stick-to-bottom on growth.** When the user is already near the
|
|
91
|
+
* bottom and content grows (e.g. they tap "Sources" to expand), the
|
|
92
|
+
* list animates to show the new content. Disabled while
|
|
93
|
+
* `isStreaming === true` to avoid fighting the anchor.
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```tsx
|
|
97
|
+
* const ref = useRef<ConversationRef>(null);
|
|
98
|
+
*
|
|
99
|
+
* <Conversation
|
|
100
|
+
* ref={ref}
|
|
101
|
+
* messages={messages} // any T extends { id, role? }
|
|
102
|
+
* renderMessage={(m) => <Bubble msg={m} />}
|
|
103
|
+
* isStreaming={isLoading}
|
|
104
|
+
* order="oldest-first" // or "newest-first"
|
|
105
|
+
* emptyState={<EmptyChat />}
|
|
106
|
+
* />
|
|
107
|
+
* ```
|
|
108
|
+
*/
|
|
109
|
+
function ConversationInner({
|
|
110
|
+
ref,
|
|
111
|
+
messages,
|
|
112
|
+
renderMessage,
|
|
113
|
+
emptyState,
|
|
114
|
+
isStreaming = false,
|
|
115
|
+
order = 'oldest-first',
|
|
116
|
+
isUserMessage = defaultIsUserMessage,
|
|
117
|
+
onIsAtBottomChange,
|
|
118
|
+
scrollBehavior = 'anchor-user-message',
|
|
119
|
+
style,
|
|
120
|
+
...viewProps
|
|
121
|
+
}) {
|
|
122
|
+
const theme = useAIElementsTheme();
|
|
123
|
+
const listRef = useRef(null);
|
|
124
|
+
|
|
125
|
+
// --- Refs (frequently updated, no re-render) ----------------------------
|
|
126
|
+
|
|
127
|
+
/** Latest scroll position (true when within threshold of the bottom). */
|
|
128
|
+
const isAtBottomRef = useRef(true);
|
|
129
|
+
/** Latest "natural" content height (i.e. without dynamic padding). */
|
|
130
|
+
const previousNaturalRef = useRef(0);
|
|
131
|
+
/** Newest natural content height — readable from the imperative API. */
|
|
132
|
+
const naturalContentHeightRef = useRef(0);
|
|
133
|
+
/** Mirror of `isStreaming` so callbacks can read the freshest value. */
|
|
134
|
+
const isStreamingRef = useRef(isStreaming);
|
|
135
|
+
isStreamingRef.current = isStreaming;
|
|
136
|
+
/** Mirror of `scrollBehavior` so callbacks read the freshest value. */
|
|
137
|
+
const scrollBehaviorRef = useRef(scrollBehavior);
|
|
138
|
+
scrollBehaviorRef.current = scrollBehavior;
|
|
139
|
+
/** Last user-message id we anchored to — guards against re-anchoring. */
|
|
140
|
+
const lastUserMsgIdRef = useRef(null);
|
|
141
|
+
/**
|
|
142
|
+
* The natural content height as it stood **before** the most recent user
|
|
143
|
+
* message was added. Used as the baseline for the dynamic-padding
|
|
144
|
+
* formula so the new user message can always be scrolled to viewport
|
|
145
|
+
* top, regardless of how much history sits above it. `null` until the
|
|
146
|
+
* first user message has been anchored.
|
|
147
|
+
*/
|
|
148
|
+
const naturalAtAnchorRef = useRef(null);
|
|
149
|
+
|
|
150
|
+
// --- onIsAtBottomChange plumbing ----------------------------------------
|
|
151
|
+
/** Mirror the callback so call sites don't bust useCallback memos. */
|
|
152
|
+
const onIsAtBottomChangeRef = useRef(onIsAtBottomChange);
|
|
153
|
+
onIsAtBottomChangeRef.current = onIsAtBottomChange;
|
|
154
|
+
/** Last value emitted to the consumer — used to dedupe transitions. */
|
|
155
|
+
const lastEmittedIsAtBottomRef = useRef(true);
|
|
156
|
+
/** Latest scroll metrics — needed so contentSize changes can recompute. */
|
|
157
|
+
const scrollMetricsRef = useRef({
|
|
158
|
+
contentOffset: 0,
|
|
159
|
+
layoutHeight: 0
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Compute isAtBottom from the latest scroll metrics + a known content
|
|
164
|
+
* height. Updates `isAtBottomRef` and fires the change callback if the
|
|
165
|
+
* value transitioned.
|
|
166
|
+
*
|
|
167
|
+
* Skips when `layoutHeight === 0` — that's the "no scroll event has
|
|
168
|
+
* fired yet" sentinel. Without this guard, the first
|
|
169
|
+
* `handleListContentSizeChange` after mount would compute
|
|
170
|
+
* `distanceFromBottom = contentHeight - 0 - 0 = contentHeight`, which
|
|
171
|
+
* is always huge, and emit a false `isAtBottom: false` before the user
|
|
172
|
+
* has even scrolled.
|
|
173
|
+
*/
|
|
174
|
+
const updateIsAtBottom = useCallback(contentHeight => {
|
|
175
|
+
const {
|
|
176
|
+
contentOffset,
|
|
177
|
+
layoutHeight
|
|
178
|
+
} = scrollMetricsRef.current;
|
|
179
|
+
if (layoutHeight === 0) return;
|
|
180
|
+
const distanceFromBottom = contentHeight - (contentOffset + layoutHeight);
|
|
181
|
+
const isAtBottom = distanceFromBottom < STICK_TO_BOTTOM_THRESHOLD;
|
|
182
|
+
isAtBottomRef.current = isAtBottom;
|
|
183
|
+
if (isAtBottom !== lastEmittedIsAtBottomRef.current) {
|
|
184
|
+
lastEmittedIsAtBottomRef.current = isAtBottom;
|
|
185
|
+
onIsAtBottomChangeRef.current?.(isAtBottom);
|
|
186
|
+
}
|
|
187
|
+
}, []);
|
|
188
|
+
|
|
189
|
+
// --- Display order ------------------------------------------------------
|
|
190
|
+
// We always render top-to-bottom = oldest-first. If the caller passes
|
|
191
|
+
// newest-first, reverse internally.
|
|
192
|
+
const orderedMessages = useMemo(() => order === 'newest-first' ? [...messages].reverse() : messages, [messages, order]);
|
|
193
|
+
|
|
194
|
+
// --- Dynamic bottom padding ---------------------------------------------
|
|
195
|
+
const [chatAreaHeight, setChatAreaHeight] = useState(0);
|
|
196
|
+
const [listPaddingBottom, setListPaddingBottom] = useState(0);
|
|
197
|
+
const handleAreaLayout = useCallback(e => {
|
|
198
|
+
setChatAreaHeight(e.nativeEvent.layout.height);
|
|
199
|
+
}, []);
|
|
200
|
+
const handleListContentSizeChange = useCallback((_w, h) => {
|
|
201
|
+
// `h` is the *total* content height, which already includes whatever
|
|
202
|
+
// bottom padding we previously set. Subtract it back out to get the
|
|
203
|
+
// natural (real) content height.
|
|
204
|
+
const natural = Math.max(0, h - listPaddingBottom);
|
|
205
|
+
const grew = natural > previousNaturalRef.current;
|
|
206
|
+
previousNaturalRef.current = natural;
|
|
207
|
+
naturalContentHeightRef.current = natural;
|
|
208
|
+
const behavior = scrollBehaviorRef.current;
|
|
209
|
+
|
|
210
|
+
// --- Dynamic bottom padding (anchor-user-message mode only) ---------
|
|
211
|
+
// Reserve enough room so the most recent user message can be
|
|
212
|
+
// scrolled to the top of the viewport. We measure this as "content
|
|
213
|
+
// added since the user message arrived" and pad the rest of the
|
|
214
|
+
// viewport. As the assistant streams below the user message,
|
|
215
|
+
// contentBelowAnchor grows and the padding shrinks proportionally —
|
|
216
|
+
// total content height stays constant until the assistant has
|
|
217
|
+
// produced enough text to fill the viewport on its own, at which
|
|
218
|
+
// point padding naturally hits zero.
|
|
219
|
+
//
|
|
220
|
+
// The other modes don't need padding manipulation, so they fall
|
|
221
|
+
// back to zero.
|
|
222
|
+
let desired = 0;
|
|
223
|
+
if (behavior === 'anchor-user-message') {
|
|
224
|
+
const contentBelowAnchor = naturalAtAnchorRef.current !== null ? Math.max(0, natural - naturalAtAnchorRef.current) : natural;
|
|
225
|
+
desired = Math.max(0, chatAreaHeight - contentBelowAnchor);
|
|
226
|
+
}
|
|
227
|
+
if (desired !== listPaddingBottom) {
|
|
228
|
+
setListPaddingBottom(desired);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
// Re-evaluate isAtBottom against the new content height. The user
|
|
232
|
+
// may have been "at the bottom" before this growth and now no longer
|
|
233
|
+
// be — common during streaming when the assistant pushes content
|
|
234
|
+
// past the viewport while the user passively watches.
|
|
235
|
+
updateIsAtBottom(h);
|
|
236
|
+
|
|
237
|
+
// --- Auto-scroll on growth ------------------------------------------
|
|
238
|
+
// Behavior depends on the mode:
|
|
239
|
+
//
|
|
240
|
+
// anchor-user-message: only follow the bottom when the user is
|
|
241
|
+
// already near it AND not streaming. Streaming uses the
|
|
242
|
+
// user-message anchor instead, and auto-scrolling would fight
|
|
243
|
+
// it. Post-streaming this catches collapsible expansions.
|
|
244
|
+
// stick-to-bottom: always follow the bottom on growth, even
|
|
245
|
+
// mid-stream — classic chat behavior.
|
|
246
|
+
// none: never auto-scroll. Consumer drives the list via the ref.
|
|
247
|
+
if (!grew || behavior === 'none') return;
|
|
248
|
+
const shouldFollow = behavior === 'stick-to-bottom' ? true : !isStreamingRef.current && isAtBottomRef.current;
|
|
249
|
+
if (shouldFollow) {
|
|
250
|
+
requestAnimationFrame(() => {
|
|
251
|
+
listRef.current?.scrollToEnd({
|
|
252
|
+
animated: true
|
|
253
|
+
});
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
}, [listPaddingBottom, chatAreaHeight, updateIsAtBottom]);
|
|
257
|
+
const handleScroll = useCallback(e => {
|
|
258
|
+
const {
|
|
259
|
+
contentOffset,
|
|
260
|
+
layoutMeasurement,
|
|
261
|
+
contentSize
|
|
262
|
+
} = e.nativeEvent;
|
|
263
|
+
scrollMetricsRef.current = {
|
|
264
|
+
contentOffset: contentOffset.y,
|
|
265
|
+
layoutHeight: layoutMeasurement.height
|
|
266
|
+
};
|
|
267
|
+
updateIsAtBottom(contentSize.height);
|
|
268
|
+
}, [updateIsAtBottom]);
|
|
269
|
+
|
|
270
|
+
// Recompute the padding if the viewport itself changes (rotation, keyboard).
|
|
271
|
+
// Mirrors the formula in handleListContentSizeChange — same anchor-aware
|
|
272
|
+
// contentBelowAnchor calculation so the user message stays anchored
|
|
273
|
+
// through orientation changes. Skipped entirely outside the
|
|
274
|
+
// anchor-user-message mode since other modes don't manage padding.
|
|
275
|
+
useEffect(() => {
|
|
276
|
+
if (chatAreaHeight === 0) return;
|
|
277
|
+
if (scrollBehavior !== 'anchor-user-message') {
|
|
278
|
+
if (listPaddingBottom !== 0) setListPaddingBottom(0);
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
const contentBelowAnchor = naturalAtAnchorRef.current !== null ? Math.max(0, naturalContentHeightRef.current - naturalAtAnchorRef.current) : naturalContentHeightRef.current;
|
|
282
|
+
const desired = Math.max(0, chatAreaHeight - contentBelowAnchor);
|
|
283
|
+
setListPaddingBottom(desired);
|
|
284
|
+
// listPaddingBottom intentionally omitted to avoid feedback loops —
|
|
285
|
+
// the same set of conditions runs again whenever it actually matters.
|
|
286
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
287
|
+
}, [chatAreaHeight, scrollBehavior]);
|
|
288
|
+
|
|
289
|
+
// --- Auto-anchor new user message to the top of the viewport -----------
|
|
290
|
+
// Only the `'anchor-user-message'` mode performs this scroll. The other
|
|
291
|
+
// modes leave scroll position to the consumer (or to stick-to-bottom).
|
|
292
|
+
useEffect(() => {
|
|
293
|
+
if (scrollBehavior !== 'anchor-user-message') return;
|
|
294
|
+
const newestUserMsg = findNewestUserMessage(messages, isUserMessage, order);
|
|
295
|
+
if (!newestUserMsg || newestUserMsg.id === lastUserMsgIdRef.current) {
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
lastUserMsgIdRef.current = newestUserMsg.id;
|
|
299
|
+
|
|
300
|
+
// Capture the natural content height as it stood **before** this new
|
|
301
|
+
// user message arrived. handleListContentSizeChange may or may not
|
|
302
|
+
// have already processed the new content, but `previousNaturalRef`
|
|
303
|
+
// always holds the value from the most recent step *before* the
|
|
304
|
+
// latest update — which for a freshly-arrived message is the height
|
|
305
|
+
// without it. This becomes the baseline for the dynamic-padding
|
|
306
|
+
// formula so the new message can be scrolled all the way to the top
|
|
307
|
+
// even when there's history above it.
|
|
308
|
+
naturalAtAnchorRef.current = previousNaturalRef.current;
|
|
309
|
+
const displayIndex = orderedMessages.findIndex(m => m.id === newestUserMsg.id);
|
|
310
|
+
if (displayIndex < 0) return;
|
|
311
|
+
|
|
312
|
+
// Wait for the new item to be laid out before scrolling.
|
|
313
|
+
requestAnimationFrame(() => {
|
|
314
|
+
listRef.current?.scrollToIndex({
|
|
315
|
+
index: displayIndex,
|
|
316
|
+
viewPosition: 0,
|
|
317
|
+
animated: true
|
|
318
|
+
});
|
|
319
|
+
});
|
|
320
|
+
}, [messages, orderedMessages, order, isUserMessage, scrollBehavior]);
|
|
321
|
+
|
|
322
|
+
// --- Imperative handle --------------------------------------------------
|
|
323
|
+
useImperativeHandle(ref, () => ({
|
|
324
|
+
scrollToIndex: (index, opts) => {
|
|
325
|
+
listRef.current?.scrollToIndex({
|
|
326
|
+
index,
|
|
327
|
+
viewPosition: opts?.viewPosition ?? 0,
|
|
328
|
+
animated: opts?.animated ?? true
|
|
329
|
+
});
|
|
330
|
+
},
|
|
331
|
+
scrollToTop: opts => {
|
|
332
|
+
listRef.current?.scrollToOffset({
|
|
333
|
+
offset: 0,
|
|
334
|
+
animated: opts?.animated ?? true
|
|
335
|
+
});
|
|
336
|
+
},
|
|
337
|
+
scrollToBottom: opts => {
|
|
338
|
+
listRef.current?.scrollToEnd({
|
|
339
|
+
animated: opts?.animated ?? true
|
|
340
|
+
});
|
|
341
|
+
},
|
|
342
|
+
isAtBottom: () => isAtBottomRef.current
|
|
343
|
+
}), []);
|
|
344
|
+
|
|
345
|
+
// --- Row renderer -------------------------------------------------------
|
|
346
|
+
const renderItem = useCallback(({
|
|
347
|
+
item
|
|
348
|
+
}) => /*#__PURE__*/_jsx(_Fragment, {
|
|
349
|
+
children: renderMessage(item)
|
|
350
|
+
}), [renderMessage]);
|
|
351
|
+
const keyExtractor = useCallback(item => item.id, []);
|
|
352
|
+
const handleScrollToIndexFailed = useCallback(info => {
|
|
353
|
+
// Fallback for items not yet measured: approximate offset, then
|
|
354
|
+
// retry once layout settles.
|
|
355
|
+
const offset = info.averageItemLength * info.index;
|
|
356
|
+
listRef.current?.scrollToOffset({
|
|
357
|
+
offset,
|
|
358
|
+
animated: true
|
|
359
|
+
});
|
|
360
|
+
setTimeout(() => {
|
|
361
|
+
listRef.current?.scrollToIndex({
|
|
362
|
+
index: info.index,
|
|
363
|
+
viewPosition: 0,
|
|
364
|
+
animated: true
|
|
365
|
+
});
|
|
366
|
+
}, SCROLL_RETRY_DELAY_MS);
|
|
367
|
+
}, []);
|
|
368
|
+
return /*#__PURE__*/_jsx(View, {
|
|
369
|
+
...viewProps,
|
|
370
|
+
style: [styles.root, style],
|
|
371
|
+
onLayout: handleAreaLayout,
|
|
372
|
+
children: messages.length === 0 ? /*#__PURE__*/_jsx(View, {
|
|
373
|
+
style: styles.emptyFill,
|
|
374
|
+
children: emptyState
|
|
375
|
+
}) : /*#__PURE__*/_jsx(FlatList, {
|
|
376
|
+
ref: listRef,
|
|
377
|
+
data: orderedMessages,
|
|
378
|
+
renderItem: renderItem,
|
|
379
|
+
keyExtractor: keyExtractor,
|
|
380
|
+
scrollEventThrottle: 16,
|
|
381
|
+
showsVerticalScrollIndicator: false,
|
|
382
|
+
keyboardDismissMode: "interactive",
|
|
383
|
+
onScroll: handleScroll,
|
|
384
|
+
onContentSizeChange: handleListContentSizeChange,
|
|
385
|
+
contentContainerStyle: {
|
|
386
|
+
paddingTop: theme.spacing.lg,
|
|
387
|
+
paddingBottom: listPaddingBottom
|
|
388
|
+
},
|
|
389
|
+
onScrollToIndexFailed: handleScrollToIndexFailed
|
|
390
|
+
})
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
ConversationInner.displayName = 'Conversation';
|
|
394
|
+
|
|
395
|
+
// `memo` strips the generic from the function signature, so we cast it back
|
|
396
|
+
// to a generic-friendly call signature for the public export. The runtime
|
|
397
|
+
// behavior is unchanged — only the type is preserved.
|
|
398
|
+
export const Conversation = /*#__PURE__*/memo(ConversationInner);
|
|
399
|
+
|
|
400
|
+
// ---------------------------------------------------------------------------
|
|
401
|
+
// Styles
|
|
402
|
+
// ---------------------------------------------------------------------------
|
|
403
|
+
|
|
404
|
+
const styles = StyleSheet.create({
|
|
405
|
+
root: {
|
|
406
|
+
flex: 1
|
|
407
|
+
},
|
|
408
|
+
emptyFill: {
|
|
409
|
+
flex: 1
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
//# sourceMappingURL=Conversation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["React","memo","useCallback","useEffect","useImperativeHandle","useMemo","useRef","useState","FlatList","StyleSheet","View","useAIElementsTheme","Fragment","_Fragment","jsx","_jsx","STICK_TO_BOTTOM_THRESHOLD","SCROLL_RETRY_DELAY_MS","defaultIsUserMessage","m","role","findNewestUserMessage","messages","isUserMessage","order","find","i","length","undefined","ConversationInner","ref","renderMessage","emptyState","isStreaming","onIsAtBottomChange","scrollBehavior","style","viewProps","theme","listRef","isAtBottomRef","previousNaturalRef","naturalContentHeightRef","isStreamingRef","current","scrollBehaviorRef","lastUserMsgIdRef","naturalAtAnchorRef","onIsAtBottomChangeRef","lastEmittedIsAtBottomRef","scrollMetricsRef","contentOffset","layoutHeight","updateIsAtBottom","contentHeight","distanceFromBottom","isAtBottom","orderedMessages","reverse","chatAreaHeight","setChatAreaHeight","listPaddingBottom","setListPaddingBottom","handleAreaLayout","e","nativeEvent","layout","height","handleListContentSizeChange","_w","h","natural","Math","max","grew","behavior","desired","contentBelowAnchor","shouldFollow","requestAnimationFrame","scrollToEnd","animated","handleScroll","layoutMeasurement","contentSize","y","newestUserMsg","id","displayIndex","findIndex","scrollToIndex","index","viewPosition","opts","scrollToTop","scrollToOffset","offset","scrollToBottom","renderItem","item","children","keyExtractor","handleScrollToIndexFailed","info","averageItemLength","setTimeout","styles","root","onLayout","emptyFill","data","scrollEventThrottle","showsVerticalScrollIndicator","keyboardDismissMode","onScroll","onContentSizeChange","contentContainerStyle","paddingTop","spacing","lg","paddingBottom","onScrollToIndexFailed","displayName","Conversation","create","flex"],"sourceRoot":"../../../src","sources":["chatbot/Conversation.tsx"],"mappings":"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","ignoreList":[]}
|