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:
commit
957184b81c
4 changed files with 138 additions and 2 deletions
|
@ -87,6 +87,10 @@ _:-ms-input-placeholder {
|
||||||
transform: scale(1.6);
|
transform: scale(1.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mdl-slider.show-focus:focus::-webkit-slider-thumb {
|
||||||
|
transform: scale(1.6);
|
||||||
|
}
|
||||||
|
|
||||||
.slider-no-webkit-thumb::-webkit-slider-thumb {
|
.slider-no-webkit-thumb::-webkit-slider-thumb {
|
||||||
opacity: 0 !important;
|
opacity: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,11 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement
|
||||||
|
|
||||||
function updateValues() {
|
function updateValues() {
|
||||||
|
|
||||||
|
// Do not update values when dragging with keyboard to keep current progress for reference
|
||||||
|
if (!!this.keyboardDragging) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var range = this;
|
var range = this;
|
||||||
var value = range.value;
|
var value = range.value;
|
||||||
|
|
||||||
|
@ -82,6 +87,9 @@ define(['browser', 'dom', 'layoutManager', 'css!./emby-slider', 'registerElement
|
||||||
if (!layoutManager.mobile) {
|
if (!layoutManager.mobile) {
|
||||||
this.classList.add('mdl-slider-hoverthumb');
|
this.classList.add('mdl-slider-hoverthumb');
|
||||||
}
|
}
|
||||||
|
if (layoutManager.tv) {
|
||||||
|
this.classList.add('show-focus');
|
||||||
|
}
|
||||||
|
|
||||||
var containerElement = this.parentNode;
|
var containerElement = this.parentNode;
|
||||||
containerElement.classList.add('mdl-slider-container');
|
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) {
|
function setRange(elem, startPercent, endPercent) {
|
||||||
|
|
||||||
var style = elem.style;
|
var style = elem.style;
|
||||||
|
|
|
@ -770,6 +770,11 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
||||||
var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
|
var isProgressClear = state.MediaSource && null == state.MediaSource.RunTimeTicks;
|
||||||
nowPlayingPositionSlider.setIsClear(isProgressClear);
|
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)) {
|
if (-1 === supportedCommands.indexOf("ToggleFullscreen") || player.isLocalPlayer && layoutManager.tv && playbackManager.isFullscreen(player)) {
|
||||||
view.querySelector(".btnFullscreen").classList.add("hide");
|
view.querySelector(".btnFullscreen").classList.add("hide");
|
||||||
} else {
|
} 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) {
|
function onWindowKeyDown(e) {
|
||||||
if (!currentVisibleMenu && 32 === e.keyCode) {
|
if (!currentVisibleMenu && 32 === e.keyCode) {
|
||||||
playbackManager.playPause(currentPlayer);
|
playbackManager.playPause(currentPlayer);
|
||||||
return void showOsd();
|
showOsd();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layoutManager.tv && NavigationKeys.indexOf(e.key) != -1) {
|
||||||
|
showOsd();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (e.key) {
|
switch (e.key) {
|
||||||
|
@ -1237,6 +1253,12 @@ define(["playbackManager", "dom", "inputManager", "datetime", "itemHelper", "med
|
||||||
var transitionEndEventName = dom.whichTransitionEvent();
|
var transitionEndEventName = dom.whichTransitionEvent();
|
||||||
var headerElement = document.querySelector(".skinHeader");
|
var headerElement = document.querySelector(".skinHeader");
|
||||||
var osdBottomElement = document.querySelector(".videoOsdBottom-maincontrols");
|
var osdBottomElement = document.querySelector(".videoOsdBottom-maincontrols");
|
||||||
|
|
||||||
|
if (layoutManager.tv) {
|
||||||
|
nowPlayingPositionSlider.classList.add("focusable");
|
||||||
|
nowPlayingPositionSlider.enableKeyboardDragging();
|
||||||
|
}
|
||||||
|
|
||||||
view.addEventListener("viewbeforeshow", function (e) {
|
view.addEventListener("viewbeforeshow", function (e) {
|
||||||
headerElement.classList.add("osdHeader");
|
headerElement.classList.add("osdHeader");
|
||||||
Emby.Page.setTransparency("full");
|
Emby.Page.setTransparency("full");
|
||||||
|
|
|
@ -31,7 +31,7 @@
|
||||||
<div class="osdTextContainer endTimeText" style="margin: 0 0 0 .25em;"></div>
|
<div class="osdTextContainer endTimeText" style="margin: 0 0 0 .25em;"></div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="buttons">
|
<div class="buttons focuscontainer-x">
|
||||||
<button is="paper-icon-button-light" class="btnRecord autoSize hide">
|
<button is="paper-icon-button-light" class="btnRecord autoSize hide">
|
||||||
<i class="xlargePaperIconButton md-icon"></i>
|
<i class="xlargePaperIconButton md-icon"></i>
|
||||||
</button>
|
</button>
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue