mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Add:Start of chromecast plugin & update cors accept header, move sortable to static
This commit is contained in:
		
							parent
							
								
									6c6a0b4ba6
								
							
						
					
					
						commit
						f51299c798
					
				| @ -1,158 +0,0 @@ | ||||
| (function (global, factory) { | ||||
|   typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : | ||||
|     typeof define === 'function' && define.amd ? define(['exports'], factory) : | ||||
|       (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global['fast-sort'] = {})); | ||||
| }(this, (function (exports) { | ||||
|   'use strict'; | ||||
| 
 | ||||
|   // >>> INTERFACES <<<
 | ||||
|   // >>> HELPERS <<<
 | ||||
|   var castComparer = function (comparer) { return function (a, b, order) { return comparer(a, b, order) * order; }; }; | ||||
|   var throwInvalidConfigErrorIfTrue = function (condition, context) { | ||||
|     if (condition) | ||||
|       throw Error("Invalid sort config: " + context); | ||||
|   }; | ||||
|   var unpackObjectSorter = function (sortByObj) { | ||||
|     var _a = sortByObj || {}, asc = _a.asc, desc = _a.desc; | ||||
|     var order = asc ? 1 : -1; | ||||
|     var sortBy = (asc || desc); | ||||
|     // Validate object config
 | ||||
|     throwInvalidConfigErrorIfTrue(!sortBy, 'Expected `asc` or `desc` property'); | ||||
|     throwInvalidConfigErrorIfTrue(asc && desc, 'Ambiguous object with `asc` and `desc` config properties'); | ||||
|     var comparer = sortByObj.comparer && castComparer(sortByObj.comparer); | ||||
|     return { order: order, sortBy: sortBy, comparer: comparer }; | ||||
|   }; | ||||
|   // >>> SORTERS <<<
 | ||||
|   var multiPropertySorterProvider = function (defaultComparer) { | ||||
|     return function multiPropertySorter(sortBy, sortByArr, depth, order, comparer, a, b) { | ||||
|       var valA; | ||||
|       var valB; | ||||
|       if (typeof sortBy === 'string') { | ||||
|         valA = a[sortBy]; | ||||
|         valB = b[sortBy]; | ||||
|       } | ||||
|       else if (typeof sortBy === 'function') { | ||||
|         valA = sortBy(a); | ||||
|         valB = sortBy(b); | ||||
|       } | ||||
|       else { | ||||
|         var objectSorterConfig = unpackObjectSorter(sortBy); | ||||
|         return multiPropertySorter(objectSorterConfig.sortBy, sortByArr, depth, objectSorterConfig.order, objectSorterConfig.comparer || defaultComparer, a, b); | ||||
|       } | ||||
|       var equality = comparer(valA, valB, order); | ||||
|       if ((equality === 0 || (valA == null && valB == null)) && | ||||
|         sortByArr.length > depth) { | ||||
|         return multiPropertySorter(sortByArr[depth], sortByArr, depth + 1, order, comparer, a, b); | ||||
|       } | ||||
|       return equality; | ||||
|     }; | ||||
|   }; | ||||
|   function getSortStrategy(sortBy, comparer, order) { | ||||
|     // Flat array sorter
 | ||||
|     if (sortBy === undefined || sortBy === true) { | ||||
|       return function (a, b) { return comparer(a, b, order); }; | ||||
|     } | ||||
|     // Sort list of objects by single object key
 | ||||
|     if (typeof sortBy === 'string') { | ||||
|       throwInvalidConfigErrorIfTrue(sortBy.includes('.'), 'String syntax not allowed for nested properties.'); | ||||
|       return function (a, b) { return comparer(a[sortBy], b[sortBy], order); }; | ||||
|     } | ||||
|     // Sort list of objects by single function sorter
 | ||||
|     if (typeof sortBy === 'function') { | ||||
|       return function (a, b) { return comparer(sortBy(a), sortBy(b), order); }; | ||||
|     } | ||||
|     // Sort by multiple properties
 | ||||
|     if (Array.isArray(sortBy)) { | ||||
|       var multiPropSorter_1 = multiPropertySorterProvider(comparer); | ||||
|       return function (a, b) { return multiPropSorter_1(sortBy[0], sortBy, 1, order, comparer, a, b); }; | ||||
|     } | ||||
|     // Unpack object config to get actual sorter strategy
 | ||||
|     var objectSorterConfig = unpackObjectSorter(sortBy); | ||||
|     return getSortStrategy(objectSorterConfig.sortBy, objectSorterConfig.comparer || comparer, objectSorterConfig.order); | ||||
|   } | ||||
|   var sortArray = function (order, ctx, sortBy, comparer) { | ||||
|     var _a; | ||||
|     if (!Array.isArray(ctx)) { | ||||
|       return ctx; | ||||
|     } | ||||
|     // Unwrap sortBy if array with only 1 value to get faster sort strategy
 | ||||
|     if (Array.isArray(sortBy) && sortBy.length < 2) { | ||||
|       _a = sortBy, sortBy = _a[0]; | ||||
|     } | ||||
|     return ctx.sort(getSortStrategy(sortBy, comparer, order)); | ||||
|   }; | ||||
|   // >>> Public <<<
 | ||||
|   var createNewSortInstance = function (opts) { | ||||
|     var comparer = castComparer(opts.comparer); | ||||
|     return function (_ctx) { | ||||
|       var ctx = Array.isArray(_ctx) && !opts.inPlaceSorting | ||||
|         ? _ctx.slice() | ||||
|         : _ctx; | ||||
|       return { | ||||
|         /** | ||||
|          * Sort array in ascending order. | ||||
|          * @example | ||||
|          * sort([3, 1, 4]).asc(); | ||||
|          * sort(users).asc(u => u.firstName); | ||||
|          * sort(users).asc([ | ||||
|          *   U => u.firstName | ||||
|          *   u => u.lastName, | ||||
|          * ]); | ||||
|          */ | ||||
|         asc: function (sortBy) { | ||||
|           return sortArray(1, ctx, sortBy, comparer); | ||||
|         }, | ||||
|         /** | ||||
|          * Sort array in descending order. | ||||
|          * @example | ||||
|          * sort([3, 1, 4]).desc(); | ||||
|          * sort(users).desc(u => u.firstName); | ||||
|          * sort(users).desc([ | ||||
|          *   U => u.firstName | ||||
|          *   u => u.lastName, | ||||
|          * ]); | ||||
|          */ | ||||
|         desc: function (sortBy) { | ||||
|           return sortArray(-1, ctx, sortBy, comparer); | ||||
|         }, | ||||
|         /** | ||||
|          * Sort array in ascending or descending order. It allows sorting on multiple props | ||||
|          * in different order for each of them. | ||||
|          * @example | ||||
|          * sort(users).by([ | ||||
|          *  { asc: u => u.score } | ||||
|          *  { desc: u => u.age } | ||||
|          * ]); | ||||
|          */ | ||||
|         by: function (sortBy) { | ||||
|           return sortArray(1, ctx, sortBy, comparer); | ||||
|         }, | ||||
|       }; | ||||
|     }; | ||||
|   }; | ||||
|   var defaultComparer = function (a, b, order) { | ||||
|     if (a == null) | ||||
|       return order; | ||||
|     if (b == null) | ||||
|       return -order; | ||||
|     if (a < b) | ||||
|       return -1; | ||||
|     if (a === b) | ||||
|       return 0; | ||||
|     return 1; | ||||
|   }; | ||||
|   var sort = createNewSortInstance({ | ||||
|     comparer: defaultComparer, | ||||
|   }); | ||||
|   var inPlaceSort = createNewSortInstance({ | ||||
|     comparer: defaultComparer, | ||||
|     inPlaceSorting: true, | ||||
|   }); | ||||
| 
 | ||||
|   exports.createNewSortInstance = createNewSortInstance; | ||||
|   exports.inPlaceSort = inPlaceSort; | ||||
|   exports.sort = sort; | ||||
| 
 | ||||
|   Object.defineProperty(exports, '__esModule', { value: true }); | ||||
| 
 | ||||
| }))); | ||||
| @ -1,13 +1,6 @@ | ||||
| <template> | ||||
|   <div class="w-full -mt-6"> | ||||
|     <div class="w-full relative mb-1"> | ||||
|       <!-- <div class="absolute top-0 left-0 w-full h-full bg-red flex items-end pointer-events-none"> | ||||
|         <p ref="currentTimestamp" class="font-mono text-sm text-gray-100 pointer-events-auto">00:00:00</p> | ||||
|         <p class="font-mono text-sm text-gray-100 pointer-events-auto"> / {{ progressPercent }}%</p> | ||||
|         <div class="flex-grow" /> | ||||
|         <p class="font-mono text-sm text-gray-100 pointer-events-auto">{{ timeRemainingPretty }}</p> | ||||
|       </div> --> | ||||
| 
 | ||||
|       <div v-if="chapters.length" class="hidden md:flex absolute right-20 top-0 bottom-0 h-full items-end"> | ||||
|         <div class="cursor-pointer text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="showChapters"> | ||||
|           <span class="material-icons text-3xl">format_list_bulleted</span> | ||||
|  | ||||
| @ -39,10 +39,6 @@ | ||||
| 
 | ||||
|       <div v-show="numAudiobooksSelected" class="absolute top-0 left-0 w-full h-full px-4 bg-primary flex items-center"> | ||||
|         <h1 class="text-2xl px-4">{{ numAudiobooksSelected }} Selected</h1> | ||||
|         <!-- <ui-btn v-show="!isHome" small class="text-sm mx-2" @click="toggleSelectAll" | ||||
|           >{{ isAllSelected ? 'Select None' : 'Select All' }}<span class="pl-2">({{ entitiesLoaded }})</span></ui-btn | ||||
|         > --> | ||||
| 
 | ||||
|         <div class="flex-grow" /> | ||||
|         <ui-tooltip :text="`Mark as ${selectedIsRead ? 'Not Read' : 'Read'}`" direction="bottom"> | ||||
|           <ui-read-icon-btn :disabled="processingBatch" :is-read="selectedIsRead" @click="toggleBatchRead" class="mx-1.5" /> | ||||
|  | ||||
| @ -30,13 +30,12 @@ module.exports = { | ||||
|     ], | ||||
|     script: [ | ||||
|       { | ||||
|         src: '//cdn.jsdelivr.net/npm/sortablejs@1.8.4/Sortable.min.js' | ||||
|         src: '/libs/sortable.js' | ||||
|       } | ||||
|     ], | ||||
|     link: [ | ||||
|       { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }, | ||||
|       { rel: 'stylesheet', href: 'https://fonts.googleapis.com/css2?family=Ubuntu+Mono&family=Source+Sans+Pro:wght@300;400;600' }, | ||||
|       // { rel: 'stylesheet', href: 'https://fonts.googleapis.com/icon?family=Material+Icons' }
 | ||||
|     ] | ||||
|   }, | ||||
| 
 | ||||
| @ -51,6 +50,7 @@ module.exports = { | ||||
| 
 | ||||
|   // Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
 | ||||
|   plugins: [ | ||||
|     // '@/plugins/chromecast.client.js',
 | ||||
|     '@/plugins/constants.js', | ||||
|     '@/plugins/init.client.js', | ||||
|     '@/plugins/axios.js', | ||||
|  | ||||
							
								
								
									
										46
									
								
								client/plugins/chromecast.client.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								client/plugins/chromecast.client.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,46 @@ | ||||
| var initializeCastApi = function () { | ||||
|   var context = cast.framework.CastContext.getInstance() | ||||
|   context.setOptions({ | ||||
|     receiverApplicationId: chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID, | ||||
|     autoJoinPolicy: chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED | ||||
|   }); | ||||
| 
 | ||||
|   context.addEventListener( | ||||
|     cast.framework.CastContextEventType.SESSION_STATE_CHANGED, | ||||
|     (event) => { | ||||
|       console.log('Session state changed event', event) | ||||
| 
 | ||||
|       switch (event.sessionState) { | ||||
|         case cast.framework.SessionState.SESSION_STARTED: | ||||
|           console.log('CAST SESSION STARTED') | ||||
| 
 | ||||
|           // Test: Casting an image
 | ||||
|           // var castSession = cast.framework.CastContext.getInstance().getCurrentSession();
 | ||||
|           // var mediaInfo = new chrome.cast.media.MediaInfo('https://images.unsplash.com/photo-1519331379826-f10be5486c6f', 'image/jpg');
 | ||||
|           // var request = new chrome.cast.media.LoadRequest(mediaInfo);
 | ||||
|           // castSession.loadMedia(request).then(
 | ||||
|           //   function () { console.log('Load succeed'); },
 | ||||
|           //   function (errorCode) { console.log('Error code: ' + errorCode); })
 | ||||
| 
 | ||||
|           break; | ||||
|         case cast.framework.SessionState.SESSION_RESUMED: | ||||
|           console.log('CAST SESSION RESUMED') | ||||
|           break; | ||||
|         case cast.framework.SessionState.SESSION_ENDED: | ||||
|           console.log('CastContext: CastSession disconnected') | ||||
|           // Update locally as necessary
 | ||||
|           break; | ||||
|       } | ||||
|     }) | ||||
| } | ||||
| 
 | ||||
| window['__onGCastApiAvailable'] = function (isAvailable) { | ||||
|   if (isAvailable) { | ||||
|     initializeCastApi() | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| var script = document.createElement('script') | ||||
| script.type = 'text/javascript' | ||||
| script.src = 'https://www.gstatic.com/cv/js/sender/v1/cast_sender.js?loadCastFramework=1' | ||||
| document.head.appendChild(script) | ||||
							
								
								
									
										3
									
								
								client/static/libs/sortable.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								client/static/libs/sortable.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| @ -28,7 +28,7 @@ class Auth { | ||||
|   cors(req, res, next) { | ||||
|     res.header('Access-Control-Allow-Origin', '*') | ||||
|     res.header("Access-Control-Allow-Methods", 'GET, POST, PATCH, PUT, DELETE, OPTIONS') | ||||
|     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization") | ||||
|     res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Accept-Encoding, Range, Authorization") | ||||
|     res.header('Access-Control-Allow-Credentials', true) | ||||
|     if (req.method === 'OPTIONS') { | ||||
|       res.sendStatus(200) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user