2019-07-04 18:06:44 +02:00
|
|
|
<template>
|
|
|
|
<div class="reader" v-shortkey="{next: ['arrowleft'], prev: ['arrowright']}" @shortkey="navigation" :style="{ 'grid-template-columns': showSidebar ? 'auto 250px' : 'auto' }">
|
|
|
|
<div>
|
|
|
|
<img :style="{ width: pageWidth + '%' }" :src="info.pages[page]">
|
|
|
|
<!-- prefetching -->
|
|
|
|
<img style="display: none;" :src="info.pages[page-1]">
|
|
|
|
<img style="display: none;" :src="info.pages[page+1]">
|
|
|
|
</div>
|
|
|
|
<div class="sidebar" :style="{ display: showSidebar ? '' : 'none' }">
|
|
|
|
<h3>{{ info.title }}</h3>
|
|
|
|
<router-link :to="'/series/' + info.series">All Volumes</router-link>
|
2019-07-04 19:32:30 +02:00
|
|
|
<p>{{ page + 1 }}/{{ info.pages.length }}</p>
|
2019-07-04 18:06:44 +02:00
|
|
|
<p>
|
|
|
|
<button v-on:click="changePageWidth(5)">+</button>
|
|
|
|
<button v-on:click="changePageWidth(-5)">-</button>
|
|
|
|
</p>
|
|
|
|
<button class="hide" v-on:click="showSidebar = false">Hide</button>
|
|
|
|
</div>
|
|
|
|
<div class="sidebar-enabler" :style="{ display: showSidebar ? 'none' : '' }" v-on:click="showSidebar = true"></div>
|
|
|
|
</div>
|
|
|
|
</template>
|
|
|
|
|
|
|
|
<script>
|
|
|
|
import API from '@/api-client.js'
|
|
|
|
|
|
|
|
export default {
|
|
|
|
name: 'Reader',
|
|
|
|
data () {
|
|
|
|
return {
|
|
|
|
info: {
|
|
|
|
pages: []
|
|
|
|
},
|
|
|
|
scrollPositions: [],
|
|
|
|
pageWidth: 60,
|
|
|
|
showSidebar: true
|
|
|
|
}
|
|
|
|
},
|
|
|
|
computed: {
|
|
|
|
page () {
|
|
|
|
if (this.$route.query.page) {
|
|
|
|
return parseInt(this.$route.query.page - 1)
|
|
|
|
} else {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
mounted () {
|
|
|
|
API.getVolumeInfo(this.$route.params.id, info => (this.info = info))
|
|
|
|
},
|
|
|
|
methods: {
|
|
|
|
setPage (page) {
|
|
|
|
// save scroll position
|
|
|
|
this.scrollPositions[this.page] = window.pageYOffset
|
|
|
|
|
|
|
|
// set page
|
|
|
|
if (page >= 0 && page < this.info.pages.length) {
|
|
|
|
this.$router.push({ query: { page: page + 1 } })
|
|
|
|
}
|
|
|
|
|
|
|
|
// load saved scroll posotion, if available, reset to 0 otherwise
|
|
|
|
if (this.scrollPositions[this.page]) {
|
|
|
|
window.scrollTo(0, this.scrollPositions[this.page])
|
|
|
|
} else {
|
|
|
|
window.scrollTo(0, 0)
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
navigation (event) {
|
|
|
|
switch (event.srcKey) {
|
|
|
|
case 'next':
|
|
|
|
this.setPage(this.page + 1)
|
|
|
|
break
|
|
|
|
case 'prev':
|
|
|
|
this.setPage(this.page - 1)
|
|
|
|
break
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
changePageWidth (change) {
|
|
|
|
if (this.pageWidth + change > 0 && this.pageWidth + change <= 100) {
|
|
|
|
this.pageWidth += change
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
</script>
|
|
|
|
|
|
|
|
<style scoped>
|
|
|
|
.reader {
|
|
|
|
display: grid;
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
|
|
|
|
.current-page {
|
|
|
|
max-width: 50vw;
|
|
|
|
}
|
|
|
|
|
|
|
|
.sidebar-enabler {
|
|
|
|
position: absolute;
|
|
|
|
top: 0px;
|
|
|
|
right: 0px;
|
|
|
|
height: 100%;
|
|
|
|
width: 250px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.sidebar {
|
|
|
|
background-color: #eee;
|
|
|
|
height: 100vh;
|
|
|
|
position: sticky;
|
|
|
|
top: 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
button.hide {
|
|
|
|
bottom: 1em;
|
|
|
|
right: 1em;
|
|
|
|
position: absolute;
|
|
|
|
}
|
|
|
|
</style>
|