mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Alternative bookshelf view with titles #232
This commit is contained in:
		
							parent
							
								
									3905ef677d
								
							
						
					
					
						commit
						e56196a137
					
				| @ -18,6 +18,7 @@ | |||||||
| } | } | ||||||
| #bookshelf { | #bookshelf { | ||||||
|   height: calc(100% - 40px); |   height: calc(100% - 40px); | ||||||
|  |   background-image: linear-gradient(to right bottom, #2e2e2e, #303030, #313131, #333333, #353535, #343434, #323232, #313131, #2c2c2c, #282828, #232323, #1f1f1f); | ||||||
| } | } | ||||||
| @media (max-width: 768px) { | @media (max-width: 768px) { | ||||||
|   #bookshelf { |   #bookshelf { | ||||||
| @ -25,6 +26,10 @@ | |||||||
|   } |   } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #page-wrapper { | ||||||
|  |   background-image: linear-gradient(to right bottom, #2e2e2e, #303030, #313131, #333333, #353535, #343434, #323232, #313131, #2c2c2c, #282828, #232323, #1f1f1f); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| /* width */ | /* width */ | ||||||
| ::-webkit-scrollbar { | ::-webkit-scrollbar { | ||||||
|   width: 8px; |   width: 8px; | ||||||
| @ -121,10 +126,6 @@ input[type=number] { | |||||||
|   font-size: 1.1rem; |   font-size: 1.1rem; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| #page-wrapper { |  | ||||||
|   background-image: linear-gradient(to right bottom, #2e2e2e, #303030, #313131, #333333, #353535, #343434, #323232, #313131, #2c2c2c, #282828, #232323, #1f1f1f); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| .box-shadow-md { | .box-shadow-md { | ||||||
|   box-shadow: 2px 8px 6px #111111aa; |   box-shadow: 2px 8px 6px #111111aa; | ||||||
| } | } | ||||||
|  | |||||||
| @ -1,11 +1,11 @@ | |||||||
| <template> | <template> | ||||||
|   <div id="bookshelf" class="w-full overflow-y-auto"> |   <div id="bookshelf" class="w-full overflow-y-auto"> | ||||||
|     <template v-for="shelf in totalShelves"> |     <template v-for="shelf in totalShelves"> | ||||||
|       <div :key="shelf" class="w-full px-4 sm:px-8 bookshelfRow relative" :id="`shelf-${shelf - 1}`" :style="{ height: shelfHeight + 'px' }"> |       <div :key="shelf" :id="`shelf-${shelf - 1}`" class="w-full px-4 sm:px-8 relative" :class="{ bookshelfRow: !isAlternativeBookshelfView }" :style="{ height: shelfHeight + 'px' }"> | ||||||
|         <!-- <div class="absolute top-0 left-0 bottom-0 p-4 z-10"> |         <!-- <div class="absolute top-0 left-0 bottom-0 p-4 z-10"> | ||||||
|           <p class="text-white text-2xl">{{ shelf }}</p> |           <p class="text-white text-2xl">{{ shelf }}</p> | ||||||
|         </div> --> |         </div> --> | ||||||
|         <div class="bookshelfDivider w-full absolute bottom-0 left-0 right-0 z-20" :class="`h-${shelfDividerHeightIndex}`" /> |         <div v-if="!isAlternativeBookshelfView" class="bookshelfDivider w-full absolute bottom-0 left-0 right-0 z-20" :class="`h-${shelfDividerHeightIndex}`" /> | ||||||
|       </div> |       </div> | ||||||
|     </template> |     </template> | ||||||
| 
 | 
 | ||||||
| @ -104,9 +104,16 @@ export default { | |||||||
|     coverAspectRatio() { |     coverAspectRatio() { | ||||||
|       return this.$store.getters['getServerSetting']('coverAspectRatio') |       return this.$store.getters['getServerSetting']('coverAspectRatio') | ||||||
|     }, |     }, | ||||||
|  |     bookshelfView() { | ||||||
|  |       return this.$store.getters['getServerSetting']('bookshelfView') | ||||||
|  |     }, | ||||||
|     isCoverSquareAspectRatio() { |     isCoverSquareAspectRatio() { | ||||||
|       return this.coverAspectRatio === this.$constants.BookCoverAspectRatio.SQUARE |       return this.coverAspectRatio === this.$constants.BookCoverAspectRatio.SQUARE | ||||||
|     }, |     }, | ||||||
|  |     isAlternativeBookshelfView() { | ||||||
|  |       if (!this.isEntityBook) return false // Only used for bookshelf showing books | ||||||
|  |       return this.bookshelfView === this.$constants.BookshelfView.TITLES | ||||||
|  |     }, | ||||||
|     bookCoverAspectRatio() { |     bookCoverAspectRatio() { | ||||||
|       return this.isCoverSquareAspectRatio ? 1 : 1.6 |       return this.isCoverSquareAspectRatio ? 1 : 1.6 | ||||||
|     }, |     }, | ||||||
| @ -149,6 +156,7 @@ export default { | |||||||
|       return 6 |       return 6 | ||||||
|     }, |     }, | ||||||
|     shelfHeight() { |     shelfHeight() { | ||||||
|  |       if (this.isAlternativeBookshelfView) return this.entityHeight + 80 * this.sizeMultiplier | ||||||
|       return this.entityHeight + 40 |       return this.entityHeight + 40 | ||||||
|     }, |     }, | ||||||
|     totalEntityCardWidth() { |     totalEntityCardWidth() { | ||||||
| @ -157,6 +165,10 @@ export default { | |||||||
|     }, |     }, | ||||||
|     selectedAudiobooks() { |     selectedAudiobooks() { | ||||||
|       return this.$store.state.selectedAudiobooks || [] |       return this.$store.state.selectedAudiobooks || [] | ||||||
|  |     }, | ||||||
|  |     sizeMultiplier() { | ||||||
|  |       var baseSize = this.isCoverSquareAspectRatio ? 192 : 120 | ||||||
|  |       return this.entityWidth / baseSize | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|  | |||||||
| @ -5,6 +5,11 @@ | |||||||
|       <div class="absolute cover-bg" ref="coverBg" /> |       <div class="absolute cover-bg" ref="coverBg" /> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|  |     <div v-if="isAlternativeBookshelfView" class="absolute left-0 z-50 w-full" :style="{ bottom: `-${sizeMultiplier * 3}rem` }"> | ||||||
|  |       <p class="truncate" :style="{ fontSize: 0.9 * sizeMultiplier + 'rem' }">{{ title }}</p> | ||||||
|  |       <p class="truncate text-gray-400" :style="{ fontSize: 0.8 * sizeMultiplier + 'rem' }">{{ authorFL }}</p> | ||||||
|  |     </div> | ||||||
|  | 
 | ||||||
|     <div class="w-full h-full absolute top-0 left-0 rounded overflow-hidden z-10"> |     <div class="w-full h-full absolute top-0 left-0 rounded overflow-hidden z-10"> | ||||||
|       <div v-show="audiobook && !imageReady" class="absolute top-0 left-0 w-full h-full flex items-center justify-center" :style="{ padding: sizeMultiplier * 0.5 + 'rem' }"> |       <div v-show="audiobook && !imageReady" class="absolute top-0 left-0 w-full h-full flex items-center justify-center" :style="{ padding: sizeMultiplier * 0.5 + 'rem' }"> | ||||||
|         <p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }" class="font-book text-gray-300 text-center">{{ title }}</p> |         <p :style="{ fontSize: sizeMultiplier * 0.8 + 'rem' }" class="font-book text-gray-300 text-center">{{ title }}</p> | ||||||
| @ -79,6 +84,7 @@ export default { | |||||||
|     }, |     }, | ||||||
|     bookCoverAspectRatio: Number, |     bookCoverAspectRatio: Number, | ||||||
|     showVolumeNumber: Boolean, |     showVolumeNumber: Boolean, | ||||||
|  |     bookshelfView: Number, | ||||||
|     bookMount: { |     bookMount: { | ||||||
|       // Book can be passed as prop or set with setEntity() |       // Book can be passed as prop or set with setEntity() | ||||||
|       type: Object, |       type: Object, | ||||||
| @ -292,6 +298,10 @@ export default { | |||||||
|         return this.authorFL.slice(0, 27) + '...' |         return this.authorFL.slice(0, 27) + '...' | ||||||
|       } |       } | ||||||
|       return this.authorFL |       return this.authorFL | ||||||
|  |     }, | ||||||
|  |     isAlternativeBookshelfView() { | ||||||
|  |       var constants = this.$constants || this.$nuxt.$constants | ||||||
|  |       return this.bookshelfView === constants.BookshelfView.TITLES | ||||||
|     } |     } | ||||||
|   }, |   }, | ||||||
|   methods: { |   methods: { | ||||||
|  | |||||||
| @ -51,7 +51,8 @@ export default { | |||||||
|         index, |         index, | ||||||
|         width: this.entityWidth, |         width: this.entityWidth, | ||||||
|         height: this.entityHeight, |         height: this.entityHeight, | ||||||
|         bookCoverAspectRatio: this.bookCoverAspectRatio |         bookCoverAspectRatio: this.bookCoverAspectRatio, | ||||||
|  |         bookshelfView: this.bookshelfView | ||||||
|       } |       } | ||||||
|       if (this.entityName === 'series-books') props.showVolumeNumber = true |       if (this.entityName === 'series-books') props.showVolumeNumber = true | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -48,6 +48,13 @@ | |||||||
|           <p class="pl-4 text-lg">Use square book covers <span class="material-icons icon-text">info_outlined</span></p> |           <p class="pl-4 text-lg">Use square book covers <span class="material-icons icon-text">info_outlined</span></p> | ||||||
|         </ui-tooltip> |         </ui-tooltip> | ||||||
|       </div> |       </div> | ||||||
|  | 
 | ||||||
|  |       <div class="flex items-center py-2"> | ||||||
|  |         <ui-toggle-switch v-model="useAlternativeBookshelfView" :disabled="updatingServerSettings" @input="updateAlternativeBookshelfView" /> | ||||||
|  |         <ui-tooltip :text="bookshelfViewTooltip"> | ||||||
|  |           <p class="pl-4 text-lg">Use alternative library bookshelf view <span class="material-icons icon-text">info_outlined</span></p> | ||||||
|  |         </ui-tooltip> | ||||||
|  |       </div> | ||||||
|     </div> |     </div> | ||||||
| 
 | 
 | ||||||
|     <div class="h-0.5 bg-primary bg-opacity-30 w-full" /> |     <div class="h-0.5 bg-primary bg-opacity-30 w-full" /> | ||||||
| @ -94,6 +101,7 @@ export default { | |||||||
|       storeCoversInAudiobookDir: false, |       storeCoversInAudiobookDir: false, | ||||||
|       updatingServerSettings: false, |       updatingServerSettings: false, | ||||||
|       useSquareBookCovers: false, |       useSquareBookCovers: false, | ||||||
|  |       useAlternativeBookshelfView: false, | ||||||
|       isPurgingCache: false, |       isPurgingCache: false, | ||||||
|       newServerSettings: {} |       newServerSettings: {} | ||||||
|     } |     } | ||||||
| @ -134,6 +142,9 @@ export default { | |||||||
|     coverAspectRatioTooltip() { |     coverAspectRatioTooltip() { | ||||||
|       return 'Prefer to use square covers over standard 1.6:1 book covers' |       return 'Prefer to use square covers over standard 1.6:1 book covers' | ||||||
|     }, |     }, | ||||||
|  |     bookshelfViewTooltip() { | ||||||
|  |       return 'Alternative bookshelf view that shows title & author under book covers' | ||||||
|  |     }, | ||||||
|     showExperimentalFeatures: { |     showExperimentalFeatures: { | ||||||
|       get() { |       get() { | ||||||
|         return this.$store.state.showExperimentalFeatures |         return this.$store.state.showExperimentalFeatures | ||||||
| @ -175,6 +186,11 @@ export default { | |||||||
|         coverAspectRatio: val ? this.$constants.BookCoverAspectRatio.SQUARE : this.$constants.BookCoverAspectRatio.STANDARD |         coverAspectRatio: val ? this.$constants.BookCoverAspectRatio.SQUARE : this.$constants.BookCoverAspectRatio.STANDARD | ||||||
|       }) |       }) | ||||||
|     }, |     }, | ||||||
|  |     updateAlternativeBookshelfView(val) { | ||||||
|  |       this.updateServerSettings({ | ||||||
|  |         bookshelfView: val ? this.$constants.BookshelfView.TITLES : this.$constants.BookshelfView.STANDARD | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|     updateServerSettings(payload) { |     updateServerSettings(payload) { | ||||||
|       this.updatingServerSettings = true |       this.updatingServerSettings = true | ||||||
|       this.$store |       this.$store | ||||||
| @ -194,6 +210,8 @@ export default { | |||||||
|       this.storeCoversInAudiobookDir = this.newServerSettings.coverDestination === this.$constants.CoverDestination.AUDIOBOOK |       this.storeCoversInAudiobookDir = this.newServerSettings.coverDestination === this.$constants.CoverDestination.AUDIOBOOK | ||||||
| 
 | 
 | ||||||
|       this.useSquareBookCovers = this.newServerSettings.coverAspectRatio === this.$constants.BookCoverAspectRatio.SQUARE |       this.useSquareBookCovers = this.newServerSettings.coverAspectRatio === this.$constants.BookCoverAspectRatio.SQUARE | ||||||
|  | 
 | ||||||
|  |       this.useAlternativeBookshelfView = this.newServerSettings.bookshelfView === this.$constants.BookshelfView.TITLES | ||||||
|     }, |     }, | ||||||
|     resetAudiobooks() { |     resetAudiobooks() { | ||||||
|       if (confirm('WARNING! This action will remove all audiobooks from the database including any updates or matches you have made. This does not do anything to your actual files. Shall we continue?')) { |       if (confirm('WARNING! This action will remove all audiobooks from the database including any updates or matches you have made. This does not do anything to your actual files. Shall we continue?')) { | ||||||
|  | |||||||
| @ -15,10 +15,16 @@ const BookCoverAspectRatio = { | |||||||
|   SQUARE: 1 |   SQUARE: 1 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | const BookshelfView = { | ||||||
|  |   STANDARD: 0, | ||||||
|  |   TITLES: 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| const Constants = { | const Constants = { | ||||||
|   DownloadStatus, |   DownloadStatus, | ||||||
|   CoverDestination, |   CoverDestination, | ||||||
|   BookCoverAspectRatio |   BookCoverAspectRatio, | ||||||
|  |   BookshelfView | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| const KeyNames = { | const KeyNames = { | ||||||
|  | |||||||
| @ -1,4 +1,4 @@ | |||||||
| const { CoverDestination, BookCoverAspectRatio } = require('../utils/constants') | const { CoverDestination, BookCoverAspectRatio, BookshelfView } = require('../utils/constants') | ||||||
| const Logger = require('../Logger') | const Logger = require('../Logger') | ||||||
| 
 | 
 | ||||||
| class ServerSettings { | class ServerSettings { | ||||||
| @ -35,6 +35,7 @@ class ServerSettings { | |||||||
| 
 | 
 | ||||||
|     // Cover
 |     // Cover
 | ||||||
|     this.coverAspectRatio = BookCoverAspectRatio.STANDARD |     this.coverAspectRatio = BookCoverAspectRatio.STANDARD | ||||||
|  |     this.bookshelfView = BookshelfView.STANDARD | ||||||
| 
 | 
 | ||||||
|     this.logLevel = Logger.logLevel |     this.logLevel = Logger.logLevel | ||||||
|     this.version = null |     this.version = null | ||||||
| @ -65,6 +66,7 @@ class ServerSettings { | |||||||
|     this.loggerScannerLogsToKeep = settings.loggerScannerLogsToKeep || 2 |     this.loggerScannerLogsToKeep = settings.loggerScannerLogsToKeep || 2 | ||||||
| 
 | 
 | ||||||
|     this.coverAspectRatio = settings.coverAspectRatio || BookCoverAspectRatio.STANDARD |     this.coverAspectRatio = settings.coverAspectRatio || BookCoverAspectRatio.STANDARD | ||||||
|  |     this.bookshelfView = settings.bookshelfView || BookshelfView.STANDARD | ||||||
| 
 | 
 | ||||||
|     this.logLevel = settings.logLevel || Logger.logLevel |     this.logLevel = settings.logLevel || Logger.logLevel | ||||||
|     this.version = settings.version || null |     this.version = settings.version || null | ||||||
| @ -93,6 +95,7 @@ class ServerSettings { | |||||||
|       loggerDailyLogsToKeep: this.loggerDailyLogsToKeep, |       loggerDailyLogsToKeep: this.loggerDailyLogsToKeep, | ||||||
|       loggerScannerLogsToKeep: this.loggerScannerLogsToKeep, |       loggerScannerLogsToKeep: this.loggerScannerLogsToKeep, | ||||||
|       coverAspectRatio: this.coverAspectRatio, |       coverAspectRatio: this.coverAspectRatio, | ||||||
|  |       bookshelfView: this.bookshelfView, | ||||||
|       logLevel: this.logLevel, |       logLevel: this.logLevel, | ||||||
|       version: this.version |       version: this.version | ||||||
|     } |     } | ||||||
|  | |||||||
| @ -16,6 +16,11 @@ module.exports.BookCoverAspectRatio = { | |||||||
|   SQUARE: 1 |   SQUARE: 1 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | module.exports.BookshelfView = { | ||||||
|  |   STANDARD: 0, | ||||||
|  |   TITLES: 1 | ||||||
|  | } | ||||||
|  | 
 | ||||||
| module.exports.LogLevel = { | module.exports.LogLevel = { | ||||||
|   TRACE: 0, |   TRACE: 0, | ||||||
|   DEBUG: 1, |   DEBUG: 1, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user