@messenger-box/tailwind-ui-inbox 10.0.3-alpha.0
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/CHANGELOG.md +16 -0
- package/LICENSE +21 -0
- package/jest.config.js +9 -0
- package/lib/cdm-locales/en/translations.json +31 -0
- package/lib/cdm-locales/es/translations.json +31 -0
- package/lib/components/AIAgent/AIAgent.d.ts +32 -0
- package/lib/components/AIAgent/AIAgent.d.ts.map +1 -0
- package/lib/components/AIAgent/AIAgent.js +1135 -0
- package/lib/components/AIAgent/AIAgent.js.map +1 -0
- package/lib/components/AIAgent/InputComponent.d.ts +84 -0
- package/lib/components/AIAgent/InputComponent.d.ts.map +1 -0
- package/lib/components/AIAgent/InputComponent.js +417 -0
- package/lib/components/AIAgent/InputComponent.js.map +1 -0
- package/lib/components/AIAgent/index.d.ts +2 -0
- package/lib/components/AIAgent/index.d.ts.map +1 -0
- package/lib/components/InboxMessage/CommonMessage.d.ts +8 -0
- package/lib/components/InboxMessage/CommonMessage.d.ts.map +1 -0
- package/lib/components/InboxMessage/CommonMessage.js +35 -0
- package/lib/components/InboxMessage/CommonMessage.js.map +1 -0
- package/lib/components/InboxMessage/ConversationItem.d.ts +14 -0
- package/lib/components/InboxMessage/ConversationItem.d.ts.map +1 -0
- package/lib/components/InboxMessage/ConversationItem.js +200 -0
- package/lib/components/InboxMessage/ConversationItem.js.map +1 -0
- package/lib/components/InboxMessage/InputComponent.d.ts +20 -0
- package/lib/components/InboxMessage/InputComponent.d.ts.map +1 -0
- package/lib/components/InboxMessage/InputComponent.js +148 -0
- package/lib/components/InboxMessage/InputComponent.js.map +1 -0
- package/lib/components/InboxMessage/LeftSidebar.d.ts +20 -0
- package/lib/components/InboxMessage/LeftSidebar.d.ts.map +1 -0
- package/lib/components/InboxMessage/LeftSidebar.js +102 -0
- package/lib/components/InboxMessage/LeftSidebar.js.map +1 -0
- package/lib/components/InboxMessage/MessageInput.d.ts +9 -0
- package/lib/components/InboxMessage/MessageInput.d.ts.map +1 -0
- package/lib/components/InboxMessage/MessageInput.js +154 -0
- package/lib/components/InboxMessage/MessageInput.js.map +1 -0
- package/lib/components/InboxMessage/MessageInputComponent.d.ts +9 -0
- package/lib/components/InboxMessage/MessageInputComponent.d.ts.map +1 -0
- package/lib/components/InboxMessage/Messages.d.ts +17 -0
- package/lib/components/InboxMessage/Messages.d.ts.map +1 -0
- package/lib/components/InboxMessage/Messages.js +99 -0
- package/lib/components/InboxMessage/Messages.js.map +1 -0
- package/lib/components/InboxMessage/MessagesBuilderUi.d.ts +17 -0
- package/lib/components/InboxMessage/MessagesBuilderUi.d.ts.map +1 -0
- package/lib/components/InboxMessage/Popover.d.ts +3 -0
- package/lib/components/InboxMessage/Popover.d.ts.map +1 -0
- package/lib/components/InboxMessage/Popover.js +31 -0
- package/lib/components/InboxMessage/Popover.js.map +1 -0
- package/lib/components/InboxMessage/RightSidebar.d.ts +9 -0
- package/lib/components/InboxMessage/RightSidebar.d.ts.map +1 -0
- package/lib/components/InboxMessage/RightSidebar.js +9 -0
- package/lib/components/InboxMessage/RightSidebar.js.map +1 -0
- package/lib/components/InboxMessage/RightSidebarAi.d.ts +37 -0
- package/lib/components/InboxMessage/RightSidebarAi.d.ts.map +1 -0
- package/lib/components/InboxMessage/RightSidebarAi.js +9 -0
- package/lib/components/InboxMessage/RightSidebarAi.js.map +1 -0
- package/lib/components/InboxMessage/ServiceConversationItem.d.ts +12 -0
- package/lib/components/InboxMessage/ServiceConversationItem.d.ts.map +1 -0
- package/lib/components/InboxMessage/ServiceConversationItem.js +185 -0
- package/lib/components/InboxMessage/ServiceConversationItem.js.map +1 -0
- package/lib/components/InboxMessage/ServiceInboxItem.d.ts +12 -0
- package/lib/components/InboxMessage/ServiceInboxItem.d.ts.map +1 -0
- package/lib/components/InboxMessage/ServiceInboxItem.js +182 -0
- package/lib/components/InboxMessage/ServiceInboxItem.js.map +1 -0
- package/lib/components/InboxMessage/StreamingMessageBubble.d.ts +18 -0
- package/lib/components/InboxMessage/StreamingMessageBubble.d.ts.map +1 -0
- package/lib/components/InboxMessage/SubscriptionHandler.d.ts +19 -0
- package/lib/components/InboxMessage/SubscriptionHandler.d.ts.map +1 -0
- package/lib/components/InboxMessage/SubscriptionHandler.js +41 -0
- package/lib/components/InboxMessage/SubscriptionHandler.js.map +1 -0
- package/lib/components/InboxMessage/TypingIndicator.d.ts +11 -0
- package/lib/components/InboxMessage/TypingIndicator.d.ts.map +1 -0
- package/lib/components/InboxMessage/UploadImageButton.d.ts +7 -0
- package/lib/components/InboxMessage/UploadImageButton.d.ts.map +1 -0
- package/lib/components/InboxMessage/UploadImageButton.js +30 -0
- package/lib/components/InboxMessage/UploadImageButton.js.map +1 -0
- package/lib/components/InboxMessage/UserModalContent.d.ts +3 -0
- package/lib/components/InboxMessage/UserModalContent.d.ts.map +1 -0
- package/lib/components/InboxMessage/UserModalContent.js +60 -0
- package/lib/components/InboxMessage/UserModalContent.js.map +1 -0
- package/lib/components/InboxMessage/index.d.ts +19 -0
- package/lib/components/InboxMessage/index.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/CommonMessage.d.ts +11 -0
- package/lib/components/InboxMessage/message-widgets/CommonMessage.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/CommonMessage.js +44 -0
- package/lib/components/InboxMessage/message-widgets/CommonMessage.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts +10 -0
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.js +194 -0
- package/lib/components/InboxMessage/message-widgets/ErrorFixCard.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/MessageCard.d.ts +8 -0
- package/lib/components/InboxMessage/message-widgets/MessageCard.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.d.ts +12 -0
- package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.js +37 -0
- package/lib/components/InboxMessage/message-widgets/MessageSliceRenderer.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts +42 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js +1339 -0
- package/lib/components/InboxMessage/message-widgets/ModernMessageGroup.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/PlainMessage.d.ts +8 -0
- package/lib/components/InboxMessage/message-widgets/PlainMessage.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/PlainMessage.js +14 -0
- package/lib/components/InboxMessage/message-widgets/PlainMessage.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/PropertyMessageWidget.d.ts +9 -0
- package/lib/components/InboxMessage/message-widgets/PropertyMessageWidget.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.d.ts +14 -0
- package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.d.ts.map +1 -0
- package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.js +333 -0
- package/lib/components/InboxMessage/message-widgets/SlackLikeMessageGroup.js.map +1 -0
- package/lib/components/InboxMessage/message-widgets/index.d.ts +4 -0
- package/lib/components/InboxMessage/message-widgets/index.d.ts.map +1 -0
- package/lib/components/ModelConfigPanel.d.ts +74 -0
- package/lib/components/ModelConfigPanel.d.ts.map +1 -0
- package/lib/components/ModelConfigPanel.js +1152 -0
- package/lib/components/ModelConfigPanel.js.map +1 -0
- package/lib/components/filler-components/RightSiderBar.d.ts +3 -0
- package/lib/components/filler-components/RightSiderBar.d.ts.map +1 -0
- package/lib/components/filler-components/RightSiderBar.js +532 -0
- package/lib/components/filler-components/RightSiderBar.js.map +1 -0
- package/lib/components/inbox/FilesList.d.ts +20 -0
- package/lib/components/inbox/FilesList.d.ts.map +1 -0
- package/lib/components/inbox/FilesList.js +68 -0
- package/lib/components/inbox/FilesList.js.map +1 -0
- package/lib/components/inbox/MessageItem.d.ts +17 -0
- package/lib/components/inbox/MessageItem.d.ts.map +1 -0
- package/lib/components/inbox/MessageItem.js +50 -0
- package/lib/components/inbox/MessageItem.js.map +1 -0
- package/lib/components/inbox/ThreadItem.d.ts +11 -0
- package/lib/components/inbox/ThreadItem.d.ts.map +1 -0
- package/lib/components/inbox/ThreadItem.js +147 -0
- package/lib/components/inbox/ThreadItem.js.map +1 -0
- package/lib/components/inbox/index.d.ts +4 -0
- package/lib/components/inbox/index.d.ts.map +1 -0
- package/lib/components/index.d.ts +10 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/components/live-code-editor/hybrid-live-editor.d.ts +20 -0
- package/lib/components/live-code-editor/hybrid-live-editor.d.ts.map +1 -0
- package/lib/components/live-code-editor/index.d.ts +4 -0
- package/lib/components/live-code-editor/index.d.ts.map +1 -0
- package/lib/components/live-code-editor/live-code-editor.d.ts +14 -0
- package/lib/components/live-code-editor/live-code-editor.d.ts.map +1 -0
- package/lib/components/messages-container-ui/MessagesContainerUI.d.ts +81 -0
- package/lib/components/messages-container-ui/MessagesContainerUI.d.ts.map +1 -0
- package/lib/components/messages-container-ui/MessagesContainerUI.js +77 -0
- package/lib/components/messages-container-ui/MessagesContainerUI.js.map +1 -0
- package/lib/components/messages-container-ui/PlanModeView.d.ts +82 -0
- package/lib/components/messages-container-ui/PlanModeView.d.ts.map +1 -0
- package/lib/components/messages-container-ui/PlanModeView.js +267 -0
- package/lib/components/messages-container-ui/PlanModeView.js.map +1 -0
- package/lib/components/messages-container-ui/index.d.ts +6 -0
- package/lib/components/messages-container-ui/index.d.ts.map +1 -0
- package/lib/components/messages-container-ui/types.d.ts +38 -0
- package/lib/components/messages-container-ui/types.d.ts.map +1 -0
- package/lib/components/slot-fill/chat-message-filler.d.ts +4 -0
- package/lib/components/slot-fill/chat-message-filler.d.ts.map +1 -0
- package/lib/components/slot-fill/chat-message-filler.js +5 -0
- package/lib/components/slot-fill/chat-message-filler.js.map +1 -0
- package/lib/components/slot-fill/chat-message-slot.d.ts +11 -0
- package/lib/components/slot-fill/chat-message-slot.d.ts.map +1 -0
- package/lib/components/slot-fill/chat-message-slot.js +6 -0
- package/lib/components/slot-fill/chat-message-slot.js.map +1 -0
- package/lib/components/slot-fill/index.d.ts +4 -0
- package/lib/components/slot-fill/index.d.ts.map +1 -0
- package/lib/components/slot-fill/right-sidebar-filler.d.ts +4 -0
- package/lib/components/slot-fill/right-sidebar-filler.d.ts.map +1 -0
- package/lib/components/slot-fill/right-sidebar-filler.js +13 -0
- package/lib/components/slot-fill/right-sidebar-filler.js.map +1 -0
- package/lib/components/ui/button.d.ts +9 -0
- package/lib/components/ui/button.d.ts.map +1 -0
- package/lib/compute.d.ts +8 -0
- package/lib/compute.d.ts.map +1 -0
- package/lib/compute.js +264 -0
- package/lib/compute.js.map +1 -0
- package/lib/config/env-config.d.ts +20 -0
- package/lib/config/env-config.d.ts.map +1 -0
- package/lib/config/env-config.js +55 -0
- package/lib/config/env-config.js.map +1 -0
- package/lib/config/index.d.ts +2 -0
- package/lib/config/index.d.ts.map +1 -0
- package/lib/constants/breakpoints.d.ts +8 -0
- package/lib/constants/breakpoints.d.ts.map +1 -0
- package/lib/constants/index.d.ts +3 -0
- package/lib/constants/index.d.ts.map +1 -0
- package/lib/container/AiInbox.d.ts +15 -0
- package/lib/container/AiInbox.d.ts.map +1 -0
- package/lib/container/AiInboxWithLoader.d.ts +36 -0
- package/lib/container/AiInboxWithLoader.d.ts.map +1 -0
- package/lib/container/AiLandingInput.d.ts +27 -0
- package/lib/container/AiLandingInput.d.ts.map +1 -0
- package/lib/container/AiLandingInput.js +149 -0
- package/lib/container/AiLandingInput.js.map +1 -0
- package/lib/container/Inbox.d.ts +15 -0
- package/lib/container/Inbox.d.ts.map +1 -0
- package/lib/container/Inbox.js +964 -0
- package/lib/container/Inbox.js.map +1 -0
- package/lib/container/InboxAiMessagesLoader.d.ts +45 -0
- package/lib/container/InboxAiMessagesLoader.d.ts.map +1 -0
- package/lib/container/InboxAiMessagesLoader.js +80 -0
- package/lib/container/InboxAiMessagesLoader.js.map +1 -0
- package/lib/container/InboxContainer.d.ts +41 -0
- package/lib/container/InboxContainer.d.ts.map +1 -0
- package/lib/container/InboxContainer.js +27 -0
- package/lib/container/InboxContainer.js.map +1 -0
- package/lib/container/InboxTemplate1.d.ts +15 -0
- package/lib/container/InboxTemplate1.d.ts.map +1 -0
- package/lib/container/InboxTemplate1WithLoader.d.ts +36 -0
- package/lib/container/InboxTemplate1WithLoader.d.ts.map +1 -0
- package/lib/container/InboxTemplate2.d.ts +15 -0
- package/lib/container/InboxTemplate2.d.ts.map +1 -0
- package/lib/container/InboxWithAiLoader.d.ts +47 -0
- package/lib/container/InboxWithAiLoader.d.ts.map +1 -0
- package/lib/container/InboxWithAiLoader.js +118 -0
- package/lib/container/InboxWithAiLoader.js.map +1 -0
- package/lib/container/InboxWithLoader.d.ts +36 -0
- package/lib/container/InboxWithLoader.d.ts.map +1 -0
- package/lib/container/InboxWithLoader.js +277 -0
- package/lib/container/InboxWithLoader.js.map +1 -0
- package/lib/container/ServiceInbox.d.ts +9 -0
- package/lib/container/ServiceInbox.d.ts.map +1 -0
- package/lib/container/ServiceInbox.js +141 -0
- package/lib/container/ServiceInbox.js.map +1 -0
- package/lib/container/TestInboxWithAiLoader.d.ts +7 -0
- package/lib/container/TestInboxWithAiLoader.d.ts.map +1 -0
- package/lib/container/TestInboxWithAiLoader.js +135 -0
- package/lib/container/TestInboxWithAiLoader.js.map +1 -0
- package/lib/container/ThreadMessages.d.ts +13 -0
- package/lib/container/ThreadMessages.d.ts.map +1 -0
- package/lib/container/ThreadMessages.js +320 -0
- package/lib/container/ThreadMessages.js.map +1 -0
- package/lib/container/ThreadMessagesInbox.d.ts +14 -0
- package/lib/container/ThreadMessagesInbox.d.ts.map +1 -0
- package/lib/container/ThreadMessagesInbox.js +347 -0
- package/lib/container/ThreadMessagesInbox.js.map +1 -0
- package/lib/container/Threads.d.ts +8 -0
- package/lib/container/Threads.d.ts.map +1 -0
- package/lib/container/Threads.js +231 -0
- package/lib/container/Threads.js.map +1 -0
- package/lib/container/ThreadsInbox.d.ts +21 -0
- package/lib/container/ThreadsInbox.d.ts.map +1 -0
- package/lib/container/ThreadsInbox.js +243 -0
- package/lib/container/ThreadsInbox.js.map +1 -0
- package/lib/container/apply-footer-styles.d.ts +2 -0
- package/lib/container/apply-footer-styles.d.ts.map +1 -0
- package/lib/container/apply-footer-styles.js +16 -0
- package/lib/container/apply-footer-styles.js.map +1 -0
- package/lib/container/index.d.ts +13 -0
- package/lib/container/index.d.ts.map +1 -0
- package/lib/enums/index.d.ts +2 -0
- package/lib/enums/index.d.ts.map +1 -0
- package/lib/enums/messenger-slot-fill-name-enum.d.ts +11 -0
- package/lib/enums/messenger-slot-fill-name-enum.d.ts.map +1 -0
- package/lib/enums/messenger-slot-fill-name-enum.js +11 -0
- package/lib/enums/messenger-slot-fill-name-enum.js.map +1 -0
- package/lib/hooks/index.d.ts +4 -0
- package/lib/hooks/index.d.ts.map +1 -0
- package/lib/hooks/usePersistentModelConfig.d.ts +33 -0
- package/lib/hooks/usePersistentModelConfig.d.ts.map +1 -0
- package/lib/hooks/usePersistentModelConfig.js +123 -0
- package/lib/hooks/usePersistentModelConfig.js.map +1 -0
- package/lib/hooks/useStreamAssembler.d.ts +8 -0
- package/lib/hooks/useStreamAssembler.d.ts.map +1 -0
- package/lib/hooks/useTemplates.d.ts +14 -0
- package/lib/hooks/useTemplates.d.ts.map +1 -0
- package/lib/hooks/useTemplates.js +59 -0
- package/lib/hooks/useTemplates.js.map +1 -0
- package/lib/index.d.ts +14 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/interfaces/index.d.ts +2 -0
- package/lib/interfaces/index.d.ts.map +1 -0
- package/lib/interfaces/message-widgets.interface.d.ts +21 -0
- package/lib/interfaces/message-widgets.interface.d.ts.map +1 -0
- package/lib/machines/aiAgentMachine.d.ts +3 -0
- package/lib/machines/aiAgentMachine.d.ts.map +1 -0
- package/lib/machines/aiAgentMachine.js +1083 -0
- package/lib/machines/aiAgentMachine.js.map +1 -0
- package/lib/machines/aiAgentMachine.simple.d.ts +3 -0
- package/lib/machines/aiAgentMachine.simple.d.ts.map +1 -0
- package/lib/machines/aiAgentMachine.simple.js +108 -0
- package/lib/machines/aiAgentMachine.simple.js.map +1 -0
- package/lib/machines/index.d.ts +3 -0
- package/lib/machines/index.d.ts.map +1 -0
- package/lib/machines/types.d.ts +77 -0
- package/lib/machines/types.d.ts.map +1 -0
- package/lib/module.d.ts +7 -0
- package/lib/module.d.ts.map +1 -0
- package/lib/module.js +26 -0
- package/lib/module.js.map +1 -0
- package/lib/routes.json +251 -0
- package/lib/styles/responsive.css +76 -0
- package/lib/templates/InboxWithAi.d.ts +44 -0
- package/lib/templates/InboxWithAi.d.ts.map +1 -0
- package/lib/templates/InboxWithAi.js +651 -0
- package/lib/templates/InboxWithAi.js.map +1 -0
- package/lib/templates/InboxWithAi.tsx +844 -0
- package/lib/templates/index.d.ts +2 -0
- package/lib/templates/index.d.ts.map +1 -0
- package/lib/templates/index.ts +1 -0
- package/lib/types/templates.d.ts +35 -0
- package/lib/types/templates.d.ts.map +1 -0
- package/lib/utils/utils.d.ts +2 -0
- package/lib/utils/utils.d.ts.map +1 -0
- package/lib/xstate/index.d.ts +3 -0
- package/lib/xstate/index.d.ts.map +1 -0
- package/lib/xstate/rightSidebar.machine.d.ts +4 -0
- package/lib/xstate/rightSidebar.machine.d.ts.map +1 -0
- package/lib/xstate/rightSidebar.types.d.ts +57 -0
- package/lib/xstate/rightSidebar.types.d.ts.map +1 -0
- package/package.json +69 -0
- package/rollup.config.mjs +47 -0
- package/src/cdm-locales/en/translations.json +31 -0
- package/src/cdm-locales/es/translations.json +31 -0
- package/src/components/AIAgent/AIAgent.tsx +1468 -0
- package/src/components/AIAgent/AIAgent.tsx.bk +1365 -0
- package/src/components/AIAgent/InputComponent.tsx +608 -0
- package/src/components/AIAgent/README.md +174 -0
- package/src/components/AIAgent/index.ts +1 -0
- package/src/components/InboxMessage/CommonMessage.tsx +40 -0
- package/src/components/InboxMessage/ConversationItem.tsx +255 -0
- package/src/components/InboxMessage/InputComponent.tsx +198 -0
- package/src/components/InboxMessage/LeftSidebar.tsx +140 -0
- package/src/components/InboxMessage/MessageInput.tsx +209 -0
- package/src/components/InboxMessage/MessageInputComponent.tsx +245 -0
- package/src/components/InboxMessage/Messages.tsx +137 -0
- package/src/components/InboxMessage/MessagesBuilderUi.tsx +205 -0
- package/src/components/InboxMessage/Popover.tsx +42 -0
- package/src/components/InboxMessage/RightSidebar.tsx +22 -0
- package/src/components/InboxMessage/RightSidebarAi.tsx +47 -0
- package/src/components/InboxMessage/ServiceConversationItem.tsx +234 -0
- package/src/components/InboxMessage/ServiceInboxItem.tsx +223 -0
- package/src/components/InboxMessage/StreamingMessageBubble.tsx +270 -0
- package/src/components/InboxMessage/SubscriptionHandler.tsx +55 -0
- package/src/components/InboxMessage/TypingIndicator.tsx +38 -0
- package/src/components/InboxMessage/UploadImageButton.tsx +46 -0
- package/src/components/InboxMessage/UserModalContent.tsx +60 -0
- package/src/components/InboxMessage/index.ts +18 -0
- package/src/components/InboxMessage/message-widgets/CommonMessage.tsx +69 -0
- package/src/components/InboxMessage/message-widgets/ErrorFixCard.tsx +239 -0
- package/src/components/InboxMessage/message-widgets/MessageCard.tsx +127 -0
- package/src/components/InboxMessage/message-widgets/MessageSliceRenderer.tsx +40 -0
- package/src/components/InboxMessage/message-widgets/ModernMessageGroup.tsx +1733 -0
- package/src/components/InboxMessage/message-widgets/PlainMessage.tsx +18 -0
- package/src/components/InboxMessage/message-widgets/PropertyMessageWidget.tsx +29 -0
- package/src/components/InboxMessage/message-widgets/SlackLikeMessageGroup.tsx +492 -0
- package/src/components/InboxMessage/message-widgets/index.ts +8 -0
- package/src/components/ModelConfigPanel.tsx +1357 -0
- package/src/components/filler-components/RightSiderBar.tsx +572 -0
- package/src/components/inbox/FilesList.tsx +89 -0
- package/src/components/inbox/MessageItem.tsx +50 -0
- package/src/components/inbox/ThreadItem.tsx +295 -0
- package/src/components/inbox/index.ts +3 -0
- package/src/components/index.ts +29 -0
- package/src/components/live-code-editor/hybrid-live-editor.tsx +105 -0
- package/src/components/live-code-editor/index.ts +3 -0
- package/src/components/live-code-editor/live-code-editor.tsx +257 -0
- package/src/components/messages-container-ui/MessagesContainerUI.tsx +151 -0
- package/src/components/messages-container-ui/PlanModeView.tsx +426 -0
- package/src/components/messages-container-ui/README.md +91 -0
- package/src/components/messages-container-ui/index.ts +5 -0
- package/src/components/messages-container-ui/types.ts +40 -0
- package/src/components/slot-fill/chat-message-filler.tsx +18 -0
- package/src/components/slot-fill/chat-message-slot.tsx +18 -0
- package/src/components/slot-fill/index.ts +3 -0
- package/src/components/slot-fill/right-sidebar-filler.tsx +48 -0
- package/src/components/ui/button.tsx +32 -0
- package/src/compute.ts +271 -0
- package/src/config/env-config.ts +24 -0
- package/src/config/index.ts +1 -0
- package/src/constants/breakpoints.ts +7 -0
- package/src/constants/index.ts +5 -0
- package/src/container/AiInbox.tsx +1879 -0
- package/src/container/AiInboxWithLoader.tsx +356 -0
- package/src/container/AiLandingInput.tsx +200 -0
- package/src/container/Inbox.tsx +1095 -0
- package/src/container/InboxAiMessagesLoader.tsx +129 -0
- package/src/container/InboxContainer.tsx +61 -0
- package/src/container/InboxTemplate1.tsx +1553 -0
- package/src/container/InboxTemplate1WithLoader.tsx +338 -0
- package/src/container/InboxTemplate2.tsx +1617 -0
- package/src/container/InboxWithAiLoader.tsx +177 -0
- package/src/container/InboxWithLoader.tsx +341 -0
- package/src/container/ServiceInbox.tsx +188 -0
- package/src/container/TestInboxWithAiLoader.tsx +147 -0
- package/src/container/ThreadMessages.tsx +378 -0
- package/src/container/ThreadMessagesInbox.tsx +457 -0
- package/src/container/Threads.tsx +270 -0
- package/src/container/ThreadsInbox.tsx +351 -0
- package/src/container/apply-footer-styles.ts +17 -0
- package/src/container/index.ts +31 -0
- package/src/enums/index.ts +1 -0
- package/src/enums/messenger-slot-fill-name-enum.ts +10 -0
- package/src/hooks/index.ts +3 -0
- package/src/hooks/usePersistentModelConfig.ts +166 -0
- package/src/hooks/useStreamAssembler.ts +7 -0
- package/src/hooks/useTemplates.ts +75 -0
- package/src/index.ts +49 -0
- package/src/interfaces/index.ts +1 -0
- package/src/interfaces/message-widgets.interface.ts +21 -0
- package/src/machines/aiAgentMachine.simple.ts +89 -0
- package/src/machines/aiAgentMachine.ts +1296 -0
- package/src/machines/aiAgentMachine.ts.bk +1296 -0
- package/src/machines/index.ts +2 -0
- package/src/machines/types.ts +59 -0
- package/src/module.tsx +32 -0
- package/src/styles/responsive.css +76 -0
- package/src/templates/InboxWithAi.tsx +844 -0
- package/src/templates/index.ts +1 -0
- package/src/types/templates.ts +35 -0
- package/src/utils/utils.ts +3 -0
- package/src/xstate/index.ts +2 -0
- package/src/xstate/rightSidebar.machine.ts +304 -0
- package/src/xstate/rightSidebar.types.ts +58 -0
- package/tsconfig.json +14 -0
- package/webpack.config.js +92 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { useLocation } from '@remix-run/react';
|
|
3
|
+
import {
|
|
4
|
+
useThreadMessagesQuery,
|
|
5
|
+
useOnThreadChatMessageAddedSubscription,
|
|
6
|
+
useOnThreadCreatedUpdatedSubscription,
|
|
7
|
+
OnThreadCreatedUpdatedDocument as THREAD_CHAT_ADDED,
|
|
8
|
+
OnThreadChatMessageAddedDocument as CHAT_MESSAGE_ADDED,
|
|
9
|
+
} from 'common/graphql';
|
|
10
|
+
import { format, isToday, isYesterday } from 'date-fns';
|
|
11
|
+
|
|
12
|
+
const createdAtText = (value) => {
|
|
13
|
+
if (!value) return '';
|
|
14
|
+
let date = new Date(value);
|
|
15
|
+
if (isToday(date)) return 'Today';
|
|
16
|
+
if (isYesterday(date)) return 'Yesterday';
|
|
17
|
+
return format(new Date(value), 'MMM dd, yyyy');
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const ServiceInboxItemComponent = ({
|
|
21
|
+
showBorder,
|
|
22
|
+
currentUser,
|
|
23
|
+
filter,
|
|
24
|
+
channel,
|
|
25
|
+
handleSelectChannel,
|
|
26
|
+
users,
|
|
27
|
+
selectedChannelId,
|
|
28
|
+
role,
|
|
29
|
+
}) => {
|
|
30
|
+
const [parentId, setParentId] = React.useState<any>(null);
|
|
31
|
+
const [messages, setMessages] = React.useState([]);
|
|
32
|
+
const [servicePostParentId, setServicePostParentId] = React.useState(null);
|
|
33
|
+
const { pathname } = useLocation();
|
|
34
|
+
const {
|
|
35
|
+
data: threadMessages,
|
|
36
|
+
loading: threadMessageLoading,
|
|
37
|
+
fetchMore: fetchMoreMessages,
|
|
38
|
+
refetch: refetchThreadMessages,
|
|
39
|
+
subscribeToMore,
|
|
40
|
+
} = useThreadMessagesQuery({
|
|
41
|
+
variables: {
|
|
42
|
+
channelId: channel?.id?.toString(),
|
|
43
|
+
role,
|
|
44
|
+
limit: 10,
|
|
45
|
+
},
|
|
46
|
+
fetchPolicy: 'cache-and-network',
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
React.useEffect(() => {
|
|
50
|
+
if (channel) refetchThreadMessages({ channelId: channel?.id?.toString(), role, limit: 10 });
|
|
51
|
+
}, [channel, pathname]);
|
|
52
|
+
|
|
53
|
+
React.useEffect(() => {
|
|
54
|
+
if (threadMessages?.threadMessages?.data?.length) {
|
|
55
|
+
const { data }: any = threadMessages.threadMessages;
|
|
56
|
+
const replies =
|
|
57
|
+
data
|
|
58
|
+
?.map((t: any) => t?.replies)
|
|
59
|
+
?.flat(1)
|
|
60
|
+
?.filter((p: any) => p?.message !== '') ?? [];
|
|
61
|
+
const post =
|
|
62
|
+
data?.find((t: any) => {
|
|
63
|
+
return t?.post?.message !== '';
|
|
64
|
+
}) ??
|
|
65
|
+
data?.find((t: any) => {
|
|
66
|
+
return t?.post;
|
|
67
|
+
}) ??
|
|
68
|
+
null;
|
|
69
|
+
|
|
70
|
+
if (replies?.length) {
|
|
71
|
+
setMessages((pre: any) => [...pre, ...replies]);
|
|
72
|
+
} else if (post) {
|
|
73
|
+
setMessages((pre: any) => [...pre, ...[post]]);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}, [threadMessages]);
|
|
77
|
+
|
|
78
|
+
const lastMessage = useMemo(() => {
|
|
79
|
+
if (!messages?.length) {
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
let filteredLastMessage =
|
|
84
|
+
messages && messages?.length
|
|
85
|
+
? messages?.reduce((a, b) => {
|
|
86
|
+
return new Date(a?.updatedAt) > new Date(b?.updatedAt) ? a : b;
|
|
87
|
+
}, []) ?? null
|
|
88
|
+
: null;
|
|
89
|
+
return filteredLastMessage;
|
|
90
|
+
}, [messages]);
|
|
91
|
+
|
|
92
|
+
React.useEffect(() => {
|
|
93
|
+
if (lastMessage) {
|
|
94
|
+
const sParentId = lastMessage?.parentId ? lastMessage?.parentId : lastMessage?.id;
|
|
95
|
+
setServicePostParentId(sParentId);
|
|
96
|
+
}
|
|
97
|
+
}, [lastMessage]);
|
|
98
|
+
|
|
99
|
+
const creatorAndMembersId = React.useMemo(() => {
|
|
100
|
+
if (!channel?.members) return null;
|
|
101
|
+
const membersIds: any =
|
|
102
|
+
channel?.members?.filter((m: any) => m?.user?.id !== currentUser?.id)?.map((mu: any) => mu?.user?.id) ?? [];
|
|
103
|
+
const creatorId: any = channel?.creator?.id;
|
|
104
|
+
const mergedIds: any = [].concat(membersIds, creatorId) ?? [];
|
|
105
|
+
return mergedIds?.filter((m: any, pos: any) => mergedIds?.indexOf(m) === pos) ?? [];
|
|
106
|
+
}, [channel]);
|
|
107
|
+
|
|
108
|
+
const postParentId = React.useMemo(() => {
|
|
109
|
+
if (!creatorAndMembersId?.length) return null;
|
|
110
|
+
|
|
111
|
+
return creatorAndMembersId?.length && creatorAndMembersId?.includes(currentUser?.id)
|
|
112
|
+
? 1
|
|
113
|
+
: lastMessage?.parentId
|
|
114
|
+
? lastMessage?.parentId
|
|
115
|
+
: lastMessage?.id ?? 0;
|
|
116
|
+
}, [creatorAndMembersId, lastMessage]);
|
|
117
|
+
|
|
118
|
+
React.useEffect(() => {
|
|
119
|
+
if (postParentId) {
|
|
120
|
+
setParentId(postParentId);
|
|
121
|
+
}
|
|
122
|
+
}, [postParentId]);
|
|
123
|
+
|
|
124
|
+
const channelType = useMemo(() => {
|
|
125
|
+
return channel?.type;
|
|
126
|
+
}, [channel]);
|
|
127
|
+
|
|
128
|
+
return (
|
|
129
|
+
<div
|
|
130
|
+
key={`services_channel_${channel.id}`}
|
|
131
|
+
className={`
|
|
132
|
+
cursor-pointer flex items-center p-3
|
|
133
|
+
border-b border-solid
|
|
134
|
+
${showBorder ? 'border-gray-300' : 'border-transparent'}
|
|
135
|
+
${channel.id == selectedChannelId ? 'bg-gray-300 dark:bg-gray-500' : ''}
|
|
136
|
+
hover:bg-gray-100 dark:hover:bg-gray-600 transition-colors
|
|
137
|
+
`}
|
|
138
|
+
onClick={() => handleSelectChannel(channel.id, postParentId)}
|
|
139
|
+
>
|
|
140
|
+
<img
|
|
141
|
+
className="w-10 h-10 rounded-full bg-gray-400"
|
|
142
|
+
src={channel?.creator?.picture || '/default-avatar.svg'}
|
|
143
|
+
alt="Avatar"
|
|
144
|
+
onError={(e) => {
|
|
145
|
+
if (e.currentTarget.src.includes('default-avatar.svg')) {
|
|
146
|
+
e.currentTarget.src =
|
|
147
|
+
'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNDAiIGhlaWdodD0iNDAiIHZpZXdCb3g9IjAgMCA0MCA0MCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KICA8Y2lyY2xlIGN4PSIyMCIgY3k9IjIwIiByPSIyMCIgZmlsbD0iI0U1RTdFQiIvPgogIDxjaXJjbGUgY3g9IjIwIiBjeT0iMTYiIHI9IjYiIGZpbGw9IiM5Q0EzQUYiLz4KICA8cGF0aCBkPSJNOCAzMmMwLTYuNjI3IDUuMzczLTEyIDEyLTEyczEyIDUuMzczIDEyIDEyIiBmaWxsPSIjOUNBM0FGIi8+Cjwvc3ZnPgo=';
|
|
148
|
+
} else {
|
|
149
|
+
e.currentTarget.src = '/default-avatar.svg';
|
|
150
|
+
}
|
|
151
|
+
}}
|
|
152
|
+
/>
|
|
153
|
+
|
|
154
|
+
<div className="ml-2 flex-grow min-w-10 max-w-96">
|
|
155
|
+
{threadMessageLoading && (
|
|
156
|
+
<div className="animate-pulse">
|
|
157
|
+
<div className="h-4 bg-gray-300 rounded mb-2"></div>
|
|
158
|
+
<div className="h-3 bg-gray-300 rounded w-3/4 mb-2"></div>
|
|
159
|
+
<div className="h-3 bg-gray-300 rounded w-1/2"></div>
|
|
160
|
+
</div>
|
|
161
|
+
)}
|
|
162
|
+
{!threadMessageLoading && (
|
|
163
|
+
<ServiceLastMessageComponent
|
|
164
|
+
channel={channel}
|
|
165
|
+
channelType={channelType}
|
|
166
|
+
lastMessage={lastMessage}
|
|
167
|
+
subscribeToNewMessages={() =>
|
|
168
|
+
subscribeToMore({
|
|
169
|
+
document: THREAD_CHAT_ADDED,
|
|
170
|
+
variables: {
|
|
171
|
+
channelId: channel?.id?.toString(),
|
|
172
|
+
postParentId: postParentId && postParentId == 1 ? null : servicePostParentId,
|
|
173
|
+
},
|
|
174
|
+
updateQuery: (prev, { subscriptionData }: any) => {
|
|
175
|
+
if (!subscriptionData.data) return prev;
|
|
176
|
+
|
|
177
|
+
const newPostThreadData: any = subscriptionData?.data?.threadCreatedUpdated?.data;
|
|
178
|
+
const newMessage: any = subscriptionData?.data?.threadCreatedUpdated?.lastMessage;
|
|
179
|
+
const data = prev?.threadMessages?.data?.map((t: any) =>
|
|
180
|
+
t.id === newPostThreadData?.id
|
|
181
|
+
? {
|
|
182
|
+
...t,
|
|
183
|
+
replies: [...t?.replies, newMessage],
|
|
184
|
+
replyCount: newPostThreadData?.replyCount,
|
|
185
|
+
lastReplyAt: newPostThreadData?.lastReplyAt,
|
|
186
|
+
updatedAt: newPostThreadData?.updatedAt,
|
|
187
|
+
}
|
|
188
|
+
: t,
|
|
189
|
+
);
|
|
190
|
+
|
|
191
|
+
return Object.assign({}, prev, {
|
|
192
|
+
threadMessages: {
|
|
193
|
+
...prev?.threadMessages,
|
|
194
|
+
data: data,
|
|
195
|
+
},
|
|
196
|
+
});
|
|
197
|
+
},
|
|
198
|
+
})
|
|
199
|
+
}
|
|
200
|
+
/>
|
|
201
|
+
)}
|
|
202
|
+
</div>
|
|
203
|
+
</div>
|
|
204
|
+
);
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
export const ServiceInboxItem = React.memo(ServiceInboxItemComponent);
|
|
208
|
+
|
|
209
|
+
const ServiceLastMessageComponent = ({ subscribeToNewMessages, channel, channelType, lastMessage }) => {
|
|
210
|
+
React.useEffect(() => subscribeToNewMessages(), []);
|
|
211
|
+
return (
|
|
212
|
+
<div className="flex flex-col w-full">
|
|
213
|
+
<div className="w-full flex justify-between items-center">
|
|
214
|
+
<span className="text-xs text-green-500 truncate">{channelType}</span>
|
|
215
|
+
<span className="text-xs text-gray-500">
|
|
216
|
+
{lastMessage ? createdAtText(lastMessage?.createdAt) : ''}
|
|
217
|
+
</span>
|
|
218
|
+
</div>
|
|
219
|
+
<h3 className="text-sm text-gray-600 dark:text-gray-300 font-bold mt-1">{channel?.title}</h3>
|
|
220
|
+
<p className="text-sm text-gray-600 dark:text-gray-400 truncate w-4/5 mt-1">{lastMessage?.message}</p>
|
|
221
|
+
</div>
|
|
222
|
+
);
|
|
223
|
+
};
|
|
@@ -0,0 +1,270 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { ActiveStream } from '../../hooks/useStreamAssembler';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Renders a message bubble for an active (in-progress) stream.
|
|
6
|
+
* Shows:
|
|
7
|
+
* - The author name
|
|
8
|
+
* - The accumulated text so far (with basic markdown rendering)
|
|
9
|
+
* - A blinking cursor at the end
|
|
10
|
+
* - A "thinking" state with animated dots when status is 'thinking'
|
|
11
|
+
* - Chunk counter for transparency
|
|
12
|
+
*/
|
|
13
|
+
export const StreamingMessageBubble: React.FC<{
|
|
14
|
+
stream: ActiveStream;
|
|
15
|
+
isDesktopView?: boolean;
|
|
16
|
+
isSmallScreen?: boolean;
|
|
17
|
+
}> = ({ stream, isDesktopView = false, isSmallScreen = false }) => {
|
|
18
|
+
const authorName =
|
|
19
|
+
stream.author?.givenName && stream.author?.familyName
|
|
20
|
+
? `${stream.author.givenName} ${stream.author.familyName}`
|
|
21
|
+
: stream.author?.username || 'AI Assistant';
|
|
22
|
+
|
|
23
|
+
const isThinking = stream.status === 'thinking' && !stream.text.trim();
|
|
24
|
+
const elapsed = useMemo(() => {
|
|
25
|
+
const secs = Math.floor((Date.now() - stream.startedAt) / 1000);
|
|
26
|
+
return secs;
|
|
27
|
+
}, [stream.chunks]); // recalc on each chunk
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<div
|
|
31
|
+
className={`group rounded transition-colors ${
|
|
32
|
+
isDesktopView ? 'mb-8 -mx-6 px-6 py-4' : isSmallScreen ? 'mb-4 -mx-2 px-2 py-2' : 'mb-6 -mx-4 px-4 py-3'
|
|
33
|
+
}`}
|
|
34
|
+
>
|
|
35
|
+
<div
|
|
36
|
+
className={`flex items-start ${
|
|
37
|
+
isDesktopView ? 'space-x-4' : isSmallScreen ? 'space-x-2' : 'space-x-3'
|
|
38
|
+
}`}
|
|
39
|
+
>
|
|
40
|
+
{/* Pulsing indicator instead of avatar */}
|
|
41
|
+
<div className="flex-shrink-0 mt-0.5">
|
|
42
|
+
<div
|
|
43
|
+
className={`rounded-lg bg-gradient-to-br from-blue-400 to-purple-500 flex items-center justify-center text-white text-xs font-bold ${
|
|
44
|
+
isDesktopView ? 'w-12 h-12' : isSmallScreen ? 'w-8 h-8' : 'w-10 h-10'
|
|
45
|
+
}`}
|
|
46
|
+
>
|
|
47
|
+
<span className="animate-pulse">✨</span>
|
|
48
|
+
</div>
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
<div className="flex-1 min-w-0 overflow-hidden">
|
|
52
|
+
{/* Author + streaming badge */}
|
|
53
|
+
<div className="flex items-center space-x-2 mb-1">
|
|
54
|
+
<span className="text-sm font-semibold text-gray-900 truncate">{authorName}</span>
|
|
55
|
+
<span className="inline-flex items-center px-1.5 py-0.5 rounded-full text-[10px] font-medium bg-blue-100 text-blue-700">
|
|
56
|
+
<span className="w-1.5 h-1.5 bg-blue-500 rounded-full mr-1 animate-pulse" />
|
|
57
|
+
typing
|
|
58
|
+
</span>
|
|
59
|
+
</div>
|
|
60
|
+
|
|
61
|
+
{/* Content area */}
|
|
62
|
+
<div className="py-1 px-1 sm:px-2">
|
|
63
|
+
{isThinking ? (
|
|
64
|
+
<div className="flex items-center space-x-2 text-gray-500">
|
|
65
|
+
<div className="flex space-x-1">
|
|
66
|
+
<span
|
|
67
|
+
className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"
|
|
68
|
+
style={{ animationDelay: '0s' }}
|
|
69
|
+
/>
|
|
70
|
+
<span
|
|
71
|
+
className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"
|
|
72
|
+
style={{ animationDelay: '0.15s' }}
|
|
73
|
+
/>
|
|
74
|
+
<span
|
|
75
|
+
className="w-2 h-2 bg-gray-400 rounded-full animate-bounce"
|
|
76
|
+
style={{ animationDelay: '0.3s' }}
|
|
77
|
+
/>
|
|
78
|
+
</div>
|
|
79
|
+
<span className="text-xs text-gray-400 italic">Thinking…</span>
|
|
80
|
+
</div>
|
|
81
|
+
) : (
|
|
82
|
+
<div className="text-sm text-gray-900 break-words leading-relaxed">
|
|
83
|
+
<StreamingContent text={stream.text} />
|
|
84
|
+
{/* Blinking cursor */}
|
|
85
|
+
{stream.status !== 'end' && (
|
|
86
|
+
<span
|
|
87
|
+
className="inline-block w-0.5 h-4 bg-blue-500 ml-0.5 align-text-bottom"
|
|
88
|
+
style={{ animation: 'cursorBlink 1s step-end infinite' }}
|
|
89
|
+
/>
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
)}
|
|
93
|
+
</div>
|
|
94
|
+
|
|
95
|
+
{/* Progress footer */}
|
|
96
|
+
{stream.chunks > 1 && (
|
|
97
|
+
<div className="flex items-center space-x-3 mt-1 px-1 sm:px-2">
|
|
98
|
+
<div className="flex-1 h-0.5 bg-gray-100 rounded-full overflow-hidden">
|
|
99
|
+
<div
|
|
100
|
+
className="h-full bg-blue-400 rounded-full transition-all duration-300 animate-pulse"
|
|
101
|
+
style={{ width: stream.status === 'end' ? '100%' : '60%' }}
|
|
102
|
+
/>
|
|
103
|
+
</div>
|
|
104
|
+
<span className="text-[10px] text-gray-400 tabular-nums">{stream.chunks} chunks</span>
|
|
105
|
+
</div>
|
|
106
|
+
)}
|
|
107
|
+
</div>
|
|
108
|
+
</div>
|
|
109
|
+
|
|
110
|
+
<style>{`
|
|
111
|
+
@keyframes cursorBlink {
|
|
112
|
+
0%, 100% { opacity: 1; }
|
|
113
|
+
50% { opacity: 0; }
|
|
114
|
+
}
|
|
115
|
+
`}</style>
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Renders streaming text with basic markdown support.
|
|
122
|
+
* Handles fenced code blocks, bold, inline code, headings, and lists.
|
|
123
|
+
*/
|
|
124
|
+
const StreamingContent: React.FC<{ text: string }> = ({ text }) => {
|
|
125
|
+
if (!text) return null;
|
|
126
|
+
|
|
127
|
+
// Simple markdown-to-JSX for streaming (must handle partial fences)
|
|
128
|
+
const lines = text.split('\n');
|
|
129
|
+
const elements: React.ReactNode[] = [];
|
|
130
|
+
let inCodeBlock = false;
|
|
131
|
+
let codeLanguage = '';
|
|
132
|
+
let codeLines: string[] = [];
|
|
133
|
+
|
|
134
|
+
for (let i = 0; i < lines.length; i++) {
|
|
135
|
+
const line = lines[i];
|
|
136
|
+
|
|
137
|
+
// Detect code fence open/close
|
|
138
|
+
if (line.trimStart().startsWith('```')) {
|
|
139
|
+
if (!inCodeBlock) {
|
|
140
|
+
inCodeBlock = true;
|
|
141
|
+
codeLanguage = line.trimStart().slice(3).trim();
|
|
142
|
+
codeLines = [];
|
|
143
|
+
continue;
|
|
144
|
+
} else {
|
|
145
|
+
// Close fence
|
|
146
|
+
elements.push(
|
|
147
|
+
<div key={`code-${i}`} className="my-2 border border-gray-200 rounded overflow-hidden">
|
|
148
|
+
{codeLanguage && (
|
|
149
|
+
<div className="px-3 py-1 text-[10px] font-semibold uppercase tracking-wide bg-gray-100 text-gray-600">
|
|
150
|
+
{codeLanguage}
|
|
151
|
+
</div>
|
|
152
|
+
)}
|
|
153
|
+
<div className="bg-gray-900 p-3 overflow-x-auto">
|
|
154
|
+
<pre className="text-xs text-gray-100 font-mono leading-relaxed">
|
|
155
|
+
<code>{codeLines.join('\n')}</code>
|
|
156
|
+
</pre>
|
|
157
|
+
</div>
|
|
158
|
+
</div>,
|
|
159
|
+
);
|
|
160
|
+
inCodeBlock = false;
|
|
161
|
+
codeLanguage = '';
|
|
162
|
+
codeLines = [];
|
|
163
|
+
continue;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (inCodeBlock) {
|
|
168
|
+
codeLines.push(line);
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Headings
|
|
173
|
+
if (line.startsWith('### ')) {
|
|
174
|
+
elements.push(
|
|
175
|
+
<h3 key={i} className="text-sm font-medium text-gray-700 mt-2">
|
|
176
|
+
{line.slice(4)}
|
|
177
|
+
</h3>,
|
|
178
|
+
);
|
|
179
|
+
} else if (line.startsWith('## ')) {
|
|
180
|
+
elements.push(
|
|
181
|
+
<h2 key={i} className="text-base font-semibold text-gray-800 mt-2">
|
|
182
|
+
{line.slice(3)}
|
|
183
|
+
</h2>,
|
|
184
|
+
);
|
|
185
|
+
} else if (line.startsWith('# ')) {
|
|
186
|
+
elements.push(
|
|
187
|
+
<h1 key={i} className="text-lg font-semibold text-gray-900 mt-2">
|
|
188
|
+
{line.slice(2)}
|
|
189
|
+
</h1>,
|
|
190
|
+
);
|
|
191
|
+
} else if (line.startsWith('- ') || line.startsWith('• ')) {
|
|
192
|
+
elements.push(
|
|
193
|
+
<div key={i} className="flex items-start space-x-2 ml-2">
|
|
194
|
+
<span className="text-gray-400 mt-1.5 text-xs">•</span>
|
|
195
|
+
<span>
|
|
196
|
+
<InlineFormatted text={line.replace(/^[-•]\s*/, '')} />
|
|
197
|
+
</span>
|
|
198
|
+
</div>,
|
|
199
|
+
);
|
|
200
|
+
} else if (line.trim() === '') {
|
|
201
|
+
elements.push(<div key={i} className="h-2" />);
|
|
202
|
+
} else {
|
|
203
|
+
elements.push(
|
|
204
|
+
<div key={i} className="whitespace-pre-wrap">
|
|
205
|
+
<InlineFormatted text={line} />
|
|
206
|
+
</div>,
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// If we're still in a code block (fence not closed yet — partial stream),
|
|
212
|
+
// render what we have so far as code
|
|
213
|
+
if (inCodeBlock && codeLines.length > 0) {
|
|
214
|
+
elements.push(
|
|
215
|
+
<div key="code-open" className="my-2 border border-gray-200 rounded overflow-hidden">
|
|
216
|
+
{codeLanguage && (
|
|
217
|
+
<div className="px-3 py-1 text-[10px] font-semibold uppercase tracking-wide bg-gray-100 text-gray-600">
|
|
218
|
+
{codeLanguage}
|
|
219
|
+
</div>
|
|
220
|
+
)}
|
|
221
|
+
<div className="bg-gray-900 p-3 overflow-x-auto">
|
|
222
|
+
<pre className="text-xs text-gray-100 font-mono leading-relaxed">
|
|
223
|
+
<code>{codeLines.join('\n')}</code>
|
|
224
|
+
</pre>
|
|
225
|
+
</div>
|
|
226
|
+
</div>,
|
|
227
|
+
);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
return <>{elements}</>;
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Inline formatting: **bold**, `inline code`.
|
|
235
|
+
*/
|
|
236
|
+
const InlineFormatted: React.FC<{ text: string }> = ({ text }) => {
|
|
237
|
+
// Split by bold and inline code patterns
|
|
238
|
+
const parts: React.ReactNode[] = [];
|
|
239
|
+
const regex = /(\*\*(.+?)\*\*|`([^`]+)`)/g;
|
|
240
|
+
let lastIndex = 0;
|
|
241
|
+
let match: RegExpExecArray | null;
|
|
242
|
+
|
|
243
|
+
while ((match = regex.exec(text)) !== null) {
|
|
244
|
+
// Text before match
|
|
245
|
+
if (match.index > lastIndex) {
|
|
246
|
+
parts.push(<span key={`t-${lastIndex}`}>{text.slice(lastIndex, match.index)}</span>);
|
|
247
|
+
}
|
|
248
|
+
if (match[2]) {
|
|
249
|
+
// Bold
|
|
250
|
+
parts.push(<strong key={`b-${match.index}`}>{match[2]}</strong>);
|
|
251
|
+
} else if (match[3]) {
|
|
252
|
+
// Inline code
|
|
253
|
+
parts.push(
|
|
254
|
+
<code key={`c-${match.index}`} className="bg-gray-100 px-1 rounded text-xs">
|
|
255
|
+
{match[3]}
|
|
256
|
+
</code>,
|
|
257
|
+
);
|
|
258
|
+
}
|
|
259
|
+
lastIndex = match.index + match[0].length;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Remaining text
|
|
263
|
+
if (lastIndex < text.length) {
|
|
264
|
+
parts.push(<span key={`t-${lastIndex}`}>{text.slice(lastIndex)}</span>);
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
return <>{parts.length > 0 ? parts : text}</>;
|
|
268
|
+
};
|
|
269
|
+
|
|
270
|
+
export default StreamingMessageBubble;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { useEffect, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Shared SubscriptionHandler for Apollo subscribeToMore
|
|
5
|
+
*
|
|
6
|
+
* @param subscribeToMore - Apollo subscribeToMore function
|
|
7
|
+
* @param document - GraphQL subscription document
|
|
8
|
+
* @param variables - Variables for the subscription
|
|
9
|
+
* @param updateQuery - Apollo updateQuery function
|
|
10
|
+
* @param onError - Optional error handler
|
|
11
|
+
* @param enabled - If false, disables the subscription
|
|
12
|
+
*/
|
|
13
|
+
export function SubscriptionHandler({
|
|
14
|
+
subscribeToMore,
|
|
15
|
+
document,
|
|
16
|
+
variables,
|
|
17
|
+
updateQuery,
|
|
18
|
+
onError,
|
|
19
|
+
enabled = true,
|
|
20
|
+
}: {
|
|
21
|
+
subscribeToMore: Function;
|
|
22
|
+
document: any;
|
|
23
|
+
variables: Record<string, any>;
|
|
24
|
+
updateQuery: (prev: any, { subscriptionData }: any) => any;
|
|
25
|
+
onError?: (error: any) => void;
|
|
26
|
+
enabled?: boolean;
|
|
27
|
+
}) {
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (!enabled) return;
|
|
30
|
+
|
|
31
|
+
console.log('SubscriptionHandler: Setting up subscription with variables:', variables);
|
|
32
|
+
|
|
33
|
+
const unsubscribe = subscribeToMore({
|
|
34
|
+
document,
|
|
35
|
+
variables,
|
|
36
|
+
updateQuery,
|
|
37
|
+
onError,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
console.log('SubscriptionHandler: Subscription setup successful, unsubscribe function:', unsubscribe);
|
|
41
|
+
|
|
42
|
+
return () => {
|
|
43
|
+
console.log('SubscriptionHandler: Cleaning up subscription');
|
|
44
|
+
if (unsubscribe && typeof unsubscribe === 'function') {
|
|
45
|
+
try {
|
|
46
|
+
unsubscribe();
|
|
47
|
+
} catch (error) {
|
|
48
|
+
console.error('Error unsubscribing:', error);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}, [subscribeToMore, document, variables, updateQuery, onError, enabled]);
|
|
53
|
+
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Animated typing indicator — three bouncing dots, similar to iMessage / Slack.
|
|
5
|
+
*/
|
|
6
|
+
export const TypingIndicator: React.FC<{
|
|
7
|
+
authorName?: string;
|
|
8
|
+
/** Extra CSS classes on container */
|
|
9
|
+
className?: string;
|
|
10
|
+
}> = ({ authorName, className = '' }) => {
|
|
11
|
+
return (
|
|
12
|
+
<div className={`flex items-center space-x-2 py-2 px-3 ${className}`}>
|
|
13
|
+
{authorName && <span className="text-xs text-gray-500 font-medium mr-1">{authorName}</span>}
|
|
14
|
+
<div className="flex items-center space-x-1">
|
|
15
|
+
<span
|
|
16
|
+
className="typing-dot w-2 h-2 bg-gray-400 rounded-full inline-block"
|
|
17
|
+
style={{ animation: 'typingBounce 1.4s infinite ease-in-out', animationDelay: '0s' }}
|
|
18
|
+
/>
|
|
19
|
+
<span
|
|
20
|
+
className="typing-dot w-2 h-2 bg-gray-400 rounded-full inline-block"
|
|
21
|
+
style={{ animation: 'typingBounce 1.4s infinite ease-in-out', animationDelay: '0.2s' }}
|
|
22
|
+
/>
|
|
23
|
+
<span
|
|
24
|
+
className="typing-dot w-2 h-2 bg-gray-400 rounded-full inline-block"
|
|
25
|
+
style={{ animation: 'typingBounce 1.4s infinite ease-in-out', animationDelay: '0.4s' }}
|
|
26
|
+
/>
|
|
27
|
+
</div>
|
|
28
|
+
<style>{`
|
|
29
|
+
@keyframes typingBounce {
|
|
30
|
+
0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }
|
|
31
|
+
30% { transform: translateY(-4px); opacity: 1; }
|
|
32
|
+
}
|
|
33
|
+
`}</style>
|
|
34
|
+
</div>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export default TypingIndicator;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import React, { ChangeEventHandler, useCallback, useRef } from 'react';
|
|
2
|
+
import { useTranslation } from 'react-i18next';
|
|
3
|
+
import { BiImage } from '@react-icons/all-files/bi/BiImage.js';
|
|
4
|
+
|
|
5
|
+
export interface IUploadImageButtonProps {
|
|
6
|
+
onChange: ChangeEventHandler<HTMLInputElement>;
|
|
7
|
+
children?: React.ReactNode;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export const UploadImageButton = (props: IUploadImageButtonProps) => {
|
|
11
|
+
const fileInput = useRef<HTMLInputElement>();
|
|
12
|
+
const { t } = useTranslation('translations');
|
|
13
|
+
|
|
14
|
+
const selectFile = useCallback(() => {
|
|
15
|
+
if (fileInput?.current) {
|
|
16
|
+
fileInput?.current?.click();
|
|
17
|
+
}
|
|
18
|
+
}, [fileInput]);
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<div className="relative group">
|
|
22
|
+
<input
|
|
23
|
+
multiple={true}
|
|
24
|
+
accept="image/apng, image/avif, image/gif, image/jpeg, image/png, image/svg+xml, image/webp"
|
|
25
|
+
type="file"
|
|
26
|
+
style={{ display: 'none' }}
|
|
27
|
+
ref={fileInput}
|
|
28
|
+
onChange={props.onChange}
|
|
29
|
+
/>
|
|
30
|
+
{/* Tooltip */}
|
|
31
|
+
{/* <div className="absolute bottom-full left-1/2 transform -translate-x-1/2 mb-2 px-3 py-2 bg-gray-900 text-white text-xs rounded-lg shadow-lg opacity-0 group-hover:opacity-100 transition-all duration-200 pointer-events-none whitespace-nowrap z-20">
|
|
32
|
+
{t('tailwind_ui_inbox.upload_image')}
|
|
33
|
+
|
|
34
|
+
<div className="absolute top-full left-1/2 transform -translate-x-1/2 w-0 h-0 border-l-4 border-r-4 border-t-4 border-l-transparent border-r-transparent border-t-gray-900"></div>
|
|
35
|
+
</div> */}
|
|
36
|
+
<button
|
|
37
|
+
type="button"
|
|
38
|
+
className="flex items-center justify-center w-8 h-8 bg-transparent hover:bg-gray-100 rounded-md focus:outline-none focus:ring-opacity-50 transition-all duration-200 ease-in-out"
|
|
39
|
+
onClick={selectFile}
|
|
40
|
+
aria-label={t('tailwind_ui_inbox.upload_image')}
|
|
41
|
+
>
|
|
42
|
+
{props.children || <BiImage className="w-5 h-5 text-gray-500 hover:text-gray-700" />}
|
|
43
|
+
</button>
|
|
44
|
+
</div>
|
|
45
|
+
);
|
|
46
|
+
};
|