From 14583cf18e824308f6e7741da95e3204129cf8d1 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Mon, 14 Sep 2020 18:51:03 +1000 Subject: [PATCH] Add next/prev chapter buttons for mobile devices Also removes touch events as they interfere with continuous scrolling --- src/plugins/bookPlayer/plugin.js | 75 +++++++++++++++++--------------- src/plugins/bookPlayer/style.css | 46 ++++++++++++++++---- 2 files changed, 77 insertions(+), 44 deletions(-) diff --git a/src/plugins/bookPlayer/plugin.js b/src/plugins/bookPlayer/plugin.js index 8cde3f400f..0c3d6850aa 100644 --- a/src/plugins/bookPlayer/plugin.js +++ b/src/plugins/bookPlayer/plugin.js @@ -19,6 +19,8 @@ export class BookPlayer { this.onDialogClosed = this.onDialogClosed.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); } @@ -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() { this.stop(); } @@ -151,27 +133,33 @@ export class BookPlayer { const elem = this._mediaElement; elem.addEventListener('close', this.onDialogClosed, {once: true}); - elem.querySelector('.btnBookplayerExit').addEventListener('click', this.onDialogClosed, {once: true}); - elem.querySelector('.btnBookplayerToc').addEventListener('click', this.openTableOfContents); + elem.querySelector('#btnBookplayerExit').addEventListener('click', this.onDialogClosed, {once: true}); + 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() { this.bindMediaElementEvents(); 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 this._rendition.on('keyup', this.onWindowKeyUp); - this._rendition.on('touchstart', this.onTouchStart); } unbindMediaElementEvents() { const elem = this._mediaElement; elem.removeEventListener('close', this.onDialogClosed); - elem.querySelector('.btnBookplayerExit').removeEventListener('click', this.onDialogClosed); - elem.querySelector('.btnBookplayerToc').removeEventListener('click', this.openTableOfContents); + elem.querySelector('#btnBookplayerExit').removeEventListener('click', this.onDialogClosed); + 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() { @@ -180,11 +168,9 @@ export class BookPlayer { } document.removeEventListener('keyup', this.onWindowKeyUp); - document.removeEventListener('touchstart', this.onTouchStart); if (this._rendition) { 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() { let elem = this._mediaElement; if (elem) { @@ -214,13 +210,22 @@ export class BookPlayer { elem.id = 'bookPlayer'; let html = ''; - html += '
'; - html += ''; + + if (browser.mobile) { + html += '
'; + } + + html += '
'; + html += '
'; + html += ''; + html += ''; html += '
'; - html += '
'; - html += ''; html += '
'; + if (browser.mobile) { + html += '
'; + } + elem.innerHTML = html; dialogHelper.open(elem); @@ -236,9 +241,7 @@ export class BookPlayer { return book.renderTo(elem, { width: '100%', height: '100%', - manager: 'continuous', - flow: 'scrolled-doc', - offset: 0 + flow: 'scrolled-doc' }); } else { return book.renderTo(elem, { @@ -266,7 +269,7 @@ export class BookPlayer { import('epubjs').then(({default: epubjs}) => { const downloadHref = apiClient.getItemDownloadUrl(item.Id); const book = epubjs(downloadHref, {openAs: 'epub'}); - const rendition = this.render(elem, book); + const rendition = this.render('viewer', book); this._currentSrc = downloadHref; this._rendition = rendition; diff --git a/src/plugins/bookPlayer/style.css b/src/plugins/bookPlayer/style.css index e37b995f31..99aad62260 100644 --- a/src/plugins/bookPlayer/style.css +++ b/src/plugins/bookPlayer/style.css @@ -7,18 +7,20 @@ background: #fff; } -.topRightActionButtons { - right: 0.5vh; +.topButtons { top: 0.5vh; z-index: 1002; - position: absolute; + position: sticky; } -.topLeftActionButtons { - left: 0.5vh; - top: 0.5vh; - z-index: 1002; - position: absolute; +#btnBookplayerToc { + float: left; + margin-left: 2vw; +} + +#btnBookplayerExit { + float: right; + margin-right: 2vw; } .bookplayerButtonIcon { @@ -37,3 +39,31 @@ .bookplayerErrorMsg { 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; +}