queue: shift back if removing playing end

Shift the queue index backwards if the current song at the end of a
queue is removed.

Without this, the index becomes OOB and makes the queue be interpreted
as entirely empty when it actually isn't, which is compounded by a
remove-1 update intruction leading to a RecyclerView inconsistency
crash.
This commit is contained in:
Alexander Capehart 2023-06-02 13:34:00 -06:00
parent df174e22f6
commit 4581532928
No known key found for this signature in database
GPG key ID: 37DBE3621FE9AD47
2 changed files with 9 additions and 4 deletions

View file

@ -107,7 +107,7 @@ interface Queue {
}
}
class EditableQueue : Queue {
class MutableQueue : Queue {
@Volatile private var heap = mutableListOf<Song>()
@Volatile private var orderedMapping = mutableListOf<Int>()
@Volatile private var shuffledMapping = mutableListOf<Int>()
@ -302,6 +302,7 @@ class EditableQueue : Queue {
* @return A [Queue.Change] instance that reflects the changes made.
*/
fun remove(at: Int): Queue.Change {
val lastIndex = orderedMapping.lastIndex
if (shuffledMapping.isNotEmpty()) {
// Remove the specified index in the shuffled mapping and the analogous song in the
// ordered mapping.
@ -321,12 +322,16 @@ class EditableQueue : Queue {
// We just removed the currently playing song.
index == at -> {
logD("Removed current song")
if (lastIndex == index) {
logD("Current song at end of queue, shift back")
--index
}
Queue.Change.Type.SONG
}
// Index was ahead of removed song, shift back to preserve consistency.
index > at -> {
logD("Removed before current song, shift back")
index -= 1
--index
Queue.Change.Type.INDEX
}
// Nothing to do

View file

@ -22,7 +22,7 @@ import javax.inject.Inject
import org.oxycblt.auxio.BuildConfig
import org.oxycblt.auxio.music.MusicParent
import org.oxycblt.auxio.music.Song
import org.oxycblt.auxio.playback.queue.EditableQueue
import org.oxycblt.auxio.playback.queue.MutableQueue
import org.oxycblt.auxio.playback.queue.Queue
import org.oxycblt.auxio.util.logD
import org.oxycblt.auxio.util.logW
@ -305,7 +305,7 @@ class PlaybackStateManagerImpl @Inject constructor() : PlaybackStateManager {
@Volatile private var pendingAction: InternalPlayer.Action? = null
@Volatile private var isInitialized = false
override val queue = EditableQueue()
override val queue = MutableQueue()
@Volatile
override var parent: MusicParent? = null
private set