diff --git a/package-lock.json b/package-lock.json
index 158ca38522..d775fbed38 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -24,7 +24,7 @@
"core-js": "3.29.0",
"date-fns": "2.29.3",
"dompurify": "3.0.1",
- "epubjs": "0.4.2",
+ "epubjs": "0.3.93",
"escape-html": "1.0.3",
"fast-text-encoding": "1.0.6",
"flv.js": "1.6.2",
@@ -3013,6 +3013,15 @@
"@types/react": "*"
}
},
+ "node_modules/@types/localforage": {
+ "version": "0.0.34",
+ "resolved": "https://registry.npmjs.org/@types/localforage/-/localforage-0.0.34.tgz",
+ "integrity": "sha512-tJxahnjm9dEI1X+hQSC5f2BSd/coZaqbIl1m3TCl0q9SVuC52XcXfV0XmoCU1+PmjyucuVITwoTnN8OlTbEXXA==",
+ "deprecated": "This is a stub types definition for localforage (https://github.com/localForage/localForage). localforage provides its own type definitions, so you don't need @types/localforage installed!",
+ "dependencies": {
+ "localforage": "*"
+ }
+ },
"node_modules/@types/lodash": {
"version": "4.14.178",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
@@ -3666,6 +3675,14 @@
}
}
},
+ "node_modules/@xmldom/xmldom": {
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz",
+ "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA==",
+ "engines": {
+ "node": ">=10.0.0"
+ }
+ },
"node_modules/@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -6181,17 +6198,19 @@
}
},
"node_modules/epubjs": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/epubjs/-/epubjs-0.4.2.tgz",
- "integrity": "sha512-ex+ntja2AmPeq++qgjYfwrEzrO8UUBbTch1RJcRftShUmn8no6qi4Cax75FH0QopLA+6L8HM6iR94M0/I8V3GQ==",
+ "version": "0.3.93",
+ "resolved": "https://registry.npmjs.org/epubjs/-/epubjs-0.3.93.tgz",
+ "integrity": "sha512-c06pNSdBxcXv3dZSbXAVLE1/pmleRhOT6mXNZo6INKmvuKpYB65MwU/lO7830czCtjIiK9i+KR+3S+p0wtljrw==",
"dependencies": {
+ "@types/localforage": "0.0.34",
+ "@xmldom/xmldom": "^0.7.5",
+ "core-js": "^3.18.3",
"event-emitter": "^0.3.5",
- "jszip": "^3.1.5",
- "lodash": "^4.17.5",
- "marks-pane": "^1.0.7",
- "path-webpack": "0.0.3",
- "stream-browserify": "^2.0.1",
- "xmldom": "^0.1.27"
+ "jszip": "^3.7.1",
+ "localforage": "^1.10.0",
+ "lodash": "^4.17.21",
+ "marks-pane": "^1.0.9",
+ "path-webpack": "0.0.3"
}
},
"node_modules/error-ex": {
@@ -9919,6 +9938,14 @@
"resolved": "https://registry.npmjs.org/libarchive.js/-/libarchive.js-1.3.0.tgz",
"integrity": "sha512-EkQfRXt9DhWwj6BnEA2TNpOf4jTnzSTUPGgE+iFxcdNqjktY8GitbDeHnx8qZA0/IukNyyBUR3oQKRdYkO+HFg=="
},
+ "node_modules/lie": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+ "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
+ "dependencies": {
+ "immediate": "~3.0.5"
+ }
+ },
"node_modules/lilconfig": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz",
@@ -9957,6 +9984,14 @@
"node": ">=8.9.0"
}
},
+ "node_modules/localforage": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
+ "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
+ "dependencies": {
+ "lie": "3.1.1"
+ }
+ },
"node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -19214,15 +19249,6 @@
"integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
"dev": true
},
- "node_modules/xmldom": {
- "version": "0.1.31",
- "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
- "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ==",
- "deprecated": "Deprecated due to CVE-2021-21366 resolved in 0.5.0",
- "engines": {
- "node": ">=0.1"
- }
- },
"node_modules/xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
@@ -21251,6 +21277,14 @@
"@types/react": "*"
}
},
+ "@types/localforage": {
+ "version": "0.0.34",
+ "resolved": "https://registry.npmjs.org/@types/localforage/-/localforage-0.0.34.tgz",
+ "integrity": "sha512-tJxahnjm9dEI1X+hQSC5f2BSd/coZaqbIl1m3TCl0q9SVuC52XcXfV0XmoCU1+PmjyucuVITwoTnN8OlTbEXXA==",
+ "requires": {
+ "localforage": "*"
+ }
+ },
"@types/lodash": {
"version": "4.14.178",
"resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.178.tgz",
@@ -21769,6 +21803,11 @@
"dev": true,
"requires": {}
},
+ "@xmldom/xmldom": {
+ "version": "0.7.9",
+ "resolved": "https://registry.npmjs.org/@xmldom/xmldom/-/xmldom-0.7.9.tgz",
+ "integrity": "sha512-yceMpm/xd4W2a85iqZyO09gTnHvXF6pyiWjD2jcOJs7hRoZtNNOO1eJlhHj1ixA+xip2hOyGn+LgcvLCMo5zXA=="
+ },
"@xtuc/ieee754": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
@@ -23644,17 +23683,19 @@
"dev": true
},
"epubjs": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/epubjs/-/epubjs-0.4.2.tgz",
- "integrity": "sha512-ex+ntja2AmPeq++qgjYfwrEzrO8UUBbTch1RJcRftShUmn8no6qi4Cax75FH0QopLA+6L8HM6iR94M0/I8V3GQ==",
+ "version": "0.3.93",
+ "resolved": "https://registry.npmjs.org/epubjs/-/epubjs-0.3.93.tgz",
+ "integrity": "sha512-c06pNSdBxcXv3dZSbXAVLE1/pmleRhOT6mXNZo6INKmvuKpYB65MwU/lO7830czCtjIiK9i+KR+3S+p0wtljrw==",
"requires": {
+ "@types/localforage": "0.0.34",
+ "@xmldom/xmldom": "^0.7.5",
+ "core-js": "^3.18.3",
"event-emitter": "^0.3.5",
- "jszip": "^3.1.5",
- "lodash": "^4.17.5",
- "marks-pane": "^1.0.7",
- "path-webpack": "0.0.3",
- "stream-browserify": "^2.0.1",
- "xmldom": "^0.1.27"
+ "jszip": "^3.7.1",
+ "localforage": "^1.10.0",
+ "lodash": "^4.17.21",
+ "marks-pane": "^1.0.9",
+ "path-webpack": "0.0.3"
}
},
"error-ex": {
@@ -26453,6 +26494,14 @@
"resolved": "https://registry.npmjs.org/libarchive.js/-/libarchive.js-1.3.0.tgz",
"integrity": "sha512-EkQfRXt9DhWwj6BnEA2TNpOf4jTnzSTUPGgE+iFxcdNqjktY8GitbDeHnx8qZA0/IukNyyBUR3oQKRdYkO+HFg=="
},
+ "lie": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz",
+ "integrity": "sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==",
+ "requires": {
+ "immediate": "~3.0.5"
+ }
+ },
"lilconfig": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz",
@@ -26482,6 +26531,14 @@
"json5": "^2.1.2"
}
},
+ "localforage": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz",
+ "integrity": "sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==",
+ "requires": {
+ "lie": "3.1.1"
+ }
+ },
"locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -33479,11 +33536,6 @@
"integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
"dev": true
},
- "xmldom": {
- "version": "0.1.31",
- "resolved": "https://registry.npmjs.org/xmldom/-/xmldom-0.1.31.tgz",
- "integrity": "sha512-yS2uJflVQs6n+CyjHoaBmVSqIDevTAWrzMmjG1Gc7h1qQ7uVozNhEPJAwZXWyGQ/Gafo3fCwrcaokezLPupVyQ=="
- },
"xtend": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
diff --git a/package.json b/package.json
index f98d2290ea..0b6aadd097 100644
--- a/package.json
+++ b/package.json
@@ -83,7 +83,7 @@
"core-js": "3.29.0",
"date-fns": "2.29.3",
"dompurify": "3.0.1",
- "epubjs": "0.4.2",
+ "epubjs": "0.3.93",
"escape-html": "1.0.3",
"fast-text-encoding": "1.0.6",
"flv.js": "1.6.2",
diff --git a/src/plugins/bookPlayer/plugin.js b/src/plugins/bookPlayer/plugin.js
index df5e213b72..8924d06951 100644
--- a/src/plugins/bookPlayer/plugin.js
+++ b/src/plugins/bookPlayer/plugin.js
@@ -17,15 +17,31 @@ import '../../elements/emby-button/paper-icon-button-light';
import html from './template.html';
import './style.scss';
+const THEMES = {
+ 'dark': { 'body': { 'color': '#d8dadc', 'background': '#000', 'font-size': 'medium' } },
+ 'sepia': { 'body': { 'color': '#d8a262', 'background': '#000', 'font-size': 'medium' } },
+ 'light': { 'body': { 'color': '#000', 'background': '#fff', 'font-size': 'medium' } }
+};
+const THEME_ORDER = ['dark', 'sepia', 'light'];
+const FONT_SIZES = ['x-small', 'small', 'medium', 'large', 'x-large'];
+
export class BookPlayer {
constructor() {
this.name = 'Book Player';
this.type = PluginType.MediaPlayer;
this.id = 'bookplayer';
this.priority = 1;
-
+ if (!userSettings.theme() || userSettings.theme() === 'dark') {
+ this.theme = 'dark';
+ } else {
+ this.theme = 'light';
+ }
+ this.fontSize = 'medium';
this.onDialogClosed = this.onDialogClosed.bind(this);
this.openTableOfContents = this.openTableOfContents.bind(this);
+ this.rotateTheme = this.rotateTheme.bind(this);
+ this.increaseFontSize = this.increaseFontSize.bind(this);
+ this.decreaseFontSize = this.decreaseFontSize.bind(this);
this.previous = this.previous.bind(this);
this.next = this.next.bind(this);
this.onWindowKeyUp = this.onWindowKeyUp.bind(this);
@@ -164,6 +180,9 @@ export class BookPlayer {
elem.querySelector('#btnBookplayerExit').addEventListener('click', this.onDialogClosed, { once: true });
elem.querySelector('#btnBookplayerToc').addEventListener('click', this.openTableOfContents);
elem.querySelector('#btnBookplayerFullscreen').addEventListener('click', this.toggleFullscreen);
+ elem.querySelector('#btnBookplayerRotateTheme').addEventListener('click', this.rotateTheme);
+ elem.querySelector('#btnBookplayerIncreaseFontSize').addEventListener('click', this.increaseFontSize);
+ elem.querySelector('#btnBookplayerDecreaseFontSize').addEventListener('click', this.decreaseFontSize);
elem.querySelector('#btnBookplayerPrev')?.addEventListener('click', this.previous);
elem.querySelector('#btnBookplayerNext')?.addEventListener('click', this.next);
}
@@ -184,6 +203,9 @@ export class BookPlayer {
elem.querySelector('#btnBookplayerExit').removeEventListener('click', this.onDialogClosed);
elem.querySelector('#btnBookplayerToc').removeEventListener('click', this.openTableOfContents);
elem.querySelector('#btnBookplayerFullscreen').removeEventListener('click', this.toggleFullscreen);
+ elem.querySelector('#btnBookplayerRotateTheme').removeEventListener('click', this.rotateTheme);
+ elem.querySelector('#btnBookplayerIncreaseFontSize').removeEventListener('click', this.increaseFontSize);
+ elem.querySelector('#btnBookplayerDecreaseFontSize').removeEventListener('click', this.decreaseFontSize);
elem.querySelector('#btnBookplayerPrev')?.removeEventListener('click', this.previous);
elem.querySelector('#btnBookplayerNext')?.removeEventListener('click', this.next);
}
@@ -214,6 +236,31 @@ export class BookPlayer {
}
}
+ rotateTheme() {
+ if (this.loaded) {
+ const newTheme = THEME_ORDER[(THEME_ORDER.indexOf(this.theme) + 1) % THEME_ORDER.length];
+ this.rendition.themes.register('default', THEMES[newTheme]);
+ this.rendition.themes.update('default');
+ this.theme = newTheme;
+ }
+ }
+
+ increaseFontSize() {
+ if (this.loaded && this.fontSize !== FONT_SIZES[FONT_SIZES.length - 1]) {
+ const newFontSize = FONT_SIZES[(FONT_SIZES.indexOf(this.fontSize) + 1)];
+ this.rendition.themes.fontSize(newFontSize);
+ this.fontSize = newFontSize;
+ }
+ }
+
+ decreaseFontSize() {
+ if (this.loaded && this.fontSize !== FONT_SIZES[0]) {
+ const newFontSize = FONT_SIZES[(FONT_SIZES.indexOf(this.fontSize) - 1)];
+ this.rendition.themes.fontSize(newFontSize);
+ this.fontSize = newFontSize;
+ }
+ }
+
previous(e) {
e?.preventDefault();
if (this.rendition) {
@@ -296,11 +343,8 @@ export class BookPlayer {
this.currentSrc = downloadHref;
this.rendition = rendition;
- rendition.themes.register('dark', { 'body': { 'color': '#fff' } });
-
- if (userSettings.theme(undefined) === 'dark' || userSettings.theme(undefined) === null) {
- rendition.themes.select('dark');
- }
+ rendition.themes.register('default', THEMES[this.theme]);
+ rendition.themes.select('default');
return rendition.display().then(() => {
const epubElem = document.querySelector('.epub-container');
diff --git a/src/plugins/bookPlayer/template.html b/src/plugins/bookPlayer/template.html
index bf71834f02..55fd02c8a1 100644
--- a/src/plugins/bookPlayer/template.html
+++ b/src/plugins/bookPlayer/template.html
@@ -11,6 +11,15 @@
+
+
+