2016-07-20 06:56:24 -07:00
|
|
|
define(['dialogHelper', 'voiceReceiver', 'voiceProcessor', 'globalize', 'emby-button', 'css!./voice.css', 'material-icons', 'css!./../formdialog'], function (dialogHelper, voicereceiver, voiceprocessor, globalize) {
|
2016-02-23 10:57:38 -07:00
|
|
|
|
|
|
|
var lang = 'en-US';
|
|
|
|
|
|
|
|
/// <summary> Shuffle array. </summary>
|
|
|
|
/// <param name="array"> The array. </param>
|
|
|
|
/// <returns> array </returns>
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> Gets sample commands. </summary>
|
|
|
|
/// <returns> The sample commands. </returns>
|
|
|
|
function getSampleCommands(groupid) {
|
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
return voiceprocessor.getCommandGroups().then(function (commandGroups) {
|
2016-02-23 10:57:38 -07:00
|
|
|
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);
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> Gets command group. </summary>
|
|
|
|
/// <param name="groupid"> The groupid. </param>
|
|
|
|
/// <returns> The command group. </returns>
|
|
|
|
function getCommandGroup(groupid) {
|
2016-07-06 11:39:04 -07:00
|
|
|
return voicereceiver.getCommandGroups()
|
|
|
|
.then(function (commandgroups) {
|
|
|
|
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;
|
|
|
|
});
|
2016-02-23 10:57:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> Renders the sample commands. </summary>
|
|
|
|
/// <param name="elem"> The element. </param>
|
|
|
|
/// <param name="commands"> The commands. </param>
|
|
|
|
/// <returns> . </returns>
|
|
|
|
function renderSampleCommands(elem, commands) {
|
|
|
|
|
|
|
|
commands.length = Math.min(commands.length, 4);
|
|
|
|
|
|
|
|
commands = commands.map(function (c) {
|
|
|
|
|
|
|
|
return '<div class="exampleCommand"><span class="exampleCommandText">"' + c + '"</span></div>';
|
|
|
|
|
|
|
|
}).join('');
|
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
elem.querySelector('.exampleCommands').innerHTML = commands;
|
2016-02-23 10:57:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
var currentDialog;
|
|
|
|
/// <summary> Shows the voice help. </summary>
|
|
|
|
/// <returns> . </returns>
|
|
|
|
function showVoiceHelp(groupid, title) {
|
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
console.log("Showing Voice Help", groupid, title);
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
var isNewDialog = false;
|
|
|
|
var dlg;
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
if (!currentDialog) {
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
isNewDialog = true;
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
dlg = dialogHelper.createDialog({
|
|
|
|
size: 'medium',
|
|
|
|
removeOnClose: true
|
|
|
|
});
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-13 11:23:01 -07:00
|
|
|
dlg.classList.add('formDialog');
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
var html = '';
|
2016-07-19 12:51:22 -07:00
|
|
|
html += '<div class="dialogHeader">';
|
2016-07-13 11:23:01 -07:00
|
|
|
html += '<button is="paper-icon-button-light" class="btnCancelVoiceInput autoSize" tabindex="-1"><i class="md-icon"></i></button>';
|
|
|
|
html += '<div class="dialogHeaderTitle">';
|
2016-07-19 23:23:18 -07:00
|
|
|
html += globalize.translate('sharedcomponents#VoiceInput');
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '</div>';
|
|
|
|
html += '</div>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '<div>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-19 12:51:22 -07:00
|
|
|
html += '<div class="dialogContent smoothScrollY" style="padding-top:2em;">';
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '<div class="dialogContentInner centeredContent">';
|
|
|
|
html += '<div class="voiceHelpContent">';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '<div class="defaultVoiceHelp">';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-13 11:23:01 -07:00
|
|
|
html += '<h1 style="margin-bottom:1.25em;margin-top:0;">' + globalize.translate('sharedcomponents#HeaderSaySomethingLike') + '</h1>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '<div class="exampleCommands">';
|
|
|
|
html += '</div>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
// defaultVoiceHelp
|
|
|
|
html += '</div>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '<div class="unrecognizedCommand hide">';
|
2016-07-13 12:21:42 -07:00
|
|
|
html += '<h1 style="margin-top:0;">' + globalize.translate('sharedcomponents#HeaderYouSaid') + '</h1>';
|
2016-07-06 11:39:04 -07:00
|
|
|
html +=
|
|
|
|
'<p class="exampleCommand voiceInputContainer"><i class="fa fa-quote-left"></i><span class="voiceInputText exampleCommandText"></span><i class="fa fa-quote-right"></i></p>';
|
2016-07-06 12:25:58 -07:00
|
|
|
html += '<p>' + globalize.translate('sharedcomponents#MessageWeDidntRecognizeCommand') + '</p>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '<br/>';
|
|
|
|
html += '<button is="emby-button" type="button" class="submit block btnRetry raised"><i class="md-icon">mic</i><span>' +
|
2016-07-06 12:25:58 -07:00
|
|
|
globalize.translate('sharedcomponents#ButtonTryAgain') +
|
2016-07-06 11:39:04 -07:00
|
|
|
'</span></button>';
|
|
|
|
html += '<p class="blockedMessage hide">' +
|
2016-07-06 12:25:58 -07:00
|
|
|
globalize.translate('sharedcomponents#MessageIfYouBlockedVoice') +
|
2016-07-06 11:39:04 -07:00
|
|
|
'<br/><br/></p>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '</div>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '</div>';
|
|
|
|
html += '</div>';
|
|
|
|
html += '</div>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
html += '</div>';
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
dlg.innerHTML = html;
|
|
|
|
document.body.appendChild(dlg);
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
dialogHelper.open(dlg);
|
|
|
|
currentDialog = dlg;
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
dlg.addEventListener('close', function () {
|
2016-07-10 21:59:35 -07:00
|
|
|
voicereceiver.cancel();
|
2016-07-06 11:39:04 -07:00
|
|
|
currentDialog = null;
|
|
|
|
});
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
function onCancelClick() {
|
|
|
|
dialogHelper.close(dlg);
|
|
|
|
}
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
var closeButtons = dlg.querySelectorAll('.btnCancelVoiceInput');
|
|
|
|
for (var i = 0, length = closeButtons.length; i < length; i++) {
|
|
|
|
closeButtons[i].addEventListener('click', onCancelClick);
|
|
|
|
}
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
dlg.querySelector('.btnRetry').addEventListener('click', function () {
|
|
|
|
dlg.querySelector('.unrecognizedCommand').classList.add('hide');
|
|
|
|
dlg.querySelector('.defaultVoiceHelp').classList.remove('hide');
|
|
|
|
listen();
|
|
|
|
});
|
|
|
|
}
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
dlg = currentDialog;
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
if (groupid) {
|
|
|
|
getCommandGroup(groupid)
|
|
|
|
.then(
|
|
|
|
function (grp) {
|
|
|
|
dlg.querySelector('#voiceDialogGroupName').innerText = ' ' + grp.name;
|
|
|
|
});
|
2016-02-23 10:57:38 -07:00
|
|
|
|
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
getSampleCommands(groupid)
|
|
|
|
.then(function (commands) {
|
|
|
|
renderSampleCommands(currentDialog, commands);
|
|
|
|
listen();
|
|
|
|
})
|
|
|
|
.catch(function (e) { console.log("Error", e); });
|
|
|
|
} else if (isNewDialog) {
|
|
|
|
getSampleCommands()
|
|
|
|
.then(function (commands) {
|
|
|
|
renderSampleCommands(currentDialog, commands);
|
|
|
|
});
|
2016-02-23 10:57:38 -07:00
|
|
|
|
|
|
|
}
|
2016-07-06 11:39:04 -07:00
|
|
|
}
|
|
|
|
function processInput(input) {
|
|
|
|
return voiceprocessor.processTranscript(input);
|
2016-02-23 10:57:38 -07:00
|
|
|
}
|
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
/// <summary> Shows the unrecognized command help. </summary>
|
2016-02-23 10:57:38 -07:00
|
|
|
/// <returns> . </returns>
|
2016-07-06 11:39:04 -07:00
|
|
|
function showUnrecognizedCommandHelp(command) {
|
|
|
|
//speak("I don't understend this command");
|
|
|
|
if (command)
|
|
|
|
currentDialog.querySelector('.voiceInputText').innerText = command;
|
|
|
|
currentDialog.querySelector('.unrecognizedCommand').classList.remove('hide');
|
|
|
|
currentDialog.querySelector('.defaultVoiceHelp').classList.add('hide');
|
2016-02-23 10:57:38 -07:00
|
|
|
}
|
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
/// <summary> Shows the commands. </summary>
|
|
|
|
/// <param name="createUI"> The create user interface. </param>
|
2016-02-23 10:57:38 -07:00
|
|
|
/// <returns> . </returns>
|
2016-07-06 11:39:04 -07:00
|
|
|
function showCommands(result) {
|
|
|
|
//speak('Hello, what can I do for you?');
|
|
|
|
if (result)
|
|
|
|
showVoiceHelp(result.groupid, result.name);
|
|
|
|
else
|
|
|
|
showVoiceHelp();
|
|
|
|
}
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
function resetDialog() {
|
|
|
|
if (currentDialog) {
|
|
|
|
currentDialog.querySelector('.unrecognizedCommand').classList.add('hide');
|
|
|
|
currentDialog.querySelector('.defaultVoiceHelp').classList.remove('hide');
|
2016-02-23 10:57:38 -07:00
|
|
|
}
|
|
|
|
}
|
2016-07-06 11:39:04 -07:00
|
|
|
function showDialog() {
|
|
|
|
resetDialog();
|
|
|
|
showCommands();
|
|
|
|
listen();
|
|
|
|
}
|
|
|
|
function listen() {
|
2016-07-20 06:56:24 -07:00
|
|
|
voicereceiver.listen({
|
|
|
|
|
|
|
|
lang: lang || "en-US"
|
|
|
|
|
|
|
|
}).then(processInput).then(function (result) {
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
closeDialog();
|
2016-02-23 10:57:38 -07:00
|
|
|
|
2016-07-06 13:16:56 -07:00
|
|
|
// Put a delay here in case navigation/popstate is involved. Allow that to flush out
|
|
|
|
setTimeout(function () {
|
|
|
|
result.fn();
|
|
|
|
}, 1);
|
|
|
|
|
2016-07-06 11:39:04 -07:00
|
|
|
}, function (result) {
|
|
|
|
if (result.error == 'group') {
|
|
|
|
showVoiceHelp(result.item.groupid, result.groupName);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
showUnrecognizedCommandHelp(result.text || '');
|
|
|
|
});
|
2016-02-23 10:57:38 -07:00
|
|
|
}
|
2016-07-06 11:39:04 -07:00
|
|
|
function closeDialog() {
|
|
|
|
dialogHelper.close(currentDialog);
|
|
|
|
voicereceiver.cancel();
|
2016-02-23 10:57:38 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary> An enum constant representing the window. voice input manager option. </summary>
|
|
|
|
return {
|
2016-07-06 11:39:04 -07:00
|
|
|
showDialog: showDialog
|
2016-02-23 10:57:38 -07:00
|
|
|
};
|
|
|
|
|
|
|
|
});
|