mirror of
https://github.com/advplyr/audiobookshelf-app.git
synced 2026-08-27 13:54:01 +02:00
Update:Show loading indicator on play buttons when starting playback
This commit is contained in:
@@ -13,8 +13,11 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-8 min-w-8 flex justify-center">
|
||||
<button v-if="showPlayBtn" class="w-8 h-8 rounded-full border border-white border-opacity-20 flex items-center justify-center" @click.stop.prevent="playClick">
|
||||
<span class="material-icons" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
|
||||
<button v-if="showPlayBtn" class="w-8 h-8 rounded-full border border-white/20 flex items-center justify-center" @click.stop.prevent="playClick">
|
||||
<span v-if="!playerIsStartingForThisMedia" class="material-icons" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
|
||||
<svg v-else class="animate-spin" style="width: 18px; height: 18px" viewBox="0 0 24 24">
|
||||
<path fill="currentColor" d="M12,4V2A10,10 0 0,0 2,12H4A8,8 0 0,1 12,4Z" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="w-8 min-w-8 flex justify-center">
|
||||
@@ -117,6 +120,15 @@ export default {
|
||||
streamIsPlaying() {
|
||||
return this.$store.state.playerIsPlaying && this.isStreaming
|
||||
},
|
||||
playerIsStartingPlayback() {
|
||||
// Play has been pressed and waiting for native play response
|
||||
return this.$store.state.playerIsStartingPlayback
|
||||
},
|
||||
playerIsStartingForThisMedia() {
|
||||
const mediaId = this.$store.state.playerStartingPlaybackMediaId
|
||||
let thisMediaId = this.episodeId || this.libraryItem.id
|
||||
return mediaId === thisMediaId
|
||||
},
|
||||
userItemProgress() {
|
||||
return this.$store.getters['user/getUserMediaProgress'](this.libraryItem.id, this.episodeId)
|
||||
},
|
||||
@@ -142,10 +154,14 @@ export default {
|
||||
this.$emit('showMore', playlistItem)
|
||||
},
|
||||
async playClick() {
|
||||
if (this.playerIsStartingPlayback) return
|
||||
|
||||
await this.$hapticsImpact()
|
||||
let mediaId = this.episodeId || this.libraryItem.id
|
||||
if (this.streamIsPlaying) {
|
||||
this.$eventBus.$emit('pause-item')
|
||||
} else if (this.localLibraryItem) {
|
||||
this.$store.commit('setPlayerIsStartingPlayback', mediaId)
|
||||
this.$eventBus.$emit('play-item', {
|
||||
libraryItemId: this.localLibraryItem.id,
|
||||
episodeId: this.localEpisode?.id,
|
||||
@@ -153,6 +169,7 @@ export default {
|
||||
serverEpisodeId: this.episodeId
|
||||
})
|
||||
} else {
|
||||
this.$store.commit('setPlayerIsStartingPlayback', mediaId)
|
||||
this.$eventBus.$emit('play-item', {
|
||||
libraryItemId: this.libraryItem.id,
|
||||
episodeId: this.episodeId
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
|
||||
<div class="flex items-center pt-2">
|
||||
<div class="h-8 px-4 border border-border rounded-full flex items-center justify-center cursor-pointer" :class="userIsFinished ? 'text-white text-opacity-40' : ''" @click.stop="playClick">
|
||||
<span class="material-icons" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
|
||||
<span v-if="!playerIsStartingForThisMedia" class="material-icons" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
|
||||
<svg v-else 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>
|
||||
<p class="pl-2 pr-1 text-sm font-semibold">{{ timeRemaining }}</p>
|
||||
</div>
|
||||
|
||||
@@ -118,6 +121,14 @@ export default {
|
||||
streamIsPlaying() {
|
||||
return this.$store.state.playerIsPlaying && this.isStreaming
|
||||
},
|
||||
playerIsStartingPlayback() {
|
||||
// Play has been pressed and waiting for native play response
|
||||
return this.$store.state.playerIsStartingPlayback
|
||||
},
|
||||
playerIsStartingForThisMedia() {
|
||||
const mediaId = this.$store.state.playerStartingPlaybackMediaId
|
||||
return mediaId === this.episode?.id
|
||||
},
|
||||
itemProgress() {
|
||||
if (this.isLocal) return this.$store.getters['globals/getLocalMediaProgressById'](this.libraryItemId, this.episode.id)
|
||||
return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId, this.episode.id)
|
||||
@@ -227,10 +238,14 @@ export default {
|
||||
}
|
||||
},
|
||||
async playClick() {
|
||||
if (this.playerIsStartingPlayback) return
|
||||
|
||||
await this.$hapticsImpact()
|
||||
if (this.streamIsPlaying) {
|
||||
this.$eventBus.$emit('pause-item')
|
||||
} else {
|
||||
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
|
||||
|
||||
if (this.localEpisode && this.localLibraryItemId) {
|
||||
console.log('Play local episode', this.localEpisode.id, this.localLibraryItemId)
|
||||
|
||||
|
||||
@@ -29,7 +29,10 @@
|
||||
|
||||
<div class="flex items-center pt-2">
|
||||
<div class="h-8 px-4 border border-border hover:bg-white hover:bg-opacity-10 rounded-full flex items-center justify-center cursor-pointer" :class="userIsFinished ? 'text-fg text-opacity-40' : ''" @click.stop="playClick">
|
||||
<span class="material-icons" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
|
||||
<span v-if="!playerIsStartingForThisMedia" class="material-icons" :class="streamIsPlaying ? '' : 'text-success'">{{ streamIsPlaying ? 'pause' : 'play_arrow' }}</span>
|
||||
<svg v-else 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>
|
||||
<p class="pl-2 pr-1 text-sm font-semibold">{{ timeRemaining }}</p>
|
||||
</div>
|
||||
|
||||
@@ -122,6 +125,15 @@ export default {
|
||||
streamIsPlaying() {
|
||||
return this.$store.state.playerIsPlaying && this.isStreaming
|
||||
},
|
||||
playerIsStartingPlayback() {
|
||||
// Play has been pressed and waiting for native play response
|
||||
return this.$store.state.playerIsStartingPlayback
|
||||
},
|
||||
playerIsStartingForThisMedia() {
|
||||
if (!this.episode?.id) return false
|
||||
const mediaId = this.$store.state.playerStartingPlaybackMediaId
|
||||
return mediaId === this.episode.id
|
||||
},
|
||||
itemProgress() {
|
||||
if (this.isLocal) return this.$store.getters['globals/getLocalMediaProgressById'](this.libraryItemId, this.episode.id)
|
||||
return this.$store.getters['user/getUserMediaProgress'](this.libraryItemId, this.episode.id)
|
||||
@@ -135,10 +147,10 @@ export default {
|
||||
}
|
||||
},
|
||||
itemProgressPercent() {
|
||||
return this.itemProgress ? this.itemProgress.progress : 0
|
||||
return this.itemProgress?.progress || 0
|
||||
},
|
||||
userIsFinished() {
|
||||
return this.itemProgress ? !!this.itemProgress.isFinished : false
|
||||
return !!this.itemProgress?.isFinished
|
||||
},
|
||||
timeRemaining() {
|
||||
if (this.streamIsPlaying) return 'Playing'
|
||||
@@ -154,7 +166,7 @@ export default {
|
||||
return this.$store.getters['globals/getDownloadItem'](this.libraryItemId, this.episode.id)
|
||||
},
|
||||
localEpisodeId() {
|
||||
return this.localEpisode ? this.localEpisode.id : null
|
||||
return this.localEpisode?.id || null
|
||||
},
|
||||
podcast() {
|
||||
return this.episode.podcast || {}
|
||||
@@ -238,10 +250,14 @@ export default {
|
||||
}
|
||||
},
|
||||
async playClick() {
|
||||
if (this.playerIsStartingPlayback) return
|
||||
|
||||
await this.$hapticsImpact()
|
||||
if (this.streamIsPlaying) {
|
||||
this.$eventBus.$emit('pause-item')
|
||||
} else {
|
||||
this.$store.commit('setPlayerIsStartingPlayback', this.episode.id)
|
||||
|
||||
if (this.localEpisode && this.localLibraryItemId) {
|
||||
console.log('Play local episode', this.localEpisode.id, this.localLibraryItemId)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user