2021-08-18 00:01:11 +02:00
< template >
2021-09-06 21:13:01 +02:00
< div class = "w-full h-full relative" >
2021-09-06 23:11:37 +02:00
< form class = "w-full h-full" @submit.prevent ="submitForm" >
< div ref = "formWrapper" class = "px-4 py-6 details-form-wrapper w-full overflow-hidden overflow-y-auto" >
2022-01-10 01:37:16 +01:00
< div class = "flex -mx-1" >
< div class = "w-1/2 px-1" >
< ui -text -input -with -label v -model = " details.title " label = "Title" / >
< / div >
< div class = "flex-grow px-1" >
< ui -text -input -with -label v -model = " details.subtitle " label = "Subtitle" / >
< / div >
< / div >
2021-09-05 02:58:39 +02:00
2021-09-06 21:13:01 +02:00
< div class = "flex mt-2 -mx-1" >
< div class = "w-3/4 px-1" >
< ui -text -input -with -label v -model = " details.author " label = "Author" / >
< / div >
< div class = "flex-grow px-1" >
< ui -text -input -with -label v -model = " details.publishYear " type = "number" label = "Publish Year" / >
< / div >
2021-08-20 02:14:24 +02:00
< / div >
2021-08-18 00:01:11 +02:00
2021-09-06 21:13:01 +02:00
< div class = "flex mt-2 -mx-1" >
< div class = "w-3/4 px-1" >
2021-12-02 02:07:03 +01:00
< ui -input -dropdown ref = "seriesDropdown" v -model = " details.series " label = "Series" :items ="series" / >
2021-09-06 21:13:01 +02:00
< / div >
< div class = "flex-grow px-1" >
< ui -text -input -with -label v -model = " details.volumeNumber " label = "Volume #" / >
< / div >
2021-08-25 03:24:40 +02:00
< / div >
2021-08-19 18:31:03 +02:00
2021-09-06 21:13:01 +02:00
< ui -textarea -with -label v -model = " details.description " :rows ="3" label = "Description" class = "mt-2" / >
2021-08-19 18:31:03 +02:00
2021-09-06 21:13:01 +02:00
< div class = "flex mt-2 -mx-1" >
< div class = "w-1/2 px-1" >
2021-12-02 02:07:03 +01:00
< ui -multi -select ref = "genresSelect" v -model = " details.genres " label = "Genres" :items ="genres" / >
2021-09-06 21:13:01 +02:00
< / div >
< div class = "flex-grow px-1" >
2021-12-02 02:07:03 +01:00
< ui -multi -select ref = "tagsSelect" v -model = " newTags " label = "Tags" :items ="tags" / >
2021-09-06 21:13:01 +02:00
< / div >
2021-08-22 15:52:37 +02:00
< / div >
2021-08-18 00:01:11 +02:00
2021-09-06 21:13:01 +02:00
< div class = "flex mt-2 -mx-1" >
2021-11-09 03:05:12 +01:00
< div class = "w-1/3 px-1" >
2021-10-07 04:08:52 +02:00
< ui -text -input -with -label v -model = " details.narrator " label = "Narrator" / >
2021-09-06 21:13:01 +02:00
< / div >
2021-11-09 03:05:12 +01:00
< div class = "w-1/3 px-1" >
< ui -text -input -with -label v -model = " details.publisher " label = "Publisher" / >
< / div >
< div class = "flex-grow px-1" >
2022-01-10 01:37:16 +01:00
< ui -text -input -with -label v -model = " details.language " label = "Language" / >
< / div >
< / div >
< div class = "flex mt-2 -mx-1" >
< div class = "w-1/3 px-1" >
2021-11-09 03:05:12 +01:00
< ui -text -input -with -label v -model = " details.isbn " label = "ISBN" / >
< / div >
2022-01-10 01:37:16 +01:00
< div class = "w-1/3 px-1" >
< ui -text -input -with -label v -model = " details.asin " label = "ASIN" / >
< / div >
2021-09-05 02:58:39 +02:00
< / div >
2021-09-06 23:11:37 +02:00
< / div >
2021-09-05 02:58:39 +02:00
2021-09-06 23:11:37 +02:00
< div class = "absolute bottom-0 left-0 w-full py-4 bg-bg" : class = "isScrollable ? 'box-shadow-md-up' : 'box-shadow-sm-up border-t border-primary border-opacity-50'" >
2021-10-27 01:35:37 +02:00
< div class = "flex items-center px-4" >
< ui -btn v-if ="userCanDelete" color="error" type="button" class="h-8" :padding-x="3" small @click.stop.prevent="deleteAudiobook" > Remove < / ui -btn >
2021-09-29 17:16:38 +02:00
2021-10-27 01:35:37 +02:00
< div class = "flex-grow" / >
2021-11-04 23:35:59 +01:00
< ui -tooltip v-if ="!isMissing" text="(Root User Only) Save a NFO metadata file in your audiobooks directory" direction="bottom" class="mr-4 hidden sm:block" >
2021-09-29 17:16:38 +02:00
< ui -btn v-if ="isRootUser" :loading="savingMetadata" color="bg" type="button" class="h-full" small @click.stop.prevent="saveMetadata" > Save Metadata < / ui -btn >
< / u i - t o o l t i p >
2021-10-27 01:35:37 +02:00
< ui -tooltip :disabled ="!!libraryScan" text = "(Root User Only) Rescan audiobook including metadata" direction = "bottom" class = "mr-4" >
2021-10-23 23:49:34 +02:00
< ui -btn v-if ="isRootUser" :loading="rescanning" :disabled="!!libraryScan" color="bg" type="button" class="h-full" small @click.stop.prevent="rescan" > Re -Scan < / ui -btn >
2021-10-01 01:52:32 +02:00
< / u i - t o o l t i p >
2021-09-06 23:11:37 +02:00
< ui -btn type = "submit" > Submit < / u i - b t n >
< / div >
2021-08-18 00:01:11 +02:00
< / div >
2021-09-06 23:11:37 +02:00
< / form >
2021-08-18 00:01:11 +02:00
< / div >
< / template >
< script >
export default {
props : {
processing : Boolean ,
audiobook : {
type : Object ,
default : ( ) => { }
}
} ,
data ( ) {
return {
details : {
title : null ,
2021-09-05 02:58:39 +02:00
subtitle : null ,
2021-08-18 00:01:11 +02:00
description : null ,
2021-08-19 18:31:03 +02:00
author : null ,
2021-10-07 04:08:52 +02:00
narrator : null ,
2021-08-19 18:31:03 +02:00
series : null ,
2021-08-25 03:24:40 +02:00
volumeNumber : null ,
2021-08-20 02:14:24 +02:00
publishYear : null ,
2021-11-09 03:05:12 +01:00
publisher : null ,
2022-01-10 01:37:16 +01:00
language : null ,
2021-11-09 03:05:12 +01:00
isbn : null ,
2022-01-10 01:37:16 +01:00
asin : null ,
2021-08-20 00:29:36 +02:00
genres : [ ]
2021-08-18 00:01:11 +02:00
} ,
2021-08-22 15:52:37 +02:00
newTags : [ ] ,
2021-09-06 21:13:01 +02:00
resettingProgress : false ,
2021-09-29 17:16:38 +02:00
isScrollable : false ,
2021-10-01 01:52:32 +02:00
savingMetadata : false ,
rescanning : false
2021-08-18 00:01:11 +02:00
}
} ,
watch : {
audiobook : {
immediate : true ,
handler ( newVal ) {
if ( newVal ) this . init ( )
}
}
} ,
computed : {
isProcessing : {
get ( ) {
return this . processing
} ,
set ( val ) {
this . $emit ( 'update:processing' , val )
}
} ,
2021-09-29 17:16:38 +02:00
isRootUser ( ) {
return this . $store . getters [ 'user/getIsRoot' ]
} ,
2021-10-27 00:55:48 +02:00
isMissing ( ) {
return ! ! this . audiobook && ! ! this . audiobook . isMissing
} ,
2021-08-18 00:01:11 +02:00
audiobookId ( ) {
return this . audiobook ? this . audiobook . id : null
} ,
book ( ) {
return this . audiobook ? this . audiobook . book || { } : { }
} ,
2021-09-07 00:42:15 +02:00
userCanDelete ( ) {
return this . $store . getters [ 'user/getUserCanDelete' ]
} ,
2021-08-22 15:52:37 +02:00
genres ( ) {
2021-12-02 02:07:03 +01:00
return this . filterData . genres || [ ]
2021-08-22 15:52:37 +02:00
} ,
tags ( ) {
2021-12-02 02:07:03 +01:00
return this . filterData . tags || [ ]
2021-08-22 15:52:37 +02:00
} ,
series ( ) {
2021-12-02 02:07:03 +01:00
return this . filterData . series || [ ]
} ,
filterData ( ) {
return this . $store . state . libraries . filterData || { }
2021-10-06 04:10:49 +02:00
} ,
libraryId ( ) {
return this . audiobook ? this . audiobook . libraryId : null
} ,
libraryScan ( ) {
if ( ! this . libraryId ) return null
return this . $store . getters [ 'scanners/getLibraryScan' ] ( this . libraryId )
2021-08-18 00:01:11 +02:00
}
} ,
methods : {
2021-10-01 01:52:32 +02:00
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 )
} ,
2021-09-29 17:16:38 +02:00
saveMetadataComplete ( result ) {
this . savingMetadata = false
if ( result . error ) {
this . $toast . error ( result . error )
} else if ( result . audiobookId ) {
var { savedPath } = result
if ( ! savedPath ) {
this . $toast . error ( ` Failed to save metadata file ( ${ result . audiobookId } ) ` )
} else {
this . $toast . success ( ` Metadata file saved " ${ result . audiobookTitle } " ` )
}
}
} ,
saveMetadata ( ) {
this . savingMetadata = true
this . $root . socket . once ( 'save_metadata_complete' , this . saveMetadataComplete )
this . $root . socket . emit ( 'save_metadata' , this . audiobookId )
} ,
2021-12-02 02:07:03 +01:00
submitForm ( ) {
2021-08-25 13:38:32 +02:00
if ( this . isProcessing ) {
return
}
2021-08-18 00:01:11 +02:00
this . isProcessing = true
2021-12-02 02:07:03 +01:00
if ( this . $refs . seriesDropdown && this . $refs . seriesDropdown . isFocused ) {
this . $refs . seriesDropdown . blur ( )
}
if ( this . $refs . genresSelect && this . $refs . genresSelect . isFocused ) {
this . $refs . genresSelect . forceBlur ( )
}
if ( this . $refs . tagsSelect && this . $refs . tagsSelect . isFocused ) {
this . $refs . tagsSelect . forceBlur ( )
}
this . $nextTick ( this . handleForm )
} ,
async handleForm ( ) {
2021-08-18 00:01:11 +02:00
const updatePayload = {
2021-08-22 15:52:37 +02:00
book : this . details ,
tags : this . newTags
2021-08-18 00:01:11 +02:00
}
2021-08-22 15:52:37 +02:00
2021-11-22 03:00:40 +01:00
var updatedAudiobook = await this . $axios . $patch ( ` /api/books/ ${ this . audiobook . id } ` , updatePayload ) . catch ( ( error ) => {
2021-08-18 00:01:11 +02:00
console . error ( 'Failed to update' , error )
return false
} )
this . isProcessing = false
if ( updatedAudiobook ) {
this . $toast . success ( 'Update Successful' )
this . $emit ( 'close' )
}
} ,
init ( ) {
this . details . title = this . book . title
2021-09-05 02:58:39 +02:00
this . details . subtitle = this . book . subtitle
2021-08-18 00:01:11 +02:00
this . details . description = this . book . description
this . details . author = this . book . author
2021-10-07 04:08:52 +02:00
this . details . narrator = this . book . narrator
2021-08-20 00:29:36 +02:00
this . details . genres = this . book . genres || [ ]
2021-08-19 18:31:03 +02:00
this . details . series = this . book . series
2021-08-25 03:24:40 +02:00
this . details . volumeNumber = this . book . volumeNumber
2021-08-20 02:14:24 +02:00
this . details . publishYear = this . book . publishYear
2021-11-09 03:05:12 +01:00
this . details . publisher = this . book . publisher || null
2022-01-10 01:37:16 +01:00
this . details . language = this . book . language || null
2021-11-09 03:05:12 +01:00
this . details . isbn = this . book . isbn || null
2022-01-10 01:37:16 +01:00
this . details . asin = this . book . asin || null
2021-08-22 15:52:37 +02:00
this . newTags = this . audiobook . tags || [ ]
2021-08-18 00:01:11 +02:00
} ,
deleteAudiobook ( ) {
2021-09-08 16:15:54 +02:00
if ( confirm ( ` Are you sure you want to remove this audiobook? \ n \ n*Does not delete your files, only removes the audiobook from AudioBookshelf ` ) ) {
2021-08-18 00:01:11 +02:00
this . isProcessing = true
this . $axios
2021-11-22 03:00:40 +01:00
. $delete ( ` /api/books/ ${ this . audiobookId } ` )
2021-08-18 00:01:11 +02:00
. then ( ( ) => {
console . log ( 'Audiobook removed' )
this . $toast . success ( 'Audiobook Removed' )
this . $emit ( 'close' )
this . isProcessing = false
} )
. catch ( ( error ) => {
console . error ( 'Remove Audiobook failed' , error )
this . isProcessing = false
} )
}
2021-09-06 21:13:01 +02:00
} ,
checkIsScrollable ( ) {
this . $nextTick ( ( ) => {
if ( this . $refs . formWrapper ) {
if ( this . $refs . formWrapper . scrollHeight > this . $refs . formWrapper . clientHeight ) {
this . isScrollable = true
} else {
this . isScrollable = false
}
}
} )
} ,
setResizeObserver ( ) {
try {
this . $nextTick ( ( ) => {
const resizeObserver = new ResizeObserver ( ( ) => {
this . checkIsScrollable ( )
} )
resizeObserver . observe ( this . $refs . formWrapper )
} )
} catch ( error ) {
console . error ( 'Failed to set resize observer' )
}
2021-08-18 00:01:11 +02:00
}
2021-09-06 21:13:01 +02:00
} ,
mounted ( ) {
this . setResizeObserver ( )
2021-08-18 00:01:11 +02:00
}
}
2021-09-06 21:13:01 +02:00
< / script >
< style scoped >
. details - form - wrapper {
height : calc ( 100 % - 70 px ) ;
2021-09-06 23:11:37 +02:00
max - height : calc ( 100 % - 70 px ) ;
2021-09-06 21:13:01 +02:00
}
< / style >