mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
use shared voice components
This commit is contained in:
parent
aece94029c
commit
07da989bfd
28 changed files with 413 additions and 185 deletions
|
@ -15,12 +15,12 @@
|
|||
},
|
||||
"devDependencies": {},
|
||||
"ignore": [],
|
||||
"version": "1.4.66",
|
||||
"_release": "1.4.66",
|
||||
"version": "1.4.68",
|
||||
"_release": "1.4.68",
|
||||
"_resolution": {
|
||||
"type": "version",
|
||||
"tag": "1.4.66",
|
||||
"commit": "16a14d612b193c7a375e2391aa9c2370add0e32d"
|
||||
"tag": "1.4.68",
|
||||
"commit": "b14aefcc4a69f3dc2dfd530ddd0b99791719d259"
|
||||
},
|
||||
"_source": "https://github.com/MediaBrowser/emby-webcomponents.git",
|
||||
"_target": "^1.2.0",
|
||||
|
|
242
dashboard-ui/bower_components/emby-webcomponents/inputmanager.js
vendored
Normal file
242
dashboard-ui/bower_components/emby-webcomponents/inputmanager.js
vendored
Normal file
|
@ -0,0 +1,242 @@
|
|||
define(['playbackManager', 'focusManager', 'embyRouter'], function (playbackManager, focusManager, embyRouter) {
|
||||
|
||||
var lastInputTime = new Date().getTime();
|
||||
|
||||
function notify() {
|
||||
lastInputTime = new Date().getTime();
|
||||
}
|
||||
|
||||
function idleTime() {
|
||||
return new Date().getTime() - lastInputTime;
|
||||
}
|
||||
|
||||
function select(sourceElement) {
|
||||
|
||||
sourceElement.click();
|
||||
}
|
||||
|
||||
var eventListenerCount = 0;
|
||||
function on(scope, fn) {
|
||||
eventListenerCount++;
|
||||
scope.addEventListener('command', fn);
|
||||
}
|
||||
|
||||
function off(scope, fn) {
|
||||
|
||||
if (eventListenerCount) {
|
||||
eventListenerCount--;
|
||||
}
|
||||
|
||||
scope.removeEventListener('command', fn);
|
||||
}
|
||||
|
||||
var commandTimes = {};
|
||||
|
||||
function checkCommandTime(command) {
|
||||
|
||||
var last = commandTimes[command] || 0;
|
||||
var now = new Date().getTime();
|
||||
|
||||
if ((now - last) < 1000) {
|
||||
return false;
|
||||
}
|
||||
|
||||
commandTimes[command] = now;
|
||||
return true;
|
||||
}
|
||||
|
||||
function handleCommand(name, options) {
|
||||
|
||||
notify();
|
||||
|
||||
var sourceElement = (options ? options.sourceElement : null);
|
||||
|
||||
if (sourceElement) {
|
||||
sourceElement = focusManager.focusableParent(sourceElement);
|
||||
}
|
||||
|
||||
sourceElement = sourceElement || document.activeElement || window;
|
||||
|
||||
if (eventListenerCount) {
|
||||
var customEvent = new CustomEvent("command", {
|
||||
detail: {
|
||||
command: name
|
||||
},
|
||||
bubbles: true,
|
||||
cancelable: true
|
||||
});
|
||||
|
||||
var eventResult = sourceElement.dispatchEvent(customEvent);
|
||||
if (!eventResult) {
|
||||
// event cancelled
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
switch (name) {
|
||||
|
||||
case 'up':
|
||||
focusManager.moveUp(sourceElement);
|
||||
break;
|
||||
case 'down':
|
||||
focusManager.moveDown(sourceElement);
|
||||
break;
|
||||
case 'left':
|
||||
focusManager.moveLeft(sourceElement);
|
||||
break;
|
||||
case 'right':
|
||||
focusManager.moveRight(sourceElement);
|
||||
break;
|
||||
case 'home':
|
||||
embyRouter.goHome();
|
||||
break;
|
||||
case 'settings':
|
||||
embyRouter.showSettings();
|
||||
break;
|
||||
case 'back':
|
||||
embyRouter.back();
|
||||
break;
|
||||
case 'forward':
|
||||
// TODO
|
||||
break;
|
||||
case 'select':
|
||||
select(sourceElement);
|
||||
break;
|
||||
case 'pageup':
|
||||
// TODO
|
||||
break;
|
||||
case 'pagedown':
|
||||
// TODO
|
||||
break;
|
||||
case 'end':
|
||||
// TODO
|
||||
break;
|
||||
case 'menu':
|
||||
case 'info':
|
||||
// TODO
|
||||
break;
|
||||
case 'next':
|
||||
if (playbackManager.isPlayingVideo()) {
|
||||
playbackManager.nextChapter();
|
||||
} else if (playbackManager.isPlaying()) {
|
||||
playbackManager.nextTrack();
|
||||
}
|
||||
break;
|
||||
case 'previous':
|
||||
|
||||
if (playbackManager.isPlayingVideo()) {
|
||||
playbackManager.previousChapter();
|
||||
} else if (playbackManager.isPlaying()) {
|
||||
playbackManager.previousTrack();
|
||||
}
|
||||
break;
|
||||
case 'guide':
|
||||
embyRouter.showGuide();
|
||||
break;
|
||||
case 'recordedtv':
|
||||
embyRouter.showRecordedTV();
|
||||
break;
|
||||
case 'record':
|
||||
// TODO
|
||||
break;
|
||||
case 'livetv':
|
||||
embyRouter.showLiveTV();
|
||||
break;
|
||||
case 'mute':
|
||||
playbackManager.mute();
|
||||
break;
|
||||
case 'unmute':
|
||||
playbackManager.unMute();
|
||||
break;
|
||||
case 'togglemute':
|
||||
playbackManager.toggleMute();
|
||||
break;
|
||||
case 'volumedown':
|
||||
playbackManager.volumeDown();
|
||||
break;
|
||||
case 'volumeup':
|
||||
playbackManager.volumeUp();
|
||||
break;
|
||||
case 'play':
|
||||
playbackManager.unpause();
|
||||
break;
|
||||
case 'pause':
|
||||
playbackManager.pause();
|
||||
break;
|
||||
case 'playpause':
|
||||
playbackManager.playPause();
|
||||
break;
|
||||
case 'stop':
|
||||
if (checkCommandTime('stop')) {
|
||||
playbackManager.stop();
|
||||
}
|
||||
break;
|
||||
case 'changezoom':
|
||||
// TODO
|
||||
break;
|
||||
case 'changeaudiotrack':
|
||||
// TODO
|
||||
break;
|
||||
case 'changesubtitletrack':
|
||||
break;
|
||||
case 'search':
|
||||
embyRouter.showSearch();
|
||||
break;
|
||||
case 'favorites':
|
||||
embyRouter.showFavorites();
|
||||
break;
|
||||
case 'fastforward':
|
||||
playbackManager.fastForward();
|
||||
break;
|
||||
case 'rewind':
|
||||
playbackManager.rewind();
|
||||
break;
|
||||
case 'togglefullscreen':
|
||||
// TODO
|
||||
break;
|
||||
case 'disabledisplaymirror':
|
||||
playbackManager.enableDisplayMirroring(false);
|
||||
break;
|
||||
case 'enabledisplaymirror':
|
||||
playbackManager.enableDisplayMirroring(true);
|
||||
break;
|
||||
case 'toggledisplaymirror':
|
||||
playbackManager.toggleDisplayMirroring();
|
||||
break;
|
||||
case 'movies':
|
||||
// TODO
|
||||
break;
|
||||
case 'music':
|
||||
// TODO
|
||||
break;
|
||||
case 'tv':
|
||||
// TODO
|
||||
break;
|
||||
case 'latestepisodes':
|
||||
// TODO
|
||||
break;
|
||||
case 'nowplaying':
|
||||
// TODO
|
||||
break;
|
||||
case 'upcomingtv':
|
||||
// TODO
|
||||
break;
|
||||
case 'nextup':
|
||||
// TODO
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('click', notify);
|
||||
|
||||
return {
|
||||
trigger: handleCommand,
|
||||
handle: handleCommand,
|
||||
notify: notify,
|
||||
idleTime: idleTime,
|
||||
on: on,
|
||||
off: off
|
||||
};
|
||||
});
|
|
@ -27,6 +27,12 @@ define(['loading', 'viewManager', 'skinManager', 'pluginManager', 'backdrop', 'b
|
|||
},
|
||||
showLiveTV: function () {
|
||||
skinManager.getCurrentSkin().showLiveTV();
|
||||
},
|
||||
showRecordedTV: function () {
|
||||
skinManager.getCurrentSkin().showRecordedTV();
|
||||
},
|
||||
showFavorites: function () {
|
||||
skinManager.getCurrentSkin().showFavorites();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -86,5 +86,11 @@
|
|||
"ReplaceAllMetadata": "Replace all metadata",
|
||||
"SearchForMissingMetadata": "Search for missing metadata",
|
||||
"LabelRefreshMode": "Refresh mode:",
|
||||
"NoItemsFound": "No items found.",
|
||||
"HeaderSaySomethingLike": "Say Something Like...",
|
||||
"ButtonTryAgain": "Try Again",
|
||||
"HeaderYouSaid": "You Said...",
|
||||
"MessageWeDidntRecognizeCommand": "We're sorry, we didn't recognize that command.",
|
||||
"MessageIfYouBlockedVoice": "If you denied voice access to the app you'll need to reconfigure before trying again.",
|
||||
"RefreshDialogHelp": "Metadata is refreshed based on settings and internet services that are enabled in the Emby Server dashboard."
|
||||
}
|
177
dashboard-ui/bower_components/emby-webcomponents/voice/Readme.md
vendored
Normal file
177
dashboard-ui/bower_components/emby-webcomponents/voice/Readme.md
vendored
Normal file
|
@ -0,0 +1,177 @@
|
|||
#Emby Voice commands
|
||||
|
||||
Emby voice commands use json and regular expression to find corresponding commands.
|
||||
|
||||
With this solution the translation to other languages will be simplified and is fully compatible with regular expression for many programming languages.
|
||||
|
||||
###Json template :
|
||||
```json
|
||||
[
|
||||
{
|
||||
"group": "general",
|
||||
"name": "General commands",
|
||||
"defaultValues": {
|
||||
"sourceid": "",
|
||||
"deviceid": "",
|
||||
"itemName": "",
|
||||
"itemType": "",
|
||||
"shuffle": false,
|
||||
"filters": [],
|
||||
"sortBy": "",
|
||||
"sortOrder": "",
|
||||
"limit": 100,
|
||||
"category": ""
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "movies",
|
||||
"menuid" : "home",
|
||||
"groupid" : "movie",
|
||||
"deviceid": "displaymirroring",
|
||||
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
|
||||
"itemName": "",
|
||||
"itemType": "movie",
|
||||
"shuffle": false,
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending",
|
||||
"limit": 100,
|
||||
"category": "",
|
||||
"commandtemplates": [
|
||||
"Show Movie based commands",
|
||||
"Show Music based commands",
|
||||
"Show Picture based commands",
|
||||
"Show TV series based commands",
|
||||
"Show general commands"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
###Json hierarchy
|
||||
|
||||
>+ Group
|
||||
- defaultValues
|
||||
- Items
|
||||
+ commandtemplates
|
||||
|
||||
###Json Description :
|
||||
|
||||
**Group**
|
||||
>**groupid** : (mandatory) id of the group commands
|
||||
>**name** : (mandatory) name of the group
|
||||
|
||||
**Items and defaultValues (mandatory)**
|
||||
|
||||
**actionid** : (mandatory) Liste of actions available
|
||||
>- show
|
||||
- play
|
||||
- shuffle
|
||||
- search
|
||||
- control
|
||||
- enable
|
||||
- disable
|
||||
- toggle
|
||||
|
||||
**sourceid** : (optional) source commands available
|
||||
>- music
|
||||
- movies
|
||||
- tvseries
|
||||
- livetv
|
||||
- recordings
|
||||
- latestepisodes
|
||||
- home
|
||||
- group
|
||||
|
||||
**menuid** : (optional) menu commands available
|
||||
>- Commands for live TV
|
||||
- livetv
|
||||
- guide
|
||||
- channels
|
||||
- recordings
|
||||
- scheduled
|
||||
- series
|
||||
- group
|
||||
>- Commands for home menus
|
||||
- home
|
||||
- nextup
|
||||
- favorites
|
||||
- upcoming
|
||||
- nowplaying
|
||||
|
||||
**groupid** : (optional) name of the group
|
||||
You can define a group name specified in the json file
|
||||
|
||||
**deviceid** : (optional) devices commands available
|
||||
>- displaymirroring
|
||||
|
||||
|
||||
**Emby filters** : (optional)
|
||||
>- itemName
|
||||
- itemType
|
||||
- shuffle : default value = false
|
||||
- filters
|
||||
- sortBy
|
||||
- sortOrder
|
||||
- limit : default value = 100
|
||||
- category
|
||||
|
||||
**commandtemplates** (mandatory)
|
||||
array : list of text commands
|
||||
|
||||
|
||||
**command** : (mandatory)
|
||||
regular expression used to filter commands
|
||||
**Exemple :**
|
||||
command: "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
altcommand: "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
|
||||
|
||||
####Regular expression description
|
||||
```json
|
||||
(?<action> or ?<MovieName>, etc) - are for defining watts is captured
|
||||
my|me - indicate each of those words/phrases can be used
|
||||
\\s? - is for spaces
|
||||
(?<MovieName>.*)? - the ? at the end of the closing brackets represent an optional value
|
||||
|
||||
```
|
||||
|
||||
In the example below theses phrases can the match for an action
|
||||
- Show my movies
|
||||
- Show movies
|
||||
- Display movies
|
||||
- Go to movies
|
||||
- etc.
|
||||
|
||||
**altcommand** : (optional)
|
||||
alternate regular expression used to filter commands if the property **command** does not match
|
||||
|
||||
|
||||
####Regular expression description
|
||||
```json
|
||||
?<action> or ?<MovieName>, etc - are for defining watts is captured
|
||||
my|me - indicate each of those words/phrases can be used
|
||||
\s? - is for spaces
|
||||
(?<MovieName>.*)? - the ? at the end of the closing brackets represent an optional value
|
||||
|
||||
```
|
||||
|
||||
####Additional properties used by regular expression
|
||||
>**action** : Linked to actionid
|
||||
>**source** : Linked to sourceid
|
||||
>**menu** : Linked to menuid
|
||||
>**group** : Linked to groupid
|
||||
>**device** : Linked to deviceid
|
||||
>**determiner1 or determiner2 etc** : used just to capture words
|
||||
>**moviename**
|
||||
>**devicename**
|
||||
>**songname**
|
||||
>**artistname**
|
||||
>**albumname**
|
||||
>**seriename**
|
||||
>**seasonname**
|
||||
>**picturename**
|
||||
>**authorname**
|
10
dashboard-ui/bower_components/emby-webcomponents/voice/commands/controlcommands.js
vendored
Normal file
10
dashboard-ui/bower_components/emby-webcomponents/voice/commands/controlcommands.js
vendored
Normal file
|
@ -0,0 +1,10 @@
|
|||
define(['playbackManager'], function (playbackManager) {
|
||||
|
||||
return function (result) {
|
||||
result.success = true;
|
||||
if (result.properties.devicename) {
|
||||
playbackManager.trySetActiveDeviceName(result.properties.devicename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
});
|
15
dashboard-ui/bower_components/emby-webcomponents/voice/commands/disablecommands.js
vendored
Normal file
15
dashboard-ui/bower_components/emby-webcomponents/voice/commands/disablecommands.js
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
define(['inputManager'], function (inputManager) {
|
||||
|
||||
return function (result) {
|
||||
result.success = true;
|
||||
switch (result.item.deviceid) {
|
||||
case 'displaymirroring':
|
||||
inputManager.trigger('disabledisplaymirror');
|
||||
break;
|
||||
default:
|
||||
result.success = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
15
dashboard-ui/bower_components/emby-webcomponents/voice/commands/enablecommands.js
vendored
Normal file
15
dashboard-ui/bower_components/emby-webcomponents/voice/commands/enablecommands.js
vendored
Normal file
|
@ -0,0 +1,15 @@
|
|||
define(['inputManager'], function (inputManager) {
|
||||
|
||||
return function (result) {
|
||||
result.success = true;
|
||||
switch (result.item.deviceid) {
|
||||
case 'displaymirroring':
|
||||
inputManager.trigger('enabledisplaymirror');
|
||||
break;
|
||||
default:
|
||||
result.success = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
106
dashboard-ui/bower_components/emby-webcomponents/voice/commands/playcommands.js
vendored
Normal file
106
dashboard-ui/bower_components/emby-webcomponents/voice/commands/playcommands.js
vendored
Normal file
|
@ -0,0 +1,106 @@
|
|||
define(['connectionManager', 'playbackManager', 'globalize'], function (connectionManager, playbackManager, globalize) {
|
||||
|
||||
/// <summary> Play items. </summary>
|
||||
/// <param name="items"> The items. </param>
|
||||
/// <param name="shuffle"> The shuffle. </param>
|
||||
/// <returns> . </returns>
|
||||
function playItems(items, shuffle) {
|
||||
|
||||
if (shuffle) {
|
||||
items = shuffleArray(items);
|
||||
}
|
||||
|
||||
items = items.map(function (i) {
|
||||
return i.Id;
|
||||
});
|
||||
|
||||
if (items.length) {
|
||||
playbackManager.play({
|
||||
ids: items
|
||||
});
|
||||
}
|
||||
else {
|
||||
require(['toast'], function (toast) {
|
||||
toast(globalize.translate('sharedcomponents#NoItemsFound'));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> Shuffle array. </summary>
|
||||
/// <param name="array"> The array. </param>
|
||||
/// <returns> . </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;
|
||||
}
|
||||
|
||||
return function (result) {
|
||||
result.success = false;
|
||||
|
||||
var query = {
|
||||
|
||||
Limit: result.item.limit || 100,
|
||||
UserId: result.userId,
|
||||
ExcludeLocationTypes: "Virtual"
|
||||
};
|
||||
|
||||
if (result.item.itemType) {
|
||||
query.IncludeItemTypes = result.item.itemType;
|
||||
}
|
||||
|
||||
var apiClient = connectionManager.currentApiClient();
|
||||
if (result.item.sourceid === 'nextup') {
|
||||
|
||||
apiClient.getNextUpEpisodes(query).then(function (queryResult) {
|
||||
|
||||
playItems(queryResult.Items, result.item.shuffle);
|
||||
|
||||
});
|
||||
result.success = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.item.shuffle) {
|
||||
result.item.sortBy = result.sortBy ? 'Random,' + result.item.sortBy : 'Random';
|
||||
}
|
||||
|
||||
query.SortBy = result.item.sortBy;
|
||||
query.SortOrder = result.item.sortOrder;
|
||||
query.Recursive = true;
|
||||
|
||||
if (result.item.filters.indexOf('unplayed') !== -1) {
|
||||
query.IsPlayed = false;
|
||||
}
|
||||
if (result.item.filters.indexOf('played') !== -1) {
|
||||
query.IsPlayed = true;
|
||||
}
|
||||
if (result.item.filters.indexOf('favorite') !== -1) {
|
||||
query.Filters = 'IsFavorite';
|
||||
}
|
||||
|
||||
|
||||
apiClient.getItems(apiClient.getCurrentUserId(), query).then(function (queryResult) {
|
||||
|
||||
playItems(queryResult.Items, result.item.shuffle);
|
||||
});
|
||||
|
||||
result.success = true;
|
||||
|
||||
return;
|
||||
|
||||
}
|
||||
});
|
11
dashboard-ui/bower_components/emby-webcomponents/voice/commands/searchcommands.js
vendored
Normal file
11
dashboard-ui/bower_components/emby-webcomponents/voice/commands/searchcommands.js
vendored
Normal file
|
@ -0,0 +1,11 @@
|
|||
define(['inputManager'], function (inputManager) {
|
||||
|
||||
return function (result) {
|
||||
switch (result.item.deviceid) {
|
||||
default:
|
||||
result.success = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
});
|
98
dashboard-ui/bower_components/emby-webcomponents/voice/commands/showcommands.js
vendored
Normal file
98
dashboard-ui/bower_components/emby-webcomponents/voice/commands/showcommands.js
vendored
Normal file
|
@ -0,0 +1,98 @@
|
|||
define(['inputManager', 'connectionManager', 'embyRouter'], function (inputManager, connectionManager, embyRouter) {
|
||||
|
||||
return function (result) {
|
||||
result.success = true;
|
||||
switch (result.item.sourceid) {
|
||||
case 'music':
|
||||
inputManager.trigger('music');
|
||||
break;
|
||||
case 'movies':
|
||||
if (result.properties.movieName) {
|
||||
|
||||
//TODO: Find a way to display movie
|
||||
var query = {
|
||||
Limit: 1,
|
||||
UserId: result.userId,
|
||||
ExcludeLocationTypes: "Virtual",
|
||||
NameStartsWith: result.item.itemType
|
||||
};
|
||||
|
||||
if (result.item.itemType) {
|
||||
query.IncludeItemTypes = result.item.itemType;
|
||||
}
|
||||
|
||||
var apiClient = connectionManager.currentApiClient();
|
||||
apiClient.getItems(apiClient.getCurrentUserId(), query).then(function (queryResult) {
|
||||
|
||||
if (queryResult.Items.length) {
|
||||
embyRouter.showItem(queryResult.Items[0]);
|
||||
}
|
||||
});
|
||||
|
||||
} else {
|
||||
inputManager.trigger('movies');
|
||||
}
|
||||
|
||||
break;
|
||||
case 'tvseries':
|
||||
inputManager.trigger('tv');
|
||||
break;
|
||||
case 'livetv':
|
||||
var act = result.item.menuid;
|
||||
if (act) {
|
||||
if (act.indexOf('livetv') != -1) {
|
||||
inputManager.trigger('livetv');
|
||||
} else if (act.indexOf('guide') != -1) {
|
||||
inputManager.trigger('guide');
|
||||
} else if (act.indexOf('channels') != -1) {
|
||||
inputManager.trigger('livetv');
|
||||
} else if (act.indexOf('recordings') != -1) {
|
||||
inputManager.trigger('recordedtv');
|
||||
} else if (act.indexOf('scheduled') != -1) {
|
||||
inputManager.trigger('recordedtv');
|
||||
} else if (act.indexOf('series') != -1) {
|
||||
inputManager.trigger('recordedtv');
|
||||
} else {
|
||||
inputManager.trigger('livetv');
|
||||
}
|
||||
} else {
|
||||
inputManager.trigger('livetv');
|
||||
}
|
||||
break;
|
||||
case 'recordings':
|
||||
inputManager.trigger('recordedtv');
|
||||
break;
|
||||
case 'latestepisodes':
|
||||
inputManager.trigger('latestepisodes');
|
||||
case 'home':
|
||||
var act = result.item.menuid;
|
||||
if (act) {
|
||||
if (act.indexOf('home') != -1) {
|
||||
inputManager.trigger('home');
|
||||
}
|
||||
else if (act.indexOf('nextup') != -1) {
|
||||
inputManager.trigger('nextup');
|
||||
}
|
||||
else if (act.indexOf('favorites') != -1) {
|
||||
inputManager.trigger('favorites');
|
||||
} else if (act.indexOf('upcoming') != -1) {
|
||||
inputManager.trigger('upcomingtv');
|
||||
}
|
||||
else if (act.indexOf('nowplaying') != -1) {
|
||||
inputManager.trigger('nowplaying');
|
||||
}
|
||||
else {
|
||||
inputManager.trigger('home');
|
||||
}
|
||||
} else {
|
||||
inputManager.trigger('home');
|
||||
}
|
||||
case 'group':
|
||||
break;
|
||||
default:
|
||||
result.success = false;
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
});
|
14
dashboard-ui/bower_components/emby-webcomponents/voice/commands/togglecommands.js
vendored
Normal file
14
dashboard-ui/bower_components/emby-webcomponents/voice/commands/togglecommands.js
vendored
Normal file
|
@ -0,0 +1,14 @@
|
|||
define(['inputManager'], function (inputManager) {
|
||||
|
||||
return function (result) {
|
||||
result.success = true;
|
||||
switch (result.item.deviceid) {
|
||||
case 'displaymirroring':
|
||||
inputManager.trigger('toggledisplaymirror');
|
||||
break;
|
||||
default:
|
||||
result.success = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
347
dashboard-ui/bower_components/emby-webcomponents/voice/grammar/en-US.json
vendored
Normal file
347
dashboard-ui/bower_components/emby-webcomponents/voice/grammar/en-US.json
vendored
Normal file
|
@ -0,0 +1,347 @@
|
|||
[
|
||||
{
|
||||
"groupid": "general",
|
||||
"name": "General commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "movie",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>Movie)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show Movie based commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "music",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>Music)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show Music based commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "picture",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>Picture)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show Picture based commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "tvseries",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>TV series)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show TV series based commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "home",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>home page)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show home page based commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "general",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>general)?\\s?(?<text>group commands)",
|
||||
"commandtemplates": [ "Show general group commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "devices",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>devices)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show devices based commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "livetv",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>live tv)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show Live TV based commands" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "home",
|
||||
"name": "Home commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "home",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>home)",
|
||||
"commandtemplates": [ "Show home" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "nextup",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>next up)",
|
||||
"commandtemplates": [ "Show next up" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "favorites",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>favorites)",
|
||||
"commandtemplates": [ "Show favorites" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "upcoming",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>upcoming)",
|
||||
"commandtemplates": [ "Show upcoming" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "nowplaying",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>now playing)",
|
||||
"commandtemplates": [ "Show now playing" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "movie",
|
||||
"name": "Movie based commands",
|
||||
"defaultValues": {
|
||||
"sourceid": "movies",
|
||||
"itemType": "Movie",
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "movies",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>movies)\\s?(?<MovieName>.*)?",
|
||||
"altcommand": "(?<action>show|display|go to|view)\\s?(?<determiner1>the)?\\s?(?<source>movie)\\s?(?<MovieName>.*)?",
|
||||
"itemName": "",
|
||||
"commandtemplates": [
|
||||
"Show movies",
|
||||
"Show my movies",
|
||||
"Show the movie [movie name]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "movies",
|
||||
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
|
||||
"itemName": "",
|
||||
"itemType": "Audio",
|
||||
"shuffle": false,
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending",
|
||||
"commandtemplates": [
|
||||
"Play music",
|
||||
"Play my music",
|
||||
"Listen to my music"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "latestmovies",
|
||||
"command": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest movies|latest films)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest movies|latest films)",
|
||||
"filters": [ "unplayed" ],
|
||||
"sortBy": "datecreated",
|
||||
"sortOrder": "Descending",
|
||||
"commandtemplates": [
|
||||
"Play my latest movies",
|
||||
"Play latest films"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "music",
|
||||
"name": "Music based commands",
|
||||
"defaultValues": {
|
||||
"itemName": "",
|
||||
"itemType": "Audio",
|
||||
"shuffle": false,
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "music",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(music|songs))\\s?(?<SongName>.*)?",
|
||||
"commandtemplates": [
|
||||
"Show music",
|
||||
"Show my music",
|
||||
"Show my songs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "music",
|
||||
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
|
||||
"itemName": "",
|
||||
"commandtemplates": [
|
||||
"Play music",
|
||||
"Play my music",
|
||||
"Listen to my music"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "shuffle",
|
||||
"sourceid": "music",
|
||||
"command": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music|favorite songs)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music|favorite songs)\\s?(?<ArtistName>.*)?",
|
||||
"shuffle": true,
|
||||
"commandtemplates": [
|
||||
"Play music",
|
||||
"Play my music",
|
||||
"Listen to my music",
|
||||
"shuffle my favorite songs"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "tvseries",
|
||||
"name": "TV series based commands",
|
||||
"defaultValues": {
|
||||
"itemType": "Series",
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "tvseries",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(tv series))\\s?(?<SerieName>.*)?",
|
||||
"commandtemplates": [
|
||||
"Show tv series",
|
||||
"Show my tv series"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "nextup",
|
||||
"command": "(?<action>play|Listen to)\\s?(?<source> next up)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play|Listen to)\\s?(?<source> next up)",
|
||||
"commandtemplates": [ "Play next up" ]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "latestepisodes",
|
||||
"command": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest episodes)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest episodes)",
|
||||
"filters": [ "unplayed" ],
|
||||
"sortBy": "datecreated",
|
||||
"sortOrder": "Descending",
|
||||
"commandtemplates": [ "Play my latest episodes" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "livetv",
|
||||
"name": "Live TV based commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "suggestions",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv|live tv suggestions)",
|
||||
"commandtemplates": [ "Show live tv" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "guide",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv guide)",
|
||||
"commandtemplates": [ "Show live tv guide" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "channels",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv channels)",
|
||||
"commandtemplates": [ "Show live tv channels" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "recordings",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv recordings)",
|
||||
"commandtemplates": [ "Show live tv recordings" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "scheduled",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv scheduled)",
|
||||
"commandtemplates": [ "Show live tv scheduled" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "series",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv series)",
|
||||
"commandtemplates": [ "Show live tv series" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "picture",
|
||||
"name": "Picture based commands",
|
||||
"defaultValues": {
|
||||
"itemType": "Picture",
|
||||
"shuffle": false,
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "tvseries",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>pictures)",
|
||||
"commandtemplates": [
|
||||
"Show pictures",
|
||||
"Show my pictures"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "devices",
|
||||
"name": "Devices based commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "enable",
|
||||
"deviceid": "displaymirroring",
|
||||
"command": "(?<action> enable|turn on)\\s?(?<device>display mirroring)",
|
||||
"commandtemplates": [ "Turn on display mirroring", "Enable display mirroring" ]
|
||||
},
|
||||
{
|
||||
"actionid": "disable",
|
||||
"deviceid": "displaymirroring",
|
||||
"command": "(?<action> disable|turn off)\\s?(?<device>display mirroring)",
|
||||
"commandtemplates": [ "Turn off display mirroring", "Disable display mirroring" ]
|
||||
},
|
||||
{
|
||||
"actionid": "toggle",
|
||||
"deviceid": "displaymirroring",
|
||||
"command": "(?<action>toggle)\\s?(?<device>display mirroring)",
|
||||
"commandtemplates": [ "Toggle display mirroring" ]
|
||||
},
|
||||
{
|
||||
"actionid": "control",
|
||||
"command": "(?<action>control)\\s?(?<Devicename>.*)",
|
||||
"commandtemplates": [ "Control [Device Name]" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
347
dashboard-ui/bower_components/emby-webcomponents/voice/grammar/grammar.json
vendored
Normal file
347
dashboard-ui/bower_components/emby-webcomponents/voice/grammar/grammar.json
vendored
Normal file
|
@ -0,0 +1,347 @@
|
|||
[
|
||||
{
|
||||
"groupid": "general",
|
||||
"name": "General commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "movie",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>Movie)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show movie commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "music",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>Music)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show music commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "picture",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>Picture)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show photo commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "tvseries",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>TV series)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show tv library commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "home",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>home page)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show home screen commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "general",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>general)?\\s?(?<text>group commands)",
|
||||
"commandtemplates": [ "Show general commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "devices",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>devices)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show device commands" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "group",
|
||||
"groupid": "livetv",
|
||||
"command": "(?<action>show|display|view)\\s?(?<source>live tv)?\\s?(?<text>based commands)",
|
||||
"commandtemplates": [ "Show live tv commands" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "home",
|
||||
"name": "Home commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "home",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>home)",
|
||||
"commandtemplates": [ "Show home" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "nextup",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>next up)",
|
||||
"commandtemplates": [ "Show next up" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "favorites",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>favorites)",
|
||||
"commandtemplates": [ "Show favorites" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "upcoming",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>upcoming)",
|
||||
"commandtemplates": [ "Show upcoming" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "home",
|
||||
"menuid": "nowplaying",
|
||||
"command": "(?<action> show|display|view)\\s?(?<menu>now playing)",
|
||||
"commandtemplates": [ "Show now playing" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "movie",
|
||||
"name": "Movie based commands",
|
||||
"defaultValues": {
|
||||
"sourceid": "movies",
|
||||
"itemType": "Movie",
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "movies",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>movies)\\s?(?<MovieName>.*)?",
|
||||
"altcommand": "(?<action>show|display|go to|view)\\s?(?<determiner1>the)?\\s?(?<source>movie)\\s?(?<MovieName>.*)?",
|
||||
"itemName": "",
|
||||
"commandtemplates": [
|
||||
"Show movies",
|
||||
"Show my movies",
|
||||
"Show the movie [movie name]"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "movies",
|
||||
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
|
||||
"itemName": "",
|
||||
"itemType": "Audio",
|
||||
"shuffle": false,
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending",
|
||||
"commandtemplates": [
|
||||
"Play music",
|
||||
"Play my music",
|
||||
"Listen to my music "
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "latestmovies",
|
||||
"command": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest movies|latest films)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest movies|latest films)",
|
||||
"filters": [ "unplayed" ],
|
||||
"sortBy": "datecreated",
|
||||
"sortOrder": "Descending",
|
||||
"commandtemplates": [
|
||||
"Play my latest movies",
|
||||
"Play latest films"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "music",
|
||||
"name": "Music based commands",
|
||||
"defaultValues": {
|
||||
"itemName": "",
|
||||
"itemType": "Audio",
|
||||
"shuffle": false,
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "music",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(music|songs))\\s?(?<SongName>.*)?",
|
||||
"commandtemplates": [
|
||||
"Show music",
|
||||
"Show my music",
|
||||
"Show my songs"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "music",
|
||||
"command": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play|Listen to)\\s?(?<determiner1>my|me)?\\s?(?<source> music)\\s?(?<ArtistName>.*)?",
|
||||
"itemName": "",
|
||||
"commandtemplates": [
|
||||
"Play music",
|
||||
"Play my music",
|
||||
"Listen to my music "
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "shuffle",
|
||||
"sourceid": "music",
|
||||
"command": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music|favorite songs)\\s?(?<ArtistName>.*)?\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>shuffle)\\s?(?<determiner1>my|me)?\\s?(?<source> music|favorite songs)\\s?(?<ArtistName>.*)?",
|
||||
"shuffle": true,
|
||||
"commandtemplates": [
|
||||
"Play music",
|
||||
"Play my music",
|
||||
"Listen to my music ",
|
||||
"shuffle my favorite songs"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "tvseries",
|
||||
"name": "TV series based commands",
|
||||
"defaultValues": {
|
||||
"itemType": "Series",
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "tvseries",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>(tv series))\\s?(?<SerieName>.*)?",
|
||||
"commandtemplates": [
|
||||
"Show tv series",
|
||||
"Show my tv series"
|
||||
]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "nextup",
|
||||
"command": "(?<action>play|Listen to)\\s?(?<source> next up)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play|Listen to)\\s?(?<source> next up)",
|
||||
"commandtemplates": [ "Play next up" ]
|
||||
},
|
||||
{
|
||||
"actionid": "play",
|
||||
"sourceid": "latestepisodes",
|
||||
"command": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest episodes)\\s?(?<deviceaction>on device|to device)\\s?(?<Devicename>.*)",
|
||||
"altcommand": "(?<action>play)\\s?(?<determiner1>my|me)?\\s?(?<source>latest episodes)",
|
||||
"filters": [ "unplayed" ],
|
||||
"sortBy": "datecreated",
|
||||
"sortOrder": "Descending",
|
||||
"commandtemplates": [ "Play my latest episodes" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "livetv",
|
||||
"name": "Live TV based commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "suggestions",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv|live tv suggestions)",
|
||||
"commandtemplates": [ "Show live tv" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "guide",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv guide)",
|
||||
"commandtemplates": [ "Show live tv guide" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "channels",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv channels)",
|
||||
"commandtemplates": [ "Show live tv channels" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "recordings",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv recordings)",
|
||||
"commandtemplates": [ "Show live tv recordings" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "scheduled",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv scheduled)",
|
||||
"commandtemplates": [ "Show live tv scheduled" ]
|
||||
},
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "livetv",
|
||||
"menuid": "series",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>Live tv series)",
|
||||
"commandtemplates": [ "Show live tv series" ]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "picture",
|
||||
"name": "Picture based commands",
|
||||
"defaultValues": {
|
||||
"itemType": "Picture",
|
||||
"shuffle": false,
|
||||
"filters": [ ],
|
||||
"sortBy": "",
|
||||
"sortOrder": "Ascending"
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"actionid": "show",
|
||||
"sourceid": "tvseries",
|
||||
"command": "(?<action>show|display|go to|view)\\s?(?<determiner1>my|me)?\\s?(?<source>pictures)",
|
||||
"commandtemplates": [
|
||||
"Show pictures",
|
||||
"Show my pictures"
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"groupid": "devices",
|
||||
"name": "Devices based commands",
|
||||
"items": [
|
||||
{
|
||||
"actionid": "enable",
|
||||
"deviceid": "displaymirroring",
|
||||
"command": "(?<action> enable|turn on)\\s?(?<device>display mirroring)",
|
||||
"commandtemplates": [ "Turn on display mirroring", "Enable display mirroring" ]
|
||||
},
|
||||
{
|
||||
"actionid": "disable",
|
||||
"deviceid": "displaymirroring",
|
||||
"command": "(?<action> disable|turn off)\\s?(?<device>display mirroring)",
|
||||
"commandtemplates": [ "Turn off display mirroring", "Disable display mirroring" ]
|
||||
},
|
||||
{
|
||||
"actionid": "toggle",
|
||||
"deviceid": "displaymirroring",
|
||||
"command": "(?<action>toggle)\\s?(?<device>display mirroring)",
|
||||
"commandtemplates": [ "Toggle display mirroring" ]
|
||||
},
|
||||
{
|
||||
"actionid": "control",
|
||||
"command": "(?<action>control)\\s?(?<Devicename>.*)",
|
||||
"commandtemplates": [ "Control [Device Name]" ]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
]
|
241
dashboard-ui/bower_components/emby-webcomponents/voice/grammarprocessor.js
vendored
Normal file
241
dashboard-ui/bower_components/emby-webcomponents/voice/grammarprocessor.js
vendored
Normal file
|
@ -0,0 +1,241 @@
|
|||
// <date>09.10.2015</date>
|
||||
// <summary>grammarprocessor class</summary>
|
||||
define([], function () {
|
||||
|
||||
/// <summary> The named register exponent. </summary>
|
||||
var NamedRegExp = function (pattern, string) {
|
||||
pattern = pattern.toString();
|
||||
var regexp = [];
|
||||
var groupRX = /\(\?\<(.*?)\>\s?(.*?)\)/i;
|
||||
while (groupRX.test(pattern)) {
|
||||
|
||||
var match = groupRX.exec(pattern);
|
||||
regexp.push({
|
||||
name: match[1].trim().toLowerCase(),
|
||||
pattern: match[2].trim().toLowerCase(),
|
||||
value: null,
|
||||
title: ''
|
||||
});
|
||||
pattern = pattern.replace(groupRX, '(' + match[2].trim() + ')');
|
||||
}
|
||||
|
||||
var finalMatch = (new RegExp(pattern, "i")).exec(string);
|
||||
if (finalMatch) {
|
||||
for (var i = 0, len = regexp.length; i < len; i++) {
|
||||
if (finalMatch[(i + 1)] !== false) {
|
||||
var mth = finalMatch[(i + 1)];
|
||||
if (mth)
|
||||
mth = mth.trim().toLowerCase();
|
||||
regexp[i].value = mth;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
regexp = null;
|
||||
return regexp;
|
||||
};
|
||||
|
||||
/// <summary> Processcommands. </summary>
|
||||
/// <param name="text"> The text. </param>
|
||||
/// <param name="commandgroups"> The command groups. </param>
|
||||
/// <returns> . </returns>
|
||||
function processcommands(text, commandgroups) {
|
||||
|
||||
var result = {
|
||||
groupid: '',
|
||||
name: '',
|
||||
item: {
|
||||
actionid: '',
|
||||
groupid: '',
|
||||
sourceid: '',
|
||||
menuid: '',
|
||||
deviceid: '',
|
||||
itemName: '',
|
||||
itemType: '',
|
||||
shuffle: false,
|
||||
filters: [],
|
||||
sortBy: '',
|
||||
sortOrder: '',
|
||||
item: 100,
|
||||
category: '',
|
||||
usedefaultvalues: true
|
||||
},
|
||||
defaultValues: {
|
||||
sourceid: '',
|
||||
deviceid: '',
|
||||
itemName: '',
|
||||
itemType: '',
|
||||
shuffle: false,
|
||||
filters: [],
|
||||
sortBy: '',
|
||||
sortOrder: '',
|
||||
limit: 100,
|
||||
category: ''
|
||||
},
|
||||
properties: {
|
||||
movieName: null,
|
||||
devicename: null,
|
||||
songName: null,
|
||||
artistName: null,
|
||||
albumName: null,
|
||||
serieName: null,
|
||||
seasonName: null,
|
||||
pictureName: null,
|
||||
authorname: null,
|
||||
},
|
||||
command: null,
|
||||
text: text,
|
||||
userId: Dashboard.getCurrentUserId(),
|
||||
success: false
|
||||
};
|
||||
|
||||
var isvalid = false;
|
||||
|
||||
commandgroups.map(function (group) {
|
||||
if (isvalid)
|
||||
return;
|
||||
|
||||
if (group.defaultValues && group.defaultValues.length > 0) {
|
||||
group.defaultValues.map(function (item) {
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
if (group.items && group.items.length > 0) {
|
||||
|
||||
group.items.map(function (item) {
|
||||
|
||||
var regex = NamedRegExp(item.command, text);
|
||||
if (!regex && item.altcommand)
|
||||
regex = NamedRegExp(item.altcommand, text)
|
||||
|
||||
if (regex && regex.length > 0) {
|
||||
|
||||
//Group data
|
||||
if (group.groupid) result.groupid = group.groupid;
|
||||
if (group.name) result.name = group.name;
|
||||
if (group.defaultValues) {
|
||||
result.defaultValues.sourceid = group.defaultValues.sourceid || result.defaultValues.sourceid;
|
||||
result.defaultValues.deviceid = group.defaultValues.deviceid || result.defaultValues.deviceid;
|
||||
result.defaultValues.itemName = group.defaultValues.itemName || result.defaultValues.itemName;
|
||||
result.defaultValues.itemType = group.defaultValues.itemType || result.defaultValues.itemType;
|
||||
result.defaultValues.shuffle = group.defaultValues.shuffle || result.defaultValues.shuffle;
|
||||
result.defaultValues.filters = group.defaultValues.filters || result.defaultValues.filters;
|
||||
result.defaultValues.sortBy = group.defaultValues.sortBy || result.defaultValues.sortBy;
|
||||
result.defaultValues.sortOrder = group.defaultValues.sortOrder || result.defaultValues.sortOrder;
|
||||
result.defaultValues.limit = group.defaultValues.limit || result.defaultValues.limit;
|
||||
result.defaultValues.category = group.defaultValues.category || result.defaultValues.category;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (group.name) result.name = group.name;
|
||||
|
||||
//Item data
|
||||
var usegroupDefault = checkItemProperty(item.usedefaultvalues, result.item.usedefaultvalues);
|
||||
|
||||
result.item.usedefaultvalues = usegroupDefault;
|
||||
result.item.actionid = checkItemProperty(item.actionid, result.item.actionid);
|
||||
result.item.groupid = checkItemProperty(item.groupid, result.item.groupid);
|
||||
result.item.menuid = checkItemProperty(item.menuid, result.item.menuid);
|
||||
result.item.sourceid = checkItemProperty(item.sourceid, result.item.sourceid, usegroupDefault, result.defaultValues.sourceid);
|
||||
result.item.deviceid = checkItemProperty(item.deviceid, result.item.deviceid, usegroupDefault, result.defaultValues.deviceid);
|
||||
result.item.itemName = checkItemProperty(item.itemName, result.item.itemName, usegroupDefault, result.defaultValues.itemName);
|
||||
result.item.itemType = checkItemProperty(item.itemType, result.item.itemType, usegroupDefault, result.defaultValues.itemType);
|
||||
result.item.shuffle = checkItemProperty(item.shuffle, result.item.shuffle, usegroupDefault, result.defaultValues.shuffle);
|
||||
result.item.filters = checkItemProperty(item.filters, result.item.filters, usegroupDefault, result.defaultValues.filters);
|
||||
result.item.sortBy = checkItemProperty(item.sortBy, result.item.sortBy, usegroupDefault, result.defaultValues.sortBy);
|
||||
result.item.sortOrder = checkItemProperty(item.sortOrder, result.item.sortOrder, usegroupDefault, result.defaultValues.sortOrder);
|
||||
result.item.limit = checkItemProperty(item.limit, result.item.limit, usegroupDefault, result.defaultValues.limit);
|
||||
|
||||
result.command = item;
|
||||
|
||||
regex.map(function (regresult) {
|
||||
|
||||
switch (regresult.name) {
|
||||
case 'moviename':
|
||||
result.properties.movieName = regresult.value;
|
||||
break;
|
||||
case 'devicename':
|
||||
result.properties.devicename = regresult.value;
|
||||
break;
|
||||
case 'songname':
|
||||
result.properties.songName = regresult.value;
|
||||
break;
|
||||
case 'artistname':
|
||||
result.properties.artistName = regresult.value;
|
||||
break;
|
||||
case 'albumname':
|
||||
result.properties.albumName = regresult.value;
|
||||
break;
|
||||
case 'seriename':
|
||||
result.properties.serieName = regresult.value;
|
||||
break;
|
||||
case 'seasonname':
|
||||
result.properties.seasonName = regresult.value;
|
||||
break;
|
||||
case 'picturename':
|
||||
result.properties.pictureName = regresult.value;
|
||||
break;
|
||||
case 'authorname':
|
||||
result.properties.authorname = regresult.value;
|
||||
break;
|
||||
}
|
||||
|
||||
if (result.text)
|
||||
result.text = result.text.replace(regresult.value, '').trim();
|
||||
});
|
||||
|
||||
isvalid = true;
|
||||
}
|
||||
|
||||
if (isvalid)
|
||||
return;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary> Gets RegEx property. </summary>
|
||||
/// <param name="actions"> The actions. </param>
|
||||
/// <param name="property"> The property. </param>
|
||||
/// <returns> The RegEx property. </returns>
|
||||
function getRegExProperty(actions, property) {
|
||||
var idx = -1;
|
||||
idx = actions.map(function (e) { return e.name; }).indexOf(name);
|
||||
|
||||
if (idx > -1)
|
||||
return actions[idx];
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary> Check item property. </summary>
|
||||
/// <param name="property"> The property. </param>
|
||||
/// <param name="itemDefaultValue"> The item default value. </param>
|
||||
/// <param name="useGroupDefaultValue"> The use group default value. </param>
|
||||
/// <param name="groupDefaultValue"> The group default value. </param>
|
||||
/// <returns> . </returns>
|
||||
function checkItemProperty(property, itemDefaultValue, useGroupDefaultValue, groupDefaultValue) {
|
||||
if (property)
|
||||
return property;
|
||||
|
||||
if (useGroupDefaultValue && groupDefaultValue)
|
||||
return groupDefaultValue;
|
||||
|
||||
return itemDefaultValue;
|
||||
}
|
||||
|
||||
return function (commandgroups, text) {
|
||||
|
||||
if (commandgroups) {
|
||||
var result = processcommands(text, commandgroups);
|
||||
console.log(text);
|
||||
console.log(commandgroups);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
});
|
20
dashboard-ui/bower_components/emby-webcomponents/voice/voice.css
vendored
Normal file
20
dashboard-ui/bower_components/emby-webcomponents/voice/voice.css
vendored
Normal file
|
@ -0,0 +1,20 @@
|
|||
.voiceHelpContent {
|
||||
max-width: 700px;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.exampleCommand {
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.exampleCommandText {
|
||||
padding-left: .25em;
|
||||
}
|
||||
|
||||
.defaultVoiceHelp {
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
.voiceInputContainer {
|
||||
margin: 1.5em 0;
|
||||
}
|
60
dashboard-ui/bower_components/emby-webcomponents/voice/voicecommands.js
vendored
Normal file
60
dashboard-ui/bower_components/emby-webcomponents/voice/voicecommands.js
vendored
Normal file
|
@ -0,0 +1,60 @@
|
|||
// <date>09.10.2015</date>
|
||||
// <summary>voicecommands class</summary>
|
||||
define([], function () {
|
||||
|
||||
/// <summary> Process the command. </summary>
|
||||
/// <param name="commandPath"> Full pathname of the command file. </param>
|
||||
/// <param name="result"> The result. </param>
|
||||
/// <returns> . </returns>
|
||||
function processCommand(commandPath, result) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
require([commandPath], function (command) {
|
||||
command(result);
|
||||
if (result.success) {
|
||||
resolve(result);
|
||||
}
|
||||
reject();
|
||||
});
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return function (result) {
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
switch (result.item.actionid) {
|
||||
|
||||
case 'show':
|
||||
processCommand('voice/commands/showcommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
case 'play':
|
||||
processCommand('voice/commands/playcommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
case 'shuffle':
|
||||
processCommand('voice/commands/playcommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
case 'search':
|
||||
processCommand('voice/commands/searchcommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
case 'control':
|
||||
processCommand('voice/commands/controlcommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
case 'enable':
|
||||
processCommand('voice/commands/enablecommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
case 'disable':
|
||||
processCommand('voice/commands/disablecommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
case 'toggle':
|
||||
processCommand('voice/commands/togglecommands.js', result).then(function (result) { resolve(result); });
|
||||
break;
|
||||
default:
|
||||
reject();
|
||||
return;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
272
dashboard-ui/bower_components/emby-webcomponents/voice/voicedialog.js
vendored
Normal file
272
dashboard-ui/bower_components/emby-webcomponents/voice/voicedialog.js
vendored
Normal file
|
@ -0,0 +1,272 @@
|
|||
define(['dialogHelper', './voicereceiver', './voiceprocessor', 'globalize', 'emby-button', 'css!./voice.css', 'material-icons', 'css!./../formdialog'], function (dialogHelper, voicereceiver, voiceprocessor, globalize) {
|
||||
|
||||
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) {
|
||||
|
||||
return voiceprocessor.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);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary> Gets command group. </summary>
|
||||
/// <param name="groupid"> The groupid. </param>
|
||||
/// <returns> The command group. </returns>
|
||||
function getCommandGroup(groupid) {
|
||||
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;
|
||||
});
|
||||
}
|
||||
|
||||
/// <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('');
|
||||
|
||||
elem.querySelector('.exampleCommands').innerHTML = commands;
|
||||
}
|
||||
|
||||
var currentDialog;
|
||||
/// <summary> Shows the voice help. </summary>
|
||||
/// <returns> . </returns>
|
||||
function showVoiceHelp(groupid, title) {
|
||||
|
||||
console.log("Showing Voice Help", groupid, title);
|
||||
|
||||
var isNewDialog = false;
|
||||
var dlg;
|
||||
|
||||
if (!currentDialog) {
|
||||
|
||||
isNewDialog = true;
|
||||
|
||||
dlg = dialogHelper.createDialog({
|
||||
size: 'medium',
|
||||
removeOnClose: true
|
||||
});
|
||||
|
||||
dlg.classList.add('ui-body-b');
|
||||
dlg.classList.add('background-theme-b');
|
||||
|
||||
var html = '';
|
||||
html += '<div class="dialogHeader" style="margin:0 0 1em;">';
|
||||
html += '<button is="paper-icon-button-light" class="btnCancel autoSize btnCancelVoiceInput" tabindex="-1"><i class="md-icon">arrow_back</i></button>';
|
||||
html += '<div class="dialogHeaderTitle" id="voiceDialogGroupName">';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
|
||||
html += '<div>';
|
||||
|
||||
html += '<div class="dialogContent smoothScrollY">';
|
||||
html += '<div class="dialogContentInner centeredContent">';
|
||||
html += '<div class="voiceHelpContent">';
|
||||
|
||||
html += '<div class="defaultVoiceHelp">';
|
||||
|
||||
html += '<h1 style="margin-bottom:1.25em;">' + globalize.translate('sharedcomponents#HeaderSaySomethingLike') + '</h1>';
|
||||
|
||||
html += '<div class="exampleCommands">';
|
||||
html += '</div>';
|
||||
|
||||
// defaultVoiceHelp
|
||||
html += '</div>';
|
||||
|
||||
html += '<div class="unrecognizedCommand hide">';
|
||||
html += '<h1>' + globalize.translate('sharedcomponents#HeaderYouSaid') + '</h1>';
|
||||
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>';
|
||||
html += '<p>' + globalize.translate('sharedcomponents#MessageWeDidntRecognizeCommand') + '</p>';
|
||||
|
||||
html += '<br/>';
|
||||
html += '<button is="emby-button" type="button" class="submit block btnRetry raised"><i class="md-icon">mic</i><span>' +
|
||||
globalize.translate('sharedcomponents#ButtonTryAgain') +
|
||||
'</span></button>';
|
||||
html += '<p class="blockedMessage hide">' +
|
||||
globalize.translate('sharedcomponents#MessageIfYouBlockedVoice') +
|
||||
'<br/><br/></p>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
html +=
|
||||
'<button is="emby-button" type="button" class="raised block btnCancelVoiceInput cancel"><i class="md-icon">close</i><span>' + globalize.translate('sharedcomponents#ButtonCancel') + '</span></button>';
|
||||
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
html += '</div>';
|
||||
|
||||
html += '</div>';
|
||||
|
||||
dlg.innerHTML = html;
|
||||
document.body.appendChild(dlg);
|
||||
|
||||
dialogHelper.open(dlg);
|
||||
currentDialog = dlg;
|
||||
|
||||
dlg.addEventListener('close', function () {
|
||||
currentDialog = null;
|
||||
});
|
||||
|
||||
function onCancelClick() {
|
||||
voicereceiver.cancel();
|
||||
dialogHelper.close(dlg);
|
||||
}
|
||||
|
||||
var closeButtons = dlg.querySelectorAll('.btnCancelVoiceInput');
|
||||
for (var i = 0, length = closeButtons.length; i < length; i++) {
|
||||
closeButtons[i].addEventListener('click', onCancelClick);
|
||||
}
|
||||
|
||||
dlg.querySelector('.btnRetry').addEventListener('click', function () {
|
||||
dlg.querySelector('.unrecognizedCommand').classList.add('hide');
|
||||
dlg.querySelector('.defaultVoiceHelp').classList.remove('hide');
|
||||
listen();
|
||||
});
|
||||
}
|
||||
|
||||
dlg = currentDialog;
|
||||
|
||||
if (groupid) {
|
||||
getCommandGroup(groupid)
|
||||
.then(
|
||||
function (grp) {
|
||||
dlg.querySelector('#voiceDialogGroupName').innerText = ' ' + grp.name;
|
||||
});
|
||||
|
||||
|
||||
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);
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
function processInput(input) {
|
||||
return voiceprocessor.processTranscript(input);
|
||||
}
|
||||
|
||||
/// <summary> Shows the unrecognized command help. </summary>
|
||||
/// <returns> . </returns>
|
||||
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');
|
||||
}
|
||||
|
||||
/// <summary> Shows the commands. </summary>
|
||||
/// <param name="createUI"> The create user interface. </param>
|
||||
/// <returns> . </returns>
|
||||
function showCommands(result) {
|
||||
//speak('Hello, what can I do for you?');
|
||||
if (result)
|
||||
showVoiceHelp(result.groupid, result.name);
|
||||
else
|
||||
showVoiceHelp();
|
||||
}
|
||||
|
||||
function resetDialog() {
|
||||
if (currentDialog) {
|
||||
currentDialog.querySelector('.unrecognizedCommand').classList.add('hide');
|
||||
currentDialog.querySelector('.defaultVoiceHelp').classList.remove('hide');
|
||||
}
|
||||
}
|
||||
function showDialog() {
|
||||
resetDialog();
|
||||
showCommands();
|
||||
listen();
|
||||
}
|
||||
function listen() {
|
||||
voicereceiver.listenForCommand(lang || "en-US").then(processInput).then(function (data) {
|
||||
|
||||
closeDialog();
|
||||
|
||||
}, function (result) {
|
||||
if (result.error == 'group') {
|
||||
showVoiceHelp(result.item.groupid, result.groupName);
|
||||
return;
|
||||
}
|
||||
showUnrecognizedCommandHelp(result.text || '');
|
||||
});
|
||||
}
|
||||
function closeDialog() {
|
||||
dialogHelper.close(currentDialog);
|
||||
voicereceiver.cancel();
|
||||
}
|
||||
|
||||
/// <summary> An enum constant representing the window. voice input manager option. </summary>
|
||||
return {
|
||||
showDialog: showDialog
|
||||
};
|
||||
|
||||
});
|
55
dashboard-ui/bower_components/emby-webcomponents/voice/voiceprocessor.js
vendored
Normal file
55
dashboard-ui/bower_components/emby-webcomponents/voice/voiceprocessor.js
vendored
Normal file
|
@ -0,0 +1,55 @@
|
|||
define(['./voicecommands.js', './grammarprocessor.js', 'require'], function (voicecommands, grammarprocessor, require) {
|
||||
|
||||
var commandgroups;
|
||||
|
||||
function getCommandGroups() {
|
||||
|
||||
if (commandgroups) {
|
||||
return Promise.resolve(commandgroups);
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
|
||||
var file = "grammar";
|
||||
|
||||
require(['text!./grammar/' + file + '.json'], function (response) {
|
||||
commandgroups = JSON.parse(response);
|
||||
resolve(commandgroups);
|
||||
});
|
||||
});
|
||||
}
|
||||
/// <summary> Process the transcript described by text. </summary>
|
||||
/// <param name="text"> The text. </param>
|
||||
/// <returns> . </returns>
|
||||
function processTranscript(text) {
|
||||
if (text) {
|
||||
var processor = grammarprocessor(commandgroups, text);
|
||||
if (processor && processor.command) {
|
||||
console.log("Command from Grammar Processor", processor);
|
||||
return voicecommands(processor)
|
||||
.then(function (result) {
|
||||
console.log("Result of executed command", result);
|
||||
if (result.item.actionid === 'show' && result.item.sourceid === 'group') {
|
||||
return Promise.reject({ error: "group", item: result.item, groupName: result.name });
|
||||
} else {
|
||||
return Promise.resolve({ item: result.item });
|
||||
}
|
||||
}, function () {
|
||||
return Promise.reject({ error: "unrecognized-command", text: text });
|
||||
});
|
||||
} else {
|
||||
return Promise.reject({ error: "unrecognized-command", text: text });
|
||||
}
|
||||
|
||||
} else {
|
||||
return Promise.reject({ error: "empty" });
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary> An enum constant representing the window. voice input manager option. </summary>
|
||||
return {
|
||||
processTranscript: processTranscript,
|
||||
getCommandGroups: getCommandGroups
|
||||
};
|
||||
|
||||
});
|
57
dashboard-ui/bower_components/emby-webcomponents/voice/voicereceiver.js
vendored
Normal file
57
dashboard-ui/bower_components/emby-webcomponents/voice/voicereceiver.js
vendored
Normal file
|
@ -0,0 +1,57 @@
|
|||
define([], function () {
|
||||
var currentRecognition = null;
|
||||
|
||||
|
||||
/// <summary> Starts listening for voice commands </summary>
|
||||
/// <returns> . </returns>
|
||||
function listenForCommand(lang) {
|
||||
return new Promise(function (resolve, reject) {
|
||||
cancelListener();
|
||||
|
||||
var recognition = new (window.SpeechRecognition ||
|
||||
window.webkitSpeechRecognition ||
|
||||
window.mozSpeechRecognition ||
|
||||
window.oSpeechRecognition ||
|
||||
window.msSpeechRecognition)();
|
||||
recognition.lang = lang;
|
||||
|
||||
recognition.onresult = function (event) {
|
||||
console.log(event);
|
||||
if (event.results.length > 0) {
|
||||
var resultInput = event.results[0][0].transcript || '';
|
||||
resolve(resultInput);
|
||||
}
|
||||
};
|
||||
|
||||
recognition.onerror = function () {
|
||||
reject({ error: event.error, message: event.message });
|
||||
};
|
||||
|
||||
recognition.onnomatch = function () {
|
||||
reject({ error: "no-match" });
|
||||
};
|
||||
currentRecognition = recognition;
|
||||
|
||||
currentRecognition.start();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/// <summary> Cancel listener. </summary>
|
||||
/// <returns> . </returns>
|
||||
function cancelListener() {
|
||||
|
||||
if (currentRecognition) {
|
||||
currentRecognition.abort();
|
||||
currentRecognition = null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary> An enum constant representing the window. voice input manager option. </summary>
|
||||
return {
|
||||
listenForCommand: listenForCommand,
|
||||
cancel: cancelListener
|
||||
};
|
||||
|
||||
});
|
Loading…
Add table
Add a link
Reference in a new issue