Fix: Setting root socket error, Change: collection books table ordering and icons #151

This commit is contained in:
advplyr 2021-11-07 15:28:06 -06:00
parent d115382abe
commit 0980b6d5d5
12 changed files with 168 additions and 22 deletions

View File

@ -14,6 +14,9 @@
#librariesTable .item {
cursor: n-resize;
}
.drag-handle {
cursor: n-resize;
}
.list-group-item:not(.exclude) {
cursor: n-resize;
}

View File

@ -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) {

View File

@ -150,8 +150,6 @@ export default {
<style>
.list-complete-item {
transition: all 0.8s ease;
/* display: block;
margin-right: 10px; */
}
.list-complete-enter-from,

View File

@ -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>

View File

@ -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() {}

View File

@ -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()
}

View File

@ -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 {}

View File

@ -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)

View File

@ -1,6 +1,6 @@
{
"name": "audiobookshelf-client",
"version": "1.6.9",
"version": "1.6.10",
"description": "Audiobook manager and player",
"main": "index.js",
"scripts": {

View File

@ -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>

View File

@ -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)
}
}

View File

@ -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": {