mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Fix: Setting root socket error, Change: collection books table ordering and icons #151
This commit is contained in:
parent
d115382abe
commit
0980b6d5d5
@ -14,6 +14,9 @@
|
||||
#librariesTable .item {
|
||||
cursor: n-resize;
|
||||
}
|
||||
.drag-handle {
|
||||
cursor: n-resize;
|
||||
}
|
||||
.list-group-item:not(.exclude) {
|
||||
cursor: n-resize;
|
||||
}
|
||||
|
@ -175,6 +175,7 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
goPrevBook() {
|
||||
console.log('GO PREV', this.currentBookshelfIndex)
|
||||
if (this.currentBookshelfIndex - 1 < 0) return
|
||||
var prevBookId = this.bookshelfBookIds[this.currentBookshelfIndex - 1]
|
||||
var prevBook = this.$store.getters['audiobooks/getAudiobook'](prevBookId)
|
||||
@ -186,6 +187,7 @@ export default {
|
||||
}
|
||||
},
|
||||
goNextBook() {
|
||||
console.log('GO NEXT', this.currentBookshelfIndex)
|
||||
if (this.currentBookshelfIndex >= this.bookshelfBookIds.length - 1) return
|
||||
|
||||
var nextBookId = this.bookshelfBookIds[this.currentBookshelfIndex + 1]
|
||||
@ -224,6 +226,7 @@ export default {
|
||||
}
|
||||
},
|
||||
hotkey(action) {
|
||||
console.log('HOTKEY', action)
|
||||
if (action === this.$hotkeys.Modal.NEXT_PAGE) {
|
||||
this.goNextBook()
|
||||
} else if (action === this.$hotkeys.Modal.PREV_PAGE) {
|
||||
|
@ -150,8 +150,6 @@ export default {
|
||||
<style>
|
||||
.list-complete-item {
|
||||
transition: all 0.8s ease;
|
||||
/* display: block;
|
||||
margin-right: 10px; */
|
||||
}
|
||||
|
||||
.list-complete-enter-from,
|
||||
|
@ -8,22 +8,39 @@
|
||||
<div class="flex-grow" />
|
||||
<p v-if="totalDuration">{{ totalDurationPretty }}</p>
|
||||
</div>
|
||||
<template v-for="book in books">
|
||||
<tables-collection-book-table-row :key="book.id" :book="book" />
|
||||
</template>
|
||||
<draggable v-model="books" v-bind="dragOptions" class="list-group" handle=".drag-handle" draggable=".item" tag="div" @start="drag = true" @end="drag = false" @update="draggableUpdate">
|
||||
<transition-group type="transition" :name="!drag ? 'list-complete' : null">
|
||||
<template v-for="book in books">
|
||||
<tables-collection-book-table-row :key="book.id" :book="book" :collection-id="collectionId" class="item list-complete-item" @edit="editBook" />
|
||||
</template>
|
||||
</transition-group>
|
||||
</draggable>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import draggable from 'vuedraggable'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
draggable
|
||||
},
|
||||
props: {
|
||||
collectionId: String,
|
||||
books: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
return {
|
||||
drag: false,
|
||||
dragOptions: {
|
||||
animation: 200,
|
||||
group: 'description',
|
||||
ghostClass: 'ghost'
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
totalDuration() {
|
||||
@ -37,7 +54,30 @@ export default {
|
||||
return this.$elapsedPretty(this.totalDuration)
|
||||
}
|
||||
},
|
||||
methods: {},
|
||||
methods: {
|
||||
draggableUpdate() {},
|
||||
editBook(book) {
|
||||
var bookIds = this.books.map((b) => b.id)
|
||||
this.$store.commit('setBookshelfBookIds', bookIds)
|
||||
this.$store.commit('showEditModal', book)
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.list-complete-item {
|
||||
transition: all 0.8s ease;
|
||||
}
|
||||
|
||||
.list-complete-enter-from,
|
||||
.list-complete-leave-to {
|
||||
opacity: 0;
|
||||
transform: translateY(30px);
|
||||
}
|
||||
|
||||
.list-complete-leave-active {
|
||||
position: absolute;
|
||||
}
|
||||
</style>
|
@ -1,6 +1,11 @@
|
||||
<template>
|
||||
<div class="w-full px-6 py-2" @mouseover="mouseover" @mouseleave="mouseleave" :class="isHovering ? 'bg-white bg-opacity-5' : ''">
|
||||
<div class="w-full px-2 py-2 overflow-hidden relative" @mouseover="mouseover" @mouseleave="mouseleave" :class="isHovering ? 'bg-white bg-opacity-5' : ''">
|
||||
<div v-if="book" class="flex h-20">
|
||||
<div class="w-16 max-w-16 h-full">
|
||||
<div class="flex h-full items-center justify-center">
|
||||
<span class="material-icons drag-handle text-xl">menu</span>
|
||||
</div>
|
||||
</div>
|
||||
<covers-book-cover :audiobook="book" :width="50" />
|
||||
<div class="w-80 h-full px-2 flex items-center">
|
||||
<div>
|
||||
@ -9,18 +14,38 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow flex items-center">
|
||||
<p>{{ bookDuration }}</p>
|
||||
<p class="font-mono text-sm">{{ bookDuration }}</p>
|
||||
</div>
|
||||
|
||||
<!-- <div class="w-12 flex items-center justify-center">
|
||||
<span class="material-icons text-lg text-white text-opacity-70 hover:text-opacity-100 cursor-pointer">radio_button_unchecked</span>
|
||||
</div> -->
|
||||
</div>
|
||||
<!-- <div class="absolute top-0 left-0 z-40 bg-red-500 w-full h-full">
|
||||
<div class="w-24 h-full absolute top-0 -right-24 transform transition-transform" :class="isHovering ? 'translate-x-0' : '-translate-x-24'">
|
||||
<span class="material-icons">edit</span>
|
||||
</div>
|
||||
</div> -->
|
||||
<div class="w-40 absolute top-0 -right-40 h-full transform transition-transform" :class="!isHovering ? 'translate-x-0' : '-translate-x-40'">
|
||||
<div class="flex h-full items-center">
|
||||
<ui-tooltip :text="isRead ? 'Mark as Not Read' : 'Mark as Read'" direction="top">
|
||||
<ui-read-icon-btn :disabled="isProcessingReadUpdate" :is-read="isRead" borderless class="mx-1 mt-0.5" @click="toggleRead" />
|
||||
</ui-tooltip>
|
||||
<div class="mx-1">
|
||||
<ui-icon-btn icon="edit" borderless @click="clickEdit" />
|
||||
</div>
|
||||
<div class="mx-1">
|
||||
<ui-icon-btn icon="close" borderless @click="removeClick" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
collectionId: String,
|
||||
book: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
@ -28,9 +53,19 @@ export default {
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
isProcessingReadUpdate: false,
|
||||
processingRemove: false,
|
||||
isHovering: false
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
userIsRead: {
|
||||
immediate: true,
|
||||
handler(newVal) {
|
||||
this.isRead = newVal
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
_book() {
|
||||
return this.book.book || {}
|
||||
@ -43,6 +78,15 @@ export default {
|
||||
},
|
||||
bookDuration() {
|
||||
return this.$secondsToTimestamp(this.book.duration)
|
||||
},
|
||||
userAudiobooks() {
|
||||
return this.$store.state.user.user ? this.$store.state.user.user.audiobooks || {} : {}
|
||||
},
|
||||
userAudiobook() {
|
||||
return this.userAudiobooks[this.book.id] || null
|
||||
},
|
||||
userIsRead() {
|
||||
return this.userAudiobook ? !!this.userAudiobook.isRead : false
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -51,6 +95,43 @@ export default {
|
||||
},
|
||||
mouseleave() {
|
||||
this.isHovering = false
|
||||
},
|
||||
clickRemove() {},
|
||||
clickEdit() {
|
||||
this.$emit('edit', this.book)
|
||||
},
|
||||
toggleRead() {
|
||||
var updatePayload = {
|
||||
isRead: !this.isRead
|
||||
}
|
||||
this.isProcessingReadUpdate = true
|
||||
this.$axios
|
||||
.$patch(`/api/user/audiobook/${this.book.id}`, 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'}`)
|
||||
})
|
||||
},
|
||||
removeClick() {
|
||||
this.processingRemove = true
|
||||
|
||||
this.$axios
|
||||
.$delete(`/api/collection/${this.collectionId}/book/${this.book.id}`)
|
||||
.then((updatedCollection) => {
|
||||
console.log(`Book removed from collection`, updatedCollection)
|
||||
this.$toast.success('Book removed from collection')
|
||||
this.processingRemove = false
|
||||
})
|
||||
.catch((error) => {
|
||||
console.error('Failed to remove book from collection', error)
|
||||
this.$toast.error('Failed to remove book from collection')
|
||||
this.processingRemove = false
|
||||
})
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<button class="icon-btn rounded-md border border-gray-600 flex items-center justify-center h-9 w-9 relative" :disabled="disabled" :class="className" @click="clickBtn">
|
||||
<button class="icon-btn rounded-md flex items-center justify-center h-9 w-9 relative" @mousedown.prevent :disabled="disabled" :class="className" @click="clickBtn">
|
||||
<span :class="outlined ? 'material-icons-outlined' : 'material-icons'" :style="{ fontSize }">{{ icon }}</span>
|
||||
</button>
|
||||
</template>
|
||||
@ -13,7 +13,8 @@ export default {
|
||||
type: String,
|
||||
default: 'primary'
|
||||
},
|
||||
outlined: Boolean
|
||||
outlined: Boolean,
|
||||
borderless: Boolean
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
@ -21,7 +22,9 @@ export default {
|
||||
computed: {
|
||||
className() {
|
||||
var classes = []
|
||||
classes.push(`bg-${this.bgColor}`)
|
||||
if (!this.borderless) {
|
||||
classes.push(`bg-${this.bgColor} border border-gray-600`)
|
||||
}
|
||||
return classes.join(' ')
|
||||
},
|
||||
fontSize() {
|
||||
@ -35,6 +38,7 @@ export default {
|
||||
e.preventDefault()
|
||||
return
|
||||
}
|
||||
e.preventDefault()
|
||||
this.$emit('click')
|
||||
e.stopPropagation()
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
<template>
|
||||
<button class="icon-btn rounded-md bg-primary border border-gray-600 flex items-center justify-center h-9 w-9 relative" @click="clickBtn">
|
||||
<button class="icon-btn rounded-md flex items-center justify-center h-9 w-9 relative" :class="borderless ? '' : 'bg-primary border border-gray-600'" @click="clickBtn">
|
||||
<div class="w-5 h-5 text-white relative">
|
||||
<svg v-if="isRead" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="rgb(63, 181, 68)">
|
||||
<path d="M19 1H5c-1.1 0-1.99.9-1.99 2L3 15.93c0 .69.35 1.3.88 1.66L12 23l8.11-5.41c.53-.36.88-.97.88-1.66L21 3c0-1.1-.9-2-2-2zm-9 15l-5-5 1.41-1.41L10 13.17l7.59-7.59L19 7l-9 9z" />
|
||||
@ -15,7 +15,8 @@
|
||||
export default {
|
||||
props: {
|
||||
isRead: Boolean,
|
||||
disabled: Boolean
|
||||
disabled: Boolean,
|
||||
borderless: Boolean
|
||||
},
|
||||
data() {
|
||||
return {}
|
||||
|
@ -309,7 +309,7 @@ export default {
|
||||
upgrade: false,
|
||||
reconnection: true
|
||||
})
|
||||
// this.$root.socket = this.socket
|
||||
this.$root.socket = this.socket
|
||||
|
||||
this.socket.on('connect', this.connect)
|
||||
this.socket.on('connect_error', this.connectError)
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "audiobookshelf-client",
|
||||
"version": "1.6.9",
|
||||
"version": "1.6.10",
|
||||
"description": "Audiobook manager and player",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
@ -23,7 +23,7 @@
|
||||
<p class="text-base text-gray-100">{{ description }}</p>
|
||||
</div>
|
||||
|
||||
<tables-collection-books-table :books="bookItems" />
|
||||
<tables-collection-books-table :books="bookItems" :collection-id="collection.id" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -47,13 +47,17 @@ export default {
|
||||
return redirect('/')
|
||||
}
|
||||
store.commit('user/addUpdateCollection', collection)
|
||||
collection.books.forEach((book) => {
|
||||
store.commit('audiobooks/addUpdate', book)
|
||||
})
|
||||
return {
|
||||
collection
|
||||
collectionId: collection.id
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
processingRemove: false
|
||||
processingRemove: false,
|
||||
collectionCopy: {}
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -68,6 +72,9 @@ export default {
|
||||
},
|
||||
description() {
|
||||
return this.collection.description || ''
|
||||
},
|
||||
collection() {
|
||||
return this.$store.getters['user/getCollection'](this.collectionId)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@ -90,8 +97,14 @@ export default {
|
||||
this.$toast.error(`Failed to remove collection`)
|
||||
})
|
||||
}
|
||||
},
|
||||
collectionsUpdated() {
|
||||
// this.collectionCopy = { ...this.collection }
|
||||
}
|
||||
},
|
||||
mounted() {}
|
||||
mounted() {
|
||||
// this.$store.commit('user/addCollectionsListener', { meth: this.collectionsUpdated, key: 'collection-page' })
|
||||
},
|
||||
beforeDestroy() {}
|
||||
}
|
||||
</script>
|
@ -51,6 +51,9 @@ export const getters = {
|
||||
if (!state.user) return false
|
||||
if (getters.getUserCanAccessAllLibraries) return true
|
||||
return getters.getLibrariesAccessible.includes(libraryId)
|
||||
},
|
||||
getCollection: state => id => {
|
||||
return state.collections.find(c => c.id === id)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "audiobookshelf",
|
||||
"version": "1.6.9",
|
||||
"version": "1.6.10",
|
||||
"description": "Self-hosted audiobook server for managing and playing audiobooks",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
|
Loading…
Reference in New Issue
Block a user