mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	* Update: `pages/items/_id` toast messages * Update: account modal strings * Update: audio file data modal strings * Update: sleep timer set string * Update: loading indicator string * Update: lazy book card strings * Reorder keys * Fix: syntax error in LazyBookCard * Fix: json ordering * Fix: fix double message definition * Update: login form toast strings * Update: batch delete toast * Update: collection add toast messages * Replace: toasts in BookShelfToolbar * Update: playlist edit toasts * Update: Details tab * Add: title required string * Update: ereader toasts * Update: author toasts, title and name required toasts * Clean up "no updates" strings * Change: slug strings * Update: cover modal toasts * Change: cancel encode toasts * Change: failed to share toasts * Simplify: "renameFail" and "removeFail" toasts * Fix: ordering * Change: chapters remove toast * Update: notification strings * Revert: loading indicator (error in browser) * Update: collectionBooksTable toast * Update: "failed to get" strings * Update: backup strings * Update: custom provider strings * Update: sessions strings * Update: email strings * Update sort display translation strings, update podcast episode queue strings to use translation * Fix loading indicator please wait translation * Consolidate translations and reduce number of toasts --------- Co-authored-by: advplyr <advplyr@protonmail.com>
		
			
				
	
	
		
			175 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			175 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | |
|   <modals-modal v-model="show" name="audiofile-data-modal" :width="700" :height="'unset'">
 | |
|     <div v-if="audioFile" ref="container" class="w-full rounded-lg bg-bg box-shadow-md overflow-y-auto overflow-x-hidden p-6" style="max-height: 80vh">
 | |
|       <div class="flex items-center justify-between">
 | |
|         <p class="text-base text-gray-200 truncate">{{ metadata.filename }}</p>
 | |
|         <ui-btn v-if="ffprobeData" small class="ml-2" @click="ffprobeData = null">{{ $strings.ButtonReset }}</ui-btn>
 | |
|         <ui-btn v-else-if="userIsAdminOrUp" small :loading="probingFile" class="ml-2" @click="getFFProbeData">{{ $strings.ButtonProbeAudioFile }}</ui-btn>
 | |
|       </div>
 | |
| 
 | |
|       <div class="w-full h-px bg-white bg-opacity-10 my-4" />
 | |
| 
 | |
|       <template v-if="!ffprobeData">
 | |
|         <ui-text-input-with-label :value="metadata.path" readonly :label="$strings.LabelPath" class="mb-4 text-sm" />
 | |
| 
 | |
|         <div class="flex flex-col sm:flex-row text-sm">
 | |
|           <div class="w-full sm:w-1/2">
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelSize }}
 | |
|               </p>
 | |
|               <p>{{ $bytesPretty(metadata.size) }}</p>
 | |
|             </div>
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelDuration }}
 | |
|               </p>
 | |
|               <p>{{ $secondsToTimestamp(audioFile.duration) }}</p>
 | |
|             </div>
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">{{ $strings.LabelFormat }}</p>
 | |
|               <p>{{ audioFile.format }}</p>
 | |
|             </div>
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelChapters }}
 | |
|               </p>
 | |
|               <p>{{ audioFile.chapters?.length || 0 }}</p>
 | |
|             </div>
 | |
|             <div v-if="audioFile.embeddedCoverArt" class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelEmbeddedCover }}
 | |
|               </p>
 | |
|               <p>{{ audioFile.embeddedCoverArt || '' }}</p>
 | |
|             </div>
 | |
|           </div>
 | |
|           <div class="w-full sm:w-1/2">
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelCodec }}
 | |
|               </p>
 | |
|               <p>{{ audioFile.codec }}</p>
 | |
|             </div>
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelChannels }}
 | |
|               </p>
 | |
|               <p>{{ audioFile.channels }} ({{ audioFile.channelLayout }})</p>
 | |
|             </div>
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelBitrate }}
 | |
|               </p>
 | |
|               <p>{{ $bytesPretty(audioFile.bitRate || 0, 0) }}</p>
 | |
|             </div>
 | |
|             <div class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">{{ $strings.LabelTimeBase }}</p>
 | |
|               <p>{{ audioFile.timeBase }}</p>
 | |
|             </div>
 | |
|             <div v-if="audioFile.language" class="flex mb-1">
 | |
|               <p class="w-32 text-black-50">
 | |
|                 {{ $strings.LabelLanguage }}
 | |
|               </p>
 | |
|               <p>{{ audioFile.language || '' }}</p>
 | |
|             </div>
 | |
|           </div>
 | |
|         </div>
 | |
| 
 | |
|         <div class="w-full h-px bg-white bg-opacity-10 my-4" />
 | |
| 
 | |
|         <p class="font-bold mb-2">{{ $strings.LabelMetaTags }}</p>
 | |
| 
 | |
|         <div v-for="(value, key) in metaTags" :key="key" class="flex mb-1 text-sm">
 | |
|           <p class="w-32 min-w-32 text-black-50 mb-1">
 | |
|             {{ key.replace('tag', '') }}
 | |
|           </p>
 | |
|           <p>{{ value }}</p>
 | |
|         </div>
 | |
|       </template>
 | |
|       <div v-else class="w-full">
 | |
|         <div class="relative">
 | |
|           <ui-textarea-with-label :value="prettyFfprobeData" readonly :rows="30" class="text-xs" />
 | |
| 
 | |
|           <button class="absolute top-4 right-4" :class="copiedToClipboard ? 'text-success' : 'text-white/50 hover:text-white/80'" @click.stop="copyFfprobeData">
 | |
|             <span class="material-symbols">{{ copiedToClipboard ? 'check' : 'content_copy' }}</span>
 | |
|           </button>
 | |
|         </div>
 | |
|       </div>
 | |
|     </div>
 | |
|   </modals-modal>
 | |
| </template>
 | |
| 
 | |
| <script>
 | |
| export default {
 | |
|   props: {
 | |
|     value: Boolean,
 | |
|     audioFile: {
 | |
|       type: Object,
 | |
|       default: () => {}
 | |
|     },
 | |
|     libraryItemId: String
 | |
|   },
 | |
|   data() {
 | |
|     return {
 | |
|       probingFile: false,
 | |
|       ffprobeData: null,
 | |
|       copiedToClipboard: false
 | |
|     }
 | |
|   },
 | |
|   watch: {
 | |
|     show(newVal) {
 | |
|       if (newVal) {
 | |
|         this.ffprobeData = null
 | |
|         this.copiedToClipboard = false
 | |
|         this.probingFile = false
 | |
|       }
 | |
|     }
 | |
|   },
 | |
|   computed: {
 | |
|     show: {
 | |
|       get() {
 | |
|         return this.value
 | |
|       },
 | |
|       set(val) {
 | |
|         this.$emit('input', val)
 | |
|       }
 | |
|     },
 | |
|     metadata() {
 | |
|       return this.audioFile?.metadata || {}
 | |
|     },
 | |
|     metaTags() {
 | |
|       return this.audioFile?.metaTags || {}
 | |
|     },
 | |
|     userIsAdminOrUp() {
 | |
|       return this.$store.getters['user/getIsAdminOrUp']
 | |
|     },
 | |
|     prettyFfprobeData() {
 | |
|       if (!this.ffprobeData) return ''
 | |
|       return JSON.stringify(this.ffprobeData, null, 2)
 | |
|     }
 | |
|   },
 | |
|   methods: {
 | |
|     getFFProbeData() {
 | |
|       this.probingFile = true
 | |
|       this.$axios
 | |
|         .$get(`/api/items/${this.libraryItemId}/ffprobe/${this.audioFile.ino}`)
 | |
|         .then((data) => {
 | |
|           console.log('Got ffprobe data', data)
 | |
|           this.ffprobeData = data
 | |
|         })
 | |
|         .catch((error) => {
 | |
|           console.error('Failed to get ffprobe data', error)
 | |
|           this.$toast.error(this.$strings.ToastFailedToLoadData)
 | |
|         })
 | |
|         .finally(() => {
 | |
|           this.probingFile = false
 | |
|         })
 | |
|     },
 | |
|     async copyFfprobeData() {
 | |
|       this.copiedToClipboard = await this.$copyToClipboard(this.prettyFfprobeData)
 | |
|     }
 | |
|   },
 | |
|   mounted() {}
 | |
| }
 | |
| </script>
 |