feat(webreader): fullscreen support

This commit is contained in:
Gauthier Roebroeck 2021-08-06 13:48:33 +08:00
parent 43733fbec3
commit 0a1761d37e
6 changed files with 73 additions and 7 deletions

View file

@ -16,6 +16,7 @@
"language-tags": "^1.0.5",
"lodash": "^4.17.19",
"qs": "^6.10.1",
"screenfull": "^5.1.0",
"vue": "^2.6.14",
"vue-i18n": "^8.24.4",
"vue-line-clamp": "^1.3.2",
@ -17172,6 +17173,17 @@
"node": ">= 8.9.0"
}
},
"node_modules/screenfull": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.1.0.tgz",
"integrity": "sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA==",
"engines": {
"node": ">=0.10.0"
},
"funding": {
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",
@ -35323,6 +35335,11 @@
"ajv-keywords": "^3.4.1"
}
},
"screenfull": {
"version": "5.1.0",
"resolved": "https://registry.npmjs.org/screenfull/-/screenfull-5.1.0.tgz",
"integrity": "sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA=="
},
"select-hose": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz",

View file

@ -19,6 +19,7 @@
"language-tags": "^1.0.5",
"lodash": "^4.17.19",
"qs": "^6.10.1",
"screenfull": "^5.1.0",
"vue": "^2.6.14",
"vue-i18n": "^8.24.4",
"vue-line-clamp": "^1.3.2",

View file

@ -11,6 +11,7 @@
@input="updateInput"
@change="updateInput"
class="float-right"
:disabled="disabled"
>
</v-switch>
</v-col>
@ -32,6 +33,10 @@ export default Vue.extend({
status: {
type: String,
},
disabled: {
type: Boolean,
default: false,
},
},
data () {
return {

View file

@ -100,6 +100,7 @@
"width": "Fit width"
},
"settings": {
"always_fullscreen": "Always Full Screen",
"animate_page_transitions": "Animate page transitions",
"background_color": "Background color",
"background_colors": {
@ -375,8 +376,6 @@
"dialog_title_single": "Edit {series}",
"field_age_rating": "Age Rating",
"field_age_rating_error": "Age rating must be 0 or more",
"field_total_book_count": "Total Book Count",
"field_total_book_count_error": "Total book count must be 1 or more",
"field_genres": "Genres",
"field_language": "Language",
"field_language_hint": "IETF BCP 47 language tag",
@ -387,6 +386,8 @@
"field_summary": "Summary",
"field_tags": "Tags",
"field_title": "Title",
"field_total_book_count": "Total Book Count",
"field_total_book_count_error": "Total book count must be 1 or more",
"mixed": "MIXED",
"tab_general": "General",
"tab_tags": "Tags",

View file

@ -16,6 +16,7 @@ export const persistedModule: Module<any, any> = {
},
readingDirection: '',
swipe: false,
alwaysFullscreen: false,
animations: true,
background: '',
},
@ -75,6 +76,9 @@ export const persistedModule: Module<any, any> = {
setWebreaderSwipe(state, val) {
state.webreader.swipe = val
},
setWebreaderAlwaysFullscreen(state, val) {
state.webreader.alwaysFullscreen = val
},
setWebreaderAnimations(state, val) {
state.webreader.animations = val
},

View file

@ -27,6 +27,13 @@
<span>{{ $t('bookreader.tooltip_incognito') }}</span>
</v-tooltip>
<v-btn
icon
:disabled="!screenfull.isEnabled"
@click="screenfull.isFullscreen ? screenfull.exit() : enterFullscreen()">
<v-icon>{{ fullscreenIcon }}</v-icon>
</v-btn>
<v-btn
icon
@click="showHelp = !showHelp">
@ -168,11 +175,15 @@
<v-list-item>
<settings-switch v-model="animations"
:label="$t('bookreader.settings.animate_page_transitions')"></settings-switch>
:label="$t('bookreader.settings.animate_page_transitions')"/>
</v-list-item>
<v-list-item>
<settings-switch v-model="swipe" :label="$t('bookreader.settings.gestures')"></settings-switch>
<settings-switch v-model="swipe" :label="$t('bookreader.settings.gestures')"/>
</v-list-item>
<v-list-item>
<settings-switch v-model="alwaysFullscreen" :label="$t('bookreader.settings.always_fullscreen')" :disabled="!screenfull.isEnabled"/>
</v-list-item>
<v-subheader class="font-weight-black text-h6">{{ $t('bookreader.settings.display') }}</v-subheader>
@ -181,8 +192,7 @@
:items="backgroundColors"
v-model="backgroundColor"
:label="$t('bookreader.settings.background_color')"
>
</settings-select>
/>
</v-list-item>
<template v-if="continuousReader">
@ -315,6 +325,7 @@ import {BookDto, PageDto, PageDtoWithUrl} from '@/types/komga-books'
import {Context, ContextOrigin} from '@/types/context'
import {SeriesDto} from '@/types/komga-series'
import jsFileDownloader from 'js-file-downloader'
import screenfull from 'screenfull'
export default Vue.extend({
name: 'BookReader',
@ -328,6 +339,8 @@ export default Vue.extend({
},
data: function () {
return {
screenfull,
fullscreenIcon: 'mdi-fullscreen',
book: {} as BookDto,
series: {} as SeriesDto,
context: {} as Context,
@ -353,7 +366,8 @@ export default Vue.extend({
goToPage: 1,
settings: {
pageLayout: PagedReaderLayout.SINGLE_PAGE,
swipe: true,
swipe: false,
alwaysFullscreen: false,
animations: true,
scale: ScaleType.SCREEN,
continuousScale: ContinuousScaleType.WIDTH,
@ -402,12 +416,14 @@ export default Vue.extend({
})
this.shortcuts = this.$_.keyBy([...shortcutsSettings, ...shortcutsSettingsPaged, ...shortcutsSettingsContinuous, ...shortcutsMenus, ...shortcutsAll], x => x.key)
window.addEventListener('keydown', this.keyPressed)
if (screenfull.isEnabled) screenfull.on('change', this.fullscreenChanged)
},
async mounted() {
this.readingDirection = this.$store.state.persistedState.webreader.readingDirection
this.animations = this.$store.state.persistedState.webreader.animations
this.pageLayout = this.$store.state.persistedState.webreader.paged.pageLayout
this.swipe = this.$store.state.persistedState.webreader.swipe
this.alwaysFullscreen = this.$store.state.persistedState.webreader.alwaysFullscreen
this.scale = this.$store.state.persistedState.webreader.paged.scale
this.continuousScale = this.$store.state.persistedState.webreader.continuous.scale
this.sidePadding = this.$store.state.persistedState.webreader.continuous.padding
@ -418,6 +434,10 @@ export default Vue.extend({
destroyed() {
this.$vuetify.rtl = (this.$t('common.locale_rtl') === 'true')
window.removeEventListener('keydown', this.keyPressed)
if (screenfull.isEnabled) {
screenfull.off('change', this.fullscreenChanged)
screenfull.exit()
}
},
props: {
bookId: {
@ -580,8 +600,26 @@ export default Vue.extend({
this.$store.commit('setWebreaderSwipe', swipe)
},
},
alwaysFullscreen: {
get: function (): boolean {
return this.settings.alwaysFullscreen
},
set: function (alwaysFullscreen: boolean): void {
this.settings.alwaysFullscreen = alwaysFullscreen
this.$store.commit('setWebreaderAlwaysFullscreen', alwaysFullscreen)
if(alwaysFullscreen) this.enterFullscreen()
else screenfull.isEnabled && screenfull.exit()
},
},
},
methods: {
enterFullscreen() {
if (screenfull.isEnabled) screenfull.request(document.documentElement, {navigationUI: 'hide'})
},
fullscreenChanged() {
if (screenfull.isEnabled && screenfull.isFullscreen) this.fullscreenIcon = 'mdi-fullscreen-exit'
else this.fullscreenIcon = 'mdi-fullscreen'
},
keyPressed(e: KeyboardEvent) {
this.shortcuts[e.key]?.execute(this)
},