Skip to content

Commit

Permalink
feat: add boe indicators, chat avatar with emitters
Browse files Browse the repository at this point in the history
  • Loading branch information
nzambello committed Dec 8, 2023
1 parent c3f1d6e commit 9c1f162
Show file tree
Hide file tree
Showing 19 changed files with 462 additions and 19 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@
"dependencies": {
"@fontsource/exo-2": "^4.5.10",
"@headlessui/react": "1.7.4",
"@memori.ai/memori-api-client": "^2.4.0",
"@memori.ai/memori-api-client": "^2.6.1",
"@react-three/drei": "8.20.2",
"@react-three/fiber": "7.0.25",
"antd": "4.18.9",
Expand Down
4 changes: 4 additions & 0 deletions src/components/Chat/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useEffect, memo } from 'react';
import cx from 'classnames';
import {
DialogState,
ExpertReference,
Memori,
Message,
Tenant,
Expand Down Expand Up @@ -62,6 +63,7 @@ export interface Props {
layout: MemoriProps['layout'];
userAvatar?: MemoriProps['userAvatar'];
user?: User;
experts?: ExpertReference[];
}

const Chat: React.FC<Props> = ({
Expand Down Expand Up @@ -103,6 +105,7 @@ const Chat: React.FC<Props> = ({
customMediaRenderer,
user,
userAvatar,
experts,
}) => {
const scrollToBottom = () => {
setTimeout(() => {
Expand Down Expand Up @@ -207,6 +210,7 @@ const Chat: React.FC<Props> = ({
}
user={user}
userAvatar={userAvatar}
experts={experts}
/>
{showDates && !!message.timestamp && (
<small
Expand Down
44 changes: 44 additions & 0 deletions src/components/Chat/__snapshots__/Chat.test.tsx.snap

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions src/components/ChatBubble/ChatBubble.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -177,3 +177,31 @@ FromUserWithAvatarAndCustomAvatar.args = {
'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
},
};

export const FromExpertOfABoard = Template.bind({});
FromExpertOfABoard.args = {
memori: {
...memori,
enableBoardOfExperts: true,
},
apiUrl: 'https://backend.memori.ai',
tenant,
experts: [
{
expertID: '9b0a2913-d3d8-4e98-a49d-6e1c99479e1b',
name: 'Expert name',
description: 'Expert description',
expertMemoriID: '9b0a2913-d3d8-4e98-a49d-6e1c99479e1b',
expertBaseURL: 'https://engine.memori.ai',
},
],
message: {
fromUser: false,
text: 'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
initial: false,
generatedByAI: true,
emitter: 'Expert name',
translatedText:
'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
},
};
32 changes: 32 additions & 0 deletions src/components/ChatBubble/ChatBubble.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,38 @@ it('renders ChatBubble with msg generated by AI unchanged', () => {
expect(container).toMatchSnapshot();
});

it('renders ChatBubble with msg from BoE expert unchanged', () => {
const { container } = render(
<ChatBubble
memori={{
...memori,
enableBoardOfExperts: true,
}}
tenant={tenant}
apiUrl="https://backend.memori.ai"
experts={[
{
expertID: '9b0a2913-d3d8-4e98-a49d-6e1c99479e1b',
name: 'Expert name',
description: 'Expert description',
expertMemoriID: '9b0a2913-d3d8-4e98-a49d-6e1c99479e1b',
expertBaseURL: 'https://engine.memori.ai',
},
]}
message={{
fromUser: true,
text: 'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
initial: false,
generatedByAI: true,
emitter: 'Expert name',
translatedText:
'Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.',
}}
/>
);
expect(container).toMatchSnapshot();
});

it('renders ChatBubble from user with avatar unchanged', () => {
const { container } = render(
<ChatBubble
Expand Down
46 changes: 37 additions & 9 deletions src/components/ChatBubble/ChatBubble.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react';
import cx from 'classnames';
import {
ExpertReference,
Memori,
Message,
Tenant,
Expand All @@ -27,6 +28,7 @@ export interface Props {
isFirst?: boolean;
userAvatar?: MemoriProps['userAvatar'];
user?: User;
experts?: ExpertReference[];
}

const ChatBubble: React.FC<Props> = ({
Expand All @@ -41,6 +43,7 @@ const ChatBubble: React.FC<Props> = ({
isFirst = false,
user,
userAvatar,
experts,
}) => {
const { t } = useTranslation();

Expand Down Expand Up @@ -74,21 +77,46 @@ const ChatBubble: React.FC<Props> = ({
leaveTo={`opacity-0 scale-075 ${
message.fromUser ? 'translate-x-15' : 'translate-x--15'
}`}
title={
!!message.emitter?.length && !!memori.enableBoardOfExperts
? message.emitter
: memori.name
}
>
<source
src={getResourceUrl({
type: 'avatar',
tenantID: tenant?.id,
resourceURI: memori.avatarURL,
baseURL: baseUrl,
apiURL: apiUrl,
})}
src={
!!message.emitter?.length &&
!!memori.enableBoardOfExperts &&
experts?.find(e => e.name === message.emitter)
? `${apiUrl}/api/v1/memoriai/memori/avatar/${
experts.find(e => e.name === message.emitter)
?.expertMemoriID
}`
: getResourceUrl({
type: 'avatar',
tenantID: tenant?.id,
resourceURI: memori.avatarURL,
baseURL: baseUrl,
apiURL: apiUrl,
})
}
/>
<img
className="memori-chat--bubble-avatar-img"
alt={memori.name}
alt={
!!message.emitter?.length && !!memori.enableBoardOfExperts
? message.emitter
: memori.name
}
src={
memori.avatarURL && memori.avatarURL.length > 0
!!message.emitter?.length &&
!!memori.enableBoardOfExperts &&
experts?.find(e => e.name === message.emitter)
? `${apiUrl}/api/v1/memoriai/memori/avatar/${
experts.find(e => e.name === message.emitter)
?.expertMemoriID
}`
: memori.avatarURL && memori.avatarURL.length > 0
? getResourceUrl({
type: 'avatar',
tenantID: tenant?.id,
Expand Down
82 changes: 82 additions & 0 deletions src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ exports[`renders ChatBubble unchanged 1`] = `
>
<picture
class="memori-chat--bubble-avatar transition ease-in-out duration-300 opacity-0 scale-075 translate-x--15"
title="Memori"
>
<source
src="https://app.twincreator.com/images/twincreator/square_logo.png"
Expand Down Expand Up @@ -111,6 +112,7 @@ exports[`renders ChatBubble with initial msg unchanged 1`] = `
>
<picture
class="memori-chat--bubble-avatar transition ease-in-out duration-300 opacity-0 scale-075 translate-x--15"
title="Memori"
>
<source
src="https://app.twincreator.com/images/twincreator/square_logo.png"
Expand All @@ -132,6 +134,86 @@ exports[`renders ChatBubble with initial msg unchanged 1`] = `
</div>
`;

exports[`renders ChatBubble with msg from BoE expert unchanged 1`] = `
<div>
<div
class="memori-chat--bubble-container memori-chat--bubble-from-user memori-chat--with-addon"
>
<div
class="memori-chat--bubble memori-chat--user-bubble memori-chat--with-addon memori-chat--ai-generated transition ease-in-out duration-300 opacity-0 scale-09 translate-x-30"
>
<p>
Proin libero ante, dignissim sit amet turpis a, pretium condimentum dolor.
</p>
<div
class="memori-chat--bubble-addon"
>
<div
class="memori-tooltip memori-tooltip--align-left memori-chat--bubble-ai-icon"
>
<div
class="memori-tooltip--content"
>
generatedByAI
</div>
<div
class="memori-tooltip--trigger"
>
<span>
<svg
aria-label="generatedByAI"
fill="none"
focusable="false"
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<g
clip-rule="evenodd"
fill="currentColor"
fill-rule="evenodd"
>
<path
clip-rule="evenodd"
d="M0 4a4 4 0 014-4h16a4 4 0 014 4v16a4 4 0 01-4 4H4a4 4 0 01-4-4zm4-2.4A2.4 2.4 0 001.6 4v16A2.4 2.4 0 004 22.4h16a2.4 2.4 0 002.4-2.4V4A2.4 2.4 0 0020 1.6z"
fill-rule="evenodd"
/>
<path
clip-rule="evenodd"
d="M9.715 8.442a.798.798 0 00-1.43 0l-3.2 6.4a.799.799 0 101.431.716l.579-1.158h3.811l.578 1.158a.8.8 0 001.431-.716zm.391 4.358L9 10.589 7.894 12.8z"
fill-rule="evenodd"
/>
<path
clip-rule="evenodd"
d="M17 8c.552 0 1 .358 1 .8v6.4c0 .442-.448.8-1 .8s-1-.358-1-.8V8.8c0-.442.448-.8 1-.8z"
fill-rule="evenodd"
/>
</g>
</svg>
</span>
</div>
</div>
</div>
</div>
<div
class="memori-chat--bubble-avatar transition ease-in-out duration-300 opacity-0 scale-075 translate-x-15"
>
<svg
aria-hidden="true"
focusable="false"
role="img"
viewBox="0 0 1024 1024"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M858.5 763.6a374 374 0 0 0-80.6-119.5 375.63 375.63 0 0 0-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 0 0-80.6 119.5A371.7 371.7 0 0 0 136 901.8a8 8 0 0 0 8 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 0 0 8-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"
/>
</svg>
</div>
</div>
</div>
`;

exports[`renders ChatBubble with msg generated by AI unchanged 1`] = `
<div>
<div
Expand Down
Loading

0 comments on commit 9c1f162

Please sign in to comment.