mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2024-12-20 19:06:06 +01:00
Add: Experimental bookmarks edit and delete #115
This commit is contained in:
parent
fffa02e7e8
commit
9f66054a72
@ -20,7 +20,7 @@
|
|||||||
-webkit-font-feature-settings: 'liga';
|
-webkit-font-feature-settings: 'liga';
|
||||||
-webkit-font-smoothing: antialiased;
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
.material-icons:not(.text-sm):not(.text-md):not(.text-base):not(.text-lg):not(.text-xl):not(.text-2xl):not(.text-3xl):not(.text-4xl):not(.text-5xl):not(.text-6xl) {
|
.material-icons:not(.text-xs):not(.text-sm):not(.text-md):not(.text-base):not(.text-lg):not(.text-xl):not(.text-2xl):not(.text-3xl):not(.text-4xl):not(.text-5xl):not(.text-6xl) {
|
||||||
font-size: 1.5rem;
|
font-size: 1.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div v-if="showExperimentalFeatures" class="absolute top-0 bottom-0 h-full flex items-end" :class="chapters.length ? ' right-32' : 'right-20'">
|
<div v-if="showExperimentalFeatures" class="absolute top-0 bottom-0 h-full flex items-end" :class="chapters.length ? ' right-32' : 'right-20'">
|
||||||
<div class="cursor-pointer text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="showBookmarks">
|
<div class="cursor-pointer text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="showBookmarks">
|
||||||
<span class="material-icons text-3xl">{{ bookmarks.length ? 'bookmarks' : 'bookmark_border' }}</span>
|
<span class="material-icons" style="font-size: 1.7rem">{{ bookmarks.length ? 'bookmarks' : 'bookmark_border' }}</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="absolute top-0 bottom-0 h-full flex items-end" :class="!showExperimentalFeatures ? (chapters.length ? ' right-32' : 'right-20') : chapters.length ? ' right-44' : 'right-32'">
|
<div class="absolute top-0 bottom-0 h-full flex items-end" :class="!showExperimentalFeatures ? (chapters.length ? ' right-32' : 'right-20') : chapters.length ? ' right-44' : 'right-32'">
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
|
|
||||||
<audio-player ref="audioPlayer" :chapters="chapters" :loading="isLoading" :bookmarks="bookmarks" @close="cancelStream" @updateTime="updateTime" @loaded="(d) => (totalDuration = d)" @showBookmarks="showBookmarks" @hook:mounted="audioPlayerMounted" />
|
<audio-player ref="audioPlayer" :chapters="chapters" :loading="isLoading" :bookmarks="bookmarks" @close="cancelStream" @updateTime="updateTime" @loaded="(d) => (totalDuration = d)" @showBookmarks="showBookmarks" @hook:mounted="audioPlayerMounted" />
|
||||||
|
|
||||||
<modals-bookmarks-modal v-model="showBookmarksModal" :bookmarks="bookmarks" :audiobook-id="bookmarkAudiobookId" :current-time="bookmarkCurrentTime" @select="selectBookmark" @create="createBookmark" />
|
<modals-bookmarks-modal v-model="showBookmarksModal" :bookmarks="bookmarks" :audiobook-id="bookmarkAudiobookId" :current-time="bookmarkCurrentTime" @select="selectBookmark" @create="createBookmark" @update="updateBookmark" @delete="deleteBookmark" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -38,8 +38,7 @@ export default {
|
|||||||
totalDuration: 0,
|
totalDuration: 0,
|
||||||
showBookmarksModal: false,
|
showBookmarksModal: false,
|
||||||
bookmarkCurrentTime: 0,
|
bookmarkCurrentTime: 0,
|
||||||
bookmarkAudiobookId: null,
|
bookmarkAudiobookId: null
|
||||||
bookmarkTimeCreating: 0
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -103,24 +102,38 @@ export default {
|
|||||||
this.bookmarkCurrentTime = currentTime
|
this.bookmarkCurrentTime = currentTime
|
||||||
this.showBookmarksModal = true
|
this.showBookmarksModal = true
|
||||||
},
|
},
|
||||||
bookmarkCreated(time) {
|
// bookmarkCreated(time) {
|
||||||
if (time === this.bookmarkTimeCreating) {
|
// if (time === this.bookmarkTimeProcessing) {
|
||||||
this.bookmarkTimeCreating = 0
|
// this.bookmarkTimeProcessing = 0
|
||||||
this.$toast.success(`${this.$secondsToTimestamp(time)} Bookmarked`)
|
// this.$toast.success(`${this.$secondsToTimestamp(time)} Bookmarked`)
|
||||||
}
|
// }
|
||||||
},
|
// },
|
||||||
createBookmark(bookmark) {
|
createBookmark(bookmark) {
|
||||||
this.bookmarkTimeCreating = bookmark.time
|
// this.bookmarkTimeProcessing = bookmark.time
|
||||||
this.$root.socket.once('bookmark_created', this.bookmarkCreated)
|
|
||||||
this.$root.socket.emit('create_bookmark', bookmark)
|
this.$root.socket.emit('create_bookmark', bookmark)
|
||||||
this.showBookmarksModal = false
|
this.showBookmarksModal = false
|
||||||
},
|
},
|
||||||
|
// bookmarkUpdated(time) {
|
||||||
|
// if (time === this.bookmarkTimeProcessing) {
|
||||||
|
// this.bookmarkTimeProcessing = 0
|
||||||
|
// this.$toast.success(`Bookmark @${this.$secondsToTimestamp(time)} Updated`)
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
updateBookmark(bookmark) {
|
||||||
|
// this.bookmarkTimeProcessing = bookmark.time
|
||||||
|
this.$root.socket.emit('update_bookmark', bookmark)
|
||||||
|
this.showBookmarksModal = false
|
||||||
|
},
|
||||||
selectBookmark(bookmark) {
|
selectBookmark(bookmark) {
|
||||||
if (this.$refs.audioPlayer) {
|
if (this.$refs.audioPlayer) {
|
||||||
this.$refs.audioPlayer.selectBookmark(bookmark)
|
this.$refs.audioPlayer.selectBookmark(bookmark)
|
||||||
}
|
}
|
||||||
this.showBookmarksModal = false
|
this.showBookmarksModal = false
|
||||||
},
|
},
|
||||||
|
deleteBookmark(bookmark) {
|
||||||
|
this.$root.socket.emit('delete_bookmark', bookmark)
|
||||||
|
this.showBookmarksModal = false
|
||||||
|
},
|
||||||
filterByAuthor() {
|
filterByAuthor() {
|
||||||
if (this.$route.name !== 'index') {
|
if (this.$route.name !== 'index') {
|
||||||
this.$router.push(`/library/${this.libraryId || this.$store.state.libraries.currentLibraryId}/bookshelf`)
|
this.$router.push(`/library/${this.libraryId || this.$store.state.libraries.currentLibraryId}/bookshelf`)
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<div class="w-9 h-9 flex items-center justify-center rounded-full hover:bg-white hover:bg-opacity-10 cursor-pointer" @click="showBookmarkTitleInput = false">
|
<div class="w-9 h-9 flex items-center justify-center rounded-full hover:bg-white hover:bg-opacity-10 cursor-pointer" @click="showBookmarkTitleInput = false">
|
||||||
<span class="material-icons text-3xl">arrow_back</span>
|
<span class="material-icons text-3xl">arrow_back</span>
|
||||||
</div>
|
</div>
|
||||||
<p class="text-xl pl-2">New Bookmark</p>
|
<p class="text-xl pl-2">{{ selectedBookmark ? 'Edit Bookmark' : 'New Bookmark' }}</p>
|
||||||
<div class="flex-grow" />
|
<div class="flex-grow" />
|
||||||
<p class="text-xl font-mono">
|
<p class="text-xl font-mono">
|
||||||
{{ this.$secondsToTimestamp(currentTime) }}
|
{{ this.$secondsToTimestamp(currentTime) }}
|
||||||
@ -15,25 +15,18 @@
|
|||||||
<form @submit.prevent="submitBookmark">
|
<form @submit.prevent="submitBookmark">
|
||||||
<ui-text-input-with-label v-model="newBookmarkTitle" label="Note" />
|
<ui-text-input-with-label v-model="newBookmarkTitle" label="Note" />
|
||||||
<div class="flex justify-end mt-6">
|
<div class="flex justify-end mt-6">
|
||||||
<ui-btn color="success" class="w-1/2" type="submit">Create Bookmark</ui-btn>
|
<ui-btn color="success" class="w-1/2" type="submit">{{ selectedBookmark ? 'Update' : 'Create' }} Bookmark</ui-btn>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="w-full h-full" v-show="!showBookmarkTitleInput">
|
<div class="w-full h-full" v-show="!showBookmarkTitleInput">
|
||||||
<template v-for="bookmark in bookmarks">
|
<template v-for="bookmark in bookmarks">
|
||||||
<div :key="bookmark.id" :id="`bookmark-row-${bookmark.id}`" class="flex items-center px-4 py-4 justify-start cursor-pointer bg-opacity-20 hover:bg-bg relative" @click="clickBookmark(bookmark)">
|
<modals-bookmarks-bookmark-item :key="bookmark.id" :highlight="currentTime === bookmark.time" :bookmark="bookmark" @click="clickBookmark" @edit="editBookmark" @delete="deleteBookmark" />
|
||||||
<span class="material-icons text-white text-opacity-60">bookmark_border</span>
|
|
||||||
<p class="pl-2 pr-16 truncate">{{ bookmark.title }}</p>
|
|
||||||
|
|
||||||
<div class="absolute right-0 top-0 h-full flex items-center pr-4">
|
|
||||||
<span class="font-mono text-sm text-gray-300">{{ $secondsToTimestamp(bookmark.time) }}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<div v-if="!bookmarks.length" class="flex h-32 items-center justify-center">
|
<div v-if="!bookmarks.length" class="flex h-32 items-center justify-center">
|
||||||
<p class="text-xl">No Bookmarks</p>
|
<p class="text-xl">No Bookmarks</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex px-4 py-2 items-center text-center justify-between border-b border-white border-opacity-10 bg-blue-500 bg-opacity-20 cursor-pointer text-white text-opacity-80 hover:bg-opacity-40 hover:text-opacity-100" @click="createBookmark">
|
<div v-show="canCreateBookmark" class="flex px-4 py-2 items-center text-center justify-between border-b border-white border-opacity-10 bg-blue-500 bg-opacity-20 cursor-pointer text-white text-opacity-80 hover:bg-opacity-40 hover:text-opacity-100" @click="createBookmark">
|
||||||
<span class="material-icons">add</span>
|
<span class="material-icons">add</span>
|
||||||
<p class="text-base pl-2">Create Bookmark</p>
|
<p class="text-base pl-2">Create Bookmark</p>
|
||||||
<p class="text-sm font-mono">
|
<p class="text-sm font-mono">
|
||||||
@ -61,6 +54,7 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
|
selectedBookmark: null,
|
||||||
showBookmarkTitleInput: false,
|
showBookmarkTitleInput: false,
|
||||||
newBookmarkTitle: ''
|
newBookmarkTitle: ''
|
||||||
}
|
}
|
||||||
@ -81,22 +75,45 @@ export default {
|
|||||||
set(val) {
|
set(val) {
|
||||||
this.$emit('input', val)
|
this.$emit('input', val)
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
canCreateBookmark() {
|
||||||
|
return !this.bookmarks.find((bm) => bm.time === this.currentTime)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
editBookmark(bm) {
|
||||||
|
this.selectedBookmark = bm
|
||||||
|
this.newBookmarkTitle = bm.title
|
||||||
|
this.showBookmarkTitleInput = true
|
||||||
|
},
|
||||||
|
deleteBookmark(bm) {
|
||||||
|
var bookmark = { ...bm, audiobookId: this.audiobookId }
|
||||||
|
this.$emit('delete', bookmark)
|
||||||
|
},
|
||||||
clickBookmark(bm) {
|
clickBookmark(bm) {
|
||||||
this.$emit('select', bm)
|
this.$emit('select', bm)
|
||||||
},
|
},
|
||||||
createBookmark() {
|
createBookmark() {
|
||||||
|
this.selectedBookmark = null
|
||||||
|
this.newBookmarkTitle = this.$formatDate(Date.now(), 'MMM dd, yyyy HH:mm')
|
||||||
this.showBookmarkTitleInput = true
|
this.showBookmarkTitleInput = true
|
||||||
},
|
},
|
||||||
submitBookmark() {
|
submitBookmark() {
|
||||||
var bookmark = {
|
if (this.selectedBookmark) {
|
||||||
audiobookId: this.audiobookId,
|
if (this.selectedBookmark.title !== this.newBookmarkTitle) {
|
||||||
title: this.newBookmarkTitle,
|
var bookmark = { ...this.selectedBookmark }
|
||||||
time: this.currentTime
|
bookmark.audiobookId = this.audiobookId
|
||||||
|
bookmark.title = this.newBookmarkTitle
|
||||||
|
this.$emit('update', bookmark)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
var bookmark = {
|
||||||
|
audiobookId: this.audiobookId,
|
||||||
|
title: this.newBookmarkTitle,
|
||||||
|
time: this.currentTime
|
||||||
|
}
|
||||||
|
this.$emit('create', bookmark)
|
||||||
}
|
}
|
||||||
this.$emit('create', bookmark)
|
|
||||||
this.newBookmarkTitle = ''
|
this.newBookmarkTitle = ''
|
||||||
this.showBookmarkTitleInput = false
|
this.showBookmarkTitleInput = false
|
||||||
}
|
}
|
||||||
|
45
client/components/modals/bookmarks/BookmarkItem.vue
Normal file
45
client/components/modals/bookmarks/BookmarkItem.vue
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<template>
|
||||||
|
<div :key="bookmark.id" :id="`bookmark-row-${bookmark.id}`" class="flex items-center px-4 py-4 justify-start cursor-pointer hover:bg-bg relative" :class="highlight ? 'bg-bg bg-opacity-60' : ' bg-opacity-20'" @click="click" @mouseover="isHovering = true" @mouseleave="isHovering = false">
|
||||||
|
<span class="material-icons" :class="highlight ? 'text-success' : 'text-white text-opacity-60'">{{ highlight ? 'bookmark' : 'bookmark_border' }}</span>
|
||||||
|
<div class="flex-grow overflow-hidden">
|
||||||
|
<p class="pl-2 pr-2 truncate">{{ bookmark.title }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="h-full flex items-center w-16 justify-end">
|
||||||
|
<span class="font-mono text-sm text-gray-300">{{ $secondsToTimestamp(bookmark.time) }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="h-full flex items-center justify-end transform" :class="isHovering ? 'transition-transform translate-0 w-16' : 'translate-x-40 w-0'">
|
||||||
|
<span class="material-icons text-lg mr-2 text-gray-200 hover:text-yellow-400" @click.stop="editClick">edit</span>
|
||||||
|
<span class="material-icons text-lg text-gray-200 hover:text-error cursor-pointer" @click.stop="deleteClick">delete</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
bookmark: {
|
||||||
|
type: Object,
|
||||||
|
default: () => {}
|
||||||
|
},
|
||||||
|
highlight: Boolean
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
isHovering: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {},
|
||||||
|
methods: {
|
||||||
|
click() {
|
||||||
|
this.$emit('click', this.bookmark)
|
||||||
|
},
|
||||||
|
deleteClick() {
|
||||||
|
this.$emit('delete', this.bookmark)
|
||||||
|
},
|
||||||
|
editClick() {
|
||||||
|
this.$emit('edit', this.bookmark)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {}
|
||||||
|
}
|
||||||
|
</script>
|
@ -239,6 +239,12 @@ export default {
|
|||||||
download.status = this.$constants.DownloadStatus.EXPIRED
|
download.status = this.$constants.DownloadStatus.EXPIRED
|
||||||
this.$store.commit('downloads/addUpdateDownload', download)
|
this.$store.commit('downloads/addUpdateDownload', download)
|
||||||
},
|
},
|
||||||
|
showErrorToast(message) {
|
||||||
|
this.$toast.error(message)
|
||||||
|
},
|
||||||
|
showSuccessToast(message) {
|
||||||
|
this.$toast.success(message)
|
||||||
|
},
|
||||||
logEvtReceived(payload) {
|
logEvtReceived(payload) {
|
||||||
this.$store.commit('logs/logEvt', payload)
|
this.$store.commit('logs/logEvt', payload)
|
||||||
},
|
},
|
||||||
@ -303,6 +309,10 @@ export default {
|
|||||||
this.socket.on('download_killed', this.downloadKilled)
|
this.socket.on('download_killed', this.downloadKilled)
|
||||||
this.socket.on('download_expired', this.downloadExpired)
|
this.socket.on('download_expired', this.downloadExpired)
|
||||||
|
|
||||||
|
// Toast Listeners
|
||||||
|
this.socket.on('show_error_toast', this.showErrorToast)
|
||||||
|
this.socket.on('show_success_toast', this.showSuccessToast)
|
||||||
|
|
||||||
this.socket.on('log', this.logEvtReceived)
|
this.socket.on('log', this.logEvtReceived)
|
||||||
|
|
||||||
this.socket.on('backup_applied', this.backupApplied)
|
this.socket.on('backup_applied', this.backupApplied)
|
||||||
|
@ -11,6 +11,7 @@ const { version } = require('../package.json')
|
|||||||
// Utils
|
// Utils
|
||||||
const { ScanResult } = require('./utils/constants')
|
const { ScanResult } = require('./utils/constants')
|
||||||
const filePerms = require('./utils/filePerms')
|
const filePerms = require('./utils/filePerms')
|
||||||
|
const { secondsToTimestamp } = require('./utils/fileUtils')
|
||||||
const Logger = require('./Logger')
|
const Logger = require('./Logger')
|
||||||
|
|
||||||
// Classes
|
// Classes
|
||||||
@ -261,6 +262,8 @@ class Server {
|
|||||||
|
|
||||||
// Bookmarks
|
// Bookmarks
|
||||||
socket.on('create_bookmark', (payload) => this.createBookmark(socket, payload))
|
socket.on('create_bookmark', (payload) => this.createBookmark(socket, payload))
|
||||||
|
socket.on('update_bookmark', (payload) => this.updateBookmark(socket, payload))
|
||||||
|
socket.on('delete_bookmark', (payload) => this.deleteBookmark(socket, payload))
|
||||||
|
|
||||||
socket.on('test', () => {
|
socket.on('test', () => {
|
||||||
socket.emit('test_received', socket.id)
|
socket.emit('test_received', socket.id)
|
||||||
@ -481,15 +484,66 @@ class Server {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var userAudiobook = client.user.createBookmark(payload)
|
var userAudiobook = client.user.createBookmark(payload)
|
||||||
if (userAudiobook) {
|
if (!userAudiobook || userAudiobook.error) {
|
||||||
await this.db.updateEntity('user', client.user)
|
var failMessage = (userAudiobook ? userAudiobook.error : null) || 'Unknown Error'
|
||||||
|
socket.emit('show_error_toast', `Failed to create Bookmark: ${failMessage}`)
|
||||||
this.clientEmitter(client.user.id, 'bookmark_created', payload.time)
|
return
|
||||||
this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
|
|
||||||
id: userAudiobook.audiobookId,
|
|
||||||
data: userAudiobook || null
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await this.db.updateEntity('user', client.user)
|
||||||
|
|
||||||
|
socket.emit('show_success_toast', `${secondsToTimestamp(payload.time)} Bookmarked`)
|
||||||
|
|
||||||
|
this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
|
||||||
|
id: userAudiobook.audiobookId,
|
||||||
|
data: userAudiobook || null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateBookmark(socket, payload) {
|
||||||
|
var client = socket.sheepClient
|
||||||
|
if (!client || !client.user) {
|
||||||
|
Logger.error('[Server] updateBookmark invalid socket client')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var userAudiobook = client.user.updateBookmark(payload)
|
||||||
|
if (!userAudiobook || userAudiobook.error) {
|
||||||
|
var failMessage = (userAudiobook ? userAudiobook.error : null) || 'Unknown Error'
|
||||||
|
socket.emit('show_error_toast', `Failed to update Bookmark: ${failMessage}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.db.updateEntity('user', client.user)
|
||||||
|
|
||||||
|
socket.emit('show_success_toast', `Bookmark ${secondsToTimestamp(payload.time)} Updated`)
|
||||||
|
|
||||||
|
this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
|
||||||
|
id: userAudiobook.audiobookId,
|
||||||
|
data: userAudiobook || null
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async deleteBookmark(socket, payload) {
|
||||||
|
var client = socket.sheepClient
|
||||||
|
if (!client || !client.user) {
|
||||||
|
Logger.error('[Server] deleteBookmark invalid socket client')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var userAudiobook = client.user.deleteBookmark(payload)
|
||||||
|
if (!userAudiobook || userAudiobook.error) {
|
||||||
|
var failMessage = (userAudiobook ? userAudiobook.error : null) || 'Unknown Error'
|
||||||
|
socket.emit('show_error_toast', `Failed to delete Bookmark: ${failMessage}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
await this.db.updateEntity('user', client.user)
|
||||||
|
|
||||||
|
socket.emit('show_success_toast', `Bookmark ${secondsToTimestamp(payload.time)} Removed`)
|
||||||
|
|
||||||
|
this.clientEmitter(client.user.id, 'current_user_audiobook_update', {
|
||||||
|
id: userAudiobook.audiobookId,
|
||||||
|
data: userAudiobook || null
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async authenticateSocket(socket, token) {
|
async authenticateSocket(socket, token) {
|
||||||
|
@ -107,11 +107,26 @@ class AudiobookProgress {
|
|||||||
return hasUpdates
|
return hasUpdates
|
||||||
}
|
}
|
||||||
|
|
||||||
|
checkBookmarkExists(time) {
|
||||||
|
return this.bookmarks.find(bm => bm.time === time)
|
||||||
|
}
|
||||||
|
|
||||||
createBookmark(time, title) {
|
createBookmark(time, title) {
|
||||||
var newBookmark = new AudioBookmark()
|
var newBookmark = new AudioBookmark()
|
||||||
newBookmark.setData(time, title)
|
newBookmark.setData(time, title)
|
||||||
this.bookmarks.push(newBookmark)
|
this.bookmarks.push(newBookmark)
|
||||||
return newBookmark
|
return newBookmark
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateBookmark(time, title) {
|
||||||
|
var bookmark = this.bookmarks.find(bm => bm.time === time)
|
||||||
|
if (!bookmark) return false
|
||||||
|
bookmark.title = title
|
||||||
|
return bookmark
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteBookmark(time) {
|
||||||
|
this.bookmarks = this.bookmarks.filter(bm => bm.time !== time)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.exports = AudiobookProgress
|
module.exports = AudiobookProgress
|
@ -281,11 +281,52 @@ class User {
|
|||||||
|
|
||||||
createBookmark({ audiobookId, time, title }) {
|
createBookmark({ audiobookId, time, title }) {
|
||||||
if (!this.audiobooks || !this.audiobooks[audiobookId]) {
|
if (!this.audiobooks || !this.audiobooks[audiobookId]) {
|
||||||
return false
|
return {
|
||||||
|
error: 'Invalid Audiobook'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if (this.audiobooks[audiobookId].checkBookmarkExists(time)) {
|
||||||
|
return {
|
||||||
|
error: 'Bookmark already exists'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var success = this.audiobooks[audiobookId].createBookmark(time, title)
|
var success = this.audiobooks[audiobookId].createBookmark(time, title)
|
||||||
if (success) return this.audiobooks[audiobookId]
|
if (success) return this.audiobooks[audiobookId]
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
updateBookmark({ audiobookId, time, title }) {
|
||||||
|
if (!this.audiobooks || !this.audiobooks[audiobookId]) {
|
||||||
|
return {
|
||||||
|
error: 'Invalid Audiobook'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.audiobooks[audiobookId].checkBookmarkExists(time)) {
|
||||||
|
return {
|
||||||
|
error: 'Bookmark does not exist'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var success = this.audiobooks[audiobookId].updateBookmark(time, title)
|
||||||
|
if (success) return this.audiobooks[audiobookId]
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteBookmark({ audiobookId, time }) {
|
||||||
|
if (!this.audiobooks || !this.audiobooks[audiobookId]) {
|
||||||
|
return {
|
||||||
|
error: 'Invalid Audiobook'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!this.audiobooks[audiobookId].checkBookmarkExists(time)) {
|
||||||
|
return {
|
||||||
|
error: 'Bookmark does not exist'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.audiobooks[audiobookId].deleteBookmark(time)
|
||||||
|
return this.audiobooks[audiobookId]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
module.exports = User
|
module.exports = User
|
@ -69,7 +69,7 @@ function secondsToTimestamp(seconds) {
|
|||||||
_seconds -= _minutes * 60
|
_seconds -= _minutes * 60
|
||||||
var _hours = Math.floor(_minutes / 60)
|
var _hours = Math.floor(_minutes / 60)
|
||||||
_minutes -= _hours * 60
|
_minutes -= _hours * 60
|
||||||
_seconds = Math.round(_seconds)
|
_seconds = Math.floor(_seconds)
|
||||||
if (!_hours) {
|
if (!_hours) {
|
||||||
return `${_minutes}:${_seconds.toString().padStart(2, '0')}`
|
return `${_minutes}:${_seconds.toString().padStart(2, '0')}`
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user