mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Merge pull request #2095 from thornbill/epub-desktop
Fix epub player issues
This commit is contained in:
commit
415e48d87f
4 changed files with 96 additions and 118 deletions
|
@ -1,14 +1,19 @@
|
||||||
|
import { Events } from 'jellyfin-apiclient';
|
||||||
|
import 'material-design-icons-iconfont';
|
||||||
|
|
||||||
import loading from '../../components/loading/loading';
|
import loading from '../../components/loading/loading';
|
||||||
import keyboardnavigation from '../../scripts/keyboardNavigation';
|
import keyboardnavigation from '../../scripts/keyboardNavigation';
|
||||||
import dialogHelper from '../../components/dialogHelper/dialogHelper';
|
import dialogHelper from '../../components/dialogHelper/dialogHelper';
|
||||||
import '../../scripts/dom';
|
|
||||||
import { Events } from 'jellyfin-apiclient';
|
|
||||||
import './style.css';
|
|
||||||
import 'material-design-icons-iconfont';
|
|
||||||
import '../../elements/emby-button/paper-icon-button-light';
|
|
||||||
import ServerConnections from '../../components/ServerConnections';
|
import ServerConnections from '../../components/ServerConnections';
|
||||||
import TableOfContents from './tableOfContents';
|
import TableOfContents from './tableOfContents';
|
||||||
import browser from '../../scripts/browser';
|
import browser from '../../scripts/browser';
|
||||||
|
import { translateHtml } from '../../scripts/globalize';
|
||||||
|
|
||||||
|
import '../../scripts/dom';
|
||||||
|
import '../../elements/emby-button/paper-icon-button-light';
|
||||||
|
|
||||||
|
import html from './template.html';
|
||||||
|
import './style.scss';
|
||||||
|
|
||||||
export class BookPlayer {
|
export class BookPlayer {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -17,6 +22,13 @@ export class BookPlayer {
|
||||||
this.id = 'bookplayer';
|
this.id = 'bookplayer';
|
||||||
this.priority = 1;
|
this.priority = 1;
|
||||||
|
|
||||||
|
this.epubOptions = {
|
||||||
|
width: '100%',
|
||||||
|
height: '100%',
|
||||||
|
// TODO: Add option for scrolled-doc
|
||||||
|
flow: 'paginated'
|
||||||
|
};
|
||||||
|
|
||||||
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.prevChapter = this.prevChapter.bind(this);
|
||||||
|
@ -134,10 +146,8 @@ export class BookPlayer {
|
||||||
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('#btnBookplayerPrev').addEventListener('click', this.prevChapter);
|
elem.querySelector('#btnBookplayerNext')?.addEventListener('click', this.nextChapter);
|
||||||
elem.querySelector('#btnBookplayerNext').addEventListener('click', this.nextChapter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bindEvents() {
|
bindEvents() {
|
||||||
|
@ -155,10 +165,8 @@ export class BookPlayer {
|
||||||
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('#btnBookplayerPrev').removeEventListener('click', this.prevChapter);
|
elem.querySelector('#btnBookplayerNext')?.removeEventListener('click', this.nextChapter);
|
||||||
elem.querySelector('#btnBookplayerNext').removeEventListener('click', this.nextChapter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unbindEvents() {
|
unbindEvents() {
|
||||||
|
@ -180,12 +188,12 @@ export class BookPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
prevChapter(e) {
|
prevChapter(e) {
|
||||||
this._rendition.prev();
|
this.rendition.prev();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
nextChapter(e) {
|
nextChapter(e) {
|
||||||
this._rendition.next();
|
this.rendition.next();
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -206,25 +214,8 @@ export class BookPlayer {
|
||||||
removeOnClose: true
|
removeOnClose: true
|
||||||
});
|
});
|
||||||
|
|
||||||
let html = '';
|
|
||||||
|
|
||||||
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>';
|
|
||||||
|
|
||||||
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.id = 'bookPlayer';
|
elem.id = 'bookPlayer';
|
||||||
elem.innerHTML = html;
|
elem.innerHTML = translateHtml(html);
|
||||||
|
|
||||||
dialogHelper.open(elem);
|
dialogHelper.open(elem);
|
||||||
}
|
}
|
||||||
|
@ -233,21 +224,6 @@ export class BookPlayer {
|
||||||
return elem;
|
return elem;
|
||||||
}
|
}
|
||||||
|
|
||||||
render(elem, book) {
|
|
||||||
if (browser.mobile) {
|
|
||||||
return book.renderTo(elem, {
|
|
||||||
width: '100%',
|
|
||||||
height: '100%',
|
|
||||||
flow: 'scrolled-doc'
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
return book.renderTo(elem, {
|
|
||||||
width: '100%',
|
|
||||||
height: '100%'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setCurrentSrc(elem, options) {
|
setCurrentSrc(elem, options) {
|
||||||
const item = options.items[0];
|
const item = options.items[0];
|
||||||
this.item = item;
|
this.item = item;
|
||||||
|
@ -266,7 +242,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('viewer', book);
|
const rendition = book.renderTo('bookPlayerContainer', this.epubOptions);
|
||||||
|
|
||||||
this.currentSrc = downloadHref;
|
this.currentSrc = downloadHref;
|
||||||
this.rendition = rendition;
|
this.rendition = rendition;
|
||||||
|
|
|
@ -1,69 +0,0 @@
|
||||||
#bookPlayer {
|
|
||||||
position: relative;
|
|
||||||
height: 100%;
|
|
||||||
width: 100%;
|
|
||||||
overflow: auto;
|
|
||||||
z-index: 100;
|
|
||||||
background: #fff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topButtons {
|
|
||||||
top: 0.5vh;
|
|
||||||
z-index: 1002;
|
|
||||||
position: sticky;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btnBookplayerToc {
|
|
||||||
float: left;
|
|
||||||
margin-left: 2vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
#btnBookplayerExit {
|
|
||||||
float: right;
|
|
||||||
margin-right: 2vw;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bookplayerButtonIcon {
|
|
||||||
color: black;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
#dialogToc {
|
|
||||||
background-color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toc li {
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
55
src/plugins/bookPlayer/style.scss
Normal file
55
src/plugins/bookPlayer/style.scss
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
#bookPlayer {
|
||||||
|
position: relative;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
z-index: 100;
|
||||||
|
background: #fff;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
|
||||||
|
.topButtons {
|
||||||
|
z-index: 1002;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: #000;
|
||||||
|
opacity: .7;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bookPlayerContainer {
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btnBookplayerToc {
|
||||||
|
float: left;
|
||||||
|
margin-left: 2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btnBookplayerExit {
|
||||||
|
float: right;
|
||||||
|
margin-right: 2vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bookplayerErrorMsg {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#btnBookplayerPrev,
|
||||||
|
#btnBookplayerNext {
|
||||||
|
margin: 0.5vh 0.5vh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#dialogToc {
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
|
.bookplayerButtonIcon {
|
||||||
|
color: black;
|
||||||
|
}
|
||||||
|
|
||||||
|
.toc li {
|
||||||
|
margin-bottom: 5px;
|
||||||
|
}
|
||||||
|
}
|
16
src/plugins/bookPlayer/template.html
Normal file
16
src/plugins/bookPlayer/template.html
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
<div class="topButtons">
|
||||||
|
<button is="paper-icon-button-light" id="btnBookplayerToc" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
|
<span class="material-icons bookplayerButtonIcon toc"></span>
|
||||||
|
</button>
|
||||||
|
<!-- <button is="paper-icon-button-light" id="btnBookplayerPrev" class="autoSize bookplayerButton pageButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
|
<span class="material-icons bookplayerButtonIcon navigate_before"></span> ${Previous}
|
||||||
|
</button>
|
||||||
|
<button is="paper-icon-button-light" id="btnBookplayerNext" class="autoSize bookplayerButton pageButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
|
${Next} <span class="material-icons bookplayerButtonIcon navigate_next"></span>
|
||||||
|
</button> -->
|
||||||
|
<button is="paper-icon-button-light" id="btnBookplayerExit" class="autoSize bookplayerButton hide-mouse-idle-tv" tabindex="-1">
|
||||||
|
<span class="material-icons bookplayerButtonIcon close"></span>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="bookPlayerContainer" class="bookPlayerContainer"></div>
|
Loading…
Add table
Add a link
Reference in a new issue