diff --git a/package-lock.json b/package-lock.json index 158ca3852..d775fbed3 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 f98d2290e..0b6aadd09 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 df5e213b7..8924d0695 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 bf71834f0..55fd02c8a 100644 --- a/src/plugins/bookPlayer/template.html +++ b/src/plugins/bookPlayer/template.html @@ -11,6 +11,15 @@ + + +