1
0
Fork 0
mirror of https://github.com/jellyfin/jellyfin-web synced 2025-03-30 19:56:21 +00:00

Refactor table of contents into its own class

This commit is contained in:
Daniyar Itegulov 2020-05-28 21:14:25 +10:00
parent 063ef77ff1
commit a711c8e9f7
No known key found for this signature in database
GPG key ID: 4DB862B7839037FD
3 changed files with 140 additions and 62 deletions

View file

@ -99,6 +99,7 @@
"src/components/sanatizefilename.js",
"src/components/scrollManager.js",
"src/components/bookPlayer/plugin.js",
"src/components/bookPlayer/tableOfContent.js",
"src/components/syncplay/playbackPermissionManager.js",
"src/components/syncplay/groupSelectionMenu.js",
"src/components/syncplay/timeSyncManager.js",

View file

@ -9,12 +9,18 @@ import 'css!./style';
import 'material-icons';
import 'paper-icon-button-light';
import TableOfContent from './tableOfContent';
export class BookPlayer {
constructor() {
this.name = 'Book Player';
this.type = 'mediaplayer';
this.id = 'bookplayer';
this.priority = 1;
this.onDialogClosed = this.onDialogClosed.bind(this);
this.openTableOfContents = this.openTableOfContents.bind(this);
this.onWindowKeyUp = this.onWindowKeyUp.bind(this);
}
play(options) {
@ -24,6 +30,8 @@ export class BookPlayer {
}
stop() {
this.unbindEvents();
let elem = this._mediaElement;
let tocElement = this._tocElement;
let rendition = this._rendition;
@ -34,7 +42,7 @@ export class BookPlayer {
}
if (tocElement) {
dialogHelper.close(tocElement);
tocElement.destroy();
this._tocElement = null;
}
@ -60,9 +68,12 @@ export class BookPlayer {
book.package.metadata.direction === 'rtl' ? rendition.next() : rendition.prev();
break;
case 'Escape':
dialogHelper.close(this._mediaElement);
if (this._tocElement) {
dialogHelper.close(this._tocElement);
// Close table of contents on ESC if it is open
this._tocElement.destroy();
} else {
// Otherwise stop the entire book player
this.stop();
}
break;
}
@ -72,17 +83,42 @@ export class BookPlayer {
this.stop();
}
replaceLinks(contents, f) {
let links = contents.querySelectorAll('a[href]');
bindMediaElementEvents() {
let elem = this._mediaElement;
links.forEach((link) => {
let href = link.getAttribute('href');
elem.addEventListener('close', this.onDialogClosed, {once: true});
elem.querySelector('.btnBookplayerExit').addEventListener('click', this.onDialogClosed, {once: true});
elem.querySelector('.btnBookplayerToc').addEventListener('click', this.openTableOfContents);
}
link.onclick = () => {
f(href);
return false;
};
});
bindEvents() {
this.bindMediaElementEvents();
document.addEventListener('keyup', this.onWindowKeyUp);
// FIXME: I don't really get why document keyup event is not triggered when epub is in focus
this._rendition.on('keyup', this.onWindowKeyUp);
}
unbindMediaElementEvents() {
let elem = this._mediaElement;
elem.removeEventListener('close', this.onDialogClosed);
elem.querySelector('.btnBookplayerExit').removeEventListener('click', this.onDialogClosed);
elem.querySelector('.btnBookplayerToc').removeEventListener('click', this.openTableOfContents);
}
unbindEvents() {
if (this._mediaElement) {
this.unbindMediaElementEvents();
}
document.removeEventListener('keyup', this.onWindowKeyUp);
if (this._rendition) {
this._rendition.off('keyup', this.onWindowKeyUp);
}
}
openTableOfContents() {
this._tocElement = new TableOfContent(this);
}
createMediaElement() {
@ -115,53 +151,7 @@ export class BookPlayer {
elem.innerHTML = html;
elem.querySelector('.btnBookplayerExit').addEventListener('click', () => {
dialogHelper.close(elem);
});
elem.querySelector('.btnBookplayerToc').addEventListener('click', () => {
let rendition = this._rendition;
if (rendition) {
let tocElement = dialogHelper.createDialog({
size: 'small',
autoFocus: false,
removeOnClose: true
});
tocElement.id = 'dialogToc';
let tocHtml = '<div class="topRightActionButtons">';
tocHtml += '<button is="paper-icon-button-light" class="autoSize bookplayerButton btnBookplayerTocClose hide-mouse-idle-tv" tabindex="-1"><span class="material-icons bookplayerButtonIcon close"></span></button>';
tocHtml += '</div>';
tocHtml += '<ul class="toc">';
rendition.book.navigation.forEach((chapter) => {
tocHtml += '<li>';
// Remove '../' from href
let link = chapter.href.startsWith('../') ? chapter.href.substr(3) : chapter.href;
tocHtml += `<a href="${rendition.book.path.directory + link}">${chapter.label}</a>`;
tocHtml += '</li>';
});
tocHtml += '</ul>';
tocElement.innerHTML = tocHtml;
tocElement.querySelector('.btnBookplayerTocClose').addEventListener('click', () => {
dialogHelper.close(tocElement);
});
this.replaceLinks(tocElement, (href) => {
let relative = rendition.book.path.relative(href);
rendition.display(relative);
dialogHelper.close(tocElement);
});
this._tocElement = tocElement;
dialogHelper.open(tocElement);
}
});
dialogHelper.open(elem);
elem.addEventListener('close', this.onDialogClosed.bind(this));
}
this._mediaElement = elem;
@ -201,10 +191,7 @@ export class BookPlayer {
this._currentSrc = downloadHref;
this._rendition = rendition;
return rendition.display().then(() => {
document.addEventListener('keyup', this.onWindowKeyUp.bind(this));
// FIXME: I don't really get why document keyup event is not triggered when epub is in focus
this._rendition.on('keyup', this.onWindowKeyUp.bind(this));
this.bindEvents();
loading.hide();
return resolve();

View file

@ -0,0 +1,90 @@
import dialogHelper from 'dialogHelper';
export default class TableOfContent {
constructor(bookPlayer) {
this._bookPlayer = bookPlayer;
this._rendition = bookPlayer._rendition;
this.onDialogClosed = this.onDialogClosed.bind(this);
this.createMediaElement();
}
destroy() {
let elem = this._elem;
if (elem) {
this.unbindEvents();
dialogHelper.close(elem);
}
this._bookPlayer._tocElement = null;
}
bindEvents() {
let elem = this._elem;
elem.addEventListener('close', this.onDialogClosed, {once: true});
elem.querySelector('.btnBookplayerTocClose').addEventListener('click', this.onDialogClosed, {once: true});
}
unbindEvents() {
let elem = this._elem;
elem.removeEventListener('close', this.onDialogClosed);
elem.querySelector('.btnBookplayerTocClose').removeEventListener('click', this.onDialogClosed);
}
onDialogClosed() {
this.destroy();
}
replaceLinks(contents, f) {
let links = contents.querySelectorAll('a[href]');
links.forEach((link) => {
let href = link.getAttribute('href');
link.onclick = () => {
f(href);
return false;
};
});
}
createMediaElement() {
let rendition = this._rendition;
let elem = dialogHelper.createDialog({
size: 'small',
autoFocus: false,
removeOnClose: true
});
elem.id = 'dialogToc';
let tocHtml = '<div class="topRightActionButtons">';
tocHtml += '<button is="paper-icon-button-light" class="autoSize bookplayerButton btnBookplayerTocClose hide-mouse-idle-tv" tabindex="-1"><span class="material-icons bookplayerButtonIcon close"></span></button>';
tocHtml += '</div>';
tocHtml += '<ul class="toc">';
rendition.book.navigation.forEach((chapter) => {
tocHtml += '<li>';
// Remove '../' from href
let link = chapter.href.startsWith('../') ? chapter.href.substr(3) : chapter.href;
tocHtml += `<a href="${rendition.book.path.directory + link}">${chapter.label}</a>`;
tocHtml += '</li>';
});
tocHtml += '</ul>';
elem.innerHTML = tocHtml;
this.replaceLinks(elem, (href) => {
let relative = rendition.book.path.relative(href);
rendition.display(relative);
this.destroy();
});
this._elem = elem;
this.bindEvents();
dialogHelper.open(elem);
}
}