mirror of
https://github.com/gotson/komga.git
synced 2026-05-09 05:10:19 +02:00
fix(webui): more logs in the frontend
This commit is contained in:
parent
b7a2c87e3e
commit
cefd3f0ee8
4 changed files with 102 additions and 41 deletions
|
|
@ -84,8 +84,9 @@ import {buildSpreads} from '@/functions/book-spreads'
|
||||||
|
|
||||||
export default Vue.extend({
|
export default Vue.extend({
|
||||||
name: 'PagedReader',
|
name: 'PagedReader',
|
||||||
data: () => {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
|
logger: 'PagedReader',
|
||||||
carouselPage: 0,
|
carouselPage: 0,
|
||||||
spreads: [] as PageDtoWithUrl[][],
|
spreads: [] as PageDtoWithUrl[][],
|
||||||
}
|
}
|
||||||
|
|
@ -122,19 +123,23 @@ export default Vue.extend({
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
pages: {
|
pages: {
|
||||||
handler (val) {
|
handler(val) {
|
||||||
this.spreads = buildSpreads(val, this.pageLayout)
|
this.spreads = buildSpreads(val, this.pageLayout)
|
||||||
},
|
},
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
currentPage (val) {
|
currentPage(val, old) {
|
||||||
|
this.$logDebug('[watch:currentPage]', `old:${old}`, `new:${val}`)()
|
||||||
this.$emit('update:page', val)
|
this.$emit('update:page', val)
|
||||||
},
|
},
|
||||||
page (val) {
|
page(val, old) {
|
||||||
this.carouselPage = this.toSpreadIndex(val)
|
this.$logDebug('[watch:page]', `old:${old}`, `new:${val}`)()
|
||||||
|
const spreadIndex = this.toSpreadIndex(val)
|
||||||
|
this.$logDebug('[watch:page]', `toSpreadIndex:${spreadIndex}`)()
|
||||||
|
this.carouselPage = spreadIndex
|
||||||
},
|
},
|
||||||
pageLayout: {
|
pageLayout: {
|
||||||
handler (val) {
|
handler(val) {
|
||||||
const current = this.page
|
const current = this.page
|
||||||
this.spreads = buildSpreads(this.pages, val)
|
this.spreads = buildSpreads(this.pages, val)
|
||||||
this.carouselPage = this.toSpreadIndex(current)
|
this.carouselPage = this.toSpreadIndex(current)
|
||||||
|
|
@ -142,14 +147,14 @@ export default Vue.extend({
|
||||||
immediate: true,
|
immediate: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
created () {
|
created() {
|
||||||
window.addEventListener('keydown', this.keyPressed)
|
window.addEventListener('keydown', this.keyPressed)
|
||||||
},
|
},
|
||||||
destroyed () {
|
destroyed() {
|
||||||
window.removeEventListener('keydown', this.keyPressed)
|
window.removeEventListener('keydown', this.keyPressed)
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
shortcuts (): any {
|
shortcuts(): any {
|
||||||
const shortcuts = []
|
const shortcuts = []
|
||||||
switch (this.readingDirection) {
|
switch (this.readingDirection) {
|
||||||
case ReadingDirection.LEFT_TO_RIGHT:
|
case ReadingDirection.LEFT_TO_RIGHT:
|
||||||
|
|
@ -164,39 +169,40 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
return this.$_.keyBy(shortcuts, x => x.key)
|
return this.$_.keyBy(shortcuts, x => x.key)
|
||||||
},
|
},
|
||||||
flipDirection (): boolean {
|
flipDirection(): boolean {
|
||||||
return this.readingDirection === ReadingDirection.RIGHT_TO_LEFT
|
return this.readingDirection === ReadingDirection.RIGHT_TO_LEFT
|
||||||
},
|
},
|
||||||
vertical (): boolean {
|
vertical(): boolean {
|
||||||
return this.readingDirection === ReadingDirection.VERTICAL
|
return this.readingDirection === ReadingDirection.VERTICAL
|
||||||
},
|
},
|
||||||
currentSlide (): number {
|
currentSlide(): number {
|
||||||
return this.carouselPage + 1
|
return this.carouselPage + 1
|
||||||
},
|
},
|
||||||
currentPage (): number {
|
currentPage(): number {
|
||||||
|
this.$logDebug('[currentPage]', `carouselPage:${this.carouselPage}`, `spreads.length:${this.spreads.length}`)()
|
||||||
if (this.carouselPage >= 0 && this.carouselPage < this.spreads.length && this.spreads.length > 0) {
|
if (this.carouselPage >= 0 && this.carouselPage < this.spreads.length && this.spreads.length > 0) {
|
||||||
return this.spreads[this.carouselPage][0].number
|
return this.spreads[this.carouselPage][0].number
|
||||||
}
|
}
|
||||||
return 1
|
return 1
|
||||||
},
|
},
|
||||||
slidesCount (): number {
|
slidesCount(): number {
|
||||||
return this.spreads.length
|
return this.spreads.length
|
||||||
},
|
},
|
||||||
canPrev (): boolean {
|
canPrev(): boolean {
|
||||||
return this.currentSlide > 1
|
return this.currentSlide > 1
|
||||||
},
|
},
|
||||||
canNext (): boolean {
|
canNext(): boolean {
|
||||||
return this.currentSlide < this.slidesCount
|
return this.currentSlide < this.slidesCount
|
||||||
},
|
},
|
||||||
isDoublePages (): boolean {
|
isDoublePages(): boolean {
|
||||||
return this.pageLayout === PagedReaderLayout.DOUBLE_PAGES || this.pageLayout === PagedReaderLayout.DOUBLE_NO_COVER
|
return this.pageLayout === PagedReaderLayout.DOUBLE_PAGES || this.pageLayout === PagedReaderLayout.DOUBLE_NO_COVER
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
keyPressed (e: KeyboardEvent) {
|
keyPressed(e: KeyboardEvent) {
|
||||||
this.shortcuts[e.key]?.execute(this)
|
this.shortcuts[e.key]?.execute(this)
|
||||||
},
|
},
|
||||||
imgClass (spread: PageDtoWithUrl[]): string {
|
imgClass(spread: PageDtoWithUrl[]): string {
|
||||||
const double = spread.length > 1
|
const double = spread.length > 1
|
||||||
switch (this.scale) {
|
switch (this.scale) {
|
||||||
case ScaleType.WIDTH:
|
case ScaleType.WIDTH:
|
||||||
|
|
@ -211,27 +217,27 @@ export default Vue.extend({
|
||||||
return 'img-fit-original'
|
return 'img-fit-original'
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
eagerLoad (spreadIndex: number): boolean {
|
eagerLoad(spreadIndex: number): boolean {
|
||||||
return Math.abs(this.carouselPage - spreadIndex) <= 2
|
return Math.abs(this.carouselPage - spreadIndex) <= 2
|
||||||
},
|
},
|
||||||
centerClick () {
|
centerClick() {
|
||||||
this.$emit('menu')
|
this.$emit('menu')
|
||||||
},
|
},
|
||||||
turnRight () {
|
turnRight() {
|
||||||
if (!this.vertical)
|
if (!this.vertical)
|
||||||
this.flipDirection ? this.prev() : this.next()
|
this.flipDirection ? this.prev() : this.next()
|
||||||
},
|
},
|
||||||
turnLeft () {
|
turnLeft() {
|
||||||
if (!this.vertical)
|
if (!this.vertical)
|
||||||
this.flipDirection ? this.next() : this.prev()
|
this.flipDirection ? this.next() : this.prev()
|
||||||
},
|
},
|
||||||
verticalPrev () {
|
verticalPrev() {
|
||||||
if (this.vertical) this.prev()
|
if (this.vertical) this.prev()
|
||||||
},
|
},
|
||||||
verticalNext () {
|
verticalNext() {
|
||||||
if (this.vertical) this.next()
|
if (this.vertical) this.next()
|
||||||
},
|
},
|
||||||
prev () {
|
prev() {
|
||||||
if (this.canPrev) {
|
if (this.canPrev) {
|
||||||
this.carouselPage--
|
this.carouselPage--
|
||||||
window.scrollTo(0, 0)
|
window.scrollTo(0, 0)
|
||||||
|
|
@ -239,7 +245,7 @@ export default Vue.extend({
|
||||||
this.$emit('jump-previous')
|
this.$emit('jump-previous')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
next () {
|
next() {
|
||||||
if (this.canNext) {
|
if (this.canNext) {
|
||||||
this.carouselPage++
|
this.carouselPage++
|
||||||
window.scrollTo(0, 0)
|
window.scrollTo(0, 0)
|
||||||
|
|
@ -247,7 +253,8 @@ export default Vue.extend({
|
||||||
this.$emit('jump-next')
|
this.$emit('jump-next')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
toSpreadIndex (i: number): number {
|
toSpreadIndex(i: number): number {
|
||||||
|
this.$logDebug('[toSpreadIndex]', `i:${i}`, `isDoublePages:${this.isDoublePages}`)()
|
||||||
if (this.spreads.length > 0) {
|
if (this.spreads.length > 0) {
|
||||||
if (this.isDoublePages) {
|
if (this.isDoublePages) {
|
||||||
for (let j = 0; j < this.spreads.length; j++) {
|
for (let j = 0; j < this.spreads.length; j++) {
|
||||||
|
|
|
||||||
|
|
@ -20,23 +20,20 @@ import komgaTransientBooks from './plugins/komga-transientbooks.plugin'
|
||||||
import komgaSse from './plugins/komga-sse.plugin'
|
import komgaSse from './plugins/komga-sse.plugin'
|
||||||
import komgaTasks from './plugins/komga-tasks.plugin'
|
import komgaTasks from './plugins/komga-tasks.plugin'
|
||||||
import vuetify from './plugins/vuetify'
|
import vuetify from './plugins/vuetify'
|
||||||
|
import logger from './plugins/logger.plugin'
|
||||||
import './public-path'
|
import './public-path'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import store from './store'
|
import store from './store'
|
||||||
import i18n from './i18n'
|
import i18n from './i18n'
|
||||||
import log from 'loglevel'
|
|
||||||
|
|
||||||
Vue.prototype.$_ = _
|
Vue.prototype.$_ = _
|
||||||
Vue.prototype.$eventHub = new Vue()
|
Vue.prototype.$eventHub = new Vue()
|
||||||
|
|
||||||
Vue.prototype.$log = log
|
|
||||||
if (process.env.VUE_APP_LOG_LEVEL)
|
|
||||||
Vue.prototype.$log.setLevel(process.env.VUE_APP_LOG_LEVEL)
|
|
||||||
|
|
||||||
Vue.use(Vuelidate)
|
Vue.use(Vuelidate)
|
||||||
Vue.use(lineClamp)
|
Vue.use(lineClamp)
|
||||||
|
|
||||||
Vue.use(httpPlugin)
|
Vue.use(httpPlugin)
|
||||||
|
Vue.use(logger)
|
||||||
Vue.use(komgaFileSystem, {http: Vue.prototype.$http})
|
Vue.use(komgaFileSystem, {http: Vue.prototype.$http})
|
||||||
Vue.use(komgaSeries, {http: Vue.prototype.$http})
|
Vue.use(komgaSeries, {http: Vue.prototype.$http})
|
||||||
Vue.use(komgaCollections, {http: Vue.prototype.$http})
|
Vue.use(komgaCollections, {http: Vue.prototype.$http})
|
||||||
|
|
@ -68,7 +65,6 @@ declare module 'vue/types/vue' {
|
||||||
interface Vue {
|
interface Vue {
|
||||||
$_: LoDashStatic;
|
$_: LoDashStatic;
|
||||||
$eventHub: Vue;
|
$eventHub: Vue;
|
||||||
$log: log.RootLogger;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
60
komga-webui/src/plugins/logger.plugin.ts
Normal file
60
komga-webui/src/plugins/logger.plugin.ts
Normal file
|
|
@ -0,0 +1,60 @@
|
||||||
|
import _Vue from 'vue'
|
||||||
|
import log from 'loglevel'
|
||||||
|
import _, {isArray, isObject} from 'lodash'
|
||||||
|
import {format} from 'date-fns'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
install(Vue: typeof _Vue) {
|
||||||
|
if (process.env.VUE_APPlog_LEVEL)
|
||||||
|
log.setLevel(process.env.VUE_APPlog_LEVEL as any)
|
||||||
|
|
||||||
|
Vue.prototype.$logTrace = function (...msg: any[]) {
|
||||||
|
const loggerName = _.get(this, 'logger') || _.get(this, '$options.name')
|
||||||
|
const logger = loggerName ? log.getLogger(loggerName) : log
|
||||||
|
return logger.trace.bind(logger, getPrefix('TRACE', loggerName), ...(stringArgs(msg)))
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$logDebug = function (...msg: any[]) {
|
||||||
|
const loggerName = _.get(this, 'logger') || _.get(this, '$options.name')
|
||||||
|
const logger = loggerName ? log.getLogger(loggerName) : log
|
||||||
|
return logger.debug.bind(logger, getPrefix('DEBUG', loggerName), ...(stringArgs(msg)))
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$logInfo = function (...msg: any[]) {
|
||||||
|
const loggerName = _.get(this, 'logger') || _.get(this, '$options.name')
|
||||||
|
const logger = loggerName ? log.getLogger(loggerName) : log
|
||||||
|
return logger.info.bind(logger, getPrefix('INFO', loggerName), ...(stringArgs(msg)))
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$logWarn = function (...msg: any[]) {
|
||||||
|
const loggerName = _.get(this, 'logger') || _.get(this, '$options.name')
|
||||||
|
const logger = loggerName ? log.getLogger(loggerName) : log
|
||||||
|
return logger.warn.bind(logger, getPrefix('WARN', loggerName), ...(stringArgs(msg)))
|
||||||
|
}
|
||||||
|
|
||||||
|
Vue.prototype.$logError = function (...msg: any[]) {
|
||||||
|
const loggerName = _.get(this, 'logger') || _.get(this, '$options.name')
|
||||||
|
const logger = loggerName ? log.getLogger(loggerName) : log
|
||||||
|
return logger.error.bind(logger, getPrefix('ERROR', loggerName), ...(stringArgs(msg)))
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
function stringArgs(msg: any[]): any[] {
|
||||||
|
return msg.map(m => isObject(m) || isArray(m) ? JSON.stringify(m) : m)
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPrefix(level: string, loggerName: string): string {
|
||||||
|
const timestamp = format(new Date(), 'yyyy-MM-dd HH:mm:ss.SSS')
|
||||||
|
return `${timestamp} ${level} --- ${loggerName} :`
|
||||||
|
}
|
||||||
|
|
||||||
|
declare module 'vue/types/vue' {
|
||||||
|
interface Vue {
|
||||||
|
$logTrace(...msg: any[]): (...msg: any[]) => void;
|
||||||
|
$logDebug(...msg: any[]): (...msg: any[]) => void;
|
||||||
|
$logInfo(...msg: any[]): (...msg: any[]) => void;
|
||||||
|
$logWarn(...msg: any[]): (...msg: any[]) => void;
|
||||||
|
$logError(...msg: any[]): (...msg: any[]) => void;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -420,8 +420,7 @@ export default Vue.extend({
|
||||||
if (screenfull.isEnabled) screenfull.on('change', this.fullscreenChanged)
|
if (screenfull.isEnabled) screenfull.on('change', this.fullscreenChanged)
|
||||||
},
|
},
|
||||||
async mounted() {
|
async mounted() {
|
||||||
this.$log.debug('mounted')
|
this.$logDebug('[mounted]', 'route.query:', this.$route.query)()
|
||||||
this.$log.debug(`route.query: ${JSON.stringify(this.$route.query)}`)
|
|
||||||
|
|
||||||
this.readingDirection = this.$store.state.persistedState.webreader.readingDirection
|
this.readingDirection = this.$store.state.persistedState.webreader.readingDirection
|
||||||
this.animations = this.$store.state.persistedState.webreader.animations
|
this.animations = this.$store.state.persistedState.webreader.animations
|
||||||
|
|
@ -454,7 +453,7 @@ export default Vue.extend({
|
||||||
// route update means either:
|
// route update means either:
|
||||||
// - going to previous/next book, in this case the query.page is not set, so it will default to first page
|
// - going to previous/next book, in this case the query.page is not set, so it will default to first page
|
||||||
// - pressing the back button of the browser and navigating to the previous book, in this case the query.page is set, so we honor it
|
// - pressing the back button of the browser and navigating to the previous book, in this case the query.page is set, so we honor it
|
||||||
this.$log.debug(`beforeRouteUpdate, to.query: ${JSON.stringify(to.query)}`)
|
this.$logDebug('[beforeRouteUpdate]', 'to.query:', to.query)()
|
||||||
this.setup(to.params.bookId, Number(to.query.page))
|
this.setup(to.params.bookId, Number(to.query.page))
|
||||||
}
|
}
|
||||||
next()
|
next()
|
||||||
|
|
@ -629,7 +628,7 @@ export default Vue.extend({
|
||||||
this.shortcuts[e.key]?.execute(this)
|
this.shortcuts[e.key]?.execute(this)
|
||||||
},
|
},
|
||||||
async setup(bookId: string, page?: number) {
|
async setup(bookId: string, page?: number) {
|
||||||
this.$log.debug(`setup bookId:${bookId}, page:${page}`)
|
this.$logDebug('[setup]', `bookId:${bookId}`, `page:${page}`)()
|
||||||
this.book = await this.$komgaBooks.getBook(bookId)
|
this.book = await this.$komgaBooks.getBook(bookId)
|
||||||
this.series = await this.$komgaSeries.getOneSeries(this.book.seriesId)
|
this.series = await this.$komgaSeries.getOneSeries(this.book.seriesId)
|
||||||
|
|
||||||
|
|
@ -654,8 +653,7 @@ export default Vue.extend({
|
||||||
pageDtos.forEach((p: any) => p['url'] = this.getPageUrl(p))
|
pageDtos.forEach((p: any) => p['url'] = this.getPageUrl(p))
|
||||||
this.pages = pageDtos as PageDtoWithUrl[]
|
this.pages = pageDtos as PageDtoWithUrl[]
|
||||||
|
|
||||||
this.$log.debug(`pages count: ${this.pagesCount}`)
|
this.$logDebug('[setup]', `pages count:${this.pagesCount}`, 'read progress:', this.book.readProgress)()
|
||||||
this.$log.debug(`read progress: ${JSON.stringify(this.book.readProgress)}`)
|
|
||||||
if (page && page >= 1 && page <= this.pagesCount) {
|
if (page && page >= 1 && page <= this.pagesCount) {
|
||||||
this.goTo(page)
|
this.goTo(page)
|
||||||
} else if (this.book.readProgress?.completed === false) {
|
} else if (this.book.readProgress?.completed === false) {
|
||||||
|
|
@ -736,7 +734,7 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
goTo(page: number) {
|
goTo(page: number) {
|
||||||
this.$log.debug(`goTo: ${page}`)
|
this.$logDebug('[goTo]', `page:${page}`)()
|
||||||
this.page = page
|
this.page = page
|
||||||
this.markProgress(page)
|
this.markProgress(page)
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue