fix(webui): scroll continuous reader to top on book change

closes #475
This commit is contained in:
Gauthier Roebroeck 2021-04-26 16:13:22 +08:00
parent 97cc3e043d
commit d27828de13

View file

@ -37,8 +37,8 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
import { ContinuousScaleType } from '@/types/enum-reader' import {ContinuousScaleType} from '@/types/enum-reader'
import { PageDtoWithUrl } from '@/types/komga-books' import {PageDtoWithUrl} from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'ContinuousReader', name: 'ContinuousReader',
@ -74,8 +74,9 @@ export default Vue.extend({
}, },
watch: { watch: {
pages: { pages: {
handler (val) { handler(val) {
this.seen = new Array(val.length).fill(false) this.seen = new Array(val.length).fill(false)
if (this.page === 1) window.scrollTo(0, 0)
}, },
immediate: true, immediate: true,
}, },
@ -90,7 +91,7 @@ export default Vue.extend({
immediate: false, immediate: false,
}, },
}, },
mounted () { mounted() {
if (this.page != this.currentPage) { if (this.page != this.currentPage) {
this.$vuetify.goTo(`#page${this.page}`, { this.$vuetify.goTo(`#page${this.page}`, {
duration: 0, duration: 0,
@ -98,26 +99,26 @@ export default Vue.extend({
} }
}, },
computed: { computed: {
canPrev (): boolean { canPrev(): boolean {
return this.offsetTop > 0 return this.offsetTop > 0
}, },
canNext (): boolean { canNext(): boolean {
return this.offsetTop + this.$vuetify.breakpoint.height < this.totalHeight return this.offsetTop + this.$vuetify.breakpoint.height < this.totalHeight
}, },
goToOptions (): object | undefined { goToOptions(): object | undefined {
if (this.animations) return undefined if (this.animations) return undefined
return { duration: 0 } return {duration: 0}
}, },
totalSidePadding (): number { totalSidePadding(): number {
return this.sidePadding * 2 return this.sidePadding * 2
}, },
}, },
methods: { methods: {
onScroll (e: any) { onScroll(e: any) {
this.offsetTop = e.target.scrollingElement.scrollTop this.offsetTop = e.target.scrollingElement.scrollTop
this.totalHeight = e.target.scrollingElement.scrollHeight this.totalHeight = e.target.scrollingElement.scrollHeight
}, },
onIntersect (entries: any) { onIntersect(entries: any) {
if (entries[0].isIntersecting) { if (entries[0].isIntersecting) {
const page = parseInt(entries[0].target.id.replace('page', '')) const page = parseInt(entries[0].target.id.replace('page', ''))
this.seen.splice(page - 1, 1, true) this.seen.splice(page - 1, 1, true)
@ -125,10 +126,10 @@ export default Vue.extend({
this.$emit('update:page', page) this.$emit('update:page', page)
} }
}, },
shouldLoad (page: number): boolean { shouldLoad(page: number): boolean {
return page == 0 || this.seen[page] || Math.abs((this.currentPage - 1) - page) <= 2 return page == 0 || this.seen[page] || Math.abs((this.currentPage - 1) - page) <= 2
}, },
calcHeight (page: PageDtoWithUrl): number | undefined { calcHeight(page: PageDtoWithUrl): number | undefined {
switch (this.scale) { switch (this.scale) {
case ContinuousScaleType.WIDTH: case ContinuousScaleType.WIDTH:
if (page.height && page.width) if (page.height && page.width)
@ -140,7 +141,7 @@ export default Vue.extend({
return undefined return undefined
} }
}, },
calcWidth (page: PageDtoWithUrl): number | undefined { calcWidth(page: PageDtoWithUrl): number | undefined {
switch (this.scale) { switch (this.scale) {
case ContinuousScaleType.WIDTH: case ContinuousScaleType.WIDTH:
return this.$vuetify.breakpoint.width - (this.$vuetify.breakpoint.width * this.totalSidePadding) / 100 return this.$vuetify.breakpoint.width - (this.$vuetify.breakpoint.width * this.totalSidePadding) / 100
@ -150,10 +151,10 @@ export default Vue.extend({
return undefined return undefined
} }
}, },
centerClick () { centerClick() {
this.$emit('menu') this.$emit('menu')
}, },
prev () { prev() {
if (this.canPrev) { if (this.canPrev) {
const step = this.$vuetify.breakpoint.height * 0.95 const step = this.$vuetify.breakpoint.height * 0.95
this.$vuetify.goTo(this.offsetTop - step, this.goToOptions) this.$vuetify.goTo(this.offsetTop - step, this.goToOptions)
@ -161,7 +162,7 @@ export default Vue.extend({
this.$emit('jump-previous') this.$emit('jump-previous')
} }
}, },
next () { next() {
if (this.canNext) { if (this.canNext) {
const step = this.$vuetify.breakpoint.height * 0.95 const step = this.$vuetify.breakpoint.height * 0.95
this.$vuetify.goTo(this.offsetTop + step, this.goToOptions) this.$vuetify.goTo(this.offsetTop + step, this.goToOptions)