mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-10-27 11:18:14 +01:00 
			
		
		
		
	Player track chapter tickmarks, highlight current chapter, progress filters, links in stream container
This commit is contained in:
		
							parent
							
								
									baccbaf82a
								
							
						
					
					
						commit
						f4d6e65380
					
				@ -12,9 +12,6 @@
 | 
			
		||||
        <div v-if="chapters.length" class="cursor-pointer flex items-center justify-center text-gray-300" @mousedown.prevent @mouseup.prevent @click.stop="showChapters">
 | 
			
		||||
          <span class="material-icons text-3xl">format_list_bulleted</span>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div v-else class="flex items-center justify-center text-gray-500">
 | 
			
		||||
          <span class="material-icons text-3xl">format_list_bulleted</span>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="absolute right-32 top-0 bottom-0">
 | 
			
		||||
@ -56,6 +53,11 @@
 | 
			
		||||
        <div ref="trackCursor" class="h-full w-0.5 bg-gray-50 absolute top-0 left-0 opacity-0 pointer-events-none" />
 | 
			
		||||
        <div v-if="loading" class="h-full w-1/4 absolute left-0 top-0 loadingTrack pointer-events-none bg-white bg-opacity-25" />
 | 
			
		||||
      </div>
 | 
			
		||||
      <div ref="track" class="w-full h-2 relative overflow-hidden">
 | 
			
		||||
        <template v-for="(tick, index) in chapterTicks">
 | 
			
		||||
          <div :key="index" :style="{ left: tick.left + 'px' }" class="absolute top-0 w-px bg-white bg-opacity-50 h-1 pointer-events-none" />
 | 
			
		||||
        </template>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <!-- Hover timestamp -->
 | 
			
		||||
      <div ref="hoverTimestamp" class="absolute -top-8 left-0 bg-white text-black rounded-full opacity-0 pointer-events-none">
 | 
			
		||||
@ -68,7 +70,7 @@
 | 
			
		||||
 | 
			
		||||
    <audio ref="audio" @pause="paused" @playing="playing" @progress="progress" @timeupdate="timeupdate" @loadeddata="audioLoadedData" />
 | 
			
		||||
 | 
			
		||||
    <modals-chapters-modal v-model="showChaptersModal" :chapters="chapters" @select="selectChapter" />
 | 
			
		||||
    <modals-chapters-modal v-model="showChaptersModal" :current-chapter="currentChapter" :chapters="chapters" @select="selectChapter" />
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
 | 
			
		||||
@ -100,7 +102,8 @@ export default {
 | 
			
		||||
      totalDuration: 0,
 | 
			
		||||
      seekedTime: 0,
 | 
			
		||||
      seekLoading: false,
 | 
			
		||||
      showChaptersModal: false
 | 
			
		||||
      showChaptersModal: false,
 | 
			
		||||
      currentTime: 0
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
@ -109,6 +112,18 @@ export default {
 | 
			
		||||
    },
 | 
			
		||||
    totalDurationPretty() {
 | 
			
		||||
      return this.$secondsToTimestamp(this.totalDuration)
 | 
			
		||||
    },
 | 
			
		||||
    chapterTicks() {
 | 
			
		||||
      return this.chapters.map((chap) => {
 | 
			
		||||
        var perc = chap.start / this.totalDuration
 | 
			
		||||
        return {
 | 
			
		||||
          title: chap.title,
 | 
			
		||||
          left: perc * this.trackWidth
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    currentChapter() {
 | 
			
		||||
      return this.chapters.find((chapter) => chapter.start <= this.currentTime && this.currentTime < chapter.end)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
@ -175,7 +190,13 @@ export default {
 | 
			
		||||
        this.$refs.hoverTimestamp.style.left = offsetX - width / 2 + 'px'
 | 
			
		||||
      }
 | 
			
		||||
      if (this.$refs.hoverTimestampText) {
 | 
			
		||||
        this.$refs.hoverTimestampText.innerText = this.$secondsToTimestamp(time)
 | 
			
		||||
        var hoverText = this.$secondsToTimestamp(time)
 | 
			
		||||
 | 
			
		||||
        var chapter = this.chapters.find((chapter) => chapter.start <= time && time < chapter.end)
 | 
			
		||||
        if (chapter && chapter.title) {
 | 
			
		||||
          hoverText += ` - ${chapter.title}`
 | 
			
		||||
        }
 | 
			
		||||
        this.$refs.hoverTimestampText.innerText = hoverText
 | 
			
		||||
      }
 | 
			
		||||
      if (this.$refs.trackCursor) {
 | 
			
		||||
        this.$refs.trackCursor.style.opacity = 1
 | 
			
		||||
@ -289,7 +310,6 @@ export default {
 | 
			
		||||
          end: end + offset
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      return ranges
 | 
			
		||||
    },
 | 
			
		||||
    getLastBufferedTime() {
 | 
			
		||||
@ -334,6 +354,8 @@ export default {
 | 
			
		||||
 | 
			
		||||
      this.updateTimestamp()
 | 
			
		||||
 | 
			
		||||
      this.currentTime = this.audioEl.currentTime
 | 
			
		||||
 | 
			
		||||
      var perc = this.audioEl.currentTime / this.audioEl.duration
 | 
			
		||||
      var ptWidth = Math.round(perc * this.trackWidth)
 | 
			
		||||
      if (this.playedTrackWidth === ptWidth) {
 | 
			
		||||
 | 
			
		||||
@ -10,8 +10,11 @@
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div v-if="!audiobooks.length" class="w-full flex flex-col items-center justify-center py-12">
 | 
			
		||||
      <p class="text-center text-2xl font-book mb-4">Your Audiobookshelf is empty!</p>
 | 
			
		||||
      <ui-btn color="success" @click="scan">Scan your Audiobooks</ui-btn>
 | 
			
		||||
      <p class="text-center text-2xl font-book mb-4 py-4">Your Audiobookshelf is empty!</p>
 | 
			
		||||
      <div class="flex">
 | 
			
		||||
        <ui-btn to="/config" color="primary" class="w-52 mr-2" @click="scan">Configure Scanner</ui-btn>
 | 
			
		||||
        <ui-btn color="success" class="w-52" @click="scan">Scan Audiobooks</ui-btn>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div v-else class="w-full flex flex-col items-center">
 | 
			
		||||
      <template v-for="(shelf, index) in groupedBooks">
 | 
			
		||||
@ -43,7 +46,8 @@ export default {
 | 
			
		||||
      availableSizes: [60, 80, 100, 120, 140, 160, 180, 200, 220],
 | 
			
		||||
      selectedSizeIndex: 3,
 | 
			
		||||
      rowPaddingX: 40,
 | 
			
		||||
      keywordFilterTimeout: null
 | 
			
		||||
      keywordFilterTimeout: null,
 | 
			
		||||
      scannerParseSubtitle: false
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
 | 
			
		||||
@ -42,7 +42,6 @@ export default {
 | 
			
		||||
      this.saveSettings()
 | 
			
		||||
    },
 | 
			
		||||
    saveSettings() {
 | 
			
		||||
      this.$store.commit('user/setSettings', this.settings) // Immediate update
 | 
			
		||||
      this.$store.dispatch('user/updateUserSettings', this.settings)
 | 
			
		||||
    },
 | 
			
		||||
    init() {
 | 
			
		||||
 | 
			
		||||
@ -1,14 +1,14 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div v-if="streamAudiobook" id="streamContainer" class="w-full fixed bottom-0 left-0 right-0 h-40 z-40 bg-primary p-4">
 | 
			
		||||
    <div class="absolute -top-16 left-4">
 | 
			
		||||
    <nuxt-link :to="`/audiobook/${streamAudiobook.id}`" class="absolute -top-16 left-4 cursor-pointer">
 | 
			
		||||
      <cards-book-cover :audiobook="streamAudiobook" :width="88" />
 | 
			
		||||
    </div>
 | 
			
		||||
    </nuxt-link>
 | 
			
		||||
    <div class="flex items-center pl-24">
 | 
			
		||||
      <div>
 | 
			
		||||
        <h1>
 | 
			
		||||
          {{ title }} <span v-if="stream" class="text-xs text-gray-400">({{ stream.id }})</span>
 | 
			
		||||
        </h1>
 | 
			
		||||
        <p class="text-gray-400 text-sm">by {{ author }}</p>
 | 
			
		||||
        <nuxt-link :to="`/audiobook/${streamAudiobook.id}`" class="hover:underline cursor-pointer">
 | 
			
		||||
          {{ title }} <span v-if="stream && $isDev" class="text-xs text-gray-400">({{ stream.id }})</span>
 | 
			
		||||
        </nuxt-link>
 | 
			
		||||
        <p class="text-gray-400 text-sm hover:underline cursor-pointer" @click="filterByAuthor">by {{ author }}</p>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="flex-grow" />
 | 
			
		||||
      <span v-if="stream" class="material-icons px-4 cursor-pointer" @click="cancelStream">close</span>
 | 
			
		||||
@ -66,6 +66,15 @@ export default {
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    filterByAuthor() {
 | 
			
		||||
      if (this.$route.name !== 'index') {
 | 
			
		||||
        this.$router.push('/')
 | 
			
		||||
      }
 | 
			
		||||
      var settingsUpdate = {
 | 
			
		||||
        filterBy: `authors.${this.$encode(this.author)}`
 | 
			
		||||
      }
 | 
			
		||||
      this.$store.dispatch('user/updateUserSettings', settingsUpdate)
 | 
			
		||||
    },
 | 
			
		||||
    audioPlayerMounted() {
 | 
			
		||||
      this.audioPlayerReady = true
 | 
			
		||||
      if (this.stream) {
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,7 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div class="relative">
 | 
			
		||||
    <!-- New Book Flag -->
 | 
			
		||||
    <div v-show="isNew" class="absolute top-4 left-0 w-4 h-10 pr-2 bg-darkgreen box-shadow-xl">
 | 
			
		||||
    <div v-show="isNew" class="absolute top-4 left-0 w-4 h-10 pr-2 bg-darkgreen box-shadow-xl z-20">
 | 
			
		||||
      <div class="absolute top-0 left-0 w-full h-full transform -rotate-90 flex items-center justify-center">
 | 
			
		||||
        <p class="text-center text-sm">New</p>
 | 
			
		||||
      </div>
 | 
			
		||||
@ -65,7 +65,7 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  computed: {
 | 
			
		||||
    isNew() {
 | 
			
		||||
      return this.tags.includes('new')
 | 
			
		||||
      return this.tags.includes('New')
 | 
			
		||||
    },
 | 
			
		||||
    tags() {
 | 
			
		||||
      return this.audiobook.tags || []
 | 
			
		||||
 | 
			
		||||
@ -86,6 +86,11 @@ export default {
 | 
			
		||||
          text: 'Authors',
 | 
			
		||||
          value: 'authors',
 | 
			
		||||
          sublist: true
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
          text: 'Progress',
 | 
			
		||||
          value: 'progress',
 | 
			
		||||
          sublist: true
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
    }
 | 
			
		||||
@ -132,6 +137,9 @@ export default {
 | 
			
		||||
    authors() {
 | 
			
		||||
      return this.$store.getters['audiobooks/getUniqueAuthors']
 | 
			
		||||
    },
 | 
			
		||||
    progress() {
 | 
			
		||||
      return ['Read', 'Unread', 'In Progress']
 | 
			
		||||
    },
 | 
			
		||||
    sublistItems() {
 | 
			
		||||
      return (this[this.sublist] || []).map((item) => {
 | 
			
		||||
        return {
 | 
			
		||||
 | 
			
		||||
@ -74,10 +74,10 @@ export default {
 | 
			
		||||
      this.showMenu = false
 | 
			
		||||
    },
 | 
			
		||||
    leftArrowClick() {
 | 
			
		||||
      this.rateIndex = Math.max(0, this.rateIndex - 4)
 | 
			
		||||
      this.rateIndex = Math.max(0, this.rateIndex - 1)
 | 
			
		||||
    },
 | 
			
		||||
    rightArrowClick() {
 | 
			
		||||
      this.rateIndex = Math.min(this.rates.length - this.numVisible, this.rateIndex + 4)
 | 
			
		||||
      this.rateIndex = Math.min(this.rates.length - this.numVisible, this.rateIndex + 1)
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {}
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
  <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">
 | 
			
		||||
      <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 bg-opacity-20 rounded-lg relative" @click="clickChapter(chap)">
 | 
			
		||||
        <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)">
 | 
			
		||||
          {{ chap.title }}
 | 
			
		||||
          <span class="flex-grow" />
 | 
			
		||||
          <span class="font-mono text-sm text-gray-300">{{ $secondsToTimestamp(chap.start) }}</span>
 | 
			
		||||
@ -19,6 +19,10 @@ export default {
 | 
			
		||||
    chapters: {
 | 
			
		||||
      type: Array,
 | 
			
		||||
      default: () => []
 | 
			
		||||
    },
 | 
			
		||||
    currentChapter: {
 | 
			
		||||
      type: Object,
 | 
			
		||||
      default: () => null
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
@ -32,6 +36,9 @@ export default {
 | 
			
		||||
      set(val) {
 | 
			
		||||
        this.$emit('input', val)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    currentChapterId() {
 | 
			
		||||
      return this.currentChapter ? this.currentChapter.id : null
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,14 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <button class="btn outline-none rounded-md shadow-md relative border border-gray-600" :disabled="disabled || loading" :type="type" :class="classList" @click="click">
 | 
			
		||||
  <nuxt-link v-if="to" :to="to" class="btn outline-none rounded-md shadow-md relative border border-gray-600" :disabled="disabled || loading" :class="classList">
 | 
			
		||||
    <slot />
 | 
			
		||||
    <div v-if="loading" class="text-white absolute top-0 left-0 w-full h-full flex items-center justify-center text-opacity-100">
 | 
			
		||||
      <!-- <span class="material-icons animate-spin">refresh</span> -->
 | 
			
		||||
      <svg class="animate-spin" style="width: 24px; height: 24px" viewBox="0 0 24 24">
 | 
			
		||||
        <path fill="currentColor" d="M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z" />
 | 
			
		||||
      </svg>
 | 
			
		||||
    </div>
 | 
			
		||||
  </nuxt-link>
 | 
			
		||||
  <button v-else class="btn outline-none rounded-md shadow-md relative border border-gray-600" :disabled="disabled || loading" :type="type" :class="classList" @click="click">
 | 
			
		||||
    <slot />
 | 
			
		||||
    <div v-if="loading" class="text-white absolute top-0 left-0 w-full h-full flex items-center justify-center text-opacity-100">
 | 
			
		||||
      <!-- <span class="material-icons animate-spin">refresh</span> -->
 | 
			
		||||
@ -13,6 +22,7 @@
 | 
			
		||||
<script>
 | 
			
		||||
export default {
 | 
			
		||||
  props: {
 | 
			
		||||
    to: String,
 | 
			
		||||
    color: {
 | 
			
		||||
      type: String,
 | 
			
		||||
      default: 'primary'
 | 
			
		||||
 | 
			
		||||
@ -113,7 +113,6 @@ export default {
 | 
			
		||||
      this.currentSearch = null
 | 
			
		||||
    },
 | 
			
		||||
    clickedOption(e, item) {
 | 
			
		||||
      var newValue = this.input === item ? null : item
 | 
			
		||||
      this.textInput = null
 | 
			
		||||
      this.currentSearch = null
 | 
			
		||||
      this.input = this.textInput ? this.textInput.trim() : null
 | 
			
		||||
 | 
			
		||||
@ -180,7 +180,7 @@ export default {
 | 
			
		||||
    submitForm() {
 | 
			
		||||
      if (!this.textInput) return
 | 
			
		||||
 | 
			
		||||
      var cleaned = this.textInput.toLowerCase().trim()
 | 
			
		||||
      var cleaned = this.textInput.trim()
 | 
			
		||||
      var matchesItem = this.items.find((i) => {
 | 
			
		||||
        return i === cleaned
 | 
			
		||||
      })
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,5 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div ref="box" class="tooltip-box" @mouseover="mouseover" @mouseleave="mouseleave">
 | 
			
		||||
  <div ref="box" @mouseover="mouseover" @mouseleave="mouseleave">
 | 
			
		||||
    <slot />
 | 
			
		||||
  </div>
 | 
			
		||||
</template>
 | 
			
		||||
@ -51,8 +51,9 @@ export default {
 | 
			
		||||
    createTooltip() {
 | 
			
		||||
      if (!this.$refs.box) return
 | 
			
		||||
      var tooltip = document.createElement('div')
 | 
			
		||||
      tooltip.className = 'absolute px-2 bg-black bg-opacity-90 py-1 text-white pointer-events-none text-xs rounded shadow-lg'
 | 
			
		||||
      tooltip.className = 'absolute px-2 py-1 text-white pointer-events-none text-xs rounded shadow-lg max-w-xs'
 | 
			
		||||
      tooltip.style.zIndex = 100
 | 
			
		||||
      tooltip.style.backgroundColor = 'rgba(0,0,0,0.75)'
 | 
			
		||||
      tooltip.innerHTML = this.text
 | 
			
		||||
 | 
			
		||||
      this.setTooltipPosition(tooltip)
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "audiobookshelf-client",
 | 
			
		||||
  "version": "1.1.13",
 | 
			
		||||
  "version": "1.1.14",
 | 
			
		||||
  "description": "Audiobook manager and player",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
 | 
			
		||||
@ -49,7 +49,12 @@
 | 
			
		||||
          <div class="flex-grow" />
 | 
			
		||||
          <div class="w-40 flex flex-col">
 | 
			
		||||
            <ui-btn color="success" class="mb-4" :loading="isScanning" :disabled="isScanningCovers" @click="scan">Scan</ui-btn>
 | 
			
		||||
            <ui-btn color="primary" small :padding-x="2" :loading="isScanningCovers" :disabled="isScanning" @click="scanCovers">Scan for Covers</ui-btn>
 | 
			
		||||
 | 
			
		||||
            <div class="w-full">
 | 
			
		||||
              <ui-tooltip direction="bottom" text="Only scans audiobooks without a cover. Covers will be applied if a close match is found." class="w-full">
 | 
			
		||||
                <ui-btn color="primary" class="w-full" small :padding-x="2" :loading="isScanningCovers" :disabled="isScanning" @click="scanCovers">Scan for Covers</ui-btn>
 | 
			
		||||
              </ui-tooltip>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
@ -16,12 +16,12 @@ export const getters = {
 | 
			
		||||
  getAudiobook: (state) => id => {
 | 
			
		||||
    return state.audiobooks.find(ab => ab.id === id)
 | 
			
		||||
  },
 | 
			
		||||
  getFiltered: (state, getters, rootState) => () => {
 | 
			
		||||
  getFiltered: (state, getters, rootState, rootGetters) => () => {
 | 
			
		||||
    var filtered = state.audiobooks
 | 
			
		||||
    var settings = rootState.user.settings || {}
 | 
			
		||||
    var filterBy = settings.filterBy || ''
 | 
			
		||||
 | 
			
		||||
    var searchGroups = ['genres', 'tags', 'series', 'authors']
 | 
			
		||||
    var searchGroups = ['genres', 'tags', 'series', 'authors', 'progress']
 | 
			
		||||
    var group = searchGroups.find(_group => filterBy.startsWith(_group + '.'))
 | 
			
		||||
    if (group) {
 | 
			
		||||
      var filter = decode(filterBy.replace(`${group}.`, ''))
 | 
			
		||||
@ -29,6 +29,16 @@ export const getters = {
 | 
			
		||||
      else if (group === 'tags') filtered = filtered.filter(ab => ab.tags.includes(filter))
 | 
			
		||||
      else if (group === 'series') filtered = filtered.filter(ab => ab.book && ab.book.series === filter)
 | 
			
		||||
      else if (group === 'authors') filtered = filtered.filter(ab => ab.book && ab.book.author === filter)
 | 
			
		||||
      else if (group === 'progress') {
 | 
			
		||||
        filtered = filtered.filter(ab => {
 | 
			
		||||
          var userAudiobook = rootGetters['user/getUserAudiobook'](ab.id)
 | 
			
		||||
          var isRead = userAudiobook && userAudiobook.isRead
 | 
			
		||||
          if (filter === 'Read' && isRead) return true
 | 
			
		||||
          if (filter === 'Unread' && !isRead) return true
 | 
			
		||||
          if (filter === 'In Progress' && (userAudiobook && !userAudiobook.isRead && userAudiobook.progress > 0)) return true
 | 
			
		||||
          return false
 | 
			
		||||
        })
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    if (state.keywordFilter) {
 | 
			
		||||
      const keywordFilterKeys = ['title', 'subtitle', 'author', 'series', 'narrarator']
 | 
			
		||||
 | 
			
		||||
@ -44,6 +44,8 @@ export const actions = {
 | 
			
		||||
    var updatePayload = {
 | 
			
		||||
      ...payload
 | 
			
		||||
    }
 | 
			
		||||
    // Immediately update
 | 
			
		||||
    commit('setSettings', updatePayload)
 | 
			
		||||
    return this.$axios.$patch('/api/user/settings', updatePayload).then((result) => {
 | 
			
		||||
      if (result.success) {
 | 
			
		||||
        commit('setSettings', result.settings)
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,6 @@
 | 
			
		||||
{
 | 
			
		||||
  "name": "audiobookshelf",
 | 
			
		||||
  "version": "1.1.13",
 | 
			
		||||
  "version": "1.1.14",
 | 
			
		||||
  "description": "Self-hosted audiobook server for managing and playing audiobooks.",
 | 
			
		||||
  "main": "index.js",
 | 
			
		||||
  "scripts": {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user