diff --git a/komga-webui/src/functions/check-image.ts b/komga-webui/src/functions/check-image.ts new file mode 100644 index 000000000..148cc78cb --- /dev/null +++ b/komga-webui/src/functions/check-image.ts @@ -0,0 +1,38 @@ +export enum ImageFeature { + WEBP_LOSSY, + WEBP_LOSSLESS, + WEBP_ALPHA, + WEBP_ANIMATION, + JPEG_XL, + AVIF, +} + +export function checkImageSupport(feature: ImageFeature, callback: (isSupported: boolean) => void) { + const img = new Image() + img.onload = function () { + callback((img.width > 0) && (img.height > 0)) + } + img.onerror = function () { + callback(false) + } + switch (feature) { + case ImageFeature.WEBP_LOSSY: + img.src = 'data:image/webp;base64,UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA' + break + case ImageFeature.WEBP_LOSSLESS: + img.src = 'data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==' + break + case ImageFeature.WEBP_ALPHA: + img.src = 'data:image/webp;base64,UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==' + break + case ImageFeature.WEBP_ANIMATION: + img.src = 'data:image/webp;base64,UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA' + break + case ImageFeature.JPEG_XL: + img.src = 'data:image/jxl;base64,/woIELASCAgQAFwASxLFgkWAHL0xqnCBCV0qDp901Te/5QM=' + break + case ImageFeature.AVIF: + img.src = 'data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=' + break + } +} diff --git a/komga-webui/src/functions/check-webp.ts b/komga-webui/src/functions/check-webp.ts deleted file mode 100644 index 52856ff4c..000000000 --- a/komga-webui/src/functions/check-webp.ts +++ /dev/null @@ -1,20 +0,0 @@ -// check_webp_feature: -// 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'. -// 'callback(feature, isSupported)' will be passed back the detection result (in an asynchronous way!) -export function checkWebpFeature (feature: string, callback: (feature: string, isSupported: boolean) => void) { - const kTestImages: any = { - lossy: 'UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA', - lossless: 'UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==', - alpha: 'UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==', - animation: 'UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA', - } - const img = new Image() - img.onload = function () { - const result = (img.width > 0) && (img.height > 0) - callback(feature, result) - } - img.onerror = function () { - callback(feature, false) - } - img.src = 'data:image/webp;base64,' + kTestImages[feature] -} diff --git a/komga-webui/src/views/BookReader.vue b/komga-webui/src/views/BookReader.vue index 7978795d9..c0805b694 100644 --- a/komga-webui/src/views/BookReader.vue +++ b/komga-webui/src/views/BookReader.vue @@ -183,7 +183,8 @@ - + {{ $t('bookreader.settings.display') }} @@ -304,7 +305,7 @@ import SettingsSwitch from '@/components/SettingsSwitch.vue' import ThumbnailExplorerDialog from '@/components/dialogs/ThumbnailExplorerDialog.vue' import ShortcutHelpDialog from '@/components/dialogs/ShortcutHelpDialog.vue' import {getBookTitleCompact} from '@/functions/book-title' -import {checkWebpFeature} from '@/functions/check-webp' +import {checkImageSupport, ImageFeature} from '@/functions/check-image' import {bookPageUrl} from '@/functions/urls' import {ReadingDirection} from '@/types/enum-books' import Vue from 'vue' @@ -410,10 +411,11 @@ export default Vue.extend({ }, created() { this.$vuetify.rtl = false - checkWebpFeature('lossy', (feature, isSupported) => { - if (isSupported) { - this.supportedMediaTypes.push('image/webp') - } + checkImageSupport(ImageFeature.WEBP_LOSSY, (isSupported) => { + if (isSupported) this.supportedMediaTypes.push('image/webp') + }) + checkImageSupport(ImageFeature.JPEG_XL, (isSupported) => { + if (isSupported) this.supportedMediaTypes.push('image/jxl') }) this.shortcuts = this.$_.keyBy([...shortcutsSettings, ...shortcutsSettingsPaged, ...shortcutsSettingsContinuous, ...shortcutsMenus, ...shortcutsAll], x => x.key) window.addEventListener('keydown', this.keyPressed) @@ -615,7 +617,7 @@ export default Vue.extend({ set: function (alwaysFullscreen: boolean): void { this.settings.alwaysFullscreen = alwaysFullscreen this.$store.commit('setWebreaderAlwaysFullscreen', alwaysFullscreen) - if(alwaysFullscreen) this.enterFullscreen() + if (alwaysFullscreen) this.enterFullscreen() else screenfull.isEnabled && screenfull.exit() }, }, @@ -629,7 +631,7 @@ export default Vue.extend({ else this.fullscreenIcon = 'mdi-fullscreen' }, keyPressed(e: KeyboardEvent) { - if(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) return + if (e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) return this.shortcuts[e.key]?.execute(this) }, async setup(bookId: string, page?: number) { @@ -872,6 +874,7 @@ export default Vue.extend({ .html-reader::-webkit-scrollbar { display: none; } + .html-reader { scrollbar-width: none; }