diff --git a/client/components/app/BookShelf.vue b/client/components/app/BookShelf.vue index 7010d21a..b11de5ab 100644 --- a/client/components/app/BookShelf.vue +++ b/client/components/app/BookShelf.vue @@ -36,7 +36,7 @@ - +
@@ -79,7 +79,10 @@ export default { rowPaddingX: 40, keywordFilterTimeout: null, scannerParseSubtitle: false, - wrapperClientWidth: 0 + wrapperClientWidth: 0, + observer: null, + booksObserved: [], + booksVisible: {} } }, watch: { @@ -351,6 +354,61 @@ export default { }, scan() { this.$root.socket.emit('scan', this.$store.state.libraries.currentLibraryId) + }, + mountedBookCard(entity, shouldUnobserve = false) { + if (!this.observer) { + console.error('Observer not loaded', entity.id) + return + } + var el = document.getElementById(`book-card-${entity.id}`) + if (el) { + if (shouldUnobserve) { + console.warn('Unobserving el', el) + this.observer.unobserve(el) + } + this.observer.observe(el) + this.booksObserved.push(entity.id) + // console.log('Book observed', this.booksObserved.length) + } else { + console.error('Could not get book card', entity.id) + } + }, + getBookCard(id) { + if (!this.$refs[id] || !this.$refs[id].length) { + return null + } + return this.$refs[id][0] + }, + observerCallback(entries, observer) { + entries.forEach((entry) => { + var bookId = entry.target.getAttribute('data-bookId') + if (!bookId) { + console.error('Invalid observe no book id', entry) + return + } + var component = this.getBookCard(entry.target.id) + if (component) { + if (entry.isIntersecting) { + if (!this.booksVisible[bookId]) { + this.booksVisible[bookId] = true + component.setShowCard(true) + } + } else if (this.booksVisible[bookId]) { + this.booksVisible[bookId] = false + component.setShowCard(false) + } + } else { + console.error('Could not get book card for id', entry.target.id) + } + }) + }, + initIO() { + let observerOptions = { + rootMargin: '0px', + threshold: 0.1 + } + + this.observer = new IntersectionObserver(this.observerCallback, observerOptions) } }, updated() { @@ -367,6 +425,18 @@ export default { this.$store.commit('user/addCollectionsListener', { id: 'bookshelf', meth: this.collectionsUpdated }) this.init() + this.initIO() + + setTimeout(() => { + var ids = {} + this.audiobooks.forEach((ab) => { + if (ids[ab.id]) { + console.error('FOUDN DUPLICATE ID', ids[ab.id], ab) + } else { + ids[ab.id] = ab + } + }) + }, 5000) }, beforeDestroy() { window.removeEventListener('resize', this.resize) diff --git a/client/components/cards/BookCard.vue b/client/components/cards/BookCard.vue index 4209524f..2c4e3536 100644 --- a/client/components/cards/BookCard.vue +++ b/client/components/cards/BookCard.vue @@ -1,70 +1,79 @@ @@ -90,14 +99,17 @@ export default { type: Number, default: 16 }, + isBookshelfBook: Boolean, showVolumeNumber: Boolean }, data() { return { + showCard: false, isHovering: false, isMoreMenuOpen: false, isProcessingReadUpdate: false, - rescanning: false + rescanning: false, + timesVisible: 0 } }, computed: { @@ -277,6 +289,10 @@ export default { } }, methods: { + setShowCard(val) { + if (val) this.timesVisible++ + this.showCard = val + }, selectBtnClick() { if (this.processingBatch) return this.$store.commit('toggleAudiobookSelected', this.audiobookId) @@ -404,6 +420,9 @@ export default { clickShowMore() { this.createMoreMenu() } + }, + mounted() { + this.showCard = !this.isBookshelfBook } } diff --git a/client/components/covers/BookCover.vue b/client/components/covers/BookCover.vue index b932a8fc..82203c6e 100644 --- a/client/components/covers/BookCover.vue +++ b/client/components/covers/BookCover.vue @@ -1,15 +1,30 @@