mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Merge pull request #1551 from mfcar/mf/alreadyInYourLibraryIndicator
Improve explicit label and add a AlreadyInYourLibrary indicator
This commit is contained in:
		
						commit
						d7b287bfed
					
				| @ -28,7 +28,11 @@ | ||||
|         </div> | ||||
|       </div> | ||||
|       <div v-else class="px-4 flex-grow"> | ||||
|         <h1>{{ book.title }}<widgets-explicit-indicator :explicit="book.explicit" /></h1> | ||||
|         <h1> | ||||
|           <div class="flex items-center"> | ||||
|             {{ book.title }}<widgets-explicit-indicator :explicit="book.explicit" /> | ||||
|           </div> | ||||
|         </h1> | ||||
|         <p class="text-base text-gray-300 whitespace-nowrap truncate">by {{ book.author }}</p> | ||||
|         <p v-if="book.genres" class="text-xs text-gray-400 leading-5">{{ book.genres.join(', ') }}</p> | ||||
|         <p class="text-xs text-gray-400 leading-5">{{ book.trackCount }} Episodes</p> | ||||
|  | ||||
| @ -7,9 +7,12 @@ | ||||
| 
 | ||||
|     <!-- Alternative bookshelf title/author/sort --> | ||||
|     <div v-if="isAlternativeBookshelfView || isAuthorBookshelfView" class="absolute left-0 z-50 w-full" :style="{ bottom: `-${titleDisplayBottomOffset}rem` }"> | ||||
|       <p class="truncate" :style="{ fontSize: 0.9 * sizeMultiplier + 'rem' }"> | ||||
|         {{ displayTitle }}<widgets-explicit-indicator :explicit="isExplicit" /> | ||||
|       </p> | ||||
|       <div :style="{ fontSize: 0.9 * sizeMultiplier + 'rem' }"> | ||||
|         <div class="flex items-center"> | ||||
|           <span class="truncate">{{ displayTitle }}</span> | ||||
|           <widgets-explicit-indicator :explicit="isExplicit" /> | ||||
|         </div> | ||||
|       </div> | ||||
|       <p class="truncate text-gray-400" :style="{ fontSize: 0.8 * sizeMultiplier + 'rem' }">{{ displayLineTwo || ' ' }}</p> | ||||
|       <p v-if="displaySortLine" class="truncate text-gray-400" :style="{ fontSize: 0.8 * sizeMultiplier + 'rem' }">{{ displaySortLine }}</p> | ||||
|     </div> | ||||
|  | ||||
							
								
								
									
										19
									
								
								client/components/widgets/AlreadyInLibraryIndicator.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								client/components/widgets/AlreadyInLibraryIndicator.vue
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,19 @@ | ||||
| <template> | ||||
|   <ui-tooltip v-if="alreadyInLibrary" :text="$strings.LabelAlreadyInYourLibrary" direction="top"> | ||||
|     <span class="material-icons ml-1" style="font-size: 0.8rem">check_circle</span> | ||||
|   </ui-tooltip> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
| export default { | ||||
|   props: { | ||||
|     alreadyInLibrary: Boolean | ||||
|   }, | ||||
|   data() { | ||||
|     return {} | ||||
|   }, | ||||
|   computed: {}, | ||||
|   methods: {}, | ||||
|   mounted() {} | ||||
| } | ||||
| </script> | ||||
| @ -1,5 +1,7 @@ | ||||
| <template> | ||||
|   <span v-if="explicit" class="material-icons ml-1" style="font-size: 0.8rem">explicit</span> | ||||
|   <ui-tooltip v-if="explicit" :text="$strings.LabelExplicit" direction="top"> | ||||
|     <span class="material-icons ml-1" style="font-size: 0.8rem">explicit</span> | ||||
|   </ui-tooltip> | ||||
| </template> | ||||
| 
 | ||||
| <script> | ||||
|  | ||||
| @ -25,7 +25,10 @@ | ||||
|           <div class="flex justify-center"> | ||||
|             <div class="mb-4"> | ||||
|               <h1 class="text-2xl md:text-3xl font-semibold"> | ||||
|                 {{ title }}<widgets-explicit-indicator :explicit="isExplicit" /> | ||||
|                 <div class="flex items-center"> | ||||
|                   {{ title }} | ||||
|                   <widgets-explicit-indicator :explicit="isExplicit" /> | ||||
|                 </div> | ||||
|               </h1> | ||||
| 
 | ||||
|               <p v-if="bookSubtitle" class="text-gray-200 text-xl md:text-2xl">{{ bookSubtitle }}</p> | ||||
|  | ||||
| @ -14,15 +14,19 @@ | ||||
|               <div class="flex md:hidden mb-2"> | ||||
|                 <covers-preview-cover :src="$store.getters['globals/getLibraryItemCoverSrcById'](episode.libraryItemId)" :width="48" :book-cover-aspect-ratio="bookCoverAspectRatio" :show-resolution="false" class="md:hidden" /> | ||||
|                 <div class="flex-grow px-2"> | ||||
|                   <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link><widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> | ||||
| 
 | ||||
|                   <div class="flex items-center"> | ||||
|                     <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link> | ||||
|                     <widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> | ||||
|                   </div> | ||||
|                   <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p> | ||||
|                 </div> | ||||
|               </div> | ||||
|               <!-- desktop --> | ||||
|               <div class="hidden md:block"> | ||||
|                 <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link><widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> | ||||
| 
 | ||||
|                 <div class="flex items-center"> | ||||
|                   <nuxt-link :to="`/item/${episode.libraryItemId}`" class="text-sm text-gray-200 hover:underline">{{ episode.podcast.metadata.title }}</nuxt-link> | ||||
|                   <widgets-explicit-indicator :explicit="episode.podcast.metadata.explicit" /> | ||||
|                 </div> | ||||
|                 <p class="text-xs text-gray-300 mb-1">{{ $dateDistanceFromNow(episode.publishedAt) }}</p> | ||||
|               </div> | ||||
| 
 | ||||
|  | ||||
| @ -5,13 +5,12 @@ | ||||
|     <div id="bookshelf" class="w-full overflow-y-auto px-2 py-6 sm:px-4 md:p-12 relative"> | ||||
|       <div class="w-full max-w-4xl mx-auto flex"> | ||||
|         <form @submit.prevent="submit" class="flex flex-grow"> | ||||
|           <ui-text-input v-model="searchInput" :disabled="processing" placeholder="Enter search term or RSS feed URL" class="flex-grow mr-2 text-sm md:text-base" /> | ||||
|           <ui-text-input v-model="searchInput" type="search" :disabled="processing" placeholder="Enter search term or RSS feed URL" class="flex-grow mr-2 text-sm md:text-base" /> | ||||
|           <ui-btn type="submit" :disabled="processing" class="hidden md:block">{{ $strings.ButtonSubmit }}</ui-btn> | ||||
|           <ui-btn type="submit" :disabled="processing" class="block md:hidden" small>{{ $strings.ButtonSubmit }}</ui-btn> | ||||
|         </form> | ||||
|         <ui-file-input ref="fileInput" :accept="'.opml, .txt'" class="ml-2" @change="opmlFileUpload">{{ $strings.ButtonUploadOPMLFile }}</ui-file-input> | ||||
|       </div> | ||||
| 
 | ||||
|       <div class="w-full max-w-3xl mx-auto py-4"> | ||||
|         <p v-if="termSearched && !results.length && !processing" class="text-center text-xl">{{ $strings.MessageNoPodcastsFound }}</p> | ||||
|         <template v-for="podcast in results"> | ||||
| @ -20,7 +19,11 @@ | ||||
|               <img v-if="podcast.cover" :src="podcast.cover" class="h-full w-full" /> | ||||
|             </div> | ||||
|             <div class="flex-grow pl-4 max-w-2xl"> | ||||
|               <a :href="podcast.pageUrl" class="text-base md:text-lg text-gray-200 hover:underline" target="_blank" @click.stop>{{ podcast.title }}</a><widgets-explicit-indicator :explicit="podcast.explicit" /> | ||||
|               <div class="flex items-center"> | ||||
|                 <a :href="podcast.pageUrl" class="text-base md:text-lg text-gray-200 hover:underline" target="_blank" @click.stop>{{ podcast.title }}</a> | ||||
|                 <widgets-explicit-indicator :explicit="podcast.explicit" /> | ||||
|                 <widgets-already-in-library-indicator :already-in-library="podcast.alreadyInLibrary"/> | ||||
|               </div> | ||||
|               <p class="text-sm md:text-base text-gray-300 whitespace-nowrap truncate">by {{ podcast.artistName }}</p> | ||||
|               <p class="text-xs text-gray-400 leading-5">{{ podcast.genres.join(', ') }}</p> | ||||
|               <p class="text-xs text-gray-400 leading-5">{{ podcast.trackCount }} {{ $strings.HeaderEpisodes }}</p> | ||||
| @ -68,10 +71,14 @@ export default { | ||||
|       selectedPodcast: null, | ||||
|       selectedPodcastFeed: null, | ||||
|       showOPMLFeedsModal: false, | ||||
|       opmlFeeds: [] | ||||
|       opmlFeeds: [], | ||||
|       existentPodcasts: [] | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     currentLibraryId() { | ||||
|       return this.$store.state.libraries.currentLibraryId | ||||
|     }, | ||||
|     streamLibraryItem() { | ||||
|       return this.$store.state.streamLibraryItem | ||||
|     } | ||||
| @ -144,6 +151,12 @@ export default { | ||||
|         return [] | ||||
|       }) | ||||
|       console.log('Got results', results) | ||||
|       for (let result of results) { | ||||
|         let podcast = this.existentPodcasts.find((p) => p.itunesId === result.id || p.title === result.title.toLowerCase()) | ||||
|         if (podcast) { | ||||
|           result.alreadyInLibrary = true | ||||
|         } | ||||
|       } | ||||
|       this.results = results | ||||
|       this.termSearched = term | ||||
|       this.processing = false | ||||
| @ -167,8 +180,25 @@ export default { | ||||
|       this.selectedPodcast = podcast | ||||
|       this.showNewPodcastModal = true | ||||
|       console.log('Got podcast feed', payload.podcast) | ||||
|     }, | ||||
|     async fetchExistentPodcastsInYourLibrary() { | ||||
|       this.processing = true | ||||
| 
 | ||||
|       const podcasts = await this.$axios.$get(`/api/libraries/${this.currentLibraryId}/items?page=0&minified=1`).catch((error) => { | ||||
|         console.error('Failed to fetch podcasts', error) | ||||
|         return [] | ||||
|       }) | ||||
|       this.existentPodcasts = podcasts.results.map((p) => { | ||||
|         return { | ||||
|           title: p.media.metadata.title.toLowerCase(), | ||||
|           itunesId: p.media.metadata.itunesId | ||||
|         } | ||||
|       }) | ||||
|       this.processing = false | ||||
|     } | ||||
|   }, | ||||
|   mounted() {} | ||||
|   mounted() { | ||||
|     this.fetchExistentPodcastsInYourLibrary() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "Füge {0} Hörbüch(er)/Podcast(s) der Wiedergabeliste hinzu", | ||||
|   "LabelAll": "Alle", | ||||
|   "LabelAllUsers": "Alle Benutzer", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Anhängen", | ||||
|   "LabelAuthor": "Autor", | ||||
|   "LabelAuthorFirstLast": "Autor (Vorname Nachname)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "Add {0} Items to Playlist", | ||||
|   "LabelAll": "All", | ||||
|   "LabelAllUsers": "All Users", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Append", | ||||
|   "LabelAuthor": "Author", | ||||
|   "LabelAuthorFirstLast": "Author (First Last)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "Add {0} Items to Playlist", | ||||
|   "LabelAll": "All", | ||||
|   "LabelAllUsers": "All Users", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Append", | ||||
|   "LabelAuthor": "Author", | ||||
|   "LabelAuthorFirstLast": "Author (First Last)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "{0} éléments ajoutés à la liste de lecture", | ||||
|   "LabelAll": "Tout", | ||||
|   "LabelAllUsers": "Tous les utilisateurs", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Ajouter", | ||||
|   "LabelAuthor": "Auteur", | ||||
|   "LabelAuthorFirstLast": "Auteur (Prénom Nom)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "Add {0} Items to Playlist", | ||||
|   "LabelAll": "All", | ||||
|   "LabelAllUsers": "Svi korisnici", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Append", | ||||
|   "LabelAuthor": "Autor", | ||||
|   "LabelAuthorFirstLast": "Author (First Last)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "Aggiungi {0} file alla Playlist", | ||||
|   "LabelAll": "Tutti", | ||||
|   "LabelAllUsers": "Tutti gli Utenti", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Appese", | ||||
|   "LabelAuthor": "Autore", | ||||
|   "LabelAuthorFirstLast": "Autore (Per Nome)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "Add {0} Items to Playlist", | ||||
|   "LabelAll": "All", | ||||
|   "LabelAllUsers": "Wszyscy użytkownicy", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Append", | ||||
|   "LabelAuthor": "Autor", | ||||
|   "LabelAuthorFirstLast": "Autor (Rosnąco)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "Добавить {0} Элементов в Плейлист", | ||||
|   "LabelAll": "Все", | ||||
|   "LabelAllUsers": "Все пользователи", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "Добавить", | ||||
|   "LabelAuthor": "Автор", | ||||
|   "LabelAuthorFirstLast": "Автор (Имя Фамилия)", | ||||
|  | ||||
| @ -163,6 +163,7 @@ | ||||
|   "LabelAddToPlaylistBatch": "添加 {0} 个项目到播放列表", | ||||
|   "LabelAll": "全部", | ||||
|   "LabelAllUsers": "所有用户", | ||||
|   "LabelAlreadyInYourLibrary": "Already in your library", | ||||
|   "LabelAppend": "附加", | ||||
|   "LabelAuthor": "作者", | ||||
|   "LabelAuthorFirstLast": "作者 (姓  名)", | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user