Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#929] Implement the option to end chat #1508

Merged
merged 3 commits into from
Apr 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions frontend/assets/images/icons/minimize-button.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,25 @@
background: transparent;
border-radius: 100%;
cursor: pointer;

path {
fill: #fff;
}
}

.minimizeButton {
outline: none;
position: absolute;
right: 12%;
padding: 2px 0 0 2px;
border: none;
height: 32px;
width: 32px;
background: #1578d4;
border-radius: 100%;
cursor: pointer;

path {
fill: #fff;
}
}
25 changes: 13 additions & 12 deletions frontend/chat-plugin/src/airyRenderProps/AiryHeaderBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
import React from 'react';
import {Config} from '../../App';
import style from './index.module.scss';
import {ReactComponent as CloseButton} from '../../../../assets/images/icons/close.svg';
import {ReactComponent as MinimizeButton} from '../../../../assets/images/icons/minimize-button.svg';

type Props = {
type AiryHeaderBarProps = {
toggleHideChat: () => void;
config?: Config;
setShowModal: React.Dispatch<React.SetStateAction<boolean>>;
};

const AiryHeaderBar = (props: Props) => {
const AiryHeaderBar = (props: AiryHeaderBarProps) => {
const showModalOnClick = () => props.setShowModal(true);
const {config} = props;

const customStyle = {
Expand All @@ -26,16 +30,13 @@ const AiryHeaderBar = (props: Props) => {
{config.headerText || 'Customer Chat'}
</h1>
</div>
<button className={style.closeButton} onClick={() => props.toggleHideChat()}>
<svg width="10px" height="10px" viewBox="0 0 10 10" version="1.1">
<g id="Page-1" stroke="#FFF" strokeWidth="1" fill="#FFF" fillRule="evenodd">
<path
d="M5,4.2928932 L9.1464466,0.14644661 C9.3417088,-0.04881554 9.6582912,-0.04881554 9.8535534,0.14644661 C10.0488155,0.34170876 10.0488155,0.65829124 9.8535534,0.85355339 L5.7071068,5 L9.8535534,9.1464466 C10.0488155,9.3417088 10.0488155,9.6582912 9.8535534,9.8535534 C9.6582912,10.0488155 9.3417088,10.0488155 9.1464466,9.8535534 L5,5.7071068 L0.85355339,9.8535534 C0.65829124,10.0488155 0.34170876,10.0488155 0.14644661,9.8535534 C-0.04881554,9.6582912 -0.04881554,9.3417088 0.14644661,9.1464466 L4.2928932,5 L0.14644661,0.85355339 C-0.04881554,0.65829124 -0.04881554,0.34170876 0.14644661,0.14644661 C0.34170876,-0.04881554 0.65829124,-0.04881554 0.85355339,0.14644661 L5,4.2928932 Z"
id="close"
fill="#FFF"
fillRule="nonzero"></path>
</g>
</svg>

<button className={style.minimizeButton} onClick={props.toggleHideChat} title="Minimize chat">
<MinimizeButton />
</button>

<button className={style.closeButton} onClick={showModalOnClick} title="End chat">
<CloseButton />
</button>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ import style from './index.module.scss';
import {cyInputbarTextarea, cyInputbarButton} from 'chat-plugin-handles';
import {Config} from '../../App';

type Props = {
type AiryInputBarProps = {
sendMessage: (text: string) => void;
messageString: string;
setMessageString: (text: string) => void;
config?: Config;
setNewConversation: React.Dispatch<React.SetStateAction<boolean>>;
};

const AiryInputBar = (props: Props) => {
const AiryInputBar = (props: AiryInputBarProps) => {
const {config} = props;

const textInputRef = createRef<HTMLTextAreaElement>();
Expand Down
42 changes: 42 additions & 0 deletions frontend/chat-plugin/src/components/chat/index.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -96,3 +96,45 @@
align-items: center;
color: white;
}

.buttonWrapper {
height: 30px;
display: flex;
justify-content: center;
button {
margin: 0 8px;
font-family: 'Lato', sans-serif;
}
}

.cancelButton {
font-weight: 600;
line-height: 16px;
font-size: 20px;
height: 40px;
background-color: white;
color: var(--color-airy-blue);
border-radius: 4px;
border: 1px solid var(--color-airy-blue);
cursor: pointer;
padding: 8px 10px;
&:hover {
background-color: rgba(128, 128, 128, 0.173);
}
}

.endChatButton {
font-weight: 600;
line-height: 16px;
font-size: 20px;
height: 40px;
background-color: var(--color-airy-blue);
color: white;
border-radius: 4px;
border: none;
cursor: pointer;
padding: 8px 10px;
&:hover {
background-color: var(--color-airy-blue-hover);
}
}
61 changes: 51 additions & 10 deletions frontend/chat-plugin/src/components/chat/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,10 @@ import {MessageInfoWrapper} from 'render/components/MessageInfoWrapper';
/* eslint-disable @typescript-eslint/no-var-requires */
const camelcaseKeys = require('camelcase-keys');
import {cyBubble, cyChatPluginMessageList} from 'chat-plugin-handles';
import {getResumeTokenFromStorage} from '../../storage';
import {getResumeTokenFromStorage, resetStorage} from '../../storage';
import {ModalDialogue} from '../../components/modal';
import NewConversation from '../../components/newConversation';
import {start} from '../../api';

let ws: WebSocket;

Expand All @@ -46,6 +49,8 @@ const Chat = (props: Props) => {
const [messages, setMessages] = useState<Message[]>([defaultWelcomeMessage]);
const [messageString, setMessageString] = useState('');
const [connectionState, setConnectionState] = useState(null);
const [showModal, setShowModal] = useState(false);
const [newConversation, setNewConversation] = useState(false);

useEffect(() => {
if (config.showMode) return;
Expand All @@ -63,6 +68,10 @@ const Chat = (props: Props) => {
updateScroll();
}, [messages]);

useEffect(() => {
setNewConversation(true);
}, []);

const setInitialMessages = (initialMessages: Array<Message>) => {
setMessages([...messages, ...initialMessages]);
};
Expand Down Expand Up @@ -123,20 +132,36 @@ const Chat = (props: Props) => {
}
};

const closeModalOnClick = () => setShowModal(false);

const cancelChatSession = () => {
setNewConversation(false);
resetStorage(props.channelId);
closeModalOnClick();
};

const reAuthenticate = () => {
start(props.channelId, getResumeTokenFromStorage(props.channelId));
};

const headerBar = props.headerBarProp
? () => props.headerBarProp(ctrl)
: () => <AiryHeaderBar toggleHideChat={ctrl.toggleHideChat} config={config} />;
: () => <AiryHeaderBar toggleHideChat={ctrl.toggleHideChat} config={config} setShowModal={setShowModal} />;

const inputBar = props.inputBarProp
? () => props.inputBarProp(ctrl)
: () => (
<AiryInputBar
sendMessage={sendMessage}
messageString={messageString}
setMessageString={setMessageString}
config={config}
/>
);
: () =>
newConversation ? (
<AiryInputBar
sendMessage={sendMessage}
messageString={messageString}
setMessageString={setMessageString}
config={config}
setNewConversation={setNewConversation}
/>
) : (
<NewConversation reAuthenticate={reAuthenticate} />
);

const bubble = props.bubbleProp
? () => props.bubbleProp(ctrl)
Expand Down Expand Up @@ -210,6 +235,22 @@ const Chat = (props: Props) => {
</div>
)}
<BubbleProp render={bubble} />
{showModal && (
<ModalDialogue close={closeModalOnClick}>
<>
<div className={style.buttonWrapper}>
<button className={style.cancelButton} onClick={closeModalOnClick}>
{' '}
Cancel
</button>
<button className={style.endChatButton} onClick={cancelChatSession}>
{' '}
End Chat
</button>
</div>
</>
</ModalDialogue>
)}
</div>
);
};
Expand Down
75 changes: 75 additions & 0 deletions frontend/chat-plugin/src/components/modal/index.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
@import '../../../../assets/scss/fonts';
@import '../../../../assets/scss/colors';

.background {
position: absolute;
height: 121%;
right: 0;
top: 0;
padding: 0;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;

&:before {
content: '';
width: 97%;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does this shrink properly?

height: 72%;
position: absolute;
top: 8px;
left: 3px;
padding-bottom: 6px;
border-radius: 8px;
background-color: var(--color-text-gray);
opacity: 0.5;
}
}

.closeButton {
border: none;
background-color: rgba(0, 0, 0, 0);
cursor: pointer;
outline: none;
position: absolute;
top: 8px;
right: 10px;
svg {
width: 14px;
height: 14px;
path {
fill: black;
}
}
}

.dialog {
z-index: 1;
display: flex;
width: 375px;
height: 350px;
flex-direction: row;
align-items: flex-start;
padding: 0px 9px 0px 16px;
}

.dialogInner {
width: 340px;
height: 150px;
background-color: white;
border-radius: 8px;
padding: 18px 14px 36px 10px;
position: relative;
}

.inviteWrapper {
width: 500px;
p {
display: flex;
color: var(--color-text-gray);
font-family: 'Lato', sans-serif;
font-weight: 500;
font-size: 18px;
padding-left: 9px;
}
}
26 changes: 26 additions & 0 deletions frontend/chat-plugin/src/components/modal/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React from 'react';
import styles from './index.module.scss';
import {ReactComponent as CloseIcon} from 'assets/images/icons/close.svg';

type ModalDialogueProps = {
close: () => void;
children: JSX.Element;
};

export const ModalDialogue = ({close, children}: ModalDialogueProps) => {
return (
<div className={styles.background}>
<div className={styles.dialog}>
<div className={styles.dialogInner}>
<button onClick={close} className={styles.closeButton}>
<CloseIcon title="Close dialog" />
</button>
<div className={styles.inviteWrapper}>
<p>Are you sure you want to end this chat?</p>
</div>
{children}
</div>
</div>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.paragraphWrapper {
margin-bottom: 20px;
}

.newConversation {
display: flex;
justify-content: center;
padding-left: 20px;
margin: 0;
font-family: 'Lato', sans-serif;
color: var(--color-airy-blue);
}

.newConversationLine {
display: flex;
justify-content: center;
font-family: 'Lato', sans-serif;
color: var(--color-airy-blue);
margin: 0;
}

.newConversationLink {
display: flex;
justify-content: center;
margin-bottom: 20px;
font-family: 'Lato', sans-serif;
font-weight: 600;
font-size: 20px;
color: #1578d4;
}
25 changes: 25 additions & 0 deletions frontend/chat-plugin/src/components/newConversation/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import style from './index.module.scss';

type newConversationProps = {
reAuthenticate: () => void;
};

const NewConversation = (props: newConversationProps) => {
return (
<div>
<div className={style.paragraphWrapper}>
<p className={style.newConversation}>Your conversation has ended. Thank you for</p>{' '}
<p className={style.newConversationLine}>chatting with us today.</p>
</div>

<div>
<a href="" onClick={props.reAuthenticate} className={style.newConversationLink}>
Click Here To Start a New Conversation
</a>
</div>
</div>
);
};

export default NewConversation;
Loading