diff --git a/CHANGELOG.md b/CHANGELOG.md index 8208167d94..88b8de86c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. ### Fixed - Fixes [#3489](https://github.com/microsoft/BotFramework-WebChat/issues/3489). Fix AT saying 'Bot undefined said', by [@corinagum](https://github.com/corinagum) in PR [#3524](https://github.com/microsoft/BotFramework-WebChat/pull/3524) +- Fixes [#3371](https://github.com/microsoft/BotFramework-WebChat/issues/3371). Add alt property for image in HeroCards, by [@corinagum](https://github.com/corinagum) in PR [#3541](https://github.com/microsoft/BotFramework-WebChat/pull/3541) +- Fixes [#3310](https://github.com/microsoft/BotFramework-WebChat/issues/3310). Add quantity, tap and text field to ReceiptCards, by [@corinagum](https://github.com/corinagum) in PR [#3541](https://github.com/microsoft/BotFramework-WebChat/pull/3541) ### Changed @@ -36,6 +38,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Resolves [#3281](https://github.com/microsoft/BotFramework-WebChat/issues/3281). Added documentation on speech permissions for Cordova apps on Android, by [@corinagum](https://github.com/corinagum), in PR [#3508](https://github.com/microsoft/BotFramework-WebChat/pull/3508) +### Samples + +- Fixes [#3526](https://github.com/microsoft/BotFramework-WebChat/issues/3526). Add info on composition mode in sample 06.d, by [@corinagum](https://github.com/corinagum) in PR [#3541](https://github.com/microsoft/BotFramework-WebChat/pull/3541) + ## [4.10.1] - 2020-09-09 ### Breaking changes diff --git a/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-5-px-should-have-corner-radius-of-5-px-2-snap.png b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-5-px-should-have-corner-radius-of-5-px-2-snap.png new file mode 100644 index 0000000000..b27567718c Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/bubble-nub-js-bubble-nub-at-corner-with-offset-of-5-px-should-have-corner-radius-of-5-px-2-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-hero-card-2-snap.png b/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-hero-card-2-snap.png new file mode 100644 index 0000000000..2dc39fa8ab Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-hero-card-2-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-receipt-card-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-receipt-card-1-snap.png index df0151d578..09a23c1f01 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-receipt-card-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-receipt-card-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-receipt-card-with-quantity-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-receipt-card-with-quantity-1-snap.png new file mode 100644 index 0000000000..8adf9d5c6a Binary files /dev/null and b/__tests__/__image_snapshots__/chrome-docker/rich-cards-js-receipt-card-with-quantity-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-should-scroll-to-bottom-on-send-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-should-scroll-to-bottom-on-send-1-snap.png index 7040876d09..acc199c08b 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-should-scroll-to-bottom-on-send-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-should-scroll-to-bottom-on-send-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-show-new-messages-button-only-when-new-message-come-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-show-new-messages-button-only-when-new-message-come-1-snap.png index 7cb02f32b7..c4de75e7a1 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-show-new-messages-button-only-when-new-message-come-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/scroll-to-bottom-js-show-new-messages-button-only-when-new-message-come-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-1-snap.png index be834929dd..d71298d730 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-1-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-2-snap.png b/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-2-snap.png index f45e627b08..7d5c9092ae 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-2-snap.png and b/__tests__/__image_snapshots__/chrome-docker/use-text-box-js-calling-submit-should-scroll-to-end-2-snap.png differ diff --git a/__tests__/__image_snapshots__/chrome-docker/video-js-video-1-snap.png b/__tests__/__image_snapshots__/chrome-docker/video-js-video-1-snap.png index 89ae7b0629..8e4120d9ec 100644 Binary files a/__tests__/__image_snapshots__/chrome-docker/video-js-video-1-snap.png and b/__tests__/__image_snapshots__/chrome-docker/video-js-video-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/accessibility-adaptive-card-interactive-js-accessibility-requirement-interactive-adaptive-card-should-be-focusable-1-snap.png b/__tests__/__image_snapshots__/html/accessibility-adaptive-card-interactive-js-accessibility-requirement-interactive-adaptive-card-should-be-focusable-1-snap.png index 98d2b346de..525ad8bbf6 100644 Binary files a/__tests__/__image_snapshots__/html/accessibility-adaptive-card-interactive-js-accessibility-requirement-interactive-adaptive-card-should-be-focusable-1-snap.png and b/__tests__/__image_snapshots__/html/accessibility-adaptive-card-interactive-js-accessibility-requirement-interactive-adaptive-card-should-be-focusable-1-snap.png differ diff --git a/__tests__/__image_snapshots__/html/transcript-activity-grouping-js-transcript-with-activity-grouping-test-8-2-snap.png b/__tests__/__image_snapshots__/html/transcript-activity-grouping-js-transcript-with-activity-grouping-test-8-2-snap.png new file mode 100644 index 0000000000..7a8d0c867a Binary files /dev/null and b/__tests__/__image_snapshots__/html/transcript-activity-grouping-js-transcript-with-activity-grouping-test-8-2-snap.png differ diff --git a/__tests__/richCards.js b/__tests__/richCards.js index bf8dba12c1..1ae4e88d79 100644 --- a/__tests__/richCards.js +++ b/__tests__/richCards.js @@ -68,6 +68,22 @@ test('receipt card', async () => { await driver.wait(minNumActivitiesShown(2), timeouts.directLine); await driver.wait(allImagesLoaded(), timeouts.fetchImage); + await driver.wait(scrollToBottomCompleted(), timeouts.scrollToBottom); + + const base64PNG = await driver.takeScreenshot(); + + expect(base64PNG).toMatchImageSnapshot(imageSnapshotOptions); +}); + +test('receipt card with quantity', async () => { + const { driver, pageObjects } = await setupWebDriver(); + + await driver.wait(uiConnected(), timeouts.directLine); + await pageObjects.sendMessageViaSendBox('receiptcard2', { waitForSend: true }); + + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + await driver.wait(allImagesLoaded(), timeouts.fetchImage); + await driver.wait(scrollToBottomCompleted(), timeouts.scrollToBottom); const base64PNG = await driver.takeScreenshot(); diff --git a/__tests__/video.js b/__tests__/video.js index c5c459b776..19a0472c82 100644 --- a/__tests__/video.js +++ b/__tests__/video.js @@ -13,9 +13,9 @@ jest.setTimeout(timeouts.test); async function clickButton(driver, locator) { await driver.wait(until.elementLocated(locator), timeouts.ui); - const pauseButton = await driver.findElement(locator); + const button = await driver.findElement(locator); - await pauseButton.click(); + await button.click(); } test('video', async () => { @@ -38,23 +38,28 @@ test('video', async () => { await clickButton(driver, By.css('button[aria-label="Pause (k)"]')); // Jump back for 10 seconds, to get the buffering bar the same - await driver - .actions() - .sendKeys('j') - .perform(); + await driver.actions().sendKeys('j').perform(); - // Wait for YouTube play/pause/rewind animation to complete - await driver.sleep(1000); + // Wait for controls to fade in + await driver.sleep(500); - // Hide the spinner animation + // Hide the spinner, play/pause/rewind and controls await driver.executeScript(() => { const spinner = document.querySelector('.ytp-spinner'); spinner && spinner.remove(); - const loadProgress = document.querySelector('.ytp-load-progress'); + const bezelText = document.querySelector('.ytp-bezel-text-hide'); - loadProgress && loadProgress.setAttribute('hidden', 'hidden'); + bezelText && bezelText.setAttribute('hidden', 'hidden'); + + const chromeBottom = document.querySelector('.ytp-chrome-bottom'); + + chromeBottom && chromeBottom.setAttribute('hidden', 'hidden'); + + const tooltip = document.querySelector('.ytp-tooltip'); + + tooltip && tooltip.setAttribute('hidden', 'hidden'); }); const base64PNG = await driver.takeScreenshot(); diff --git a/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardBuilder.ts b/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardBuilder.ts index 94a5e181ba..622f07cc3d 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardBuilder.ts +++ b/packages/bundle/src/adaptiveCards/Attachment/AdaptiveCardBuilder.ts @@ -64,9 +64,10 @@ export default class AdaptiveCardBuilder { this.card.addItem(this.container); } - addColumnSet(sizes: number[], container: Container = this.container) { + addColumnSet(sizes: number[], container: Container = this.container, selectAction?: CardAction) { const columnSet = new ColumnSet(); + columnSet.selectAction = selectAction && addCardAction(selectAction); container.addItem(columnSet); return sizes.map(size => { @@ -123,11 +124,12 @@ export default class AdaptiveCardBuilder { this.addButtons(content.buttons); } - addImage(url: string, container?: Container, selectAction?: CardAction) { + addImage(url: string, container?: Container, selectAction?: CardAction, altText?: string) { container = container || this.container; const image = new Image(); + image.altText = altText; image.url = url; image.selectAction = selectAction && addCardAction(selectAction); image.size = Size.Stretch; diff --git a/packages/bundle/src/adaptiveCards/Attachment/HeroCardAttachment.js b/packages/bundle/src/adaptiveCards/Attachment/HeroCardAttachment.js index cfc75bfc52..eb66864816 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/HeroCardAttachment.js +++ b/packages/bundle/src/adaptiveCards/Attachment/HeroCardAttachment.js @@ -13,7 +13,18 @@ HeroCardAttachment.defaultProps = { HeroCardAttachment.propTypes = { attachment: PropTypes.shape({ content: PropTypes.shape({ - tap: PropTypes.any + buttons: PropTypes.any, + images: PropTypes.arrayOf( + PropTypes.shape({ + alt: PropTypes.string.isRequired, + tap: PropTypes.any, + url: PropTypes.string.isRequired + }) + ), + subtitle: PropTypes.string, + tap: PropTypes.any, + text: PropTypes.string, + title: PropTypes.string }).isRequired }).isRequired, disabled: PropTypes.bool diff --git a/packages/bundle/src/adaptiveCards/Attachment/HeroCardContent.js b/packages/bundle/src/adaptiveCards/Attachment/HeroCardContent.js index d4bf6430f9..d940b0e0c5 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/HeroCardContent.js +++ b/packages/bundle/src/adaptiveCards/Attachment/HeroCardContent.js @@ -16,7 +16,7 @@ const HeroCardContent = ({ actionPerformedClassName, content, disabled }) => { const builder = new AdaptiveCardBuilder(adaptiveCardsPackage, styleOptions, direction); if (content) { - (content.images || []).forEach(image => builder.addImage(image.url, null, image.tap)); + (content.images || []).forEach(image => builder.addImage(image.url, null, image.tap, image.alt)); builder.addCommon(content); @@ -44,8 +44,9 @@ HeroCardContent.propTypes = { content: PropTypes.shape({ images: PropTypes.arrayOf( PropTypes.shape({ + alt: PropTypes.string.isRequired, tap: PropTypes.any, - url: PropTypes.string + url: PropTypes.string.isRequired }) ), tap: PropTypes.any diff --git a/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardAttachment.js b/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardAttachment.js index 9026e6469a..5f75b9bbaf 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardAttachment.js +++ b/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardAttachment.js @@ -24,11 +24,15 @@ ReceiptCardAttachment.propTypes = { items: PropTypes.arrayOf( PropTypes.shape({ image: PropTypes.shape({ + alt: PropTypes.string.isRequired, tap: PropTypes.any, url: PropTypes.string.isRequired }), price: PropTypes.string.isRequired, + quantity: PropTypes.string, subtitle: PropTypes.string, + tap: PropTypes.any, + text: PropTypes.string, title: PropTypes.string.isRequired }) ), diff --git a/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardContent.js b/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardContent.js index 2b14af4f40..9c6cf3fa56 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardContent.js +++ b/packages/bundle/src/adaptiveCards/Attachment/ReceiptCardContent.js @@ -1,4 +1,4 @@ -/* eslint no-magic-numbers: ["error", { "ignore": [0, 1, 10, 15, 25, 75] }] */ +/* eslint no-magic-numbers: ["error", { "ignore": [0, 1, 10, 15, 25, 50, 75] }] */ import { hooks } from 'botframework-webchat-component'; import PropTypes from 'prop-types'; @@ -47,27 +47,31 @@ const ReceiptCardContent = ({ actionPerformedClassName, content, disabled }) => } items && - items.map(({ image: { tap, url } = {}, price, subtitle, title }) => { + items.map(({ image: { alt, tap: imageTap, url } = {}, price, quantity, subtitle, tap, text, title }) => { let itemColumns; if (url) { const [itemImageColumn, ...columns] = builder.addColumnSet([15, 75, 10]); itemColumns = columns; - builder.addImage(url, itemImageColumn, tap); + builder.addImage(url, itemImageColumn, imageTap, alt); } else { - itemColumns = builder.addColumnSet([75, 25]); + itemColumns = builder.addColumnSet([75, 25], undefined, tap && tap); } const [itemTitleColumn, itemPriceColumn] = itemColumns; builder.addTextBlock( - title, + quantity ? `${title} × ${quantity}` : title, { size: TextSize.Medium, weight: TextWeight.Bolder, wrap: richCardWrapTitle }, itemTitleColumn ); builder.addTextBlock(subtitle, { size: TextSize.Medium, wrap: richCardWrapTitle }, itemTitleColumn); builder.addTextBlock(price, { horizontalAlignment: HorizontalAlignment.Right }, itemPriceColumn); + + if (text) { + builder.addTextBlock(text, { size: TextSize.Medium, wrap: richCardWrapTitle }, itemTitleColumn); + } }); if (!nullOrUndefined(vat)) { @@ -129,11 +133,15 @@ ReceiptCardContent.propTypes = { items: PropTypes.arrayOf( PropTypes.shape({ image: PropTypes.shape({ + alt: PropTypes.string.isRequired, tap: PropTypes.any, url: PropTypes.string.isRequired }), price: PropTypes.string.isRequired, + quantity: PropTypes.string, subtitle: PropTypes.string, + tap: PropTypes.any, + text: PropTypes.string, title: PropTypes.string.isRequired }) ), diff --git a/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardAttachment.js b/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardAttachment.js index 9bac7d2423..e73a3dcfe9 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardAttachment.js +++ b/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardAttachment.js @@ -17,6 +17,7 @@ ThumbnailCardAttachment.propTypes = { buttons: PropTypes.array, images: PropTypes.arrayOf( PropTypes.shape({ + alt: PropTypes.string.isRequired, tap: PropTypes.any, url: PropTypes.string.isRequired }) diff --git a/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardContent.js b/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardContent.js index 9b10a22150..bd2c6446a8 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardContent.js +++ b/packages/bundle/src/adaptiveCards/Attachment/ThumbnailCardContent.js @@ -23,7 +23,7 @@ const ThumbnailCardContent = ({ actionPerformedClassName, content, disabled }) = if (images && images.length) { const [firstColumn, lastColumn] = builder.addColumnSet([75, 25]); - const [{ tap, url }] = images; + const [{ alt, tap, url }] = images; builder.addTextBlock( title, @@ -32,7 +32,7 @@ const ThumbnailCardContent = ({ actionPerformedClassName, content, disabled }) = ); builder.addTextBlock(subtitle, { isSubtle: true, wrap: richCardWrapTitle }, firstColumn); - builder.addImage(url, lastColumn, tap); + builder.addImage(url, lastColumn, tap, alt); builder.addTextBlock(text, { wrap: true }); builder.addButtons(buttons); } else { @@ -63,6 +63,7 @@ ThumbnailCardContent.propTypes = { buttons: PropTypes.array, images: PropTypes.arrayOf( PropTypes.shape({ + alt: PropTypes.string.isRequired, tap: PropTypes.any, url: PropTypes.string.isRequired }) diff --git a/packages/bundle/src/adaptiveCards/Attachment/VideoCardAttachment.js b/packages/bundle/src/adaptiveCards/Attachment/VideoCardAttachment.js index ece216add9..a65e775e2f 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/VideoCardAttachment.js +++ b/packages/bundle/src/adaptiveCards/Attachment/VideoCardAttachment.js @@ -19,10 +19,11 @@ VideoCardAttachment.propTypes = { autoloop: PropTypes.bool, autostart: PropTypes.bool, image: PropTypes.shape({ - url: PropTypes.string + url: PropTypes.string.isRequired }), media: PropTypes.arrayOf( PropTypes.shape({ + profile: PropTypes.string.isRequired, url: PropTypes.string }) ) diff --git a/packages/bundle/src/adaptiveCards/Attachment/VideoCardContent.js b/packages/bundle/src/adaptiveCards/Attachment/VideoCardContent.js index 58ccea4f97..ae2d2adff4 100644 --- a/packages/bundle/src/adaptiveCards/Attachment/VideoCardContent.js +++ b/packages/bundle/src/adaptiveCards/Attachment/VideoCardContent.js @@ -38,11 +38,12 @@ VideoCardContent.propTypes = { autoloop: PropTypes.bool, autostart: PropTypes.bool, image: PropTypes.shape({ - url: PropTypes.string + url: PropTypes.string.isRequired }), media: PropTypes.arrayOf( PropTypes.shape({ - url: PropTypes.string + profile: PropTypes.string.isRequired, + url: PropTypes.string.isRequired }) ) }).isRequired, diff --git a/packages/component/src/Composer.js b/packages/component/src/Composer.js index cd8462ff05..9f67020b9d 100644 --- a/packages/component/src/Composer.js +++ b/packages/component/src/Composer.js @@ -1,3 +1,5 @@ +/* eslint-disable react/prop-types */ +/* eslint-disable react/destructuring-assignment */ import { Composer as SayComposer } from 'react-say'; import { Composer as ScrollToBottomComposer } from 'react-scroll-to-bottom'; diff --git a/packages/component/src/SendBox/SuggestedActions.js b/packages/component/src/SendBox/SuggestedActions.js index d884b1fa87..d28bbe7525 100644 --- a/packages/component/src/SendBox/SuggestedActions.js +++ b/packages/component/src/SendBox/SuggestedActions.js @@ -70,7 +70,11 @@ const SuggestedActions = ({ className, suggestedActions = [] }) => { flipperBoxWidth: suggestedActionsCarouselFlipperBoxWidth, flipperSize: suggestedActionsCarouselFlipperSize }), - [] + [ + suggestedActionsCarouselFlipperBoxWidth, + suggestedActionsCarouselFlipperCursor, + suggestedActionsCarouselFlipperSize + ] ); const suggestedActionsContainerText = localize( diff --git a/packages/component/src/Utils/InlineMarkdown.js b/packages/component/src/Utils/InlineMarkdown.js index 0f7c17c1f3..85ace47525 100644 --- a/packages/component/src/Utils/InlineMarkdown.js +++ b/packages/component/src/Utils/InlineMarkdown.js @@ -67,7 +67,7 @@ const InlineMarkdown = ({ children, onReference, references }) => { padding: 0 } }) + '', - [accent] + [accent, styleToClassName] ); // Markdown-It only support references in uppercase. diff --git a/packages/directlinespeech/src/playCognitiveServicesStream.js b/packages/directlinespeech/src/playCognitiveServicesStream.js index a6ac97579a..39a7b8f52f 100644 --- a/packages/directlinespeech/src/playCognitiveServicesStream.js +++ b/packages/directlinespeech/src/playCognitiveServicesStream.js @@ -123,6 +123,7 @@ export default async function playCognitiveServicesStream(audioContext, stream, const read = () => Promise.race([ // Abort will gracefully end the queue. We will check signal.aborted later to throw abort exception. + // eslint-disable-next-line no-empty-function abortPromise.catch(() => {}), streamRead(array.buffer).then(numBytes => numBytes === array.byteLength ? array : numBytes ? array.slice(0, numBytes) : undefined diff --git a/packages/playground/package.json b/packages/playground/package.json index 9ba679c155..c7d43c80b3 100644 --- a/packages/playground/package.json +++ b/packages/playground/package.json @@ -14,6 +14,7 @@ "adaptivecards": "1.2.6", "botframework-directlinejs": "^0.13.0", "botframework-webchat": "0.0.0-0", + "botframework-webchat-core": "0.0.0-0", "classnames": "2.2.6", "memoize-one": "5.1.1", "on-error-resume-next": "1.1.0", diff --git a/packages/playground/src/DropdownOptions.js b/packages/playground/src/DropdownOptions.js index 373272e697..524f414a10 100644 --- a/packages/playground/src/DropdownOptions.js +++ b/packages/playground/src/DropdownOptions.js @@ -10,8 +10,8 @@ const dirOptions = [ ]; const groupTimestampOptions = [ - { key: true, text: 'Show timestamp (default)' }, - { key: false, text: "Don't show timestamp" }, + { key: 'true', text: 'Show timestamp (default)' }, + { key: 'false', text: "Don't show timestamp" }, { key: 0, text: "Don't group" }, { key: 1000, text: '1 second' }, { key: 2000, text: '2 seconds' }, @@ -90,7 +90,7 @@ const sendTimeoutOptions = [ ]; const speechOptions = [ - { key: 'off', text: 'Disabled (default)' }, + { key: false, text: 'Disabled (default)' }, { key: 'speechservices', text: 'Speech services' }, { key: 'webspeech', text: 'Web speech' } ]; diff --git a/samples/06.recomposing-ui/d.plain-ui/README.md b/samples/06.recomposing-ui/d.plain-ui/README.md index c9462ad2ad..ee6e31ae43 100644 --- a/samples/06.recomposing-ui/d.plain-ui/README.md +++ b/samples/06.recomposing-ui/d.plain-ui/README.md @@ -6,7 +6,7 @@ When we designed Web Chat, we heavily considered the importance of customization 1. Using all of our layers: using all of our layers as-is, 2. Using just business layers: building their own UI from the ground up using Web Chat's business logic, or -3. Using business layers and some UI components: opting into our UI but replacing just a handful of components as needed. +3. Using business layers and some UI components: opting into our UI but replacing just a handful of components as needed. Note that composition mode is not available in all scenarios (e.g. adding further functionality like a button to the SendBox). In this sample, we are demonstrating the ability to rebuild Web Chat UI using just the business layer of Web Chat.