Merge branch '310-player-shuffling-restart' into 'develop'
Resolve "shuffling restarts current song" Closes #310 See merge request funkwhale/funkwhale!268
This commit is contained in:
commit
0d84e31a71
|
@ -0,0 +1 @@
|
|||
Fixed current track restart/hiccup when shuffling queue, deleting track from queue or reordering (#310)
|
|
@ -116,8 +116,8 @@
|
|||
</div>
|
||||
<div class="ui bottom attached tab" data-tab="queue">
|
||||
<table class="ui compact inverted very basic fixed single line unstackable table">
|
||||
<draggable v-model="queue.tracks" element="tbody" @update="reorder">
|
||||
<tr @click="$store.dispatch('queue/currentIndex', index)" v-for="(track, index) in queue.tracks" :key="index" :class="[{'active': index === queue.currentIndex}]">
|
||||
<draggable v-model="tracks" element="tbody" @update="reorder">
|
||||
<tr @click="$store.dispatch('queue/currentIndex', index)" v-for="(track, index) in tracks" :key="index" :class="[{'active': index === queue.currentIndex}]">
|
||||
<td class="right aligned">{{ index + 1}}</td>
|
||||
<td class="center aligned">
|
||||
<img class="ui mini image" v-if="track.album.cover" :src="$store.getters['instance/absoluteUrl'](track.album.cover)">
|
||||
|
@ -176,6 +176,7 @@ export default {
|
|||
return {
|
||||
selectedTab: 'library',
|
||||
backend: backend,
|
||||
tracksChangeBuffer: null,
|
||||
isCollapsed: true,
|
||||
fetchInterval: null
|
||||
}
|
||||
|
@ -207,6 +208,14 @@ export default {
|
|||
return adminPermissions.filter(e => {
|
||||
return e
|
||||
}).length > 0
|
||||
},
|
||||
tracks: {
|
||||
get () {
|
||||
return this.$store.state.queue.tracks
|
||||
},
|
||||
set (value) {
|
||||
this.tracksChangeBuffer = value
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -219,7 +228,7 @@ export default {
|
|||
},
|
||||
reorder: function (event) {
|
||||
this.$store.commit('queue/reorder', {
|
||||
oldIndex: event.oldIndex, newIndex: event.newIndex})
|
||||
tracks: this.tracksChangeBuffer, oldIndex: event.oldIndex, newIndex: event.newIndex})
|
||||
},
|
||||
scrollToCurrent () {
|
||||
let current = $(this.$el).find('[data-tab="queue"] .active')[0]
|
||||
|
|
|
@ -1,16 +1,16 @@
|
|||
<template>
|
||||
<div class="ui inverted segment player-wrapper" :style="style">
|
||||
<div class="player">
|
||||
<audio-track
|
||||
ref="currentAudio"
|
||||
v-if="renderAudio && currentTrack"
|
||||
:key="currentTrack.id"
|
||||
:is-current="true"
|
||||
:start-time="$store.state.player.currentTime"
|
||||
:autoplay="$store.state.player.playing"
|
||||
:track="currentTrack">
|
||||
</audio-track>
|
||||
|
||||
<keep-alive>
|
||||
<audio-track
|
||||
ref="currentAudio"
|
||||
v-if="renderAudio && currentTrack"
|
||||
:is-current="true"
|
||||
:start-time="$store.state.player.currentTime"
|
||||
:autoplay="$store.state.player.playing"
|
||||
:track="currentTrack">
|
||||
</audio-track>
|
||||
</keep-alive>
|
||||
<div v-if="currentTrack" class="track-area ui unstackable items">
|
||||
<div class="ui inverted item">
|
||||
<div class="ui tiny image">
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
@error="errored"
|
||||
@loadeddata="loaded"
|
||||
@durationchange="updateDuration"
|
||||
@timeupdate="updateProgress"
|
||||
@timeupdate="updateProgressThrottled"
|
||||
@ended="ended"
|
||||
preload>
|
||||
<source
|
||||
|
@ -30,6 +30,7 @@ export default {
|
|||
},
|
||||
data () {
|
||||
return {
|
||||
realTrack: this.track,
|
||||
sourceErrors: 0,
|
||||
isUpdatingTime: false
|
||||
}
|
||||
|
@ -43,7 +44,7 @@ export default {
|
|||
looping: state => state.player.looping
|
||||
}),
|
||||
srcs: function () {
|
||||
let file = this.track.files[0]
|
||||
let file = this.realTrack.files[0]
|
||||
if (!file) {
|
||||
this.$store.dispatch('player/trackErrored')
|
||||
return []
|
||||
|
@ -61,6 +62,9 @@ export default {
|
|||
})
|
||||
}
|
||||
return sources
|
||||
},
|
||||
updateProgressThrottled () {
|
||||
return _.throttle(this.updateProgress, 250)
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
@ -100,30 +104,40 @@ export default {
|
|||
}
|
||||
}
|
||||
},
|
||||
updateProgress: _.throttle(function () {
|
||||
updateProgress: function () {
|
||||
this.isUpdatingTime = true
|
||||
if (this.$refs.audio) {
|
||||
this.$store.dispatch('player/updateProgress', this.$refs.audio.currentTime)
|
||||
}
|
||||
}, 250),
|
||||
},
|
||||
ended: function () {
|
||||
let onlyTrack = this.$store.state.queue.tracks.length === 1
|
||||
if (this.looping === 1 || (onlyTrack && this.looping === 2)) {
|
||||
this.setCurrentTime(0)
|
||||
this.$refs.audio.play()
|
||||
} else {
|
||||
this.$store.dispatch('player/trackEnded', this.track)
|
||||
this.$store.dispatch('player/trackEnded', this.realTrack)
|
||||
}
|
||||
},
|
||||
setCurrentTime (t) {
|
||||
if (t < 0 | t > this.duration) {
|
||||
return
|
||||
}
|
||||
this.updateProgress(t)
|
||||
if (t === this.$refs.audio.currentTime) {
|
||||
return
|
||||
}
|
||||
if (t === 0) {
|
||||
this.updateProgressThrottled.cancel()
|
||||
}
|
||||
this.$refs.audio.currentTime = t
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
track: _.debounce(function (newValue) {
|
||||
this.realTrack = newValue
|
||||
this.setCurrentTime(0)
|
||||
this.$refs.audio.load()
|
||||
}, 1000, {leading: true, trailing: true}),
|
||||
playing: function (newValue) {
|
||||
if (newValue === true) {
|
||||
this.$refs.audio.play()
|
||||
|
@ -131,6 +145,11 @@ export default {
|
|||
this.$refs.audio.pause()
|
||||
}
|
||||
},
|
||||
'$store.state.queue.currentIndex' () {
|
||||
if (this.$store.state.player.playing) {
|
||||
this.$refs.audio.play()
|
||||
}
|
||||
},
|
||||
volume: function (newValue) {
|
||||
this.$refs.audio.volume = newValue
|
||||
},
|
||||
|
|
|
@ -31,9 +31,10 @@ export default {
|
|||
insert (state, {track, index}) {
|
||||
state.tracks.splice(index, 0, track)
|
||||
},
|
||||
reorder (state, {oldIndex, newIndex}) {
|
||||
reorder (state, {tracks, oldIndex, newIndex}) {
|
||||
// called when the user uses drag / drop to reorder
|
||||
// tracks in queue
|
||||
state.tracks = tracks
|
||||
if (oldIndex === state.currentIndex) {
|
||||
state.currentIndex = newIndex
|
||||
return
|
||||
|
@ -102,7 +103,7 @@ export default {
|
|||
}
|
||||
if (current) {
|
||||
// we play next track, which now have the same index
|
||||
dispatch('currentIndex', index)
|
||||
commit('currentIndex', index)
|
||||
}
|
||||
if (state.currentIndex + 1 === state.tracks.length) {
|
||||
dispatch('radios/populateQueue', null, {root: true})
|
||||
|
@ -156,7 +157,6 @@ export default {
|
|||
let toKeep = state.tracks.slice(0, state.currentIndex + 1)
|
||||
let toShuffle = state.tracks.slice(state.currentIndex + 1)
|
||||
let shuffled = toKeep.concat(_.shuffle(toShuffle))
|
||||
commit('player/currentTime', 0, {root: true})
|
||||
commit('tracks', [])
|
||||
let params = {tracks: shuffled}
|
||||
if (callback) {
|
||||
|
|
|
@ -169,11 +169,11 @@ describe('store/queue', () => {
|
|||
payload: 2,
|
||||
params: {state: {currentIndex: 2}},
|
||||
expectedMutations: [
|
||||
{ type: 'splice', payload: {start: 2, size: 1} }
|
||||
{ type: 'splice', payload: {start: 2, size: 1} },
|
||||
{ type: 'currentIndex', payload: 2 }
|
||||
],
|
||||
expectedActions: [
|
||||
{ type: 'player/stop', payload: null, options: {root: true} },
|
||||
{ type: 'currentIndex', payload: 2 }
|
||||
{ type: 'player/stop', payload: null, options: {root: true} }
|
||||
]
|
||||
}, done)
|
||||
})
|
||||
|
@ -324,7 +324,6 @@ describe('store/queue', () => {
|
|||
action: store.actions.shuffle,
|
||||
params: {state: {currentIndex: 1, tracks: tracks}},
|
||||
expectedMutations: [
|
||||
{ type: 'player/currentTime', payload: 0, options: {root: true} },
|
||||
{ type: 'tracks', payload: [] }
|
||||
],
|
||||
expectedActions: [
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import store from '@/store/ui'
|
||||
|
||||
import { testAction } from '../../utils'
|
||||
|
||||
describe('store/ui', () => {
|
||||
describe('mutations', () => {
|
||||
it('addMessage', () => {
|
||||
|
|
Loading…
Reference in New Issue