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

[#1111] Customize Chat Plugin #1456

Merged
merged 17 commits into from
Apr 7, 2021
Merged
1 change: 1 addition & 0 deletions frontend/assets/scss/colors.scss
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
--color-airy-logo-blue: #4bb3fd;
--color-hover-blue: #337bb3;
--color-airy-blue: #1578d4;
--color-airy-accent: #1578d4;
--color-airy-blue-hover: #1e62d0;
--color-airy-blue-pressed: #1b4469;
--color-fb-cta: #1877f2;
Expand Down
44 changes: 23 additions & 21 deletions frontend/chat-plugin/example.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,29 +11,31 @@
w[n] = w[n] || {};
w[n].channelId = search.get('channel_id');
w[n].host = '{*API_HOST*}';
w[n].welcomeMessage = {
fallback: 'Hello!\n\nWelcome to Airy!',
richCard: {
standaloneCard: {
cardContent: {
title: 'Hey there!',
description: 'Welcome to Airy!',
media: {
height: 'MEDIUM',
contentInfo: {
altText: 'Airy logo',
fileUrl: 'https://picsum.photos/200',
forceRefresh: 'false',
},
},
suggestions: [
{
reply: {
text: "Let's start",
postbackData: '/start',
w[n].config = {
welcomeMessage: {
fallback: 'Hello!\n\nWelcome to Airy!',
richCard: {
standaloneCard: {
cardContent: {
title: 'Hey there!',
description: 'Welcome to Airy!',
media: {
height: 'MEDIUM',
contentInfo: {
altText: 'Airy logo',
fileUrl: 'https://picsum.photos/200',
forceRefresh: 'false',
},
},
],
suggestions: [
{
reply: {
text: "Let's start",
postbackData: '/start',
},
},
],
},
},
},
},
Expand Down
89 changes: 56 additions & 33 deletions frontend/chat-plugin/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,50 +1,73 @@
import React, {Component} from 'react';

import style from './App.module.scss';
import Chat from './components/chat';
import style from './App.module.scss';

export default class App extends Component {
render() {
const queryParams = new URLSearchParams(window.location.search);
const channelId = queryParams.get('channel_id');

const customStyle = {
background: 'transparent',
...(config?.primaryColor && {
'--color-airy-blue': config?.primaryColor,
}),
...(config?.accentColor && {
'--color-airy-accent': config?.accentColor,
'--color-airy-blue-hover': config?.accentColor,
'--color-airy-blue-pressed': config?.accentColor,
}),
};

return (
<div className={style.container}>
<div className={style.container} style={customStyle}>
{channelId ? (
<Chat
channelId={channelId}
welcomeMessage={{
fallback: 'Hello!\n\nWelcome to Airy!',
richCard: {
standaloneCard: {
cardContent: {
title: 'Hello!',
description: 'Welcome to Airy!',
media: {
height: 'MEDIUM',
contentInfo: {
altText: 'Airy logo',
fileUrl: 'https://picsum.photos/200',
forceRefresh: 'false',
},
},
suggestions: [
{
reply: {
text: "Let's start",
postbackData: '/start',
},
},
],
},
},
},
}}
/>
<Chat channelId={channelId} config={config} />
) : (
<span style={{color: 'red'}}>Widget authorization failed. Please check your installation.</span>
)}
</div>
);
}
}

export type Config = {
welcomeMessage?: {};
headerText?: string;
headerTextColor?: string;
backgroundColor?: string;
primaryColor?: string;
accentColor?: string;
bubbleIcon?: string;
sendMessageIcon?: string;
};

export const config: Config = {
welcomeMessage: {
fallback: 'Hello!\n\nWelcome to Airy!',
richCard: {
standaloneCard: {
cardContent: {
title: 'Hola!',
description: 'Welcome to Airy!',
media: {
height: 'MEDIUM',
contentInfo: {
altText: 'Airy logo',
fileUrl: 'https://picsum.photos/200',
forceRefresh: 'false',
},
},
suggestions: [
{
reply: {
text: "Let's start",
postbackData: '/start',
},
},
],
},
},
},
},
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
width: 60px;
height: 60px;
border-radius: 50%;
background: #4bb3fd;
background: var(--color-airy-blue);
text-align: center;
transition: all 0.2s ease-in-out;
cursor: pointer;
Expand All @@ -25,7 +25,7 @@
bottom: 9px;
right: 51px;
transform: rotateZ(42deg);
border-top: 14px solid #4bb3fd;
border-top: 14px solid var(--color-airy-blue);
border-left: 8px solid transparent;
border-right: 14px solid transparent;
cursor: pointer;
Expand Down
40 changes: 32 additions & 8 deletions frontend/chat-plugin/src/airyRenderProps/AiryBubble/index.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,44 @@
import React from 'react';
import {Config} from '../../App';
import style from './index.module.scss';

type Props = {
isChatHidden: boolean;
toggleHideChat: () => void;
dataCyId?: string;
config?: Config;
};

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

const BubbleImage = () => {
if (config?.bubbleIcon) {
return (
<img
style={{
padding: '10px 6px 8px 6px',
maxHeight: '60px',
maxWidth: '60px',
objectFit: 'contain',
borderRadius: '50%',
}}
src={config.bubbleIcon}
/>
);
}
return (
<svg height="40" className={style.bubbleIcon} viewBox="0 0 39 40" width="39" xmlns="http://www.w3.org/2000/svg">
<g fill="#fff" fillRule="evenodd" transform="translate(.030165 .02054)">
<path d="m37.1887765 33.360495-10.066549 4.0324258-13.4940785-33.36076733 10.066549-4.03215347z" />
<path d="m17.3157765 18.1023243-11.86678434 4.7221039 7.08317644-16.54846533z" />
<path d="m25.3931725 38.0753564-19.37490191-13.3660891 12.03396081-4.7839109z" />
<path d="m11.5947451 30.9400594-11.5947451 4.6153713 4.16898039-9.7363614z" />
</g>
</svg>
);
};

return (
<div className={style.hideBubble} onClick={() => props.toggleHideChat()} data-cy={props.dataCyId}>
{!props.isChatHidden ? (
Expand All @@ -27,14 +58,7 @@ const AiryBubble = (props: Props) => {
</g>
</svg>
) : (
<svg height="40" className={style.bubbleIcon} viewBox="0 0 39 40" width="39" xmlns="http://www.w3.org/2000/svg">
<g fill="#fff" fillRule="evenodd" transform="translate(.030165 .02054)">
<path d="m37.1887765 33.360495-10.066549 4.0324258-13.4940785-33.36076733 10.066549-4.03215347z" />
<path d="m17.3157765 18.1023243-11.86678434 4.7221039 7.08317644-16.54846533z" />
<path d="m25.3931725 38.0753564-19.37490191-13.3660891 12.03396081-4.7839109z" />
<path d="m11.5947451 30.9400594-11.5947451 4.6153713 4.16898039-9.7363614z" />
</g>
</svg>
<BubbleImage />
)}
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
display: flex;
justify-content: space-between;
align-items: center;
background-color: #1578d4;
background-color: var(--color-airy-blue);
border-top-left-radius: 8px;
border-top-right-radius: 8px;
border-bottom: 1px solid #fff;
Expand Down Expand Up @@ -37,7 +37,7 @@
border: none;
height: 32px;
width: 32px;
background: #1578d4;
background: transparent;
border-radius: 100%;
cursor: pointer;
}
17 changes: 16 additions & 1 deletion frontend/chat-plugin/src/airyRenderProps/AiryHeaderBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,30 @@
import React from 'react';
import {Config} from '../../App';
import style from './index.module.scss';

type Props = {
toggleHideChat: () => void;
config?: Config;
};

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

const customStyle = {
...(config?.accentColor && {
color: config?.accentColor,
}),
...(config?.headerTextColor && {
color: config?.headerTextColor,
}),
};

return (
<div className={style.header}>
<div className={style.headerInfo}>
<h1 className={style.headerTitle}>Customer Chat</h1>
<h1 className={style.headerTitle} style={customStyle}>
{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">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
outline: none;
box-sizing: border-box;
&:focus {
border: 1px solid #1578d4;
border: 1px solid var(--color-airy-accent);
}
}

Expand Down Expand Up @@ -63,8 +63,17 @@
border: none;
height: 32px;
width: 32px;
background: #1578d4;
background: var(--color-airy-accent);
border-radius: 100%;
align-self: center;
cursor: pointer;

img {
display: block;
max-width: 28px;
max-height: 28px;
width: auto;
height: auto;
padding: 0px 1px 1px 0px;
}
}
18 changes: 13 additions & 5 deletions frontend/chat-plugin/src/airyRenderProps/AiryInputBar/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
import React, {ChangeEvent, FormEvent, KeyboardEvent, createRef, useEffect} from 'react';
import style from './index.module.scss';
import {cyInputbarTextarea, cyInputbarButton} from 'chat-plugin-handles';
import {Config} from '../../App';

type Props = {
sendMessage: (text: string) => void;
messageString: string;
setMessageString: (text: string) => void;
config?: Config;
};

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

const textInputRef = createRef<HTMLTextAreaElement>();
const dataCyButtonId = cyInputbarButton;
const dataCyTextareaId = cyInputbarTextarea;
Expand Down Expand Up @@ -67,11 +71,15 @@ const AiryInputBar = (props: Props) => {
data-cy={dataCyTextareaId}
/>
<button className={style.sendButton} type="submit" data-cy={dataCyButtonId}>
<svg width="32px" height="28px" version="1.1" viewBox="0 0 32 32">
<g id="send" fill="#FFF">
<path d="M 4.204896700000001 4.1195648527004405 L 4.0115967 3.9293212999999954 L 26.806220699999997 15.60647032325003 C 27.038809399999998 15.725619970668763 27.222648999999997 15.941497277564224 27.320137699999997 16.20994757774927 C 27.3590557 16.317114218006374 27.382557300000002 16.427165455874935 27.391807 16.536902967267633 L 27.398838400000002 16.540668482394658 L 27.392079699999996 16.54018877934823 C 27.3921007 16.54044645882842 27.392121699999997 16.54070402439193 27.3921426 16.54096170387211 L 27.398838400000002 16.540668482394658 L 27.392382599999998 16.543964319141168 C 27.4304225 17.027113800145607 27.192606599999998 17.50284650930388 26.7783607 17.698066169454904 L 5.363240899999999 27.790260720697574 L 4 28.4862211 L 5.5693217 19.257384836767415 C 5.746012199999999 18.218306686439767 6.5275848 17.45467240775926 7.4559937000000005 17.414015096886477 L 15.929362999999999 17.042945253761246 L 15.9669189 17.00707039202062 C 16.2459878 16.993653971552554 16.4762258 16.753711315008147 16.5127314 16.438251711105558 C 16.5480464 16.133081515411554 16.3928866 15.84932685398698 16.1518743 15.74236389671421 L 7.4157525 15.122277821325797 C 6.5061810000000015 15.057716808541617 5.7499406 14.30085293859034 5.576627500000001 13.281636271485022 L 4 4.009836112890403 L 4.204896700000001 4.1195648527004405 Z" />
</g>
</svg>
{config?.sendMessageIcon ? (
<img src={config.sendMessageIcon} />
) : (
<svg width="32px" height="28px" version="1.1" viewBox="0 0 32 32">
<g id="send" fill="#FFF">
<path d="M 4.204896700000001 4.1195648527004405 L 4.0115967 3.9293212999999954 L 26.806220699999997 15.60647032325003 C 27.038809399999998 15.725619970668763 27.222648999999997 15.941497277564224 27.320137699999997 16.20994757774927 C 27.3590557 16.317114218006374 27.382557300000002 16.427165455874935 27.391807 16.536902967267633 L 27.398838400000002 16.540668482394658 L 27.392079699999996 16.54018877934823 C 27.3921007 16.54044645882842 27.392121699999997 16.54070402439193 27.3921426 16.54096170387211 L 27.398838400000002 16.540668482394658 L 27.392382599999998 16.543964319141168 C 27.4304225 17.027113800145607 27.192606599999998 17.50284650930388 26.7783607 17.698066169454904 L 5.363240899999999 27.790260720697574 L 4 28.4862211 L 5.5693217 19.257384836767415 C 5.746012199999999 18.218306686439767 6.5275848 17.45467240775926 7.4559937000000005 17.414015096886477 L 15.929362999999999 17.042945253761246 L 15.9669189 17.00707039202062 C 16.2459878 16.993653971552554 16.4762258 16.753711315008147 16.5127314 16.438251711105558 C 16.5480464 16.133081515411554 16.3928866 15.84932685398698 16.1518743 15.74236389671421 L 7.4157525 15.122277821325797 C 6.5061810000000015 15.057716808541617 5.7499406 14.30085293859034 5.576627500000001 13.281636271485022 L 4 4.009836112890403 L 4.204896700000001 4.1195648527004405 Z" />
</g>
</svg>
)}
</button>
</form>
);
Expand Down
Loading