mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-06-26 10:49:00 +02:00
Add: More menu on book card #173, Fix: Download worker ffmpeg logs
This commit is contained in:
parent
7141f70aa5
commit
54570a3b27
10 changed files with 295 additions and 54 deletions
|
@ -1,5 +1,5 @@
|
|||
<template>
|
||||
<div class="relative">
|
||||
<div ref="wrapper" class="relative">
|
||||
<!-- New Book Flag -->
|
||||
<div v-show="isNew" class="absolute top-4 left-0 w-4 h-10 pr-2 bg-darkgreen box-shadow-xl z-20">
|
||||
<div class="absolute top-0 left-0 w-full h-full transform -rotate-90 flex items-center justify-center">
|
||||
|
@ -8,13 +8,13 @@
|
|||
<div class="absolute -bottom-4 left-0 triangle-right" />
|
||||
</div>
|
||||
|
||||
<div class="rounded-sm h-full overflow-hidden relative" :style="{ padding: `${paddingY}px ${paddingX}px` }" @click.stop>
|
||||
<div class="rounded-sm h-full overflow-hidden relative" :style="{ padding: `${paddingY}px ${paddingX}px` }">
|
||||
<nuxt-link :to="isSelectionMode ? '' : `/audiobook/${audiobookId}`" class="cursor-pointer">
|
||||
<div class="w-full relative box-shadow-book" :style="{ height: height + 'px' }" @click="clickCard" @mouseover="isHovering = true" @mouseleave="isHovering = false">
|
||||
<covers-book-cover :audiobook="audiobook" :author-override="authorFormat" :width="width" />
|
||||
|
||||
<!-- Hidden SM and DOWN -->
|
||||
<div v-show="isHovering || isSelectionMode" class="absolute top-0 left-0 w-full h-full bg-black rounded hidden md:block" :class="overlayWrapperClasslist">
|
||||
<div v-show="isHovering || isSelectionMode || isMoreMenuOpen" class="absolute top-0 left-0 w-full h-full bg-black rounded hidden md:block" :class="overlayWrapperClasslist">
|
||||
<div v-show="showPlayButton" class="h-full flex items-center justify-center">
|
||||
<div class="hover:text-gray-200 hover:scale-110 transform duration-200" @click.stop.prevent="play">
|
||||
<span class="material-icons" :style="{ fontSize: playIconFontSize + 'rem' }">play_circle_filled</span>
|
||||
|
@ -33,6 +33,11 @@
|
|||
<div class="absolute cursor-pointer hover:text-yellow-300 hover:scale-125 transform duration-100" :style="{ top: 0.375 * sizeMultiplier + 'rem', left: 0.375 * sizeMultiplier + 'rem' }" @click.stop.prevent="selectBtnClick">
|
||||
<span class="material-icons" :class="selected ? 'text-yellow-400' : ''" :style="{ fontSize: 1.25 * sizeMultiplier + 'rem' }">{{ selected ? 'radio_button_checked' : 'radio_button_unchecked' }}</span>
|
||||
</div>
|
||||
|
||||
<!-- More Icon -->
|
||||
<div ref="moreIcon" v-show="!isSelectionMode" class="hidden md:block absolute cursor-pointer hover:text-yellow-300" :style="{ bottom: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem' }" @click.stop.prevent="clickShowMore">
|
||||
<span class="material-icons" :style="{ fontSize: 1.2 * sizeMultiplier + 'rem' }">more_vert</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-if="volumeNumber && showVolumeNumber && !isHovering && !isSelectionMode" class="absolute rounded-lg bg-black bg-opacity-90 box-shadow-md" :style="{ top: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem` }">
|
||||
|
@ -43,7 +48,7 @@
|
|||
<div
|
||||
v-if="showSmallEBookIcon"
|
||||
class="absolute rounded-full bg-blue-500 flex items-center justify-center bg-opacity-90 hover:scale-125 transform duration-200"
|
||||
:style="{ bottom: 0.375 * sizeMultiplier + 'rem', right: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem`, width: 1.5 * sizeMultiplier + 'rem', height: 1.5 * sizeMultiplier + 'rem' }"
|
||||
:style="{ bottom: 0.375 * sizeMultiplier + 'rem', left: 0.375 * sizeMultiplier + 'rem', padding: `${0.1 * sizeMultiplier}rem ${0.25 * sizeMultiplier}rem`, width: 1.5 * sizeMultiplier + 'rem', height: 1.5 * sizeMultiplier + 'rem' }"
|
||||
@click.stop.prevent="clickReadEBook"
|
||||
>
|
||||
<!-- <p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }">EBook</p> -->
|
||||
|
@ -64,6 +69,9 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Vue from 'vue'
|
||||
import MoreMenu from '@/components/widgets/MoreMenu'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
audiobook: {
|
||||
|
@ -86,7 +94,10 @@ export default {
|
|||
},
|
||||
data() {
|
||||
return {
|
||||
isHovering: false
|
||||
isHovering: false,
|
||||
isMoreMenuOpen: false,
|
||||
isProcessingReadUpdate: false,
|
||||
rescanning: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -220,6 +231,46 @@ export default {
|
|||
},
|
||||
userCanDelete() {
|
||||
return this.$store.getters['user/getUserCanDelete']
|
||||
},
|
||||
userCanDownload() {
|
||||
return this.$store.getters['user/getUserCanDownload']
|
||||
},
|
||||
userIsRoot() {
|
||||
return this.$store.getters['user/getIsRoot']
|
||||
},
|
||||
moreMenuItems() {
|
||||
var items = [
|
||||
{
|
||||
func: 'toggleRead',
|
||||
text: `Mark as ${this.userIsRead ? 'Not Read' : 'Read'}`
|
||||
}
|
||||
]
|
||||
if (this.userCanUpdate) {
|
||||
if (this.hasTracks) {
|
||||
items.push({
|
||||
func: 'showEditModalTracks',
|
||||
text: 'Tracks'
|
||||
})
|
||||
}
|
||||
|
||||
items.push({
|
||||
func: 'showEditModalMatch',
|
||||
text: 'Match'
|
||||
})
|
||||
}
|
||||
if (this.userCanDownload) {
|
||||
items.push({
|
||||
func: 'showEditModalDownload',
|
||||
text: 'Download'
|
||||
})
|
||||
}
|
||||
if (this.userIsRoot) {
|
||||
items.push({
|
||||
func: 'rescan',
|
||||
text: 'Re-Scan'
|
||||
})
|
||||
}
|
||||
return items
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -248,6 +299,103 @@ export default {
|
|||
},
|
||||
clickReadEBook() {
|
||||
this.$store.commit('showEReader', this.audiobook)
|
||||
},
|
||||
toggleRead() {
|
||||
// More menu func
|
||||
var updatePayload = {
|
||||
isRead: !this.userIsRead
|
||||
}
|
||||
this.isProcessingReadUpdate = true
|
||||
this.$axios
|
||||
.$patch(`/api/user/audiobook/${this.audiobookId}`, updatePayload)
|
||||
.then(() => {
|
||||
this.isProcessingReadUpdate = false
|
||||
this.$toast.success(`"${this.title}" Marked as ${updatePayload.isRead ? 'Read' : 'Not Read'}`)
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed', error)
|
||||
this.isProcessingReadUpdate = false
|
||||
this.$toast.error(`Failed to mark as ${updatePayload.isRead ? 'Read' : 'Not Read'}`)
|
||||
})
|
||||
},
|
||||
audiobookScanComplete(result) {
|
||||
this.rescanning = false
|
||||
if (!result) {
|
||||
this.$toast.error(`Re-Scan Failed for "${this.title}"`)
|
||||
} else if (result === 'UPDATED') {
|
||||
this.$toast.success(`Re-Scan complete audiobook was updated`)
|
||||
} else if (result === 'UPTODATE') {
|
||||
this.$toast.success(`Re-Scan complete audiobook was up to date`)
|
||||
} else if (result === 'REMOVED') {
|
||||
this.$toast.error(`Re-Scan complete audiobook was removed`)
|
||||
}
|
||||
},
|
||||
rescan() {
|
||||
this.rescanning = true
|
||||
this.$root.socket.once('audiobook_scan_complete', this.audiobookScanComplete)
|
||||
this.$root.socket.emit('scan_audiobook', this.audiobookId)
|
||||
},
|
||||
showEditModalTracks() {
|
||||
// More menu func
|
||||
this.$store.commit('showEditModalOnTab', { audiobook: this.audiobook, tab: 'tracks' })
|
||||
},
|
||||
showEditModalMatch() {
|
||||
// More menu func
|
||||
this.$store.commit('showEditModalOnTab', { audiobook: this.audiobook, tab: 'match' })
|
||||
},
|
||||
showEditModalDownload() {
|
||||
// More menu func
|
||||
this.$store.commit('showEditModalOnTab', { audiobook: this.audiobook, tab: 'download' })
|
||||
},
|
||||
createMoreMenu() {
|
||||
if (!this.$refs.moreIcon) return
|
||||
|
||||
var ComponentClass = Vue.extend(MoreMenu)
|
||||
|
||||
var _this = this
|
||||
var instance = new ComponentClass({
|
||||
propsData: {
|
||||
items: this.moreMenuItems
|
||||
},
|
||||
created() {
|
||||
this.$on('action', (func) => {
|
||||
if (_this[func]) _this[func]()
|
||||
})
|
||||
this.$on('close', () => {
|
||||
_this.isMoreMenuOpen = false
|
||||
})
|
||||
}
|
||||
})
|
||||
instance.$mount()
|
||||
|
||||
var wrapperBox = this.$refs.moreIcon.getBoundingClientRect()
|
||||
var el = instance.$el
|
||||
|
||||
var elHeight = this.moreMenuItems.length * 28 + 2
|
||||
var elWidth = 130
|
||||
|
||||
var bottomOfIcon = wrapperBox.top + wrapperBox.height
|
||||
var rightOfIcon = wrapperBox.left + wrapperBox.width
|
||||
|
||||
var elTop = bottomOfIcon
|
||||
var elLeft = rightOfIcon
|
||||
if (bottomOfIcon + elHeight > window.innerHeight - 100) {
|
||||
elTop = wrapperBox.top - elHeight
|
||||
elLeft = wrapperBox.left
|
||||
}
|
||||
|
||||
if (rightOfIcon + elWidth > window.innerWidth - 100) {
|
||||
elLeft = rightOfIcon - elWidth
|
||||
}
|
||||
|
||||
el.style.top = elTop + 'px'
|
||||
el.style.left = elLeft + 'px'
|
||||
|
||||
this.isMoreMenuOpen = true
|
||||
document.body.appendChild(el)
|
||||
},
|
||||
clickShowMore() {
|
||||
this.createMoreMenu()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue