BotFramework-WebChat
BotFramework-WebChat copied to clipboard
Investigate Web Chat Editor, playground, and Web Chat Designer
- Compare the three projects and plan to bring alignment & reduce overlapping work
- Expand scope of playground with action items for the following:
- a demo app/playground
- Composer extension
- future hosting surfaces yet to be defined
Current resources:
- https://github.com/pavolum/WebChat-Editor
- https://webchateditor.azurewebsites.net/
- Web Chat Designer:
import React, { useState } from 'react';
import AdaptiveForm from '@bfc/adaptive-form';
import ReactWebChat from 'botframework-webchat';
import { JSONSchema7 } from '@bfc/extension-client';
const schema: JSONSchema7 = {
"title": "Web Chat Designer",
"description": "Web Chat Designer",
"type": "object",
"properties": {
"accent": {
"$role": "color",
"type": "string"
},
"backgroundColor": {
"$role": "color",
"type": "string"
},
"cardEmphasisBackgroundColor": {
"$role": "color",
"type": "string"
},
"paddingRegular": {
"oneOf":[
{
"type": "string"
},
{
"type": "number"
}
]
},
"paddingWide": {
"oneOf":[
{
"type": "string"
},
{
"type": "number"
}
]
},
"subtle": {
"$role": "color",
"type": "string"
},
"messageActivityWordBreak": {
"type": "string",
"enum": [
"break-word",
"normal",
"break-all",
"break-word",
"keep-all"
]
},
"fontSizeSmall": {
"type": "string"
},
"monospaceFont": {
"type": "string"
},
"primaryFont": {
"type": "string"
},
"avatarBorderRadius": {
"type": "string"
},
"avatarSize": {
"oneOf":[
{
"type": "string"
},
{
"type": "number"
}
]
},
"botAvatarBackgroundColor": {
"$role": "color",
"description": "defaults to accent color",
"type": "string"
},
"botAvatarImage": {
"description": "Data URI, blob, or Image URL",
"type": "string"
},
"botAvatarInitials": {
"description": "Empty strings means it has avatar but not initials inside.",
"type": "string"
},
"userAvatarBackgroundColor": {
"$role": "color",
"description": "defaults to accent color",
"type": "string"
},
"userAvatarImage": {
"description": "Or a string of URL. Can be a data URI or blob.",
"type": "string"
},
"userAvatarInitials": {
"description": "Or a string. Empty strings means it has avatar but not initials inside.",
"type": "string"
},
"showAvatarInGroup": {
"oneOf": [
{
"type": "boolean"
},
{
"type": "string",
"enum": [
"status",
"sender"
]
}
]
},
"bubbleBackground": {
"$role": "color",
"type": "string"
},
"bubbleBorderColor": {
"$role": "color",
"type": "string"
},
"bubbleBorderRadius": {
"type": "number"
},
"bubbleBorderStyle": {
"type": "string",
"enum": [
"dotted",
"dashed",
"solid",
"double",
"groove",
"ridge",
"inset",
"outset",
"none",
"hidden",
"mix"
]
},
"bubbleBorderWidth": {
"type": "number"
},
"bubbleFromUserBackground": {
"$role": "color",
"type": "string"
},
"bubbleFromUserBorderColor": {
"$role": "color",
"type": "string"
},
"bubbleFromUserBorderRadius": {
"type": "number"
},
"bubbleFromUserBorderStyle": {
"type": "string",
"enum": [
"dotted",
"dashed",
"solid",
"double",
"groove",
"ridge",
"inset",
"outset",
"none",
"hidden",
"mix"
]
},
"bubbleFromUserBorderWidth": {
"type": "number"
},
"bubbleFromUserNubOffset": {
"oneOf": [
{
"type": "string",
"const": "bottom"
},
{
"type": "number"
}
]
},
"bubbleFromUserNubSize": {
"type": "number"
},
"bubbleFromUserTextColor": {
"$role": "color",
"type": "string"
},
"bubbleImageHeight": {
"type": "number"
},
"bubbleMaxWidth": {
"type": "number"
},
"bubbleMinHeight": {
"type": "number"
},
"bubbleMinWidth": {
"type": "number"
},
"bubbleNubOffset": {
"type": "number"
},
"bubbleNubSize": {
"type": "number"
},
"bubbleTextColor": {
"$role": "color",
"type": "string"
},
"markdownRespectCRLF": {
"type": "boolean"
},
"richCardWrapTitle": {
"description": "Applies to subtitles as well",
"type": "boolean"
},
"rootHeight": {
"type": "string"
},
"rootWidth": {
"type": "string"
},
"rootZIndex": {
"description": "\"z-index\" for the root container of Web Chat. This will form a new stacking context so \"z-index\" used in children won't pollute.",
"type": "number"
},
"hideScrollToEndButton": {
"type": "boolean"
},
"hideSendBox": {
"type": "boolean"
},
"hideUploadButton": {
"type": "boolean"
},
"microphoneButtonColorOnDictate": {
"$role": "color",
"type": "string"
},
"sendBoxBackground": {
"$role": "color",
"type": "string"
},
"sendBoxButtonColor": {
"$role": "color",
"type": "string"
},
"sendBoxButtonColorOnDisabled": {
"$role": "color",
"type": "string"
},
"sendBoxButtonColorOnFocus": {
"$role": "color",
"type": "string"
},
"sendBoxButtonColorOnHover": {
"$role": "color",
"type": "string"
},
"sendBoxDisabledTextColor": {
"$role": "color",
"type": "string"
},
"sendBoxHeight": {
"type": "number"
},
"sendBoxMaxHeight": {
"type": "number"
},
"sendBoxTextColor": {
"$role": "color",
"type": "string"
},
"sendBoxPlaceholderColor": {
"$role": "color",
"description": "defaults to subtle",
"type": "string"
},
"sendBoxTextWrap": {
"type": "boolean"
},
"showSpokenText": {
"description": "Visually show spoken text",
"type": "boolean"
},
"suggestedActionBackground": {
"$role": "color",
"type": "string"
},
"suggestedActionBorderColor": {
"$role": "color",
"description": "defaults to accent",
"type": "string"
},
"suggestedActionBorderRadius": {
"type": "number"
},
"suggestedActionBorderStyle": {
"type": "string",
"enum": [
"dotted",
"dashed",
"solid",
"double",
"groove",
"ridge",
"inset",
"outset",
"none",
"hidden",
"mix"
]
},
"suggestedActionBorderWidth": {
"type": "number"
},
"suggestedActionDisabledBackground": {
"$role": "color",
"description": "",
"type": "string"
},
"suggestedActionDisabledBorderColor": {
"$role": "color",
"type": "string"
},
"suggestedActionDisabledBorderStyle": {
"type": "string",
"enum": [
"dotted",
"dashed",
"solid",
"double",
"groove",
"ridge",
"inset",
"outset",
"none",
"hidden",
"mix"
]
},
"suggestedActionDisabledTextColor": {
"$role": "color",
"description": "defaults to subtle",
"type": "string"
},
"suggestedActionLayout": {
"type": "string",
"enum": [
"carousel",
"stacked"
]
}
}
};
const uiOptions = {
fieldsets: [
{ title: 'Avatar', fields: ['avatarBorderRadius', 'avatarSize', 'botAvatarBackgroundColor', 'botAvatarImage', 'botAvatarInitials', 'userAvatarBackgroundColor', 'userAvatarImage', 'userAvatarInitials', 'showAvatarInGroup'] },
{ title: 'Bubble', fields: ['bubbleBackground'] },
{ title: 'Markdown', fields: ['markdownRespectCRLF'] },
{ title: 'Send box', fields: ['hideSendBox', 'hideUploadButton'] },
{ title: 'Suggested actions', fields: ['suggestedActionBackground', 'suggestedActionBorder'] },
{ title: 'Other' }]
};
export const WebChatDesigner: React.FC = () => {
const [styleOptions, setStyleOptions] = useState({});
return (
<div style={{ display: 'flex', height: '100%' }}>
<div style={{ flex: 1, background: 'lightgrey', textAlign: 'center' }}>
<ReactWebChat styleOptions={styleOptions} />
</div>
<div style={{ overflowY: 'auto' }}>
<AdaptiveForm formData={styleOptions} onChange={setStyleOptions} schema={schema} uiOptions={uiOptions} />
</div>
</div>
)
}
export default WebChatDesigner;
Playground to do items:
-
[ ] Reliable connection
-
[ ] Speech
-
[ ] Voice gender preference
-
[ ] Make all
defaultStyleOptionsconfigurable in the side panel- [ ] Color / padding / root
- [ ] Fonts
- [ ] Avatar
- [ ] Bubble
- [ ] Markdown
- [ ] Rich cards
- [ ] Send box
- [ ] Show spoken text
- [ ] Suggested actions
- [ ] Timestamp
- [ ] Transcript overlay buttons
- [ ] Video
- [ ] Connectivity
- [x] Typing animation
- [ ] Spinner animation
- [ ] Upload thumbnail
- [ ] Toast
- [ ] Emoji
- [x] Use fluent to intuitively group different sections/props
- [x] Use fluent to add info icons w/ descriptions / suggested commands
- [ ] Add a section in a side panel with a note that says 'Selecting these options will restart Web Chat':
- [ ] Changing
username - [ ] Changing
userID
- [ ] Changing
- [ ] Set up @emotion/core properly
-
[ ] Add buttons to manually test Mock Bot commands?
-
[ ] use utils to indicate what browser we're using
-
[ ] DARK MODE
-
[ ] Middleware: Connection status always visible
-
[ ] Middleware:
<ScreenReaderText>components visible -
[ ] Store whether last token fetch was from local or official MockBot
-
[ ] Change alerts and console logs to toasts
-
[ ] Enable search