mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #702 from dmitrylyzo/playback_remote
Add playback control from TV remote
This commit is contained in:
commit
7af58a03dd
4 changed files with 169 additions and 31 deletions
|
@ -1,36 +1,133 @@
|
|||
define(['inputManager', 'focusManager'], function(inputManager, focusManager) {
|
||||
'use strict';
|
||||
define(["inputManager", "layoutManager"], function (inputManager, layoutManager) {
|
||||
"use strict";
|
||||
|
||||
console.log("keyboardnavigation");
|
||||
|
||||
/**
|
||||
* Key name mapping.
|
||||
*/
|
||||
// Add more to support old browsers
|
||||
var KeyNames = {
|
||||
13: "Enter",
|
||||
19: "Pause",
|
||||
27: "Escape",
|
||||
32: "Space",
|
||||
37: "ArrowLeft",
|
||||
38: "ArrowUp",
|
||||
39: "ArrowRight",
|
||||
40: "ArrowDown",
|
||||
// MediaRewind (Tizen/WebOS)
|
||||
412: "MediaRewind",
|
||||
// MediaStop (Tizen/WebOS)
|
||||
413: "MediaStop",
|
||||
// MediaPlay (Tizen/WebOS)
|
||||
415: "MediaPlay",
|
||||
// MediaFastForward (Tizen/WebOS)
|
||||
417: "MediaFastForward",
|
||||
// Back (WebOS)
|
||||
461: "Back",
|
||||
// Back (Tizen)
|
||||
10009: "Back",
|
||||
// MediaTrackPrevious (Tizen)
|
||||
10232: "MediaTrackPrevious",
|
||||
// MediaTrackNext (Tizen)
|
||||
10233: "MediaTrackNext",
|
||||
// MediaPlayPause (Tizen)
|
||||
10252: "MediaPlayPause"
|
||||
};
|
||||
|
||||
var hasFieldKey = false;
|
||||
try {
|
||||
hasFieldKey = "key" in new KeyboardEvent("keydown");
|
||||
} catch (e) {
|
||||
console.log("error checking 'key' field");
|
||||
}
|
||||
|
||||
if (!hasFieldKey) {
|
||||
// Add [a..z]
|
||||
for (var i = 65; i <= 90; i++) {
|
||||
KeyNames[i] = String.fromCharCode(i).toLowerCase();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns key name from event.
|
||||
*
|
||||
* @param {KeyboardEvent} keyboard event
|
||||
* @return {string} key name
|
||||
*/
|
||||
function getKeyName(event) {
|
||||
return KeyNames[event.keyCode] || event.key;
|
||||
}
|
||||
|
||||
function enable() {
|
||||
document.addEventListener('keydown', function(e) {
|
||||
document.addEventListener("keydown", function (e) {
|
||||
var capture = true;
|
||||
|
||||
switch (e.keyCode) {
|
||||
case 37: // ArrowLeft
|
||||
inputManager.handle('left');
|
||||
switch (getKeyName(e)) {
|
||||
case "ArrowLeft":
|
||||
inputManager.handle("left");
|
||||
break;
|
||||
case 38: // ArrowUp
|
||||
inputManager.handle('up');
|
||||
case "ArrowUp":
|
||||
inputManager.handle("up");
|
||||
break;
|
||||
case 39: // ArrowRight
|
||||
inputManager.handle('right');
|
||||
case "ArrowRight":
|
||||
inputManager.handle("right");
|
||||
break;
|
||||
case 40: // ArrowDown
|
||||
inputManager.handle('down');
|
||||
case "ArrowDown":
|
||||
inputManager.handle("down");
|
||||
break;
|
||||
|
||||
case "Back":
|
||||
inputManager.handle("back");
|
||||
break;
|
||||
|
||||
case "Escape":
|
||||
if (layoutManager.tv) {
|
||||
inputManager.handle("back");
|
||||
} else {
|
||||
capture = false;
|
||||
}
|
||||
break;
|
||||
|
||||
case "MediaPlay":
|
||||
inputManager.handle("play");
|
||||
break;
|
||||
case "Pause":
|
||||
inputManager.handle("pause");
|
||||
break;
|
||||
case "MediaPlayPause":
|
||||
inputManager.handle("playpause");
|
||||
break;
|
||||
case "MediaRewind":
|
||||
inputManager.handle("rewind");
|
||||
break;
|
||||
case "MediaFastForward":
|
||||
inputManager.handle("fastforward");
|
||||
break;
|
||||
case "MediaStop":
|
||||
inputManager.handle("stop");
|
||||
break;
|
||||
case "MediaTrackPrevious":
|
||||
inputManager.handle("previoustrack");
|
||||
break;
|
||||
case "MediaTrackNext":
|
||||
inputManager.handle("nexttrack");
|
||||
break;
|
||||
|
||||
default:
|
||||
capture = false;
|
||||
}
|
||||
|
||||
if (capture) {
|
||||
console.log("Disabling default event handling");
|
||||
e.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return {
|
||||
enable: enable
|
||||
enable: enable,
|
||||
getKeyName: getKeyName
|
||||
};
|
||||
});
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "mediaInfo", "focusManager", "imageLoader", "scrollHelper", "events", "connectionManager", "browser", "globalize", "apphost", "layoutManager", "userSettings", "scrollStyles", "emby-slider", "paper-icon-button-light", "css!assets/css/videoosd"], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings) {
|
||||
define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "mediaInfo", "focusManager", "imageLoader", "scrollHelper", "events", "connectionManager", "browser", "globalize", "apphost", "layoutManager", "userSettings", "keyboardnavigation", "scrollStyles", "emby-slider", "paper-icon-button-light", "css!assets/css/videoosd"], function (playbackManager, dom, inputManager, datetime, itemHelper, mediaInfo, focusManager, imageLoader, scrollHelper, events, connectionManager, browser, globalize, appHost, layoutManager, userSettings, keyboardnavigation) {
|
||||
"use strict";
|
||||
|
||||
function seriesImageUrl(item, options) {
|
||||
|
@ -437,6 +437,11 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
});
|
||||
currentVisibleMenu = null;
|
||||
toggleSubtitleSync("hide");
|
||||
|
||||
// Firefox does not blur by itself
|
||||
if (document.activeElement) {
|
||||
document.activeElement.blur();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1087,50 +1092,66 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
*/
|
||||
var NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"];
|
||||
|
||||
/**
|
||||
* Clicked element.
|
||||
* To skip 'click' handling on Firefox/Edge.
|
||||
*/
|
||||
var clickedElement;
|
||||
|
||||
function onWindowKeyDown(e) {
|
||||
clickedElement = e.srcElement;
|
||||
|
||||
var key = keyboardnavigation.getKeyName(e);
|
||||
|
||||
if (!currentVisibleMenu && 32 === e.keyCode) {
|
||||
playbackManager.playPause(currentPlayer);
|
||||
showOsd();
|
||||
return;
|
||||
}
|
||||
|
||||
if (layoutManager.tv && NavigationKeys.indexOf(e.key) != -1) {
|
||||
if (layoutManager.tv && NavigationKeys.indexOf(key) != -1) {
|
||||
showOsd();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (e.key) {
|
||||
switch (key) {
|
||||
case "Enter":
|
||||
showOsd();
|
||||
break;
|
||||
case "Escape":
|
||||
case "Back":
|
||||
// Ignore key when some dialog is opened
|
||||
if (currentVisibleMenu === "osd" && !document.querySelector(".dialogContainer")) {
|
||||
hideOsd();
|
||||
e.stopPropagation();
|
||||
}
|
||||
break;
|
||||
case "k":
|
||||
playbackManager.playPause(currentPlayer);
|
||||
showOsd();
|
||||
break;
|
||||
|
||||
case "l":
|
||||
case "ArrowRight":
|
||||
case "Right":
|
||||
playbackManager.fastForward(currentPlayer);
|
||||
showOsd();
|
||||
break;
|
||||
|
||||
case "j":
|
||||
case "ArrowLeft":
|
||||
case "Left":
|
||||
playbackManager.rewind(currentPlayer);
|
||||
showOsd();
|
||||
break;
|
||||
|
||||
case "f":
|
||||
if (!e.ctrlKey && !e.metaKey) {
|
||||
playbackManager.toggleFullscreen(currentPlayer);
|
||||
showOsd();
|
||||
}
|
||||
break;
|
||||
|
||||
case "m":
|
||||
playbackManager.toggleMute(currentPlayer);
|
||||
showOsd();
|
||||
break;
|
||||
|
||||
case "NavigationLeft":
|
||||
case "GamepadDPadLeft":
|
||||
case "GamepadLeftThumbstickLeft":
|
||||
|
@ -1140,7 +1161,6 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
showOsd();
|
||||
}
|
||||
break;
|
||||
|
||||
case "NavigationRight":
|
||||
case "GamepadDPadRight":
|
||||
case "GamepadLeftThumbstickRight":
|
||||
|
@ -1152,6 +1172,14 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
}
|
||||
}
|
||||
|
||||
function onWindowMouseDown(e) {
|
||||
clickedElement = e.srcElement;
|
||||
}
|
||||
|
||||
function onWindowTouchStart(e) {
|
||||
clickedElement = e.srcElement;
|
||||
}
|
||||
|
||||
function getImgUrl(item, chapter, index, maxWidth, apiClient) {
|
||||
if (chapter.ImageTag) {
|
||||
return apiClient.getScaledImageUrl(item.Id, {
|
||||
|
@ -1280,6 +1308,12 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
showOsd();
|
||||
inputManager.on(window, onInputCommand);
|
||||
dom.addEventListener(window, "keydown", onWindowKeyDown, {
|
||||
capture: true
|
||||
});
|
||||
dom.addEventListener(window, window.PointerEvent ? "pointerdown" : "mousedown", onWindowMouseDown, {
|
||||
passive: true
|
||||
});
|
||||
dom.addEventListener(window, "touchstart", onWindowTouchStart, {
|
||||
passive: true
|
||||
});
|
||||
} catch (e) {
|
||||
|
@ -1294,6 +1328,12 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
}
|
||||
|
||||
dom.removeEventListener(window, "keydown", onWindowKeyDown, {
|
||||
capture: true
|
||||
});
|
||||
dom.removeEventListener(window, window.PointerEvent ? "pointerdown" : "mousedown", onWindowMouseDown, {
|
||||
passive: true
|
||||
});
|
||||
dom.removeEventListener(window, "touchstart", onWindowTouchStart, {
|
||||
passive: true
|
||||
});
|
||||
stopOsdHideTimer();
|
||||
|
@ -1465,7 +1505,10 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
|||
playbackManager.previousTrack(currentPlayer);
|
||||
});
|
||||
view.querySelector(".btnPause").addEventListener("click", function () {
|
||||
// Ignore 'click' if another element was originally clicked (Firefox/Edge issue)
|
||||
if (this.contains(clickedElement)) {
|
||||
playbackManager.playPause(currentPlayer);
|
||||
}
|
||||
});
|
||||
view.querySelector(".btnNextTrack").addEventListener("click", function () {
|
||||
playbackManager.nextTrack(currentPlayer);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement', 'emby-input'], function (browser, dom, layoutManager) {
|
||||
define(['browser', 'dom', 'layoutManager', 'keyboardnavigation', 'css!./emby-slider', 'registerElement', 'emby-input'], function (browser, dom, layoutManager, keyboardnavigation) {
|
||||
'use strict';
|
||||
|
||||
var EmbySliderPrototype = Object.create(HTMLInputElement.prototype);
|
||||
|
@ -250,7 +250,7 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement
|
|||
* Handle KeyDown event
|
||||
*/
|
||||
function onKeyDown(e) {
|
||||
switch (e.key) {
|
||||
switch (keyboardnavigation.getKeyName(e)) {
|
||||
case 'ArrowLeft':
|
||||
case 'Left':
|
||||
stepKeyboard(this, -this.keyboardStepDown || -1);
|
||||
|
|
|
@ -22,9 +22,7 @@ define(['playbackManager', 'focusManager', 'appRouter', 'dom'], function (playba
|
|||
|
||||
var eventListenerCount = 0;
|
||||
function on(scope, fn) {
|
||||
if (eventListenerCount) {
|
||||
eventListenerCount++;
|
||||
}
|
||||
dom.addEventListener(scope, 'command', fn, {});
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue