mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2025-07-15 08:24:50 +02:00
Fix:Prevent pressing download buttons twice causing crash in iOS
This commit is contained in:
parent
023c83ee78
commit
4dd67adcab
5 changed files with 48 additions and 32 deletions
|
@ -9,22 +9,18 @@
|
|||
<p v-else>No Server Media Progress</p>
|
||||
<p v-if="localMediaProgress">Local Media Progress {{ Math.round(localMediaProgress.progress * 100) }}</p>
|
||||
<p v-else>No Local Media Progress</p>
|
||||
</template> -->
|
||||
</template>-->
|
||||
|
||||
<p v-if="publishedAt" class="text-xs text-fg-muted mb-1">Published {{ $formatDate(publishedAt, 'MMM do, yyyy') }}</p>
|
||||
|
||||
<p class="text-sm font-semibold">
|
||||
{{ title }}
|
||||
</p>
|
||||
<p class="text-sm font-semibold">{{ title }}</p>
|
||||
|
||||
<p class="text-sm text-fg episode-subtitle mt-1.5 mb-0.5" v-html="subtitle" />
|
||||
|
||||
<div v-if="episodeNumber || season || episodeType" class="flex py-2 items-center -mx-0.5">
|
||||
<div v-if="episodeNumber" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg">Episode #{{ episodeNumber }}</div>
|
||||
<div v-if="season" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg">Season #{{ season }}</div>
|
||||
<div v-if="episodeType" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg capitalize">
|
||||
{{ episodeType }}
|
||||
</div>
|
||||
<div v-if="episodeType" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg capitalize">{{ episodeType }}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center pt-2">
|
||||
|
@ -44,7 +40,7 @@
|
|||
|
||||
<div v-if="userCanDownload">
|
||||
<span v-if="isLocal" class="material-icons-outlined px-2 text-success text-lg">audio_file</span>
|
||||
<span v-else-if="!localEpisode" class="material-icons mx-1.5 mt-2 text-xl" :class="downloadItem ? 'animate-bounce text-warning text-opacity-75' : ''" @click.stop="downloadClick">{{ downloadItem ? 'downloading' : 'download' }}</span>
|
||||
<span v-else-if="!localEpisode" class="material-icons mx-1.5 mt-2 text-xl" :class="(downloadItem || startingDownload) ? 'animate-bounce text-warning text-opacity-75' : ''" @click.stop="downloadClick">{{ (downloadItem || startingDownload) ? 'downloading' : 'download' }}</span>
|
||||
<span v-else class="material-icons px-2 text-success text-xl">download_done</span>
|
||||
</div>
|
||||
|
||||
|
@ -80,7 +76,8 @@ export default {
|
|||
data() {
|
||||
return {
|
||||
isProcessingReadUpdate: false,
|
||||
processing: false
|
||||
processing: false,
|
||||
startingDownload: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -179,7 +176,13 @@ export default {
|
|||
return folderObj
|
||||
},
|
||||
async downloadClick() {
|
||||
if (this.downloadItem) return
|
||||
if (this.downloadItem || this.startingDownload) return
|
||||
|
||||
this.startingDownload = true
|
||||
setTimeout(() => {
|
||||
this.startingDownload = false
|
||||
}, 1000)
|
||||
|
||||
await this.$hapticsImpact()
|
||||
if (this.isIos) {
|
||||
// no local folders on iOS
|
||||
|
|
|
@ -13,18 +13,14 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<p class="text-sm font-semibold">
|
||||
{{ title }}
|
||||
</p>
|
||||
<p class="text-sm font-semibold">{{ title }}</p>
|
||||
|
||||
<p class="text-sm text-fg episode-subtitle mt-1.5 mb-0.5" v-html="subtitle" />
|
||||
|
||||
<div v-if="episodeNumber || season || episodeType" class="flex pt-2 items-center -mx-0.5">
|
||||
<div v-if="episodeNumber" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg">{{ $strings.LabelEpisode }} #{{ episodeNumber }}</div>
|
||||
<div v-if="season" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg">{{ $strings.LabelSeason }} #{{ season }}</div>
|
||||
<div v-if="episodeType" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg capitalize">
|
||||
{{ episodeType }}
|
||||
</div>
|
||||
<div v-if="episodeType" class="px-2 pt-px pb-0.5 mx-0.5 bg-primary bg-opacity-50 rounded-full text-xs font-light text-fg capitalize">{{ episodeType }}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center pt-2">
|
||||
|
@ -196,7 +192,10 @@ export default {
|
|||
} else {
|
||||
await this.download()
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
this.pendingDownload = false
|
||||
}, 1000)
|
||||
},
|
||||
async download(selectedLocalFolder = null) {
|
||||
let localFolder = selectedLocalFolder
|
||||
|
|
|
@ -34,7 +34,7 @@
|
|||
<span class="px-1 text-sm">{{ playerIsPlaying ? $strings.ButtonPause : localEpisodeId ? $strings.ButtonPlay : $strings.ButtonStream }}</span>
|
||||
</ui-btn>
|
||||
<ui-btn v-if="showDownload" :color="downloadItem ? 'warning' : 'primary'" class="flex items-center justify-center mx-1" :padding-x="2" @click="downloadClick">
|
||||
<span class="material-icons" :class="downloadItem ? 'animate-pulse' : ''">{{ downloadItem ? 'downloading' : 'download' }}</span>
|
||||
<span class="material-icons" :class="(downloadItem || startingDownload) ? 'animate-pulse' : ''">{{ (downloadItem || startingDownload) ? 'downloading' : 'download' }}</span>
|
||||
</ui-btn>
|
||||
<ui-btn color="primary" class="flex items-center justify-center mx-1" :padding-x="2" @click="showMoreMenu = true">
|
||||
<span class="material-icons">more_vert</span>
|
||||
|
@ -111,7 +111,8 @@ export default {
|
|||
return {
|
||||
showMoreMenu: false,
|
||||
processing: false,
|
||||
resettingProgress: false
|
||||
resettingProgress: false,
|
||||
startingDownload: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -369,7 +370,13 @@ export default {
|
|||
}
|
||||
},
|
||||
async downloadClick() {
|
||||
if (this.downloadItem) return
|
||||
if (this.downloadItem || this.startingDownload) return
|
||||
|
||||
this.startingDownload = true
|
||||
setTimeout(() => {
|
||||
this.startingDownload = false
|
||||
}, 1000)
|
||||
|
||||
await this.$hapticsImpact()
|
||||
if (this.isIos) {
|
||||
// no local folders on iOS
|
||||
|
|
|
@ -54,7 +54,7 @@
|
|||
<span v-if="!showPlay" class="px-2 text-base">{{ $strings.ButtonRead }} {{ ebookFormat }}</span>
|
||||
</ui-btn>
|
||||
<ui-btn v-if="showDownload" :color="downloadItem ? 'warning' : 'primary'" class="flex items-center justify-center mx-1" :padding-x="2" @click="downloadClick">
|
||||
<span class="material-icons" :class="downloadItem ? 'animate-pulse' : ''">{{ downloadItem ? 'downloading' : 'download' }}</span>
|
||||
<span class="material-icons" :class="(downloadItem || startingDownload) ? 'animate-pulse' : ''">{{ (downloadItem || startingDownload) ? 'downloading' : 'download' }}</span>
|
||||
</ui-btn>
|
||||
<ui-btn color="primary" class="flex items-center justify-center mx-1" :padding-x="2" @click="moreButtonPress">
|
||||
<span class="material-icons">more_vert</span>
|
||||
|
@ -79,8 +79,8 @@
|
|||
<div v-if="podcastAuthor" class="text-sm">{{ podcastAuthor }}</div>
|
||||
<div v-else-if="bookAuthors && bookAuthors.length" class="text-sm">
|
||||
<template v-for="(author, index) in bookAuthors">
|
||||
<nuxt-link :key="author.id" :to="`/bookshelf/library?filter=authors.${$encode(author.id)}`" class="underline">{{ author.name }}</nuxt-link
|
||||
><span :key="`${author.id}-comma`" v-if="index < bookAuthors.length - 1">, </span>
|
||||
<nuxt-link :key="author.id" :to="`/bookshelf/library?filter=authors.${$encode(author.id)}`" class="underline">{{ author.name }}</nuxt-link>
|
||||
<span :key="`${author.id}-comma`" v-if="index < bookAuthors.length - 1">,</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
|
@ -90,8 +90,8 @@
|
|||
<div v-if="series && series.length" class="text-fg-muted uppercase text-sm">{{ $strings.LabelSeries }}</div>
|
||||
<div v-if="series && series.length" class="truncate text-sm">
|
||||
<template v-for="(series, index) in seriesList">
|
||||
<nuxt-link :key="series.id" :to="`/bookshelf/series/${series.id}`" class="underline">{{ series.text }}</nuxt-link
|
||||
><span :key="`${series.id}-comma`" v-if="index < seriesList.length - 1">, </span>
|
||||
<nuxt-link :key="series.id" :to="`/bookshelf/series/${series.id}`" class="underline">{{ series.text }}</nuxt-link>
|
||||
<span :key="`${series.id}-comma`" v-if="index < seriesList.length - 1">,</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
|
@ -101,16 +101,16 @@
|
|||
<div v-if="narrators && narrators.length" class="text-fg-muted uppercase text-sm">{{ $strings.LabelNarrators }}</div>
|
||||
<div v-if="narrators && narrators.length" class="truncate text-sm">
|
||||
<template v-for="(narrator, index) in narrators">
|
||||
<nuxt-link :key="narrator" :to="`/bookshelf/library?filter=narrators.${$encode(narrator)}`" class="underline">{{ narrator }}</nuxt-link
|
||||
><span :key="index" v-if="index < narrators.length - 1">, </span>
|
||||
<nuxt-link :key="narrator" :to="`/bookshelf/library?filter=narrators.${$encode(narrator)}`" class="underline">{{ narrator }}</nuxt-link>
|
||||
<span :key="index" v-if="index < narrators.length - 1">,</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div v-if="genres.length" class="text-fg-muted uppercase text-sm">{{ $strings.LabelGenres }}</div>
|
||||
<div v-if="genres.length" class="truncate text-sm">
|
||||
<template v-for="(genre, index) in genres">
|
||||
<nuxt-link :key="genre" :to="`/bookshelf/library?filter=genres.${$encode(genre)}`" class="underline">{{ genre }}</nuxt-link
|
||||
><span :key="index" v-if="index < genres.length - 1">, </span>
|
||||
<nuxt-link :key="genre" :to="`/bookshelf/library?filter=genres.${$encode(genre)}`" class="underline">{{ genre }}</nuxt-link>
|
||||
<span :key="index" v-if="index < genres.length - 1">,</span>
|
||||
</template>
|
||||
</div>
|
||||
|
||||
|
@ -206,7 +206,8 @@ export default {
|
|||
windowWidth: 0,
|
||||
descriptionClamped: false,
|
||||
showFullDescription: false,
|
||||
episodeStartingPlayback: null
|
||||
episodeStartingPlayback: null,
|
||||
startingDownload: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -585,9 +586,14 @@ export default {
|
|||
this.download(localFolder)
|
||||
},
|
||||
async downloadClick() {
|
||||
if (this.downloadItem) {
|
||||
if (this.downloadItem || this.startingDownload) {
|
||||
return
|
||||
}
|
||||
this.startingDownload = true
|
||||
setTimeout(() => {
|
||||
this.startingDownload = false
|
||||
}, 1000)
|
||||
|
||||
await this.$hapticsImpact()
|
||||
if (this.isIos) {
|
||||
// no local folders on iOS
|
||||
|
|
|
@ -46,7 +46,8 @@ export const state = () => ({
|
|||
export const getters = {
|
||||
getDownloadItem: state => (libraryItemId, episodeId = null) => {
|
||||
return state.itemDownloads.find(i => {
|
||||
if (episodeId && !i.episodes.some(e => e.id == episodeId)) return false
|
||||
// if (episodeId && !i.episodes.some(e => e.id == episodeId)) return false
|
||||
if (episodeId && i.episodeId !== episodeId) return false
|
||||
return i.libraryItemId == libraryItemId
|
||||
})
|
||||
},
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue