mirror of
https://github.com/jellyfin/jellyfin-web
synced 2025-03-30 19:56:21 +00:00
Make book player report percentage progress based on CFI location
This commit is contained in:
parent
8d51ae6fb4
commit
fe9a825aa1
1 changed files with 85 additions and 5 deletions
|
@ -2,6 +2,7 @@ import connectionManager from 'connectionManager';
|
||||||
import loading from 'loading';
|
import loading from 'loading';
|
||||||
import keyboardnavigation from 'keyboardnavigation';
|
import keyboardnavigation from 'keyboardnavigation';
|
||||||
import dialogHelper from 'dialogHelper';
|
import dialogHelper from 'dialogHelper';
|
||||||
|
import events from 'events';
|
||||||
import 'css!./style';
|
import 'css!./style';
|
||||||
import 'material-icons';
|
import 'material-icons';
|
||||||
import 'paper-icon-button-light';
|
import 'paper-icon-button-light';
|
||||||
|
@ -21,6 +22,9 @@ export class BookPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
play(options) {
|
play(options) {
|
||||||
|
this._progress = 0;
|
||||||
|
this._loaded = false;
|
||||||
|
|
||||||
loading.show();
|
loading.show();
|
||||||
let elem = this.createMediaElement();
|
let elem = this.createMediaElement();
|
||||||
return this.setCurrentSrc(elem, options);
|
return this.setCurrentSrc(elem, options);
|
||||||
|
@ -46,6 +50,45 @@ export class BookPlayer {
|
||||||
if (rendition) {
|
if (rendition) {
|
||||||
rendition.destroy();
|
rendition.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hide loader in case player was not fully loaded yet
|
||||||
|
loading.hide();
|
||||||
|
this._cancellationToken.shouldCancel = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentItem() {
|
||||||
|
return this._currentItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
currentTime() {
|
||||||
|
return this._progress * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
duration() {
|
||||||
|
return 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBufferedRanges() {
|
||||||
|
return [{
|
||||||
|
start: 0,
|
||||||
|
end: 10000000
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
volume() {
|
||||||
|
return 100;
|
||||||
|
}
|
||||||
|
|
||||||
|
isMuted() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
paused() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
seekable() {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
onWindowKeyUp(e) {
|
onWindowKeyUp(e) {
|
||||||
|
@ -57,12 +100,16 @@ export class BookPlayer {
|
||||||
case 'l':
|
case 'l':
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
case 'Right':
|
case 'Right':
|
||||||
|
if (this._loaded) {
|
||||||
book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next();
|
book.package.metadata.direction === 'rtl' ? rendition.prev() : rendition.next();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
case 'Left':
|
case 'Left':
|
||||||
|
if (this._loaded) {
|
||||||
book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev();
|
book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 'Escape':
|
case 'Escape':
|
||||||
if (this._tocElement) {
|
if (this._tocElement) {
|
||||||
|
@ -115,8 +162,10 @@ export class BookPlayer {
|
||||||
}
|
}
|
||||||
|
|
||||||
openTableOfContents() {
|
openTableOfContents() {
|
||||||
|
if (this._loaded) {
|
||||||
this._tocElement = new TableOfContent(this);
|
this._tocElement = new TableOfContent(this);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
createMediaElement() {
|
createMediaElement() {
|
||||||
let elem = this._mediaElement;
|
let elem = this._mediaElement;
|
||||||
|
@ -158,6 +207,14 @@ export class BookPlayer {
|
||||||
|
|
||||||
setCurrentSrc(elem, options) {
|
setCurrentSrc(elem, options) {
|
||||||
let item = options.items[0];
|
let item = options.items[0];
|
||||||
|
this._currentItem = item;
|
||||||
|
this.streamInfo = {
|
||||||
|
started: true,
|
||||||
|
ended: false,
|
||||||
|
mediaSource: {
|
||||||
|
Id: item.Id
|
||||||
|
}
|
||||||
|
};
|
||||||
if (!item.Path.endsWith('.epub')) {
|
if (!item.Path.endsWith('.epub')) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let errorDialog = dialogHelper.createDialog({
|
let errorDialog = dialogHelper.createDialog({
|
||||||
|
@ -187,11 +244,34 @@ export class BookPlayer {
|
||||||
|
|
||||||
this._currentSrc = downloadHref;
|
this._currentSrc = downloadHref;
|
||||||
this._rendition = rendition;
|
this._rendition = rendition;
|
||||||
|
let cancellationToken = {
|
||||||
|
shouldCancel: false
|
||||||
|
};
|
||||||
|
this._cancellationToken = cancellationToken;
|
||||||
|
|
||||||
return rendition.display().then(() => {
|
return rendition.display().then(() => {
|
||||||
|
let epubElem = document.querySelector('.epub-container');
|
||||||
|
epubElem.style.display = 'none';
|
||||||
|
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
|
|
||||||
|
return this._rendition.book.locations.generate(1024).then(() => {
|
||||||
|
if (cancellationToken.shouldCancel) {
|
||||||
|
return reject();
|
||||||
|
}
|
||||||
|
|
||||||
|
this._loaded = true;
|
||||||
|
epubElem.style.display = 'block';
|
||||||
|
rendition.on('relocated', (locations) => {
|
||||||
|
this._progress = book.locations.percentageFromCfi(locations.start.cfi);
|
||||||
|
|
||||||
|
events.trigger(this, 'timeupdate');
|
||||||
|
});
|
||||||
|
|
||||||
loading.hide();
|
loading.hide();
|
||||||
|
|
||||||
return resolve();
|
return resolve();
|
||||||
|
});
|
||||||
}, () => {
|
}, () => {
|
||||||
console.error('Failed to display epub');
|
console.error('Failed to display epub');
|
||||||
return reject();
|
return reject();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue