diff --git a/CHANGELOG.md b/CHANGELOG.md index 3629a9f230..ee92a953f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -91,6 +91,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - Fix [#2415](https://github.com/microsoft/BotFramework-WebChat/issues/2415) and [#2416](https://github.com/microsoft/BotFramework-WebChat/issues/2416). Fix receipt card rendering, by [@compulim](https://github.com/compulim) in PR [#2417](https://github.com/microsoft/BotFramework-WebChat/issues/2417) - Fix [#2415](https://github.com/microsoft/BotFramework-WebChat/issues/2415) and [#2416](https://github.com/microsoft/BotFramework-WebChat/issues/2416). Fix Adaptive Cards cannot be disabled on-the-fly, by [@compulim](https://github.com/compulim) in PR [#2417](https://github.com/microsoft/BotFramework-WebChat/issues/2417) - Fix [#2360](https://github.com/microsoft/BotFramework-WebChat/issues/2360). Timestamp should update on language change, by [@compulim](https://github.com/compulim) in PR [#2414](https://github.com/microsoft/BotFramework-WebChat/pull/2414) +- Fix [#2428](https://github.com/microsoft/BotFramework-WebChat/issues/2428). Should interrupt speech synthesis after microphone button is clicked, by [@compulim](https://github.com/compulim) in PR [#2429](https://github.com/microsoft/BotFramework-WebChat/pull/2429) ### Added diff --git a/__tests__/speech.synthesis.js b/__tests__/speech.synthesis.js index 5a8aa48f32..f10b141096 100644 --- a/__tests__/speech.synthesis.js +++ b/__tests__/speech.synthesis.js @@ -1,6 +1,7 @@ import { timeouts } from './constants.json'; import minNumActivitiesShown from './setup/conditions/minNumActivitiesShown'; +import negateCondition from './setup/conditions/negate'; import speechRecognitionStartCalled from './setup/conditions/speechRecognitionStartCalled'; import speechSynthesisUtterancePended from './setup/conditions/speechSynthesisUtterancePended'; @@ -98,4 +99,29 @@ describe('speech synthesis', () => { expect((await pageObjects.getConsoleLogs()).filter(([type]) => type === 'error')).toEqual([]); }); + + test('should stop synthesis after clicking on microphone button', async () => { + const { driver, pageObjects } = await setupWebDriver({ + props: { + webSpeechPonyfillFactory: () => window.WebSpeechMock + } + }); + + await pageObjects.sendMessageViaMicrophone('echo Hello, World!'); + + await expect(speechRecognitionStartCalled().fn(driver)).resolves.toBeFalsy(); + await driver.wait(minNumActivitiesShown(2), timeouts.directLine); + + await expect(pageObjects.startSpeechSynthesize()).resolves.toHaveProperty( + 'text', + 'Echoing back in a separate activity.' + ); + + await driver.wait(speechSynthesisUtterancePended(), timeouts.ui); + + await pageObjects.clickMicrophoneButton(); + + await expect(speechRecognitionStartCalled().fn(driver)).resolves.toBeTruthy(); + await driver.wait(negateCondition(speechSynthesisUtterancePended()), timeouts.ui); + }); }); diff --git a/packages/component/src/SendBox/MicrophoneButton.js b/packages/component/src/SendBox/MicrophoneButton.js index b7e138a272..97de6addca 100644 --- a/packages/component/src/SendBox/MicrophoneButton.js +++ b/packages/component/src/SendBox/MicrophoneButton.js @@ -52,6 +52,7 @@ const connectMicrophoneButton = (...selectors) => { setSendBox, startDictate, stopDictate, + stopSpeakingActivity, webSpeechPonyfill: { speechSynthesis, SpeechSynthesisUtterance } = {} }) => ({ click: () => { @@ -59,6 +60,7 @@ const connectMicrophoneButton = (...selectors) => { stopDictate(); setSendBox(dictateInterims.join(' ')); } else { + stopSpeakingActivity(); startDictate(); } diff --git a/packages/embed/package-lock.json b/packages/embed/package-lock.json index 903f9a3e71..dbeda5a7a2 100644 --- a/packages/embed/package-lock.json +++ b/packages/embed/package-lock.json @@ -2677,9 +2677,9 @@ "dev": true }, "csv-parse": { - "version": "4.4.5", - "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.4.5.tgz", - "integrity": "sha512-koPV9m9AjNJCK3ig4ErgRJalZsLxWI7NP0Fd3+CO9hgDZt3FSljTeESnfWTbyRc8qk/3/LgX1s5naDqLxiuK9w==", + "version": "4.4.7", + "resolved": "https://registry.npmjs.org/csv-parse/-/csv-parse-4.4.7.tgz", + "integrity": "sha512-QfjZ9mhBHcNDUM7Ab1sLC5HNa7wVFSl5jDK3lpM0YyvAUb9bVgO1Veht13tWJno8cEZ2eSowFDwcvRCO4BVvNA==", "dev": true }, "csv-stringify": { @@ -4433,9 +4433,9 @@ "dev": true }, "handlebars": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.1.2.tgz", - "integrity": "sha512-nvfrjqvt9xQ8Z/w0ijewdD/vvWDTOweBUm96NTr66Wfvo1mJenBLwcYmPs3TIBP5ruzYGD7Hx/DaM9RmhroGPw==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.3.1.tgz", + "integrity": "sha512-c0HoNHzDiHpBt4Kqe99N8tdLPKAnGCQ73gYMPWtAYM4PwGnf7xl8PBUHJqh9ijlzt2uQKaSRxbXRt+rZ7M2/kA==", "dev": true, "requires": { "neo-async": "^2.6.0", diff --git a/samples/06.a.cognitive-services-bing-speech-js/index.html b/samples/06.a.cognitive-services-bing-speech-js/index.html index 04dce91054..083c2d3133 100644 --- a/samples/06.a.cognitive-services-bing-speech-js/index.html +++ b/samples/06.a.cognitive-services-bing-speech-js/index.html @@ -56,7 +56,7 @@ } // Pass a Web Speech ponyfill factory to renderWebChat. - // You can also use your own speech engine given it is compliant to W3C Web Speech API, https://w3c.github.io/speech-api/. + // You can also use your own speech engine given it is compliant to W3C Web Speech API: https://w3c.github.io/speech-api/. // For implementor, look at createBrowserWebSpeechPonyfill.js for details. window.WebChat.renderWebChat( { diff --git a/samples/06.b.cognitive-services-bing-speech-react/index.html b/samples/06.b.cognitive-services-bing-speech-react/index.html index f41dd8f2ae..a62b286979 100644 --- a/samples/06.b.cognitive-services-bing-speech-react/index.html +++ b/samples/06.b.cognitive-services-bing-speech-react/index.html @@ -68,7 +68,7 @@ } // Pass a Web Speech ponyfill factory to renderWebChat. - // You can also use your own speech engine given it is complaint to W3C Web Speech API, https://w3c.github.io/speech-api/. + // You can also use your own speech engine given it is complaint to W3C Web Speech API: https://w3c.github.io/speech-api/. // For implementor, look at createBrowserWebSpeechPonyfill.js for details. render( , diff --git a/samples/06.c.cognitive-services-speech-services-js/README.md b/samples/06.c.cognitive-services-speech-services-js/README.md index 46c4160088..7d7ef76a05 100644 --- a/samples/06.c.cognitive-services-speech-services-js/README.md +++ b/samples/06.c.cognitive-services-speech-services-js/README.md @@ -34,100 +34,72 @@ Cognitive Services Speech Services has published a new API to provide speech rec ## Completed code -#### Using subscription key - -> This approach is for demonstration purposes only. In production code, you should always store the subscription key on a secured token server. The token server should only send out limited authorization code. This [article on authorizations](https://docs.microsoft.com/en-us/azure/cognitive-services/speech/api-reference-rest/websocketprotocol#authorization) outlines the authorization process. - -In this portion, we are hardcoding the subscription key in the client code. - -Here is the finished `index.html` for subscription key flow: +### Using authorization token ```diff - - - - Web Chat: Cognitive Services Speech Services using JavaScript - - - - - -
- + + + +
+ - - -``` - -#### Using authorization token + window.WebChat.renderWebChat({ + directLine: window.WebChat.createDirectLine({ token }), ++ webSpeechPonyfillFactory + }, document.getElementById('webchat')); -```diff - - - - Web Chat: Cognitive Services Speech Services using JavaScript - - - - -
- - - + document.querySelector('#webchat > *').focus(); + })().catch(err => console.error(err)); + + + ``` # Further reading diff --git a/samples/06.c.cognitive-services-speech-services-js/index.html b/samples/06.c.cognitive-services-speech-services-js/index.html index 915b20c1eb..7c39629406 100644 --- a/samples/06.c.cognitive-services-speech-services-js/index.html +++ b/samples/06.c.cognitive-services-speech-services-js/index.html @@ -28,39 +28,62 @@
- - - -
- + + + +
+ - - + + window.WebChat.renderWebChat({ + directLine: window.WebChat.createDirectLine({ token }), +- webSpeechPonyfillFactory ++ webSpeechPonyfillFactory: await createHybridPonyfillFactory({ authorizationToken, region }) + }, document.getElementById('webchat')); + + document.querySelector('#webchat > *').focus(); + })().catch(err => console.error(err)); + + + ``` # Further Reading diff --git a/samples/06.f.hybrid-speech/index.html b/samples/06.f.hybrid-speech/index.html index c4a70fa176..14c69c626a 100644 --- a/samples/06.f.hybrid-speech/index.html +++ b/samples/06.f.hybrid-speech/index.html @@ -28,6 +28,41 @@
+ + + +
+ + + +``` + +# Further Reading + +- [Cognitive Speech Speech Services](https://azure.microsoft.com/en-us/services/cognitive-services/speech-services/) +- [W3C Web Speech API](https://w3c.github.io/speech-api/) +- [JavaScript Factory Functions with ES6+](https://medium.com/javascript-scene/javascript-factory-functions-with-es6-4d224591a8b1) + +- [Cognitive Services Speech Services bot](https://microsoft.github.io/BotFramework-WebChat/06.c.cognitive-services-speech-services-js) | [(Cognitive Services Speech Services source code)](https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/06.c.cognitive-services-speech-services-js) +- [Speech Web browser bot](https://microsoft.github.io/BotFramework-WebChat/06.f.hybrid-speech) | [(Speech Web browser source code)](https://github.com/microsoft/BotFramework-WebChat/tree/master/samples/06.f.hybrid-speech) + +## Full list of Web Chat hosted samples + +View the list of [available Web Chat samples](https://github.com/microsoft/BotFramework-WebChat/tree/master/samples) --> diff --git a/samples/06.h.cognitive-services-speech-recognition-only/index.html b/samples/06.h.cognitive-services-speech-recognition-only/index.html new file mode 100644 index 0000000000..034d6d71c5 --- /dev/null +++ b/samples/06.h.cognitive-services-speech-recognition-only/index.html @@ -0,0 +1,118 @@ + + + + Web Chat: Speech recognition only + + + + + + + + +
+ + +