From 622aa0f2b001e8b94b7974fdbf0d0e6998216d59 Mon Sep 17 00:00:00 2001 From: Eric Rosenbaum Date: Mon, 24 Sep 2018 17:16:10 -0400 Subject: [PATCH] =?UTF-8?q?Add=20=E2=80=9Cset=20language=E2=80=9D=20block?= =?UTF-8?q?=20(#1610)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/extensions/scratch3_text2speech/index.js | 71 +++++++++++++++++++- 1 file changed, 69 insertions(+), 2 deletions(-) diff --git a/src/extensions/scratch3_text2speech/index.js b/src/extensions/scratch3_text2speech/index.js index add1d55c3..39d8694d2 100644 --- a/src/extensions/scratch3_text2speech/index.js +++ b/src/extensions/scratch3_text2speech/index.js @@ -62,6 +62,12 @@ class Scratch3Text2SpeechBlocks { */ this.runtime = runtime; + /** + * The current language code to use for speech synthesis. + * @type {string} + */ + this.currentLanguage = 'en-US'; + /** * Map of soundPlayers by sound id. * @type {Map} @@ -132,6 +138,28 @@ class Scratch3Text2SpeechBlocks { }; } + /** + * An object with language names mapped to their language codes. + */ + get LANGUAGE_INFO () { + return { + 'Danish': 'da-DK', + 'Dutch': 'nl-NL', + 'English': 'en-US', + 'French': 'fr-FR', + 'German': 'de-DE', + 'Icelandic': 'is-IS', + 'Italian': 'it-IT', + 'Japanese': 'ja-JP', + 'Polish': 'pl-PL', + 'Portuguese (Brazilian)': 'pt-BR', + 'Portuguese (European)': 'pt-PT', + 'Russian': 'ru-RU', + 'Spanish (European)': 'es-ES', + 'Spanish (Latin American)': 'es-US' + }; + } + /** * The key to load & store a target's text2speech state. * @return {string} The key. @@ -224,10 +252,27 @@ class Scratch3Text2SpeechBlocks { defaultValue: QUINN_ID } } + }, + { + opcode: 'setLanguage', + text: formatMessage({ + id: 'text2speech.setLanguageBlock', + default: 'set language to [LANGUAGE]', + description: 'Set the language for speech synthesis.' + }), + blockType: BlockType.COMMAND, + arguments: { + LANGUAGE: { + type: ArgumentType.STRING, + menu: 'languages', + defaultValue: this.currentLanguage + } + } } ], menus: { - voices: this.getVoiceMenu() + voices: this.getVoiceMenu(), + languages: this.getLanguageMenu() } }; } @@ -260,6 +305,17 @@ class Scratch3Text2SpeechBlocks { })); } + /** + * Get the menu of languages for the "set language" block. + * @return {array} the text and value for each menu item. + */ + getLanguageMenu () { + return Object.keys(this.LANGUAGE_INFO).map(languageName => ({ + text: languageName, + value: this.LANGUAGE_INFO[languageName] + })); + } + /** * Set the voice for speech synthesis for this sprite. * @param {object} args Block arguments @@ -274,6 +330,17 @@ class Scratch3Text2SpeechBlocks { } } + /** + * Set the language for speech synthesis. + * @param {object} args Block arguments + */ + setLanguage (args) { + // Only set the language if the arg is a valid language code. + if (Object.values(this.LANGUAGE_INFO).includes(args.LANGUAGE)) { + this.currentLanguage = args.LANGUAGE; + } + } + /** * Stop all currently playing speech sounds. */ @@ -305,7 +372,7 @@ class Scratch3Text2SpeechBlocks { // Build up URL let path = `${SERVER_HOST}/synth`; - path += `?locale=${this.getViewerLanguageCode()}`; + path += `?locale=${this.currentLanguage}`; path += `&gender=${gender}`; path += `&text=${encodeURI(words.substring(0, 128))}`;