1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Merge pull request #566 from dmitrylyzo/tv_playback_navigation

Make navigation and playback control TV-friendly
This commit is contained in:
dkanada 2019-11-19 09:10:09 +09:00 committed by GitHub
commit 957184b81c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 138 additions and 2 deletions

View file

@ -87,6 +87,10 @@ _:-ms-input-placeholder {
transform: scale(1.6);
}
.mdl-slider.show-focus:focus::-webkit-slider-thumb {
transform: scale(1.6);
}
.slider-no-webkit-thumb::-webkit-slider-thumb {
opacity: 0 !important;
}

View file

@ -19,6 +19,11 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement
function updateValues() {
// Do not update values when dragging with keyboard to keep current progress for reference
if (!!this.keyboardDragging) {
return;
}
var range = this;
var value = range.value;
@ -82,6 +87,9 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement
if (!layoutManager.mobile) {
this.classList.add('mdl-slider-hoverthumb');
}
if (layoutManager.tv) {
this.classList.add('show-focus');
}
var containerElement = this.parentNode;
containerElement.classList.add('mdl-slider-container');
@ -177,6 +185,108 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement
}
};
/**
* Keyboard dragging timeout.
* After this delay "change" event will be fired.
*/
var KeyboardDraggingTimeout = 1000;
/**
* Keyboard dragging timer.
*/
var keyboardDraggingTimer;
/**
* Start keyboard dragging.
*
* @param {Object} elem slider itself
*/
function startKeyboardDragging(elem) {
elem.keyboardDragging = true;
clearTimeout(keyboardDraggingTimer);
keyboardDraggingTimer = setTimeout(function () {
finishKeyboardDragging(elem);
}, KeyboardDraggingTimeout);
}
/**
* Finish keyboard dragging.
*
* @param {Object} elem slider itself
*/
function finishKeyboardDragging(elem) {
clearTimeout(keyboardDraggingTimer);
keyboardDraggingTimer = undefined;
elem.keyboardDragging = false;
var event = new Event('change', {
bubbles: true,
cancelable: false
});
elem.dispatchEvent(event);
}
/**
* Do step by delta.
*
* @param {Object} elem slider itself
* @param {number} delta step amount
*/
function stepKeyboard(elem, delta) {
startKeyboardDragging(elem);
elem.value = Math.max(elem.min, Math.min(elem.max, parseFloat(elem.value) + delta));
var event = new Event('input', {
bubbles: true,
cancelable: false
});
elem.dispatchEvent(event);
}
/**
* Handle KeyDown event
*/
function onKeyDown(e) {
switch (e.key) {
case 'ArrowLeft':
case 'Left':
stepKeyboard(this, -this.keyboardStepDown || -1);
e.preventDefault();
e.stopPropagation();
break;
case 'ArrowRight':
case 'Right':
stepKeyboard(this, this.keyboardStepUp || 1);
e.preventDefault();
e.stopPropagation();
break;
}
}
/**
* Enable keyboard dragging.
*/
EmbySliderPrototype.enableKeyboardDragging = function () {
if (!this.keyboardDraggingEnabled) {
this.addEventListener('keydown', onKeyDown);
this.keyboardDraggingEnabled = true;
}
}
/**
* Set steps for keyboard input.
*
* @param {number} stepDown step to reduce
* @param {number} stepUp step to increase
*/
EmbySliderPrototype.setKeyboardSteps = function (stepDown, stepUp) {
this.keyboardStepDown = stepDown || stepUp || 1;
this.keyboardStepUp = stepUp || stepDown || 1;
}
function setRange(elem, startPercent, endPercent) {
var style = elem.style;

View file

@ -770,6 +770,11 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
nowPlayingPositionSlider.setIsClear(isProgressClear);
if (nowPlayingItem.RunTimeTicks) {
nowPlayingPositionSlider.setKeyboardSteps(userSettings.skipBackLength() * 1000000 / nowPlayingItem.RunTimeTicks,
userSettings.skipForwardLength() * 1000000 / nowPlayingItem.RunTimeTicks);
}
if (-1 === supportedCommands.indexOf("ToggleFullscreen") || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) {
view.querySelector(".btnFullscreen").classList.add("hide");
} else {
@ -1070,10 +1075,21 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
}
}
/**
* Keys used for keyboard navigation.
*/
var NavigationKeys = ["ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown"];
function onWindowKeyDown(e) {
if (!currentVisibleMenu && 32 === e.keyCode) {
playbackManager.playPause(currentPlayer);
return void showOsd();
showOsd();
return;
}
if (layoutManager.tv && NavigationKeys.indexOf(e.key) != -1) {
showOsd();
return;
}
switch (e.key) {
@ -1237,6 +1253,12 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
var transitionEndEventName = dom.whichTransitionEvent();
var headerElement = document.querySelector(".skinHeader");
var osdBottomElement = document.querySelector(".videoOsdBottom-maincontrols");
if (layoutManager.tv) {
nowPlayingPositionSlider.classList.add("focusable");
nowPlayingPositionSlider.enableKeyboardDragging();
}
view.addEventListener("viewbeforeshow", function (e) {
headerElement.classList.add("osdHeader");
Emby.Page.setTransparency("full");

View file

@ -31,7 +31,7 @@
<div class="osdTextContainer endTimeText" style="margin: 0 0 0 .25em;"></div>
</div>
<div class="buttons">
<div class="buttons focuscontainer-x">
<button is="paper-icon-button-light" class="btnRecord autoSize hide">
<i class="xlargePaperIconButton md-icon">&#xE061;</i>
</button>