Skip to content

Commit

Permalink
feat: add support for plugins rendering DIDComm messages in Chat (#238)
Browse files Browse the repository at this point in the history
* feat: add support for plugins rendering DIDComm messages in Chat

* fix: uncomment
  • Loading branch information
nickreynolds authored Apr 18, 2024
1 parent 0d08fb2 commit 33fb7fe
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 14 deletions.
30 changes: 24 additions & 6 deletions packages/agent-explore/src/plugins/chats/ChatBubble.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,33 @@
import React from 'react'
import { Row, theme } from 'antd'
const { useToken } = theme
import { MarkDown } from '@veramo-community/agent-explorer-plugin'
import { usePlugins } from '@veramo-community/agent-explorer-plugin'
import { IMessage } from '@veramo/core-types'
import { ChatMarkdown } from './ChatMarkdown'

interface ChatBubbleProps {
text: string
isSender?: boolean
export interface ChatBubbleProps {
message: IMessage & { isSender: boolean }
}

const ChatBubble: React.FC<ChatBubbleProps> = ({ text, isSender }) => {
const ChatBubble: React.FC<ChatBubbleProps> = ({ message }) => {
const { isSender } = message
const { plugins } = usePlugins()
const { token } = useToken()

let Component: React.FC<ChatBubbleProps> | undefined = undefined
plugins.forEach((plugin) => {
if (Component === undefined && plugin.getMessageComponent) {
const Obj = plugin.getMessageComponent(message)
if (Obj) {
Component = Obj
}
}
})

if (Component === undefined) {
Component = ChatMarkdown
}

return (
<Row
style={{
Expand All @@ -31,7 +49,7 @@ const ChatBubble: React.FC<ChatBubbleProps> = ({ text, isSender }) => {
color: token.colorText,
}}
>
<MarkDown content={text} />
<Component message={message} />
</div>
</Row>
)
Expand Down
8 changes: 8 additions & 0 deletions packages/agent-explore/src/plugins/chats/ChatMarkdown.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { MarkDown } from "@veramo-community/agent-explorer-plugin"
import { ChatBubbleProps } from "./ChatBubble.js"

export const ChatMarkdown = ({ message }: ChatBubbleProps) => {
// @ts-ignore
const content = message && message.data && message.data.content || ''
return <MarkDown content={content} />
}
10 changes: 4 additions & 6 deletions packages/agent-explore/src/plugins/chats/ChatWindow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,21 @@ import { scrollMessages } from './scroll'
import { useChat } from '../../context/ChatProvider'
import { IdentifierProfile } from '@veramo-community/agent-explorer-plugin'
import { Button, Col, Row, theme } from 'antd'
import { IDataStoreORM } from '@veramo/core-types'

const ChatWindow: React.FC = () => {
const { threadId } = useParams<{ threadId: string }>()
const { selectedDid, newRecipient } = useChat()
const newThread = threadId === 'new-thread'
const { agent } = useVeramo()
const { agent } = useVeramo<IDataStoreORM>()
const { token } = theme.useToken()
const navigate = useNavigate()

const { data: messages, refetch } = useQuery(
['chats', { id: agent?.context.id, threadId: threadId }],
async () => {
const _messages = await agent?.dataStoreORMGetMessages({
where: [{ column: 'threadId', value: [threadId] }],
where: [{ column: 'threadId', value: [threadId!] }],
order: [{ column: 'createdAt', direction: 'ASC' }],
})
return _messages?.map((_msg: any) => {
Expand Down Expand Up @@ -104,11 +105,8 @@ const ChatWindow: React.FC = () => {
{messages?.map((message: any) => {
return (
<ChatBubble
// @ts-ignore
text={message?.data?.content}
message={message}
key={message.id}
// @ts-ignore
isSender={message.isSender}
/>
)
})}
Expand Down
7 changes: 6 additions & 1 deletion packages/agent-explore/src/plugins/chats/Chats.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { useChat } from '../../context/ChatProvider'
import { IDataStoreORM, IMessage } from '@veramo/core'
import { useEffect } from 'react'
import { Col, Row, theme } from 'antd'
import { usePlugins } from '@veramo-community/agent-explorer-plugin'
const { useToken } = theme

const groupBy = (arr: any[], property: string) => {
Expand All @@ -25,13 +26,17 @@ interface IsSenderTaggedMessage extends IMessage {
const ChatView = () => {
const { token } = useToken()
const { agent } = useVeramo<IDataStoreORM>()
const { plugins } = usePlugins()
const allChats: string[] = ['https://didcomm.org/basicmessage/2.0/message']
// find all supported message types in plugins
plugins.forEach((plugin) => plugin.supportedChatMessages && allChats.push(...(plugin.supportedChatMessages)))
const { selectedDid } = useChat()
const { threadId } = useParams<{ threadId: string }>()
const { data: threads, refetch } = useQuery(
['threads', { id: agent?.context.id, selectedDid, threadId }],
async () => {
const messages = await agent?.dataStoreORMGetMessages({
where: [{ column: 'type', value: ['https://didcomm.org/basicmessage/2.0/message'] }],
where: [{ column: 'type', value: allChats }],
order: [{ column: 'createdAt', direction: 'DESC' }],
})
// TODO: should be able to do this filter in the query instead of here
Expand Down
8 changes: 7 additions & 1 deletion packages/plugin/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { MenuProps } from 'antd';
import { MenuDataItem } from '@ant-design/pro-components';
import { UniqueVerifiableCredential } from '@veramo/core-types'
import { IMessage, UniqueVerifiableCredential } from '@veramo/core-types'
import { IAgentPlugin } from '@veramo/core'
import { Components } from 'react-markdown'
import { PluggableList } from 'unified'
Expand Down Expand Up @@ -84,6 +84,12 @@ export type IAgentExplorerPlugin = {
/** Returns a react component that will be displayed in the identifier hover component */
getIdentifierHoverComponent?: () => React.FC<IIdentifierHoverComponentProps>;

/** Returns an array of supported chat message types */
supportedChatMessages?: string[];

/** Returns a react component for a given DIDComm message */
getMessageComponent?: (message: IMessage) => React.FC | undefined;

/** Returns an array of react components and labels that will be displayed as tabs in the indentifier profile page */
getIdentifierTabsComponents?: () => Array<{ label: string, component: React.FC<IIdentifierTabsComponentProps> }>;

Expand Down

0 comments on commit 33fb7fe

Please sign in to comment.