Skip to content

Commit

Permalink
Support 3>= user conversation in the chatbot
Browse files Browse the repository at this point in the history
  • Loading branch information
AhyoungRyu committed Oct 11, 2023
1 parent f4eaaf6 commit aa18e8e
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 15 deletions.
12 changes: 2 additions & 10 deletions .env
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
# Vite prefix is required for Vite to load the env variables
# Plz modify below two env variables on your needs
#VITE_CHAT_WIDGET_APP_ID=CEA3E63E-BBA0-4188-A181-0985DE7BB350
#VITE_CHAT_WIDGET_BOT_ID=makro_bot

#VITE_CHAT_WIDGET_APP_ID=EBFA7043-07D8-4F87-AB0D-A0C62A62A70B
#VITE_CHAT_WIDGET_BOT_ID=grug-brained-bot
# form related
VITE_CHAT_WIDGET_APP_ID=E5776D10-64C2-48DC-BA11-7F7B34204E9A
VITE_CHAT_WIDGET_BOT_ID=bot_test_0a780
#VITE_CHAT_WIDGET_APP_ID=AE8F7EEA-4555-4F86-AD8B-5E0BD86BFE67
#VITE_CHAT_WIDGET_BOT_ID=khan-academy-bot
VITE_CHAT_WIDGET_APP_ID=AE8F7EEA-4555-4F86-AD8B-5E0BD86BFE67
VITE_CHAT_WIDGET_BOT_ID=khan-academy-bot
3 changes: 1 addition & 2 deletions src/components/BotMessageWithBodyInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { UserMessage } from '@sendbird/chat/message';
import { ReactNode } from 'react';
import styled from 'styled-components';

import { StartingPageAnimatorProps } from './CustomChannelComponent';
import { ReactionContainer } from './ReactionContainer';
import { useConstantState } from '../context/ConstantContext';
import botMessageImage from '../icons/bot-message-image.png';
Expand All @@ -18,7 +17,7 @@ const Root = styled.div`
position: relative;
`;

const Sender = styled.div<StartingPageAnimatorProps>`
const Sender = styled.div`
font-style: normal;
font-weight: 700;
font-size: 12px;
Expand Down
4 changes: 3 additions & 1 deletion src/components/CustomChannelComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,9 @@ export function CustomChannelComponent(props: CustomChannelComponentProps) {
lastMessage &&
!(lastMessage?.messageType === 'admin') &&
lastMessage.sender?.userId === userId &&
lastMessage.sendingStatus === SendingStatus.SUCCEEDED
lastMessage.sendingStatus === SendingStatus.SUCCEEDED &&
// this bubble loading should be shown only when there're only bot and 1 user in the channel
channel?.memberCount === 2
) {
setActiveSpinnerId(lastMessage.messageId);
scrollUtil();
Expand Down
24 changes: 22 additions & 2 deletions src/components/CustomMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import FormMessage from './FormMessage';
import ParsedBotMessageBody from './ParsedBotMessageBody';
import PendingMessage from './PendingMessage';
import SuggestedReplyMessageBody from './SuggestedReplyMessageBody';
import UserMessageWithBodyInput from './UserMessageWithBodyInput';
import { LOCAL_MESSAGE_CUSTOM_TYPE } from '../const';
import { useConstantState } from '../context/ConstantContext';
import {
Expand Down Expand Up @@ -43,7 +44,7 @@ export default function CustomMessage(props: Props) {
chainBottom,
isBotWelcomeMessage,
} = props;
const { replacementTextList } = useConstantState();
const { replacementTextList, userId } = useConstantState();

const { allMessages } = useChannelContext();
const firstMessage: UserMessage = allMessages[0] as UserMessage;
Expand Down Expand Up @@ -72,7 +73,7 @@ export default function CustomMessage(props: Props) {
}

// Sent by current user
if ((message as UserMessage).sender?.userId !== botUser.userId) {
if ((message as UserMessage).sender?.userId === userId) {
return (
<div>
{<CurrentUserMessage message={message as UserMessage} />}
Expand All @@ -81,6 +82,25 @@ export default function CustomMessage(props: Props) {
);
}

// Sent by other users
if ((message as UserMessage).sender?.userId !== botUser.userId) {
return (
<div ref={lastMessageRef}>
{
<UserMessageWithBodyInput
message={message as UserMessage}
user={message?.sender}
chainTop={chainTop}
chainBottom={chainBottom}
bodyComponent={
<CustomMessageBody message={(message as UserMessage).message} />
}
/>
}
</div>
);
}

if (message.messageId === firstMessageId) {
return (
<div>
Expand Down
101 changes: 101 additions & 0 deletions src/components/UserMessageWithBodyInput.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { User } from '@sendbird/chat';
import { UserMessage } from '@sendbird/chat/message';
import Avatar from '@sendbird/uikit-react/ui/Avatar';
import { ReactNode } from 'react';
import styled from 'styled-components';

import { formatCreatedAtToAMPM } from '../utils';

const Root = styled.div`
display: flex;
align-items: flex-end;
margin-bottom: 6px;
flex-wrap: wrap;
gap: 8px;
position: relative;
`;

const Sender = styled.div`
font-style: normal;
font-weight: 700;
font-size: 12px;
line-height: 12px;
color: rgba(0, 0, 0, 0.5);
transition: color 0.5s;
transition-timing-function: ease;
margin: 0 0 4px 12px;
`;

interface BodyContainerProps {
maxWidth?: string;
}

const BodyContainer = styled.div<BodyContainerProps>`
font-size: 14px;
color: rgba(0, 0, 0, 0.88);
max-width: calc(100% - 96px);
font-weight: normal;
font-stretch: normal;
font-style: normal;
line-height: 1.43;
letter-spacing: normal;
`;

const SentTime = styled.div`
width: fit-content;
color: rgba(0, 0, 0, 0.38);
font-size: 12px;
line-height: 1;
margin-bottom: 6px;
`;

type Props = {
user: User;
message: UserMessage;
bodyComponent: ReactNode;
chainTop: boolean;
chainBottom: boolean;
bodyStyle?: object;
isBotWelcomeMessage?: boolean;
isFormMessage?: boolean;
};

const ImageContainer = styled.div``;

const EmptyImageContainer = styled.div`
width: 28px;
`;

export default function UserMessageWithBodyInput(props: Props) {
const { user, message, bodyComponent, bodyStyle, chainTop, chainBottom } =
props;

const nonChainedMessage = chainTop == null && chainBottom == null;
const displayProfileImage = nonChainedMessage || chainBottom;
const displaySender = nonChainedMessage || chainTop;

return (
<Root>
{displayProfileImage ? (
<ImageContainer>
<Avatar height="28px" width="28px" src={user?.profileUrl} />
</ImageContainer>
) : (
<EmptyImageContainer />
)}
<BodyContainer style={bodyStyle ?? {}}>
{displaySender && (
<Sender
style={{
textAlign: 'left',
}}
>
{user.nickname}
</Sender>
)}
{bodyComponent}
</BodyContainer>
<SentTime>{formatCreatedAtToAMPM(message.createdAt)}</SentTime>
</Root>
);
}

0 comments on commit aa18e8e

Please sign in to comment.