mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-03 19:07:00 -05:00 
			
		
		
		
	Update chapters modal, search page, fix version check, ignore matching audio file paths on rescan
This commit is contained in:
		
							parent
							
								
									37c38e69df
								
							
						
					
					
						commit
						e1fd74caaf
					
				@ -30,8 +30,10 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
      <div v-show="!shelves.length" class="w-full py-16 text-center text-xl">
 | 
					      <div v-show="!shelves.length" class="w-full py-16 text-center text-xl">
 | 
				
			||||||
        <div class="py-4">No {{ showGroups ? 'Series' : 'Audiobooks' }}</div>
 | 
					        <div v-if="page === 'search'" class="py-4 mb-6"><p class="text-2xl">No Results</p></div>
 | 
				
			||||||
 | 
					        <div v-else class="py-4">No {{ showGroups ? 'Series' : 'Audiobooks' }}</div>
 | 
				
			||||||
        <ui-btn v-if="!showGroups && (filterBy !== 'all' || keywordFilter)" @click="clearFilter">Clear Filter</ui-btn>
 | 
					        <ui-btn v-if="!showGroups && (filterBy !== 'all' || keywordFilter)" @click="clearFilter">Clear Filter</ui-btn>
 | 
				
			||||||
 | 
					        <ui-btn v-else-if="page === 'search'" to="/library">Back to Library</ui-btn>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
@ -41,7 +43,12 @@
 | 
				
			|||||||
export default {
 | 
					export default {
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
    page: String,
 | 
					    page: String,
 | 
				
			||||||
    selectedSeries: String
 | 
					    selectedSeries: String,
 | 
				
			||||||
 | 
					    searchResults: {
 | 
				
			||||||
 | 
					      type: Array,
 | 
				
			||||||
 | 
					      default: () => []
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    searchQuery: String
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
@ -62,6 +69,11 @@ export default {
 | 
				
			|||||||
      this.$nextTick(() => {
 | 
					      this.$nextTick(() => {
 | 
				
			||||||
        this.setBookshelfEntities()
 | 
					        this.setBookshelfEntities()
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    searchResults() {
 | 
				
			||||||
 | 
					      this.$nextTick(() => {
 | 
				
			||||||
 | 
					        this.setBookshelfEntities()
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
@ -96,11 +108,13 @@ export default {
 | 
				
			|||||||
      return this.$store.getters['user/getUserSetting']('filterBy')
 | 
					      return this.$store.getters['user/getUserSetting']('filterBy')
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    showGroups() {
 | 
					    showGroups() {
 | 
				
			||||||
      return this.page !== '' && !this.selectedSeries
 | 
					      return this.page !== '' && this.page !== 'search' && !this.selectedSeries
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
    entities() {
 | 
					    entities() {
 | 
				
			||||||
      if (this.page === '') {
 | 
					      if (this.page === '') {
 | 
				
			||||||
        return this.$store.getters['audiobooks/getFilteredAndSorted']()
 | 
					        return this.$store.getters['audiobooks/getFilteredAndSorted']()
 | 
				
			||||||
 | 
					      } else if (this.page === 'search') {
 | 
				
			||||||
 | 
					        return this.searchResults || []
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        var seriesGroups = this.$store.getters['audiobooks/getSeriesGroups']()
 | 
					        var seriesGroups = this.$store.getters['audiobooks/getSeriesGroups']()
 | 
				
			||||||
        if (this.selectedSeries) {
 | 
					        if (this.selectedSeries) {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,21 +1,32 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="w-full h-10 relative">
 | 
					  <div class="w-full h-10 relative">
 | 
				
			||||||
    <div id="toolbar" class="absolute top-0 left-0 w-full h-full z-20 flex items-center px-8">
 | 
					    <div id="toolbar" class="absolute top-0 left-0 w-full h-full z-20 flex items-center px-8">
 | 
				
			||||||
      <p v-if="!selectedSeries" class="font-book">{{ numShowing }} {{ entityName }}</p>
 | 
					      <template v-if="page !== 'search'">
 | 
				
			||||||
      <div v-else class="flex items-center">
 | 
					        <p v-if="!selectedSeries" class="font-book">{{ numShowing }} {{ entityName }}</p>
 | 
				
			||||||
        <div @click="seriesBackArrow" class="rounded-full h-10 w-10 flex items-center justify-center hover:bg-white hover:bg-opacity-10 cursor-pointer">
 | 
					        <div v-else class="flex items-center">
 | 
				
			||||||
 | 
					          <div @click="seriesBackArrow" class="rounded-full h-10 w-10 flex items-center justify-center hover:bg-white hover:bg-opacity-10 cursor-pointer">
 | 
				
			||||||
 | 
					            <span class="material-icons text-3xl text-white">west</span>
 | 
				
			||||||
 | 
					          </div>
 | 
				
			||||||
 | 
					          <!-- <span class="material-icons text-2xl cursor-pointer" @click="seriesBackArrow">west</span> -->
 | 
				
			||||||
 | 
					          <p class="pl-4 font-book text-lg">
 | 
				
			||||||
 | 
					            {{ selectedSeries }} <span class="ml-3 font-mono text-lg bg-black bg-opacity-30 rounded-lg px-1 py-0.5">{{ numShowing }}</span>
 | 
				
			||||||
 | 
					          </p>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <div class="flex-grow" />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        <ui-text-input v-show="showSortFilters" v-model="_keywordFilter" placeholder="Keyword Filter" :padding-y="1.5" class="text-xs w-40" />
 | 
				
			||||||
 | 
					        <controls-filter-select v-show="showSortFilters" v-model="settings.filterBy" class="w-48 h-7.5 ml-4" @change="updateFilter" />
 | 
				
			||||||
 | 
					        <controls-order-select v-show="showSortFilters" v-model="settings.orderBy" :descending.sync="settings.orderDesc" class="w-48 h-7.5 ml-4" @change="updateOrder" />
 | 
				
			||||||
 | 
					      </template>
 | 
				
			||||||
 | 
					      <template v-else>
 | 
				
			||||||
 | 
					        <div @click="searchBackArrow" class="rounded-full h-10 w-10 flex items-center justify-center hover:bg-white hover:bg-opacity-10 cursor-pointer">
 | 
				
			||||||
          <span class="material-icons text-3xl text-white">west</span>
 | 
					          <span class="material-icons text-3xl text-white">west</span>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <!-- <span class="material-icons text-2xl cursor-pointer" @click="seriesBackArrow">west</span> -->
 | 
					        <!-- <p class="font-book pl-4">{{ numShowing }} showing</p> -->
 | 
				
			||||||
        <p class="pl-4 font-book text-lg">
 | 
					        <div class="flex-grow" />
 | 
				
			||||||
          {{ selectedSeries }} <span class="ml-3 font-mono text-lg bg-black bg-opacity-30 rounded-lg px-1 py-0.5">{{ numShowing }}</span>
 | 
					        <p>Search results for "{{ searchQuery }}"</p>
 | 
				
			||||||
        </p>
 | 
					        <div class="flex-grow" />
 | 
				
			||||||
      </div>
 | 
					      </template>
 | 
				
			||||||
      <div class="flex-grow" />
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      <ui-text-input v-show="showSortFilters" v-model="_keywordFilter" placeholder="Keyword Filter" :padding-y="1.5" class="text-xs w-40" />
 | 
					 | 
				
			||||||
      <controls-filter-select v-show="showSortFilters" v-model="settings.filterBy" class="w-48 h-7.5 ml-4" @change="updateFilter" />
 | 
					 | 
				
			||||||
      <controls-order-select v-show="showSortFilters" v-model="settings.orderBy" :descending.sync="settings.orderDesc" class="w-48 h-7.5 ml-4" @change="updateOrder" />
 | 
					 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
@ -24,7 +35,12 @@
 | 
				
			|||||||
export default {
 | 
					export default {
 | 
				
			||||||
  props: {
 | 
					  props: {
 | 
				
			||||||
    page: String,
 | 
					    page: String,
 | 
				
			||||||
    selectedSeries: String
 | 
					    selectedSeries: String,
 | 
				
			||||||
 | 
					    searchResults: {
 | 
				
			||||||
 | 
					      type: Array,
 | 
				
			||||||
 | 
					      default: () => []
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    searchQuery: String
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
@ -39,6 +55,8 @@ export default {
 | 
				
			|||||||
    numShowing() {
 | 
					    numShowing() {
 | 
				
			||||||
      if (this.page === '') {
 | 
					      if (this.page === '') {
 | 
				
			||||||
        return this.$store.getters['audiobooks/getFiltered']().length
 | 
					        return this.$store.getters['audiobooks/getFiltered']().length
 | 
				
			||||||
 | 
					      } else if (this.page === 'search') {
 | 
				
			||||||
 | 
					        return (this.searchResults || []).length
 | 
				
			||||||
      } else {
 | 
					      } else {
 | 
				
			||||||
        var groups = this.$store.getters['audiobooks/getSeriesGroups']()
 | 
					        var groups = this.$store.getters['audiobooks/getSeriesGroups']()
 | 
				
			||||||
        if (this.selectedSeries) {
 | 
					        if (this.selectedSeries) {
 | 
				
			||||||
@ -65,6 +83,9 @@ export default {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 | 
					    searchBackArrow() {
 | 
				
			||||||
 | 
					      this.$router.replace('/library')
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    seriesBackArrow() {
 | 
					    seriesBackArrow() {
 | 
				
			||||||
      this.$router.replace('/library/series')
 | 
					      this.$router.replace('/library/series')
 | 
				
			||||||
      this.$emit('update:selectedSeries', null)
 | 
					      this.$emit('update:selectedSeries', null)
 | 
				
			||||||
 | 
				
			|||||||
@ -29,7 +29,7 @@
 | 
				
			|||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
          </div>
 | 
					          </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <div v-show="!isSelectionMode" class="absolute bottom-0 left-0 h-1 shadow-sm" :class="userIsRead ? 'bg-success' : 'bg-yellow-400'" :style="{ width: width * userProgressPercent + 'px' }"></div>
 | 
					          <div v-show="!isSelectionMode" class="absolute bottom-0 left-0 h-1 shadow-sm max-w-full" :class="userIsRead ? 'bg-success' : 'bg-yellow-400'" :style="{ width: width * userProgressPercent + 'px' }"></div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
          <ui-tooltip v-if="showError" :text="errorText" class="absolute bottom-4 left-0">
 | 
					          <ui-tooltip v-if="showError" :text="errorText" class="absolute bottom-4 left-0">
 | 
				
			||||||
            <div :style="{ height: 1.5 * sizeMultiplier + 'rem', width: 2.5 * sizeMultiplier + 'rem' }" class="bg-error rounded-r-full shadow-md flex items-center justify-end border-r border-b border-red-300">
 | 
					            <div :style="{ height: 1.5 * sizeMultiplier + 'rem', width: 2.5 * sizeMultiplier + 'rem' }" class="bg-error rounded-r-full shadow-md flex items-center justify-end border-r border-b border-red-300">
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,8 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <div class="w-64 ml-8 relative">
 | 
					  <div class="w-64 ml-8 relative">
 | 
				
			||||||
    <ui-text-input v-model="search" placeholder="Search.." @input="inputUpdate" @focus="focussed" @blur="blurred" class="w-full h-8 text-sm" />
 | 
					    <form @submit.prevent="submitSearch">
 | 
				
			||||||
 | 
					      <ui-text-input ref="input" v-model="search" placeholder="Search.." @input="inputUpdate" @focus="focussed" @blur="blurred" class="w-full h-8 text-sm" />
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
    <div class="absolute top-0 right-0 bottom-0 h-full flex items-center px-2 text-gray-400 cursor-pointer" @click="clickClear">
 | 
					    <div class="absolute top-0 right-0 bottom-0 h-full flex items-center px-2 text-gray-400 cursor-pointer" @click="clickClear">
 | 
				
			||||||
      <span v-if="!search" class="material-icons" style="font-size: 1.2rem">search</span>
 | 
					      <span v-if="!search" class="material-icons" style="font-size: 1.2rem">search</span>
 | 
				
			||||||
      <span v-else class="material-icons" style="font-size: 1.2rem">close</span>
 | 
					      <span v-else class="material-icons" style="font-size: 1.2rem">close</span>
 | 
				
			||||||
@ -51,6 +53,19 @@ export default {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
 | 
					    submitSearch() {
 | 
				
			||||||
 | 
					      if (!this.search) return
 | 
				
			||||||
 | 
					      this.$router.push(`/library/search?query=${this.search}`)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      this.search = null
 | 
				
			||||||
 | 
					      this.items = []
 | 
				
			||||||
 | 
					      this.showMenu = false
 | 
				
			||||||
 | 
					      this.$nextTick(() => {
 | 
				
			||||||
 | 
					        if (this.$refs.input) {
 | 
				
			||||||
 | 
					          this.$refs.input.blur()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    focussed() {
 | 
					    focussed() {
 | 
				
			||||||
      this.isFocused = true
 | 
					      this.isFocused = true
 | 
				
			||||||
      this.showMenu = true
 | 
					      this.showMenu = true
 | 
				
			||||||
@ -73,6 +88,10 @@ export default {
 | 
				
			|||||||
        return []
 | 
					        return []
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      this.isFetching = false
 | 
					      this.isFetching = false
 | 
				
			||||||
 | 
					      if (!this.showMenu) {
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      this.items = results.map((res) => {
 | 
					      this.items = results.map((res) => {
 | 
				
			||||||
        return {
 | 
					        return {
 | 
				
			||||||
          id: res.id,
 | 
					          id: res.id,
 | 
				
			||||||
 | 
				
			|||||||
@ -1,11 +1,13 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <modals-modal v-model="show" :width="500" :height="'unset'">
 | 
					  <modals-modal v-model="show" :width="500" :height="'unset'">
 | 
				
			||||||
    <div class="w-full rounded-lg bg-primary box-shadow-md overflow-y-auto overflow-x-hidden" style="max-height: 500px">
 | 
					    <div ref="container" class="w-full rounded-lg bg-primary box-shadow-md overflow-y-auto overflow-x-hidden" style="max-height: 80vh">
 | 
				
			||||||
      <template v-for="chap in chapters">
 | 
					      <template v-for="chap in chapters">
 | 
				
			||||||
        <div :key="chap.id" class="flex items-center px-6 py-3 justify-start cursor-pointer hover:bg-bg relative" :class="chap.id === currentChapterId ? 'bg-bg bg-opacity-80' : 'bg-opacity-20'" @click="clickChapter(chap)">
 | 
					        <div :key="chap.id" :id="`chapter-row-${chap.id}`" class="flex items-center px-6 py-3 justify-start cursor-pointer hover:bg-bg relative" :class="chap.id === currentChapterId ? 'bg-bg bg-opacity-80' : 'bg-opacity-20'" @click="clickChapter(chap)">
 | 
				
			||||||
          {{ chap.title }}
 | 
					          {{ chap.title }}
 | 
				
			||||||
          <span class="flex-grow" />
 | 
					          <span class="flex-grow" />
 | 
				
			||||||
          <span class="font-mono text-sm text-gray-300">{{ $secondsToTimestamp(chap.start) }}</span>
 | 
					          <span class="font-mono text-sm text-gray-300">{{ $secondsToTimestamp(chap.start) }}</span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          <div v-show="chap.id === currentChapterId" class="w-0.5 h-full absolute top-0 left-0 bg-yellow-400" />
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
      </template>
 | 
					      </template>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
@ -28,6 +30,11 @@ export default {
 | 
				
			|||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {}
 | 
					    return {}
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  watch: {
 | 
				
			||||||
 | 
					    value(newVal) {
 | 
				
			||||||
 | 
					      this.$nextTick(this.scrollToChapter)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    show: {
 | 
					    show: {
 | 
				
			||||||
      get() {
 | 
					      get() {
 | 
				
			||||||
@ -44,8 +51,20 @@ export default {
 | 
				
			|||||||
  methods: {
 | 
					  methods: {
 | 
				
			||||||
    clickChapter(chap) {
 | 
					    clickChapter(chap) {
 | 
				
			||||||
      this.$emit('select', chap)
 | 
					      this.$emit('select', chap)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    scrollToChapter() {
 | 
				
			||||||
 | 
					      if (!this.currentChapterId) return
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      var container = this.$refs.container
 | 
				
			||||||
 | 
					      if (container) {
 | 
				
			||||||
 | 
					        var currChapterEl = document.getElementById(`chapter-row-${this.currentChapterId}`)
 | 
				
			||||||
 | 
					        if (currChapterEl) {
 | 
				
			||||||
 | 
					          var offsetTop = currChapterEl.offsetTop
 | 
				
			||||||
 | 
					          var containerHeight = container.clientHeight
 | 
				
			||||||
 | 
					          container.scrollTo({ top: offsetTop - containerHeight / 2 })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  }
 | 
				
			||||||
  mounted() {}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@ -1,5 +1,5 @@
 | 
				
			|||||||
<template>
 | 
					<template>
 | 
				
			||||||
  <input v-model="inputValue" :type="type" :readonly="readonly" :disabled="disabled" :placeholder="placeholder" class="rounded bg-primary text-gray-200 focus:border-gray-500 focus:outline-none border border-gray-600" :class="classList" @keyup="keyup" @change="change" @focus="focused" @blur="blurred" />
 | 
					  <input ref="input" v-model="inputValue" :type="type" :readonly="readonly" :disabled="disabled" :placeholder="placeholder" class="rounded bg-primary text-gray-200 focus:border-gray-500 focus:outline-none border border-gray-600" :class="classList" @keyup="keyup" @change="change" @focus="focused" @blur="blurred" />
 | 
				
			||||||
</template>
 | 
					</template>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
@ -53,6 +53,9 @@ export default {
 | 
				
			|||||||
    },
 | 
					    },
 | 
				
			||||||
    keyup(e) {
 | 
					    keyup(e) {
 | 
				
			||||||
      this.$emit('keyup', e)
 | 
					      this.$emit('keyup', e)
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    blur() {
 | 
				
			||||||
 | 
					      if (this.$refs.input) this.$refs.input.blur()
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  mounted() {}
 | 
					  mounted() {}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "audiobookshelf-client",
 | 
					  "name": "audiobookshelf-client",
 | 
				
			||||||
  "version": "1.2.0",
 | 
					  "version": "1.2.1",
 | 
				
			||||||
  "description": "Audiobook manager and player",
 | 
					  "description": "Audiobook manager and player",
 | 
				
			||||||
  "main": "index.js",
 | 
					  "main": "index.js",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
 | 
				
			|||||||
@ -3,8 +3,8 @@
 | 
				
			|||||||
    <div class="flex h-full">
 | 
					    <div class="flex h-full">
 | 
				
			||||||
      <app-side-rail />
 | 
					      <app-side-rail />
 | 
				
			||||||
      <div class="flex-grow">
 | 
					      <div class="flex-grow">
 | 
				
			||||||
        <app-book-shelf-toolbar :page="id || ''" :selected-series.sync="selectedSeries" />
 | 
					        <app-book-shelf-toolbar :page="id || ''" :search-results="searchResults" :search-query="searchQuery" :selected-series.sync="selectedSeries" />
 | 
				
			||||||
        <app-book-shelf :page="id || ''" :selected-series.sync="selectedSeries" />
 | 
					        <app-book-shelf :page="id || ''" :search-results="searchResults" :search-query="searchQuery" :selected-series.sync="selectedSeries" />
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
  </div>
 | 
					  </div>
 | 
				
			||||||
@ -12,24 +12,53 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
export default {
 | 
					export default {
 | 
				
			||||||
  asyncData({ params, query, store, app }) {
 | 
					  async asyncData({ params, query, store, app }) {
 | 
				
			||||||
    if (query.filter) {
 | 
					    if (query.filter) {
 | 
				
			||||||
      store.dispatch('user/updateUserSettings', { filterBy: query.filter })
 | 
					      store.dispatch('user/updateUserSettings', { filterBy: query.filter })
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    var searchResults = []
 | 
				
			||||||
 | 
					    var searchQuery = null
 | 
				
			||||||
 | 
					    if (params.id === 'search' && query.query) {
 | 
				
			||||||
 | 
					      searchQuery = query.query
 | 
				
			||||||
 | 
					      searchResults = await app.$axios.$get(`/api/audiobooks?q=${query.query}`).catch((error) => {
 | 
				
			||||||
 | 
					        console.error('Search error', error)
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return {
 | 
					    return {
 | 
				
			||||||
      id: params.id,
 | 
					      id: params.id,
 | 
				
			||||||
 | 
					      searchQuery,
 | 
				
			||||||
 | 
					      searchResults,
 | 
				
			||||||
      selectedSeries: query.series ? app.$decode(query.series) : null
 | 
					      selectedSeries: query.series ? app.$decode(query.series) : null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  data() {
 | 
					  data() {
 | 
				
			||||||
    return {}
 | 
					    return {}
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
 | 
					  watch: {
 | 
				
			||||||
 | 
					    '$route.query'(newVal) {
 | 
				
			||||||
 | 
					      if (this.id === 'search' && this.$route.query.query) {
 | 
				
			||||||
 | 
					        if (this.$route.query.query !== this.searchQuery) {
 | 
				
			||||||
 | 
					          this.newQuery()
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  computed: {
 | 
					  computed: {
 | 
				
			||||||
    streamAudiobook() {
 | 
					    streamAudiobook() {
 | 
				
			||||||
      return this.$store.state.streamAudiobook
 | 
					      return this.$store.state.streamAudiobook
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  methods: {},
 | 
					  methods: {
 | 
				
			||||||
 | 
					    async newQuery() {
 | 
				
			||||||
 | 
					      var query = this.$route.query.query
 | 
				
			||||||
 | 
					      this.searchResults = await this.$axios.$get(`/api/audiobooks?q=${query}`).catch((error) => {
 | 
				
			||||||
 | 
					        console.error('Search error', error)
 | 
				
			||||||
 | 
					        return []
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      this.searchQuery = query
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  mounted() {}
 | 
					  mounted() {}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
</script>
 | 
					</script>
 | 
				
			||||||
@ -5,7 +5,7 @@ function parseSemver(ver) {
 | 
				
			|||||||
  if (!ver) return null
 | 
					  if (!ver) return null
 | 
				
			||||||
  var groups = ver.match(/^v((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/)
 | 
					  var groups = ver.match(/^v((([0-9]+)\.([0-9]+)\.([0-9]+)(?:-([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?)$/)
 | 
				
			||||||
  if (groups && groups.length > 6) {
 | 
					  if (groups && groups.length > 6) {
 | 
				
			||||||
    var total = Number(groups[3]) * 100 + Number(groups[4]) * 10 + Number(groups[5])
 | 
					    var total = Number(groups[3]) * 10000 + Number(groups[4]) * 100 + Number(groups[5])
 | 
				
			||||||
    if (isNaN(total)) {
 | 
					    if (isNaN(total)) {
 | 
				
			||||||
      console.warn('Invalid version total', groups[3], groups[4], groups[5])
 | 
					      console.warn('Invalid version total', groups[3], groups[4], groups[5])
 | 
				
			||||||
      return null
 | 
					      return null
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,6 @@
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
  "name": "audiobookshelf",
 | 
					  "name": "audiobookshelf",
 | 
				
			||||||
  "version": "1.2.0",
 | 
					  "version": "1.2.1",
 | 
				
			||||||
  "description": "Self-hosted audiobook server for managing and playing audiobooks.",
 | 
					  "description": "Self-hosted audiobook server for managing and playing audiobooks.",
 | 
				
			||||||
  "main": "index.js",
 | 
					  "main": "index.js",
 | 
				
			||||||
  "scripts": {
 | 
					  "scripts": {
 | 
				
			||||||
 | 
				
			|||||||
@ -100,7 +100,12 @@ class Scanner {
 | 
				
			|||||||
            hasUpdatedAudioFiles = true
 | 
					            hasUpdatedAudioFiles = true
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
          newAudioFiles.push(file)
 | 
					          var audioFileWithMatchingPath = existingAudiobook.getAudioFileByPath(file.fullPath)
 | 
				
			||||||
 | 
					          if (audioFileWithMatchingPath) {
 | 
				
			||||||
 | 
					            Logger.warn(`[Scanner] Audio file with path already exists with different inode, New: "${file.filename}" (${file.ino}) | Existing: ${audioFileWithMatchingPath.filename} (${audioFileWithMatchingPath.ino})`)
 | 
				
			||||||
 | 
					          } else {
 | 
				
			||||||
 | 
					            newAudioFiles.push(file)
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      })
 | 
					      })
 | 
				
			||||||
      if (newAudioFiles.length) {
 | 
					      if (newAudioFiles.length) {
 | 
				
			||||||
 | 
				
			|||||||
@ -425,6 +425,10 @@ class Audiobook {
 | 
				
			|||||||
    return this.audioFiles.find(af => af.ino === ino)
 | 
					    return this.audioFiles.find(af => af.ino === ino)
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  getAudioFileByPath(fullPath) {
 | 
				
			||||||
 | 
					    return this.audioFiles.find(af => af.fullPath === fullPath)
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  setChapters() {
 | 
					  setChapters() {
 | 
				
			||||||
    // If 1 audio file without chapters, then no chapters will be set
 | 
					    // If 1 audio file without chapters, then no chapters will be set
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user