mirror of
https://github.com/gotson/komga.git
synced 2025-12-25 09:53:20 +01:00
refactor: carve out card visibility to mixin
This commit is contained in:
parent
1ebe86df9b
commit
2ca304847e
5 changed files with 39 additions and 28 deletions
5
komga-webui/package-lock.json
generated
5
komga-webui/package-lock.json
generated
|
|
@ -15670,6 +15670,11 @@
|
|||
"integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
|
||||
"dev": true
|
||||
},
|
||||
"vue-typed-mixins": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/vue-typed-mixins/-/vue-typed-mixins-0.2.0.tgz",
|
||||
"integrity": "sha512-0OxuinandPWv3nm5k/reYkuKtX3jjPZ40Sy9roJz0ih8PUzmI7zSRiXFEJ62LsyRegw9Tqy+qMkajk7ipKP8Vg=="
|
||||
},
|
||||
"vuelidate": {
|
||||
"version": "0.7.5",
|
||||
"resolved": "https://registry.npmjs.org/vuelidate/-/vuelidate-0.7.5.tgz",
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
"vue-cookies": "^1.6.1",
|
||||
"vue-line-clamp": "^1.3.2",
|
||||
"vue-router": "^3.1.4",
|
||||
"vue-typed-mixins": "^0.2.0",
|
||||
"vuelidate": "^0.7.5",
|
||||
"vuetify": "^2.2.4",
|
||||
"vuex": "^3.1.2",
|
||||
|
|
|
|||
21
komga-webui/src/mixins/VisibleElements.ts
Normal file
21
komga-webui/src/mixins/VisibleElements.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import Vue from 'vue'
|
||||
|
||||
const visibleElements = Vue.extend({
|
||||
data: () => {
|
||||
return {
|
||||
visibleElements: [] as number[]
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async onElementIntersect (entries: any, observer: any, isIntersecting: boolean) {
|
||||
const elementIndex = Number(entries[0].target.dataset['index'])
|
||||
if (isIntersecting) {
|
||||
this.visibleElements.push(elementIndex)
|
||||
} else {
|
||||
this.$_.pull(this.visibleElements, elementIndex)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
export default visibleElements
|
||||
|
|
@ -57,7 +57,7 @@
|
|||
:loading="s === null"
|
||||
type="card, text"
|
||||
class="ma-3 mx-2"
|
||||
v-intersect="onCardIntersect"
|
||||
v-intersect="onElementIntersect"
|
||||
:data-index="i"
|
||||
>
|
||||
<card-series :series="s" :width="cardWidth"/>
|
||||
|
|
@ -88,10 +88,11 @@ import SortMenuButton from '@/components/SortMenuButton.vue'
|
|||
import ToolbarSticky from '@/components/ToolbarSticky.vue'
|
||||
import { computeCardWidth } from '@/functions/grid-utilities'
|
||||
import { parseQuerySort } from '@/functions/query-params'
|
||||
import VisibleElements from '@/mixins/VisibleElements'
|
||||
import { LoadState, SeriesStatus } from '@/types/common'
|
||||
import Vue from 'vue'
|
||||
import mixins from 'vue-typed-mixins'
|
||||
|
||||
export default Vue.extend({
|
||||
export default mixins(VisibleElements).extend({
|
||||
name: 'BrowseLibraries',
|
||||
components: { LibraryActionsMenu, CardSeries, EmptyState, ToolbarSticky, SortMenuButton, Badge },
|
||||
data: () => {
|
||||
|
|
@ -100,7 +101,6 @@ export default Vue.extend({
|
|||
series: [] as SeriesDto[],
|
||||
pagesState: [] as LoadState[],
|
||||
pageSize: 20,
|
||||
visibleCards: [] as number[],
|
||||
totalElements: null as number | null,
|
||||
sortOptions: [{ name: 'Name', key: 'name' }, { name: 'Date added', key: 'createdDate' }, {
|
||||
name: 'Date updated',
|
||||
|
|
@ -128,7 +128,7 @@ export default Vue.extend({
|
|||
this.updateRoute()
|
||||
this.reloadData(this.libraryId)
|
||||
},
|
||||
async visibleCards (val) {
|
||||
async visibleElements (val) {
|
||||
for (const i of val) {
|
||||
const pageNumber = Math.floor(i / this.pageSize)
|
||||
if (this.pagesState[pageNumber] === undefined || this.pagesState[pageNumber] === LoadState.NotLoaded) {
|
||||
|
|
@ -182,18 +182,10 @@ export default Vue.extend({
|
|||
parseQueryFilterStatus (queryStatus: any): string[] {
|
||||
return queryStatus ? queryStatus.toString().split(',').filter((x: string) => Object.keys(SeriesStatus).includes(x)) : []
|
||||
},
|
||||
async onCardIntersect (entries: any, observer: any, isIntersecting: boolean) {
|
||||
const elementIndex = Number(entries[0].target.dataset['index'])
|
||||
if (isIntersecting) {
|
||||
this.visibleCards.push(elementIndex)
|
||||
} else {
|
||||
this.$_.pull(this.visibleCards, elementIndex)
|
||||
}
|
||||
},
|
||||
reloadData (libraryId: number) {
|
||||
this.totalElements = null
|
||||
this.pagesState = []
|
||||
this.visibleCards = []
|
||||
this.visibleElements = []
|
||||
this.series = Array(this.pageSize).fill(null)
|
||||
this.loadInitialData(libraryId)
|
||||
},
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@
|
|||
:loading="b === null"
|
||||
type="card, text"
|
||||
class="ma-3 mx-2"
|
||||
v-intersect="onCardIntersect"
|
||||
v-intersect="onElementIntersect"
|
||||
:data-index="i"
|
||||
>
|
||||
<card-book :book="b" :width="cardWidth"/>
|
||||
|
|
@ -94,10 +94,11 @@ import ToolbarSticky from '@/components/ToolbarSticky.vue'
|
|||
import { computeCardWidth } from '@/functions/grid-utilities'
|
||||
import { parseQuerySort } from '@/functions/query-params'
|
||||
import { seriesThumbnailUrl } from '@/functions/urls'
|
||||
import VisibleElements from '@/mixins/VisibleElements'
|
||||
import { LoadState } from '@/types/common'
|
||||
import Vue from 'vue'
|
||||
import mixins from 'vue-typed-mixins'
|
||||
|
||||
export default Vue.extend({
|
||||
export default mixins(VisibleElements).extend({
|
||||
name: 'BrowseSeries',
|
||||
components: { CardBook, ToolbarSticky, SortMenuButton, Badge },
|
||||
data: () => {
|
||||
|
|
@ -106,7 +107,6 @@ export default Vue.extend({
|
|||
books: [] as BookDto[],
|
||||
pagesState: [] as LoadState[],
|
||||
pageSize: 20,
|
||||
visibleCards: [] as number[],
|
||||
totalElements: null as number | null,
|
||||
sortOptions: [{ name: 'Number', key: 'number' }, { name: 'Date added', key: 'createdDate' }, {
|
||||
name: 'File size',
|
||||
|
|
@ -139,7 +139,7 @@ export default Vue.extend({
|
|||
this.updateRoute()
|
||||
this.reloadData(this.seriesId)
|
||||
},
|
||||
async visibleCards (val) {
|
||||
async visibleElements (val) {
|
||||
for (const i of val) {
|
||||
const pageNumber = Math.floor(i / this.pageSize)
|
||||
if (this.pagesState[pageNumber] === undefined || this.pagesState[pageNumber] === LoadState.NotLoaded) {
|
||||
|
|
@ -186,14 +186,6 @@ export default Vue.extend({
|
|||
parseQuerySortOrDefault (querySort: any): SortActive {
|
||||
return parseQuerySort(querySort, this.sortOptions) || this.$_.clone(this.sortDefault)
|
||||
},
|
||||
async onCardIntersect (entries: any, observer: any, isIntersecting: boolean) {
|
||||
const elementIndex = Number(entries[0].target.dataset['index'])
|
||||
if (isIntersecting) {
|
||||
this.visibleCards.push(elementIndex)
|
||||
} else {
|
||||
this.$_.pull(this.visibleCards, elementIndex)
|
||||
}
|
||||
},
|
||||
updateRoute (index?: string) {
|
||||
this.$router.replace({
|
||||
name: this.$route.name,
|
||||
|
|
@ -207,7 +199,7 @@ export default Vue.extend({
|
|||
reloadData (seriesId: number) {
|
||||
this.totalElements = null
|
||||
this.pagesState = []
|
||||
this.visibleCards = []
|
||||
this.visibleElements = []
|
||||
this.books = Array(this.pageSize).fill(null)
|
||||
this.loadInitialData(seriesId)
|
||||
},
|
||||
|
|
|
|||
Loading…
Reference in a new issue