define(['dialogHelper', 'jQuery'], function (dialogHelper, $) { var currentRecognition; var lang = 'en-US'; var commandgroups; function getCommandGroups() { if (commandgroups) { return Promise.resolve(commandgroups); } return new Promise(function (resolve, reject) { var file = "grammar"; //if (language && language.length > 0) // file = language; var xhr = new XMLHttpRequest(); xhr.open('GET', "voice/grammar/" + file + ".json", true); xhr.onload = function (e) { commandgroups = JSON.parse(this.response); resolve(commandgroups); } xhr.onerror = reject; xhr.send(); }); } /// Shuffle array. /// The array. /// array function shuffleArray(array) { var currentIndex = array.length, temporaryValue, randomIndex; // While there remain elements to shuffle... while (0 !== currentIndex) { // Pick a remaining element... randomIndex = Math.floor(Math.random() * currentIndex); currentIndex -= 1; // And swap it with the current element. temporaryValue = array[currentIndex]; array[currentIndex] = array[randomIndex]; array[randomIndex] = temporaryValue; } return array; } /// Gets sample commands. /// The sample commands. function getSampleCommands(groupid) { return getCommandGroups().then(function (commandGroups) { groupid = typeof (groupid) !== 'undefined' ? groupid : ''; var commands = []; commandGroups.map(function (group) { if ((group.items && group.items.length > 0) && (groupid == group.groupid || groupid == '')) { group.items.map(function (item) { if (item.commandtemplates && item.commandtemplates.length > 0) { item.commandtemplates.map(function (templates) { commands.push(templates); }); } }); } }); return shuffleArray(commands); }); } /// Gets command group. /// The groupid. /// The command group. function getCommandGroup(groupid) { if (commandgroups) { var idx = -1; idx = commandgroups.map(function (e) { return e.groupid; }).indexOf(groupid); if (idx > -1) return commandgroups[idx]; else return null; } else return null; } /// Renders the sample commands. /// The element. /// The commands. /// . function renderSampleCommands(elem, commands) { commands.length = Math.min(commands.length, 4); commands = commands.map(function (c) { return '
"' + c + '"
'; }).join(''); $('.exampleCommands', elem).html(commands); } var currentDialog; /// Shows the voice help. /// . function showVoiceHelp(groupid, title) { var dlg = dialogHelper.createDialog({ size: 'medium', removeOnClose: true }); dlg.classList.add('ui-body-b'); dlg.classList.add('background-theme-b'); var html = ''; html += '

'; html += ''; if (groupid) { var grp = getCommandGroup(groupid); if (grp) html += ' ' + grp.name; } html += '

'; html += '
'; var getCommandsPromise = getSampleCommands(groupid); html += '
'; html += '
'; html += '

' + Globalize.translate('HeaderSaySomethingLike') + '

'; html += '
'; html += '
'; // defaultVoiceHelp html += '
'; html += ''; html += '' + Globalize.translate('ButtonCancel') + ''; // voiceHelpContent html += '
'; html += '
'; dlg.innerHTML = html; document.body.appendChild(dlg); dialogHelper.open(dlg); currentDialog = dlg; dlg.addEventListener('close', function () { currentDialog = null; }); $('.btnCancelVoiceInput', dlg).on('click', function () { destroyCurrentRecognition(); dialogHelper.close(dlg); }); $('.btnRetry', dlg).on('click', function () { $('.unrecognizedCommand').hide(); $('.defaultVoiceHelp').show(); startListening(false); }); getCommandsPromise.then(function (commands) { renderSampleCommands(dlg.querySelector('.voiceHelpContent'), commands); }); } /// Hides the voice help. /// . function hideVoiceHelp() { $('.voiceInputHelp').remove(); } /// Shows the unrecognized command help. /// . function showUnrecognizedCommandHelp() { //speak("I don't understend this command"); $('.unrecognizedCommand').show(); $('.defaultVoiceHelp').hide(); } /// Process the transcript described by text. /// The text. /// . function processTranscript(text, isCancelled) { $('.voiceInputText').html(text); if (text || AppInfo.isNativeApp) { $('.blockedMessage').hide(); } else { $('.blockedMessage').show(); } if (text) { require(['voice/voicecommands.js', 'voice/grammarprocessor.js'], function (voicecommands, grammarprocessor) { var processor = grammarprocessor(commandgroups, text); if (processor && processor.command) { voicecommands(processor) .then(function (result) { if (result.item.actionid === 'show' && result.item.sourceid === 'group') { var dlg = currentDialog; if (dlg) showCommands(false, result) else showCommands(true, result) } }) .catch(showUnrecognizedCommandHelp); } else showUnrecognizedCommandHelp(); var dlg = currentDialog; if (dlg) { dialogHelper.close(dlg); } }); } else if (!isCancelled) { showUnrecognizedCommandHelp(); } } /// Starts listening internal. /// . function startListening(createUI) { destroyCurrentRecognition(); var recognition = new (window.SpeechRecognition || window.webkitSpeechRecognition || window.mozSpeechRecognition || window.oSpeechRecognition || window.msSpeechRecognition)(); recognition.lang = lang; var groupid = ''; //recognition.continuous = true; //recognition.interimResults = true; recognition.onresult = function (event) { if (event.results.length > 0) { processTranscript(event.results[0][0].transcript || ''); } }; recognition.onerror = function () { processTranscript('', recognition.cancelled); }; recognition.onnomatch = function () { processTranscript('', recognition.cancelled); }; recognition.start(); currentRecognition = recognition; showCommands(createUI); } /// Destroys the current recognition. /// . function destroyCurrentRecognition() { var recognition = currentRecognition; if (recognition) { recognition.abort(); currentRecognition = null; } } /// Cancel listener. /// . function cancelListener() { destroyCurrentRecognition(); hideVoiceHelp(); } /// Shows the commands. /// The create user interface. /// . function showCommands(createUI, result) { if (createUI !== false) { //speak('Hello, what can I do for you?'); require(['paper-fab', 'css!voice/voice.css'], function () { if (result) showVoiceHelp(result.groupid, result.name); else showVoiceHelp(); }); } } /// Speaks the given text. /// The text. /// . function speak(text) { if (!SpeechSynthesisUtterance) { console.log('API not supported'); } var utterance = new SpeechSynthesisUtterance(text); utterance.lang = lang; utterance.rate = 0.9; utterance.pitch = 1; utterance.addEventListener('end', function () { console.log('Synthesizing completed'); }); utterance.addEventListener('error', function (event) { console.log('Synthesizing error'); }); console.log('Synthesizing the text: ' + text); speechSynthesis.speak(utterance); } /// An enum constant representing the window. voice input manager option. return { startListening: startListening }; });