mirror of
https://github.com/advplyr/audiobookshelf.git
synced 2025-03-22 11:27:11 +01:00
Add book item more menu item for Share, restrict share to admin or up, add admin socket events for open/close shares
This commit is contained in:
parent
e05ab14ad2
commit
2f2ec2ec1f
client
components
layouts
pages/item/_id
store
server
controllers
managers
models
utils/queries
@ -601,6 +601,30 @@ export default {
|
||||
this.executeRebuild()
|
||||
}
|
||||
},
|
||||
shareOpen(mediaItemShare) {
|
||||
if (this.entityName === 'items' || this.entityName === 'series-books') {
|
||||
var indexOf = this.entities.findIndex((ent) => ent?.media?.id === mediaItemShare.mediaItemId)
|
||||
if (indexOf >= 0) {
|
||||
if (this.entityComponentRefs[indexOf]) {
|
||||
const libraryItem = { ...this.entityComponentRefs[indexOf].libraryItem }
|
||||
libraryItem.mediaItemShare = mediaItemShare
|
||||
this.entityComponentRefs[indexOf].setEntity?.(libraryItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
shareClosed(mediaItemShare) {
|
||||
if (this.entityName === 'items' || this.entityName === 'series-books') {
|
||||
var indexOf = this.entities.findIndex((ent) => ent?.media?.id === mediaItemShare.mediaItemId)
|
||||
if (indexOf >= 0) {
|
||||
if (this.entityComponentRefs[indexOf]) {
|
||||
const libraryItem = { ...this.entityComponentRefs[indexOf].libraryItem }
|
||||
libraryItem.mediaItemShare = null
|
||||
this.entityComponentRefs[indexOf].setEntity?.(libraryItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
updatePagesLoaded() {
|
||||
let numPages = Math.ceil(this.totalEntities / this.booksPerFetch)
|
||||
for (let page = 0; page < numPages; page++) {
|
||||
@ -703,6 +727,8 @@ export default {
|
||||
this.$root.socket.on('playlist_added', this.playlistAdded)
|
||||
this.$root.socket.on('playlist_updated', this.playlistUpdated)
|
||||
this.$root.socket.on('playlist_removed', this.playlistRemoved)
|
||||
this.$root.socket.on('share_open', this.shareOpen)
|
||||
this.$root.socket.on('share_closed', this.shareClosed)
|
||||
} else {
|
||||
console.error('Bookshelf - Socket not initialized')
|
||||
}
|
||||
@ -730,6 +756,8 @@ export default {
|
||||
this.$root.socket.off('playlist_added', this.playlistAdded)
|
||||
this.$root.socket.off('playlist_updated', this.playlistUpdated)
|
||||
this.$root.socket.off('playlist_removed', this.playlistRemoved)
|
||||
this.$root.socket.off('share_open', this.shareOpen)
|
||||
this.$root.socket.off('share_closed', this.shareClosed)
|
||||
} else {
|
||||
console.error('Bookshelf - Socket not initialized')
|
||||
}
|
||||
|
@ -528,6 +528,12 @@ export default {
|
||||
func: 'openPlaylists',
|
||||
text: this.$strings.LabelAddToPlaylist
|
||||
})
|
||||
if (this.userIsAdminOrUp) {
|
||||
items.push({
|
||||
func: 'openShare',
|
||||
text: this.$strings.LabelShare
|
||||
})
|
||||
}
|
||||
}
|
||||
if (this.ebookFormat && this.store.state.libraries.ereaderDevices?.length) {
|
||||
items.push({
|
||||
@ -880,6 +886,10 @@ export default {
|
||||
this.store.commit('globals/setSelectedPlaylistItems', [{ libraryItem: this.libraryItem, episode: this.recentEpisode }])
|
||||
this.store.commit('globals/setShowPlaylistsModal', true)
|
||||
},
|
||||
openShare() {
|
||||
this.store.commit('setSelectedLibraryItem', this.libraryItem)
|
||||
this.store.commit('globals/setShareModal', this.mediaItemShare)
|
||||
},
|
||||
deleteLibraryItem() {
|
||||
const payload = {
|
||||
message: this.$strings.MessageConfirmDeleteLibraryItem,
|
||||
|
@ -89,6 +89,9 @@ export default {
|
||||
this.$emit('input', val)
|
||||
}
|
||||
},
|
||||
userIsAdminOrUp() {
|
||||
return this.$store.getters['user/getIsAdminOrUp']
|
||||
},
|
||||
libraryMediaType() {
|
||||
return this.$store.getters['libraries/getCurrentLibraryMediaType']
|
||||
},
|
||||
@ -148,7 +151,7 @@ export default {
|
||||
]
|
||||
},
|
||||
bookItems() {
|
||||
return [
|
||||
const items = [
|
||||
{
|
||||
text: this.$strings.LabelAll,
|
||||
value: 'all'
|
||||
@ -229,13 +232,16 @@ export default {
|
||||
text: this.$strings.LabelRSSFeedOpen,
|
||||
value: 'feed-open',
|
||||
sublist: false
|
||||
},
|
||||
{
|
||||
}
|
||||
]
|
||||
if (this.userIsAdminOrUp) {
|
||||
items.push({
|
||||
text: this.$strings.LabelShareOpen,
|
||||
value: 'share-open',
|
||||
sublist: false
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
return items
|
||||
},
|
||||
podcastItems() {
|
||||
return [
|
||||
|
@ -53,17 +53,7 @@
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: Boolean,
|
||||
libraryItem: {
|
||||
type: Object,
|
||||
default: () => null
|
||||
},
|
||||
mediaItemShare: {
|
||||
type: Object,
|
||||
default: () => null
|
||||
}
|
||||
},
|
||||
props: {},
|
||||
data() {
|
||||
return {
|
||||
processing: false,
|
||||
@ -99,12 +89,18 @@ export default {
|
||||
computed: {
|
||||
show: {
|
||||
get() {
|
||||
return this.value
|
||||
return this.$store.state.globals.showShareModal
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('input', val)
|
||||
this.$store.commit('globals/setShowShareModal', val)
|
||||
}
|
||||
},
|
||||
mediaItemShare() {
|
||||
return this.$store.state.globals.selectedMediaItemShare
|
||||
},
|
||||
libraryItem() {
|
||||
return this.$store.state.selectedLibraryItem
|
||||
},
|
||||
user() {
|
||||
return this.$store.state.user.user
|
||||
},
|
||||
|
@ -20,6 +20,7 @@
|
||||
<modals-batch-quick-match-model />
|
||||
<modals-rssfeed-open-close-modal />
|
||||
<modals-raw-cover-preview-modal />
|
||||
<modals-share-modal />
|
||||
<prompt-confirm />
|
||||
<readers-reader />
|
||||
</div>
|
||||
@ -598,4 +599,4 @@ export default {
|
||||
margin-left: 0px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
@ -147,7 +147,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<modals-share-modal v-model="showShareModal" :media-item-share="mediaItemShare" :library-item="libraryItem" @opened="openedShare" @removed="removedShare" />
|
||||
<modals-podcast-episode-feed v-model="showPodcastEpisodeFeed" :library-item="libraryItem" :episodes="podcastFeedEpisodes" />
|
||||
<modals-bookmarks-modal v-model="showBookmarksModal" :bookmarks="bookmarks" :library-item-id="libraryItemId" hide-create @select="selectBookmark" />
|
||||
</div>
|
||||
@ -186,8 +185,7 @@ export default {
|
||||
episodeDownloadsQueued: [],
|
||||
showBookmarksModal: false,
|
||||
isDescriptionClamped: false,
|
||||
showFullDescription: false,
|
||||
showShareModal: false
|
||||
showFullDescription: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@ -440,7 +438,7 @@ export default {
|
||||
})
|
||||
}
|
||||
|
||||
if (this.userIsAdminOrUp && !this.isPodcast) {
|
||||
if (this.userIsAdminOrUp && !this.isPodcast && this.tracks.length) {
|
||||
items.push({
|
||||
text: this.$strings.LabelShare,
|
||||
action: 'share'
|
||||
@ -458,12 +456,6 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openedShare(mediaItemShare) {
|
||||
this.mediaItemShare = mediaItemShare
|
||||
},
|
||||
removedShare() {
|
||||
this.mediaItemShare = null
|
||||
},
|
||||
selectBookmark(bookmark) {
|
||||
if (!bookmark) return
|
||||
if (this.isStreaming) {
|
||||
@ -682,6 +674,16 @@ export default {
|
||||
this.rssFeed = null
|
||||
}
|
||||
},
|
||||
shareOpen(mediaItemShare) {
|
||||
if (mediaItemShare.mediaItemId === this.media.id) {
|
||||
this.mediaItemShare = mediaItemShare
|
||||
}
|
||||
},
|
||||
shareClosed(mediaItemShare) {
|
||||
if (mediaItemShare.mediaItemId === this.media.id) {
|
||||
this.mediaItemShare = null
|
||||
}
|
||||
},
|
||||
queueBtnClick() {
|
||||
if (this.isQueued) {
|
||||
// Remove from queue
|
||||
@ -778,7 +780,8 @@ export default {
|
||||
} else if (action === 'sendToDevice') {
|
||||
this.sendToDevice(data)
|
||||
} else if (action === 'share') {
|
||||
this.showShareModal = true
|
||||
this.$store.commit('setSelectedLibraryItem', this.libraryItem)
|
||||
this.$store.commit('globals/setShareModal', this.mediaItemShare)
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -796,6 +799,8 @@ export default {
|
||||
this.$root.socket.on('item_updated', this.libraryItemUpdated)
|
||||
this.$root.socket.on('rss_feed_open', this.rssFeedOpen)
|
||||
this.$root.socket.on('rss_feed_closed', this.rssFeedClosed)
|
||||
this.$root.socket.on('share_open', this.shareOpen)
|
||||
this.$root.socket.on('share_closed', this.shareClosed)
|
||||
this.$root.socket.on('episode_download_queued', this.episodeDownloadQueued)
|
||||
this.$root.socket.on('episode_download_started', this.episodeDownloadStarted)
|
||||
this.$root.socket.on('episode_download_finished', this.episodeDownloadFinished)
|
||||
@ -805,6 +810,8 @@ export default {
|
||||
this.$root.socket.off('item_updated', this.libraryItemUpdated)
|
||||
this.$root.socket.off('rss_feed_open', this.rssFeedOpen)
|
||||
this.$root.socket.off('rss_feed_closed', this.rssFeedClosed)
|
||||
this.$root.socket.off('share_open', this.shareOpen)
|
||||
this.$root.socket.off('share_closed', this.shareClosed)
|
||||
this.$root.socket.off('episode_download_queued', this.episodeDownloadQueued)
|
||||
this.$root.socket.off('episode_download_started', this.episodeDownloadStarted)
|
||||
this.$root.socket.off('episode_download_finished', this.episodeDownloadFinished)
|
||||
|
@ -10,6 +10,7 @@ export const state = () => ({
|
||||
showEditPodcastEpisode: false,
|
||||
showViewPodcastEpisodeModal: false,
|
||||
showRSSFeedOpenCloseModal: false,
|
||||
showShareModal: false,
|
||||
showConfirmPrompt: false,
|
||||
showRawCoverPreviewModal: false,
|
||||
confirmPromptOptions: null,
|
||||
@ -22,6 +23,7 @@ export const state = () => ({
|
||||
selectedAuthor: null,
|
||||
selectedMediaItems: [],
|
||||
selectedRawCoverUrl: null,
|
||||
selectedMediaItemShare: null,
|
||||
isCasting: false, // Actively casting
|
||||
isChromecastInitialized: false, // Script loadeds
|
||||
showBatchQuickMatchModal: false,
|
||||
@ -157,6 +159,13 @@ export const mutations = {
|
||||
state.rssFeedEntity = entity
|
||||
state.showRSSFeedOpenCloseModal = true
|
||||
},
|
||||
setShowShareModal(state, val) {
|
||||
state.showShareModal = val
|
||||
},
|
||||
setShareModal(state, mediaItemShare) {
|
||||
state.selectedMediaItemShare = mediaItemShare
|
||||
state.showShareModal = true
|
||||
},
|
||||
setShowConfirmPrompt(state, val) {
|
||||
state.showConfirmPrompt = val
|
||||
},
|
||||
|
@ -43,7 +43,7 @@ class LibraryItemController {
|
||||
item.rssFeed = feedData?.toJSONMinified() || null
|
||||
}
|
||||
|
||||
if (item.mediaType === 'book' && includeEntities.includes('share')) {
|
||||
if (item.mediaType === 'book' && req.user.isAdminOrUp && includeEntities.includes('share')) {
|
||||
item.mediaItemShare = ShareManager.findByMediaItemId(item.media.id)
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
const Database = require('../Database')
|
||||
const Logger = require('../Logger')
|
||||
const SocketAuthority = require('../SocketAuthority')
|
||||
|
||||
/**
|
||||
* @typedef OpenMediaItemShareObject
|
||||
@ -136,6 +137,7 @@ class ShareManager {
|
||||
} else {
|
||||
this.openMediaItemShares.push({ id: mediaItemShare.id, mediaItemShare: mediaItemShare.toJSON() })
|
||||
}
|
||||
SocketAuthority.adminEmitter('share_open', mediaItemShare.toJSONForClient())
|
||||
}
|
||||
|
||||
/**
|
||||
@ -153,6 +155,12 @@ class ShareManager {
|
||||
this.openMediaItemShares = this.openMediaItemShares.filter((s) => s.id !== mediaItemShareId)
|
||||
this.openSharePlaybackSessions = this.openSharePlaybackSessions.filter((s) => s.mediaItemShareId !== mediaItemShareId)
|
||||
await this.destroyMediaItemShare(mediaItemShareId)
|
||||
|
||||
const mediaItemShareObjectForClient = { ...mediaItemShare.mediaItemShare }
|
||||
delete mediaItemShareObjectForClient.pash
|
||||
delete mediaItemShareObjectForClient.userId
|
||||
delete mediaItemShareObjectForClient.extraData
|
||||
SocketAuthority.adminEmitter('share_closed', mediaItemShareObjectForClient)
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -567,8 +567,8 @@ class LibraryItem extends Model {
|
||||
if (li.numEpisodesIncomplete) {
|
||||
oldLibraryItem.numEpisodesIncomplete = li.numEpisodesIncomplete
|
||||
}
|
||||
if (li.mediaType === 'book' && options.include?.includes?.('share')) {
|
||||
oldLibraryItem.mediaItemShare = ShareManager.findByMediaItemId(li.mediaId)
|
||||
if (li.mediaItemShare) {
|
||||
oldLibraryItem.mediaItemShare = li.mediaItemShare
|
||||
}
|
||||
|
||||
return oldLibraryItem
|
||||
|
@ -332,9 +332,9 @@ module.exports = {
|
||||
/**
|
||||
* Get library items for book media type using filter and sort
|
||||
* @param {string} libraryId
|
||||
* @param {[oldUser]} user
|
||||
* @param {[string]} filterGroup
|
||||
* @param {[string]} filterValue
|
||||
* @param {import('../../objects/user/User')} user
|
||||
* @param {string|null} filterGroup
|
||||
* @param {string|null} filterValue
|
||||
* @param {string} sortBy
|
||||
* @param {string} sortDesc
|
||||
* @param {boolean} collapseseries
|
||||
@ -356,7 +356,7 @@ module.exports = {
|
||||
sortBy = 'media.metadata.title'
|
||||
}
|
||||
const includeRSSFeed = include.includes('rssfeed')
|
||||
const includeMediaItemShare = include.includes('share')
|
||||
const includeMediaItemShare = !!user?.isAdminOrUp && include.includes('share')
|
||||
|
||||
// For sorting by author name an additional attribute must be added
|
||||
// with author names concatenated
|
||||
|
Loading…
Reference in New Issue
Block a user