feat(webui): navigate between books of a readlist

This commit is contained in:
Gauthier Roebroeck 2021-01-06 15:12:19 +08:00
parent bcfb203f74
commit 88d4342ef5
28 changed files with 170 additions and 18 deletions

View file

@ -92,6 +92,7 @@ import Vue from 'vue'
import ReadListAddToDialog from '@/components/dialogs/ReadListAddToDialog.vue' import ReadListAddToDialog from '@/components/dialogs/ReadListAddToDialog.vue'
import ReadListDeleteDialog from '@/components/dialogs/ReadListDeleteDialog.vue' import ReadListDeleteDialog from '@/components/dialogs/ReadListDeleteDialog.vue'
import ReadListEditDialog from '@/components/dialogs/ReadListEditDialog.vue' import ReadListEditDialog from '@/components/dialogs/ReadListEditDialog.vue'
import { BookDto } from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'Dialogs', name: 'Dialogs',

View file

@ -50,7 +50,7 @@
x-large x-large
color="accent" color="accent"
style="position: absolute; top: 50%; left: 50%; margin-left: -36px; margin-top: -36px" style="position: absolute; top: 50%; left: 50%; margin-left: -36px; margin-top: -36px"
:to="{name: 'read-book', params: { bookId: item.id}}" :to="fabTo"
> >
<v-icon>mdi-book-open-page-variant</v-icon> <v-icon>mdi-book-open-page-variant</v-icon>
</v-btn> </v-btn>
@ -124,6 +124,7 @@ import { createItem, Item, ItemTypes } from '@/types/items'
import Vue from 'vue' import Vue from 'vue'
import { RawLocation } from 'vue-router' import { RawLocation } from 'vue-router'
import ReadListActionsMenu from '@/components/menus/ReadListActionsMenu.vue' import ReadListActionsMenu from '@/components/menus/ReadListActionsMenu.vue'
import { BookDto } from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'ItemCard', name: 'ItemCard',
@ -232,6 +233,9 @@ export default Vue.extend({
to (): RawLocation { to (): RawLocation {
return this.computedItem.to() return this.computedItem.to()
}, },
fabTo (): RawLocation {
return this.computedItem.fabTo()
},
}, },
methods: { methods: {
onClick () { onClick () {

View file

@ -30,6 +30,8 @@
import HorizontalScroller from '@/components/HorizontalScroller.vue' import HorizontalScroller from '@/components/HorizontalScroller.vue'
import ItemBrowser from '@/components/ItemBrowser.vue' import ItemBrowser from '@/components/ItemBrowser.vue'
import Vue from 'vue' import Vue from 'vue'
import { BookDto } from '@/types/komga-books'
import { ContextOrigin } from '@/types/context'
export default Vue.extend({ export default Vue.extend({
name: 'ReadListsExpansionPanels', name: 'ReadListsExpansionPanels',
@ -62,6 +64,7 @@ export default Vue.extend({
const rlId = this.readLists[val].id const rlId = this.readLists[val].id
if (this.$_.isEmpty(this.readListsContent[val])) { if (this.$_.isEmpty(this.readListsContent[val])) {
const content = (await this.$komgaReadLists.getBooks(rlId, { unpaged: true } as PageRequest)).content const content = (await this.$komgaReadLists.getBooks(rlId, { unpaged: true } as PageRequest)).content
content.forEach((x: BookDto) => x.context = { origin: ContextOrigin.READLIST, id: rlId })
this.readListsContent.splice(val, 1, content) this.readListsContent.splice(val, 1, content)
} }
} }

View file

@ -105,6 +105,7 @@
import { bookThumbnailUrl, collectionThumbnailUrl, readListThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls' import { bookThumbnailUrl, collectionThumbnailUrl, readListThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls'
import { debounce } from 'lodash' import { debounce } from 'lodash'
import Vue from 'vue' import Vue from 'vue'
import { BookDto } from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'SearchBox', name: 'SearchBox',

View file

@ -279,6 +279,7 @@ import { authorRoles } from '@/types/author-roles'
import moment from 'moment' import moment from 'moment'
import Vue from 'vue' import Vue from 'vue'
import { helpers, requiredIf } from 'vuelidate/lib/validators' import { helpers, requiredIf } from 'vuelidate/lib/validators'
import { BookDto } from '@/types/komga-books'
const validDate = (value: any) => !helpers.req(value) || moment(value, 'YYYY-MM-DD', true).isValid() const validDate = (value: any) => !helpers.req(value) || moment(value, 'YYYY-MM-DD', true).isValid()

View file

@ -80,6 +80,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
import { BookDto } from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'ReadListAddToDialog', name: 'ReadListAddToDialog',

View file

@ -31,6 +31,7 @@ import { getReadProgress } from '@/functions/book-progress'
import { ReadStatus } from '@/types/enum-books' import { ReadStatus } from '@/types/enum-books'
import { BOOK_CHANGED, bookToEventBookChanged } from '@/types/events' import { BOOK_CHANGED, bookToEventBookChanged } from '@/types/events'
import Vue from 'vue' import Vue from 'vue'
import { BookDto, ReadProgressUpdateDto } from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'BookActionsMenu', name: 'BookActionsMenu',

View file

@ -38,6 +38,7 @@
<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'
export default Vue.extend({ export default Vue.extend({
name: 'ContinuousReader', name: 'ContinuousReader',

View file

@ -80,6 +80,7 @@ import Vue from 'vue'
import { ReadingDirection } from '@/types/enum-books' import { ReadingDirection } from '@/types/enum-books'
import { PagedReaderLayout, ScaleType } from '@/types/enum-reader' import { PagedReaderLayout, ScaleType } from '@/types/enum-reader'
import { shortcutsLTR, shortcutsRTL, shortcutsVertical } from '@/functions/shortcuts/paged-reader' import { shortcutsLTR, shortcutsRTL, shortcutsVertical } from '@/functions/shortcuts/paged-reader'
import { PageDtoWithUrl } from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'PagedReader', name: 'PagedReader',

View file

@ -1,5 +1,6 @@
import { get, groupBy, mapKeys, mapValues } from 'lodash' import { get, groupBy, mapKeys, mapValues } from 'lodash'
import { authorRoles } from '@/types/author-roles' import { authorRoles } from '@/types/author-roles'
import { AuthorDto } from '@/types/komga-books'
// return an object where keys are roles, and values are string[] // return an object where keys are roles, and values are string[]
export function groupAuthorsByRole (authors: AuthorDto[]): any { export function groupAuthorsByRole (authors: AuthorDto[]): any {

View file

@ -1,3 +1,5 @@
import { BookFormat } from '@/types/komga-books'
export function getBookFormatFromMediaType (mediaType: string): BookFormat { export function getBookFormatFromMediaType (mediaType: string): BookFormat {
switch (mediaType) { switch (mediaType) {
case 'application/x-rar-compressed': case 'application/x-rar-compressed':

View file

@ -1,4 +1,5 @@
import { ReadStatus } from '@/types/enum-books' import { ReadStatus } from '@/types/enum-books'
import { BookDto } from '@/types/komga-books'
export function getReadProgress (book: BookDto): ReadStatus { export function getReadProgress (book: BookDto): ReadStatus {
if (book.readProgress?.completed) return ReadStatus.READ if (book.readProgress?.completed) return ReadStatus.READ

View file

@ -1,3 +1,5 @@
import { PageDto } from '@/types/komga-books'
export function isPageLandscape (p: PageDto): boolean { export function isPageLandscape (p: PageDto): boolean {
return (p?.width ?? 0) > (p?.height ?? 0) return (p?.width ?? 0) > (p?.height ?? 0)
} }

View file

@ -1,4 +1,5 @@
import { AxiosInstance } from 'axios' import { AxiosInstance } from 'axios'
import { BookDto, BookMetadataUpdateDto, PageDto, ReadProgressUpdateDto } from '@/types/komga-books'
const qs = require('qs') const qs = require('qs')

View file

@ -1,4 +1,5 @@
import { AxiosInstance } from 'axios' import { AxiosInstance } from 'axios'
import { BookDto } from '@/types/komga-books'
const qs = require('qs') const qs = require('qs')
@ -92,4 +93,28 @@ export default class KomgaReadListsService {
throw new Error(msg) throw new Error(msg)
} }
} }
async getBookSiblingNext (readListId: string, bookId: string): Promise<BookDto> {
try {
return (await this.http.get(`${API_READLISTS}/${readListId}/books/${bookId}/next`)).data
} catch (e) {
let msg = 'An error occurred while trying to retrieve book'
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
throw new Error(msg)
}
}
async getBookSiblingPrevious (readListId: string, bookId: string): Promise<BookDto> {
try {
return (await this.http.get(`${API_READLISTS}/${readListId}/books/${bookId}/previous`)).data
} catch (e) {
let msg = 'An error occurred while trying to retrieve book'
if (e.response.data.message) {
msg += `: ${e.response.data.message}`
}
throw new Error(msg)
}
}
} }

View file

@ -1,4 +1,5 @@
import { AxiosInstance } from 'axios' import { AxiosInstance } from 'axios'
import { BookDto } from '@/types/komga-books'
const qs = require('qs') const qs = require('qs')

View file

@ -1,5 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import Vuex from 'vuex' import Vuex from 'vuex'
import { BookDto } from '@/types/komga-books'
Vue.use(Vuex) Vue.use(Vuex)

View file

@ -0,0 +1,9 @@
export enum ContextOrigin {
SERIES = 'SERIES',
READLIST = 'READLIST'
}
export interface Context {
origin: ContextOrigin,
id: string,
}

View file

@ -1,3 +1,5 @@
import { BookDto } from '@/types/komga-books'
export const BOOK_CHANGED = 'book-changed' export const BOOK_CHANGED = 'book-changed'
export const SERIES_CHANGED = 'series-changed' export const SERIES_CHANGED = 'series-changed'
export const COLLECTION_DELETED = 'collection-deleted' export const COLLECTION_DELETED = 'collection-deleted'

View file

@ -1,5 +1,6 @@
import { bookThumbnailUrl, collectionThumbnailUrl, readListThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls' import { bookThumbnailUrl, collectionThumbnailUrl, readListThumbnailUrl, seriesThumbnailUrl } from '@/functions/urls'
import { RawLocation } from 'vue-router/types/router' import { RawLocation } from 'vue-router/types/router'
import { BookDto } from '@/types/komga-books'
function plural (count: number, singular: string, plural: string) { function plural (count: number, singular: string, plural: string) {
return `${count} ${count === 1 ? singular : plural}` return `${count} ${count === 1 ? singular : plural}`
@ -47,6 +48,8 @@ export abstract class Item<T> {
abstract body (): string abstract body (): string
abstract to (): RawLocation abstract to (): RawLocation
abstract fabTo (): RawLocation
} }
export class BookItem extends Item<BookDto> { export class BookItem extends Item<BookDto> {
@ -69,7 +72,19 @@ export class BookItem extends Item<BookDto> {
} }
to (): RawLocation { to (): RawLocation {
return { name: 'browse-book', params: { bookId: this.item.id.toString() } } return {
name: 'browse-book',
params: { bookId: this.item.id },
query: { context: this.item?.context?.origin, contextId: this.item?.context?.id },
}
}
fabTo (): RawLocation {
return {
name: 'read-book',
params: { bookId: this.item.id },
query: { context: this.item?.context?.origin, contextId: this.item?.context?.id },
}
} }
} }
@ -94,6 +109,10 @@ export class SeriesItem extends Item<SeriesDto> {
to (): RawLocation { to (): RawLocation {
return { name: 'browse-series', params: { seriesId: this.item.id.toString() } } return { name: 'browse-series', params: { seriesId: this.item.id.toString() } }
} }
fabTo (): RawLocation {
return undefined as unknown as RawLocation
}
} }
export class CollectionItem extends Item<CollectionDto> { export class CollectionItem extends Item<CollectionDto> {
@ -117,6 +136,10 @@ export class CollectionItem extends Item<CollectionDto> {
to (): RawLocation { to (): RawLocation {
return { name: 'browse-collection', params: { collectionId: this.item.id.toString() } } return { name: 'browse-collection', params: { collectionId: this.item.id.toString() } }
} }
fabTo (): RawLocation {
return undefined as unknown as RawLocation
}
} }
export class ReadListItem extends Item<ReadListDto> { export class ReadListItem extends Item<ReadListDto> {
@ -140,4 +163,8 @@ export class ReadListItem extends Item<ReadListDto> {
to (): RawLocation { to (): RawLocation {
return { name: 'browse-readlist', params: { readListId: this.item.id.toString() } } return { name: 'browse-readlist', params: { readListId: this.item.id.toString() } }
} }
fabTo (): RawLocation {
return undefined as unknown as RawLocation
}
} }

View file

@ -1,4 +1,6 @@
interface BookDto { import { Context } from '@/types/context'
export interface BookDto {
id: string, id: string,
seriesId: string, seriesId: string,
libraryId: string, libraryId: string,
@ -11,16 +13,19 @@ interface BookDto {
media: MediaDto, media: MediaDto,
metadata: BookMetadataDto, metadata: BookMetadataDto,
readProgress?: ReadProgressDto readProgress?: ReadProgressDto
// custom fields
context: Context
} }
interface MediaDto { export interface MediaDto {
status: string, status: string,
mediaType: string, mediaType: string,
pagesCount: number, pagesCount: number,
comment: string comment: string
} }
interface PageDto { export interface PageDto {
number: number, number: number,
fileName: string, fileName: string,
mediaType: string, mediaType: string,
@ -28,7 +33,7 @@ interface PageDto {
height?: number, height?: number,
} }
interface PageDtoWithUrl { export interface PageDtoWithUrl {
number: number, number: number,
fileName: string, fileName: string,
mediaType: string, mediaType: string,
@ -37,7 +42,7 @@ interface PageDtoWithUrl {
url: string, url: string,
} }
interface BookMetadataDto { export interface BookMetadataDto {
created: string, created: string,
lastModified: string, lastModified: string,
title: string, title: string,
@ -56,14 +61,14 @@ interface BookMetadataDto {
tagsLock: boolean tagsLock: boolean
} }
interface ReadProgressDto { export interface ReadProgressDto {
page: number, page: number,
completed: boolean, completed: boolean,
created: string, created: string,
lastModified: string lastModified: string
} }
interface BookMetadataUpdateDto { export interface BookMetadataUpdateDto {
title?: string, title?: string,
titleLock?: boolean, titleLock?: boolean,
summary?: string, summary?: string,
@ -80,17 +85,17 @@ interface BookMetadataUpdateDto {
tagsLock?: boolean tagsLock?: boolean
} }
interface AuthorDto { export interface AuthorDto {
name: string, name: string,
role: string role: string
} }
interface ReadProgressUpdateDto { export interface ReadProgressUpdateDto {
page?: number, page?: number,
completed?: boolean completed?: boolean
} }
interface BookFormat { export interface BookFormat {
type: string, type: string,
color: string color: string
} }

View file

@ -288,6 +288,7 @@ import {
import { shortcutsMenus, shortcutsSettings } from '@/functions/shortcuts/bookreader' import { shortcutsMenus, shortcutsSettings } from '@/functions/shortcuts/bookreader'
import { shortcutsAll } from '@/functions/shortcuts/reader' import { shortcutsAll } from '@/functions/shortcuts/reader'
import { shortcutsSettingsContinuous } from '@/functions/shortcuts/continuous-reader' import { shortcutsSettingsContinuous } from '@/functions/shortcuts/continuous-reader'
import { BookDto, PageDto, PageDtoWithUrl } from '@/types/komga-books'
const cookieFit = 'webreader.fit' const cookieFit = 'webreader.fit'
const cookieContinuousReaderFit = 'webreader.continuousReaderFit' const cookieContinuousReaderFit = 'webreader.continuousReaderFit'

View file

@ -12,14 +12,28 @@
<v-spacer/> <v-spacer/>
<!-- Context notification for navigation -->
<v-alert
v-if="contextReadList"
type="info"
text
dense
border="right"
class="mb-0"
>
Navigation within the readlist: {{ contextName }}
</v-alert>
<!-- Navigate to previous book -->
<v-btn <v-btn
icon icon
:disabled="$_.isEmpty(siblingPrevious)" :disabled="$_.isEmpty(siblingPrevious)"
:to="{ name: 'browse-book', params: { bookId: previousId } }" :to="{ name: 'browse-book', params: { bookId: previousId }, query: { context: context.origin, contextId: context.id} }"
> >
<v-icon>mdi-chevron-left</v-icon> <v-icon>mdi-chevron-left</v-icon>
</v-btn> </v-btn>
<!-- List of all books in context (series/readlist) for navigation -->
<v-menu bottom <v-menu bottom
offset-y offset-y
:max-height="$vuetify.breakpoint.height * .7" :max-height="$vuetify.breakpoint.height * .7"
@ -38,7 +52,7 @@
<v-list-item <v-list-item
v-for="(book, i) in siblings" v-for="(book, i) in siblings"
:key="i" :key="i"
:to="{ name: 'browse-book', params: { bookId: book.id } }" :to="{ name: 'browse-book', params: { bookId: book.id }, query: { context: context.origin, contextId: context.id} }"
> >
<v-list-item-title class="text-wrap text-body-2">{{ book.metadata.number }} - {{ book.metadata.title }} <v-list-item-title class="text-wrap text-body-2">{{ book.metadata.number }} - {{ book.metadata.title }}
</v-list-item-title> </v-list-item-title>
@ -47,10 +61,11 @@
</v-list> </v-list>
</v-menu> </v-menu>
<!-- Navigate to next book -->
<v-btn <v-btn
icon icon
:disabled="$_.isEmpty(siblingNext)" :disabled="$_.isEmpty(siblingNext)"
:to="{ name: 'browse-book', params: { bookId: nextId } }" :to="{ name: 'browse-book', params: { bookId: nextId }, query: { context: context.origin, contextId: context.id} }"
> >
<v-icon>mdi-chevron-right</v-icon> <v-icon>mdi-chevron-right</v-icon>
</v-btn> </v-btn>
@ -212,6 +227,8 @@ import { ReadStatus } from '@/types/enum-books'
import { BOOK_CHANGED, LIBRARY_DELETED } from '@/types/events' import { BOOK_CHANGED, LIBRARY_DELETED } from '@/types/events'
import Vue from 'vue' import Vue from 'vue'
import ReadListsExpansionPanels from '@/components/ReadListsExpansionPanels.vue' import ReadListsExpansionPanels from '@/components/ReadListsExpansionPanels.vue'
import { BookDto, BookFormat } from '@/types/komga-books'
import { Context, ContextOrigin } from '@/types/context'
export default Vue.extend({ export default Vue.extend({
name: 'BrowseBook', name: 'BrowseBook',
@ -220,6 +237,8 @@ export default Vue.extend({
return { return {
book: {} as BookDto, book: {} as BookDto,
series: {} as SeriesDto, series: {} as SeriesDto,
context: {} as Context,
contextName: '',
siblings: [] as BookDto[], siblings: [] as BookDto[],
siblingPrevious: {} as BookDto, siblingPrevious: {} as BookDto,
siblingNext: {} as BookDto, siblingNext: {} as BookDto,
@ -288,6 +307,9 @@ export default Vue.extend({
nextId (): string { nextId (): string {
return this.siblingNext?.id?.toString() || '0' return this.siblingNext?.id?.toString() || '0'
}, },
contextReadList (): boolean {
return this.context.origin === ContextOrigin.READLIST
},
}, },
methods: { methods: {
libraryDeleted (event: EventLibraryDeleted) { libraryDeleted (event: EventLibraryDeleted) {
@ -301,7 +323,30 @@ export default Vue.extend({
async loadBook (bookId: string) { async loadBook (bookId: string) {
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)
// parse query params to get context and contextId
if (this.$route.query.contextId && this.$route.query.context
&& Object.values(ContextOrigin).includes(this.$route.query.context as ContextOrigin)) {
this.context = {
origin: this.$route.query.context as ContextOrigin,
id: this.$route.query.contextId as string,
}
this.book.context = this.context
this.contextName = (await (this.$komgaReadLists.getOneReadList(this.context.id))).name
} else {
this.context = {
origin: ContextOrigin.SERIES,
id: this.book.seriesId,
}
}
// Get siblings depending on origin
if (this?.context.origin === ContextOrigin.SERIES) {
this.siblings = (await this.$komgaSeries.getBooks(this.book.seriesId, { unpaged: true } as PageRequest)).content this.siblings = (await this.$komgaSeries.getBooks(this.book.seriesId, { unpaged: true } as PageRequest)).content
} else if (this.context.origin === ContextOrigin.READLIST) {
this.siblings = (await this.$komgaReadLists.getBooks(this.context.id, { unpaged: true } as PageRequest)).content
}
this.readLists = await this.$komgaBooks.getReadLists(this.bookId) this.readLists = await this.$komgaBooks.getReadLists(this.bookId)
if (this.$_.has(this.book, 'metadata.title')) { if (this.$_.has(this.book, 'metadata.title')) {
@ -309,12 +354,20 @@ export default Vue.extend({
} }
try { try {
if (this?.context.origin === ContextOrigin.SERIES) {
this.siblingNext = await this.$komgaBooks.getBookSiblingNext(bookId) this.siblingNext = await this.$komgaBooks.getBookSiblingNext(bookId)
} else if (this.context.origin === ContextOrigin.READLIST) {
this.siblingNext = await this.$komgaReadLists.getBookSiblingNext(this.context.id, bookId)
}
} catch (e) { } catch (e) {
this.siblingNext = {} as BookDto this.siblingNext = {} as BookDto
} }
try { try {
if (this?.context.origin === ContextOrigin.SERIES) {
this.siblingPrevious = await this.$komgaBooks.getBookSiblingPrevious(bookId) this.siblingPrevious = await this.$komgaBooks.getBookSiblingPrevious(bookId)
} else if (this.context.origin === ContextOrigin.READLIST) {
this.siblingPrevious = await this.$komgaReadLists.getBookSiblingPrevious(this.context.id, bookId)
}
} catch (e) { } catch (e) {
this.siblingPrevious = {} as BookDto this.siblingPrevious = {} as BookDto
} }

View file

@ -80,6 +80,8 @@ import { BOOK_CHANGED, READLIST_CHANGED, READLIST_DELETED } from '@/types/events
import Vue from 'vue' import Vue from 'vue'
import ReadListActionsMenu from '@/components/menus/ReadListActionsMenu.vue' import ReadListActionsMenu from '@/components/menus/ReadListActionsMenu.vue'
import BooksMultiSelectBar from '@/components/bars/BooksMultiSelectBar.vue' import BooksMultiSelectBar from '@/components/bars/BooksMultiSelectBar.vue'
import { BookDto, ReadProgressUpdateDto } from '@/types/komga-books'
import { ContextOrigin } from '@/types/context'
export default Vue.extend({ export default Vue.extend({
name: 'BrowseReadList', name: 'BrowseReadList',
@ -156,6 +158,7 @@ export default Vue.extend({
async loadReadList (readListId: string) { async loadReadList (readListId: string) {
this.readList = await this.$komgaReadLists.getOneReadList(readListId) this.readList = await this.$komgaReadLists.getOneReadList(readListId)
this.books = (await this.$komgaReadLists.getBooks(readListId, { unpaged: true } as PageRequest)).content this.books = (await this.$komgaReadLists.getBooks(readListId, { unpaged: true } as PageRequest)).content
this.books.forEach((x: BookDto) => x.context = { origin: ContextOrigin.READLIST, id: readListId })
this.booksCopy = [...this.books] this.booksCopy = [...this.books]
this.selectedBooks = [] this.selectedBooks = []
}, },

View file

@ -205,6 +205,7 @@ import { ReadStatus } from '@/types/enum-books'
import { BOOK_CHANGED, LIBRARY_DELETED, READLIST_CHANGED, SERIES_CHANGED } from '@/types/events' import { BOOK_CHANGED, LIBRARY_DELETED, READLIST_CHANGED, SERIES_CHANGED } from '@/types/events'
import Vue from 'vue' import Vue from 'vue'
import { Location } from 'vue-router' import { Location } from 'vue-router'
import { BookDto } from '@/types/komga-books'
import { SeriesStatus } from '@/types/enum-series' import { SeriesStatus } from '@/types/enum-series'
import FilterDrawer from '@/components/FilterDrawer.vue' import FilterDrawer from '@/components/FilterDrawer.vue'
import FilterList from '@/components/FilterList.vue' import FilterList from '@/components/FilterList.vue'

View file

@ -111,6 +111,7 @@ import EmptyState from '@/components/EmptyState.vue'
import HorizontalScroller from '@/components/HorizontalScroller.vue' import HorizontalScroller from '@/components/HorizontalScroller.vue'
import ItemBrowser from '@/components/ItemBrowser.vue' import ItemBrowser from '@/components/ItemBrowser.vue'
import { ReadStatus } from '@/types/enum-books' import { ReadStatus } from '@/types/enum-books'
import { BookDto } from '@/types/komga-books'
import { BOOK_CHANGED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events' import { BOOK_CHANGED, LIBRARY_DELETED, SERIES_CHANGED } from '@/types/events'
import Vue from 'vue' import Vue from 'vue'

View file

@ -107,6 +107,7 @@ import ToolbarSticky from '@/components/bars/ToolbarSticky.vue'
import EmptyState from '@/components/EmptyState.vue' import EmptyState from '@/components/EmptyState.vue'
import HorizontalScroller from '@/components/HorizontalScroller.vue' import HorizontalScroller from '@/components/HorizontalScroller.vue'
import ItemBrowser from '@/components/ItemBrowser.vue' import ItemBrowser from '@/components/ItemBrowser.vue'
import { BookDto } from '@/types/komga-books'
import { import {
BOOK_CHANGED, BOOK_CHANGED,
COLLECTION_CHANGED, COLLECTION_CHANGED,

View file

@ -23,6 +23,7 @@
<script lang="ts"> <script lang="ts">
import Vue from 'vue' import Vue from 'vue'
import { MediaStatus } from '@/types/enum-books' import { MediaStatus } from '@/types/enum-books'
import { BookDto } from '@/types/komga-books'
export default Vue.extend({ export default Vue.extend({
name: 'SettingsMediaAnalysis', name: 'SettingsMediaAnalysis',