mirror of
https://github.com/jellyfin/jellyfin-web.git
synced 2024-11-19 20:08:20 -07:00
Add next/prev chapter buttons for mobile devices
Also removes touch events as they interfere with continuous scrolling
This commit is contained in:
parent
270f585b26
commit
14583cf18e
@ -19,6 +19,8 @@ export class BookPlayer {
|
|||||||
|
|
||||||
this.onDialogClosed = this.onDialogClosed.bind(this);
|
this.onDialogClosed = this.onDialogClosed.bind(this);
|
||||||
this.openTableOfContents = this.openTableOfContents.bind(this);
|
this.openTableOfContents = this.openTableOfContents.bind(this);
|
||||||
|
this.prevChapter = this.prevChapter.bind(this);
|
||||||
|
this.nextChapter = this.nextChapter.bind(this);
|
||||||
this.onWindowKeyUp = this.onWindowKeyUp.bind(this);
|
this.onWindowKeyUp = this.onWindowKeyUp.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,26 +125,6 @@ export class BookPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onTouchStart(e) {
|
|
||||||
// TODO: depending on the event this can be the document or the rendition itself
|
|
||||||
const rendition = this._rendition || this;
|
|
||||||
const book = rendition.book;
|
|
||||||
|
|
||||||
// check that the event is from the book or the document
|
|
||||||
if (!book || this._loaded === false) return;
|
|
||||||
|
|
||||||
// epubjs stores pages off the screen or something for preloading
|
|
||||||
// get the modulus of the touch event to account for the increased width
|
|
||||||
if (!e.touches || e.touches.length === 0) return;
|
|
||||||
|
|
||||||
const touch = e.touches[0].clientX % dom.getWindowSize().innerWidth;
|
|
||||||
if (touch < dom.getWindowSize().innerWidth / 2) {
|
|
||||||
book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev();
|
|
||||||
} else {
|
|
||||||
book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onDialogClosed() {
|
onDialogClosed() {
|
||||||
this.stop();
|
this.stop();
|
||||||
}
|
}
|
||||||
@ -151,27 +133,33 @@ export class BookPlayer {
|
|||||||
const elem = this._mediaElement;
|
const elem = this._mediaElement;
|
||||||
|
|
||||||
elem.addEventListener('close', this.onDialogClosed, {once: true});
|
elem.addEventListener('close', this.onDialogClosed, {once: true});
|
||||||
elem.querySelector('.btnBookplayerExit').addEventListener('click', this.onDialogClosed, {once: true});
|
elem.querySelector('#btnBookplayerExit').addEventListener('click', this.onDialogClosed, {once: true});
|
||||||
elem.querySelector('.btnBookplayerToc').addEventListener('click', this.openTableOfContents);
|
elem.querySelector('#btnBookplayerToc').addEventListener('click', this.openTableOfContents);
|
||||||
|
if (browser.mobile) {
|
||||||
|
elem.querySelector('#btnBookplayerPrev').addEventListener('click', this.prevChapter);
|
||||||
|
elem.querySelector('#btnBookplayerNext').addEventListener('click', this.nextChapter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bindEvents() {
|
bindEvents() {
|
||||||
this.bindMediaElementEvents();
|
this.bindMediaElementEvents();
|
||||||
|
|
||||||
document.addEventListener('keyup', this.onWindowKeyUp);
|
document.addEventListener('keyup', this.onWindowKeyUp);
|
||||||
document.addEventListener('touchstart', this.onTouchStart);
|
|
||||||
|
|
||||||
// FIXME: I don't really get why document keyup event is not triggered when epub is in focus
|
// FIXME: I don't really get why document keyup event is not triggered when epub is in focus
|
||||||
this._rendition.on('keyup', this.onWindowKeyUp);
|
this._rendition.on('keyup', this.onWindowKeyUp);
|
||||||
this._rendition.on('touchstart', this.onTouchStart);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unbindMediaElementEvents() {
|
unbindMediaElementEvents() {
|
||||||
const elem = this._mediaElement;
|
const elem = this._mediaElement;
|
||||||
|
|
||||||
elem.removeEventListener('close', this.onDialogClosed);
|
elem.removeEventListener('close', this.onDialogClosed);
|
||||||
elem.querySelector('.btnBookplayerExit').removeEventListener('click', this.onDialogClosed);
|
elem.querySelector('#btnBookplayerExit').removeEventListener('click', this.onDialogClosed);
|
||||||
elem.querySelector('.btnBookplayerToc').removeEventListener('click', this.openTableOfContents);
|
elem.querySelector('#btnBookplayerToc').removeEventListener('click', this.openTableOfContents);
|
||||||
|
if (browser.mobile) {
|
||||||
|
elem.querySelector('#btnBookplayerPrev').removeEventListener('click', this.prevChapter);
|
||||||
|
elem.querySelector('#btnBookplayerNext').removeEventListener('click', this.nextChapter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unbindEvents() {
|
unbindEvents() {
|
||||||
@ -180,11 +168,9 @@ export class BookPlayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
document.removeEventListener('keyup', this.onWindowKeyUp);
|
document.removeEventListener('keyup', this.onWindowKeyUp);
|
||||||
document.removeEventListener('touchstart', this.onTouchStart);
|
|
||||||
|
|
||||||
if (this._rendition) {
|
if (this._rendition) {
|
||||||
this._rendition.off('keyup', this.onWindowKeyUp);
|
this._rendition.off('keyup', this.onWindowKeyUp);
|
||||||
this._rendition.off('touchstart', this.onTouchStart);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,6 +180,16 @@ export class BookPlayer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
prevChapter(e) {
|
||||||
|
this._rendition.prev();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
nextChapter(e) {
|
||||||
|
this._rendition.next();
|
||||||
|
e.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
createMediaElement() {
|
createMediaElement() {
|
||||||
let elem = this._mediaElement;
|
let elem = this._mediaElement;
|
||||||
if (elem) {
|
if (elem) {
|
||||||
@ -214,13 +210,22 @@ export class BookPlayer {
|
|||||||
elem.id = 'bookPlayer';
|
elem.id = 'bookPlayer';
|
||||||
|
|
||||||
let html = '';
|
let html = '';
|
||||||
html += '<div class="topRightActionButtons">';
|
|
||||||
html += '<button is="paper-icon-button-light" class="autoSize bookplayerButton btnBookplayerExit hide-mouse-idle-tv" tabindex="-1"><i class="material-icons bookplayerButtonIcon close"></i></button>';
|
if (browser.mobile) {
|
||||||
|
html += '<div class="button-wrapper top-button"><button id="btnBookplayerPrev" is="paper-icon-button-light" class="autoSize bookplayerButton hide-mouse-idle-tv"><i class="material-icons bookplayerButtonIcon navigate_before"></i> Prev</button></div>';
|
||||||
|
}
|
||||||
|
|
||||||
|
html += '<div id="viewer">';
|
||||||
|
html += '<div class="topButtons">';
|
||||||
|
html += '<button is="paper-icon-button-light" id="btnBookplayerToc" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1"><i class="material-icons bookplayerButtonIcon toc"></i></button>';
|
||||||
|
html += '<button is="paper-icon-button-light" id="btnBookplayerExit" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1"><i class="material-icons bookplayerButtonIcon close"></i></button>';
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
html += '<div class="topLeftActionButtons">';
|
|
||||||
html += '<button is="paper-icon-button-light" class="autoSize bookplayerButton btnBookplayerToc hide-mouse-idle-tv" tabindex="-1"><i class="material-icons bookplayerButtonIcon toc"></i></button>';
|
|
||||||
html += '</div>';
|
html += '</div>';
|
||||||
|
|
||||||
|
if (browser.mobile) {
|
||||||
|
html += '<div class="button-wrapper bottom-button"><button id="btnBookplayerNext" is="paper-icon-button-light" class="autoSize bookplayerButton hide-mouse-idle-tv">Next <i class="material-icons bookplayerButtonIcon navigate_next"></i></button></div>';
|
||||||
|
}
|
||||||
|
|
||||||
elem.innerHTML = html;
|
elem.innerHTML = html;
|
||||||
|
|
||||||
dialogHelper.open(elem);
|
dialogHelper.open(elem);
|
||||||
@ -236,9 +241,7 @@ export class BookPlayer {
|
|||||||
return book.renderTo(elem, {
|
return book.renderTo(elem, {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: '100%',
|
height: '100%',
|
||||||
manager: 'continuous',
|
flow: 'scrolled-doc'
|
||||||
flow: 'scrolled-doc',
|
|
||||||
offset: 0
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
return book.renderTo(elem, {
|
return book.renderTo(elem, {
|
||||||
@ -266,7 +269,7 @@ export class BookPlayer {
|
|||||||
import('epubjs').then(({default: epubjs}) => {
|
import('epubjs').then(({default: epubjs}) => {
|
||||||
const downloadHref = apiClient.getItemDownloadUrl(item.Id);
|
const downloadHref = apiClient.getItemDownloadUrl(item.Id);
|
||||||
const book = epubjs(downloadHref, {openAs: 'epub'});
|
const book = epubjs(downloadHref, {openAs: 'epub'});
|
||||||
const rendition = this.render(elem, book);
|
const rendition = this.render('viewer', book);
|
||||||
|
|
||||||
this._currentSrc = downloadHref;
|
this._currentSrc = downloadHref;
|
||||||
this._rendition = rendition;
|
this._rendition = rendition;
|
||||||
|
@ -7,18 +7,20 @@
|
|||||||
background: #fff;
|
background: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topRightActionButtons {
|
.topButtons {
|
||||||
right: 0.5vh;
|
|
||||||
top: 0.5vh;
|
top: 0.5vh;
|
||||||
z-index: 1002;
|
z-index: 1002;
|
||||||
position: absolute;
|
position: sticky;
|
||||||
}
|
}
|
||||||
|
|
||||||
.topLeftActionButtons {
|
#btnBookplayerToc {
|
||||||
left: 0.5vh;
|
float: left;
|
||||||
top: 0.5vh;
|
margin-left: 2vw;
|
||||||
z-index: 1002;
|
}
|
||||||
position: absolute;
|
|
||||||
|
#btnBookplayerExit {
|
||||||
|
float: right;
|
||||||
|
margin-right: 2vw;
|
||||||
}
|
}
|
||||||
|
|
||||||
.bookplayerButtonIcon {
|
.bookplayerButtonIcon {
|
||||||
@ -37,3 +39,31 @@
|
|||||||
.bookplayerErrorMsg {
|
.bookplayerErrorMsg {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#viewer {
|
||||||
|
align-items: flex-start;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btnBookplayerPrev {
|
||||||
|
margin: 0.5vh 0.5vh;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btnBookplayerNext {
|
||||||
|
margin: 0.5vh 0.5vh;
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-wrapper {
|
||||||
|
text-align: center;
|
||||||
|
position: relative;
|
||||||
|
height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.top-button {
|
||||||
|
margin: 0.5vh 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bottom-button {
|
||||||
|
margin: 2em 0.5vh;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user