mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-15 00:42:54 +01:00
queue: retain reset identity across duplicate edits
This commit is contained in:
@@ -169,6 +169,7 @@ data class QueueResetItem(
|
|||||||
val upNext: Boolean,
|
val upNext: Boolean,
|
||||||
val entryOccurrence: Int = 0,
|
val entryOccurrence: Int = 0,
|
||||||
val occurrence: Long = 0,
|
val occurrence: Long = 0,
|
||||||
|
val originEntryId: Long? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
data class QueueResetPoint(
|
data class QueueResetPoint(
|
||||||
@@ -720,7 +721,7 @@ class QueueRepository(
|
|||||||
} else {
|
} else {
|
||||||
0L
|
0L
|
||||||
}
|
}
|
||||||
return QueueResetItem(origin, resolvedSongId, position, upNext, entryOccurrence, occurrence)
|
return QueueResetItem(origin, resolvedSongId, position, upNext, entryOccurrence, occurrence, entry.originEntryId)
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class OriginEntryKey(
|
private data class OriginEntryKey(
|
||||||
@@ -797,6 +798,7 @@ class QueueRepository(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private data class OriginEntryGroup(
|
private data class OriginEntryGroup(
|
||||||
|
val key: OriginEntryKey,
|
||||||
val starts: List<Long>,
|
val starts: List<Long>,
|
||||||
val entries: List<ResolvedQueueEntry>,
|
val entries: List<ResolvedQueueEntry>,
|
||||||
)
|
)
|
||||||
@@ -814,7 +816,7 @@ class QueueRepository(
|
|||||||
val index = groupIndices[key]
|
val index = groupIndices[key]
|
||||||
if (index == null) {
|
if (index == null) {
|
||||||
groupIndices[key] = groups.size
|
groupIndices[key] = groups.size
|
||||||
groups += OriginEntryGroup(listOf(start), listOf(resolved))
|
groups += OriginEntryGroup(key, listOf(start), listOf(resolved))
|
||||||
} else {
|
} else {
|
||||||
groups[index] =
|
groups[index] =
|
||||||
groups[index].copy(
|
groups[index].copy(
|
||||||
@@ -834,9 +836,15 @@ class QueueRepository(
|
|||||||
): Long? {
|
): Long? {
|
||||||
val entries = if (item.upNext) snapshot.upNext else snapshot.entries
|
val entries = if (item.upNext) snapshot.upNext else snapshot.entries
|
||||||
val groups = originEntryGroups(entries, item.origin)
|
val groups = originEntryGroups(entries, item.origin)
|
||||||
val group = groups.getOrNull(item.entryOccurrence) ?: return null
|
val group =
|
||||||
|
if (item.originEntryId == null) {
|
||||||
|
groups.getOrNull(item.entryOccurrence)
|
||||||
|
} else {
|
||||||
|
groups.firstOrNull { it.key == OriginEntryKey(item.origin, item.originEntryId) }
|
||||||
|
} ?: return null
|
||||||
for ((index, resolved) in group.entries.withIndex()) {
|
for ((index, resolved) in group.entries.withIndex()) {
|
||||||
val entry = resolved.entry
|
val entry = resolved.entry
|
||||||
|
if (entry.originOccurrence != null && entry.originOccurrence != item.occurrence) continue
|
||||||
val rank =
|
val rank =
|
||||||
if (entry.kind == QueueKind.Playlist) {
|
if (entry.kind == QueueKind.Playlist) {
|
||||||
val position = dao.playlistPositionForOccurrence(entry.sourceId, entry.refId, item.songId, item.occurrence)
|
val position = dao.playlistPositionForOccurrence(entry.sourceId, entry.refId, item.songId, item.occurrence)
|
||||||
|
|||||||
@@ -508,6 +508,29 @@ class QueueRepositoryTest {
|
|||||||
assertEquals(2L, repository.cursor())
|
assertEquals(2L, repository.cursor())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun anUnrelatedOriginResetSkipsMovedSongsFromOtherPlaylistOccurrences() =
|
||||||
|
runTest {
|
||||||
|
seedLibrary()
|
||||||
|
db.libraryDao().upsertSongs(listOf(song("s0", "al1", track = 0, album = "First Album")))
|
||||||
|
setPlaylist("p2", "s4")
|
||||||
|
setPlaylist("p1", "s1", "s2", "s1")
|
||||||
|
val snapshot = repository.snapshotAfter(listOf(repository.playlistEntry(1, "p2"), repository.playlistEntry(1, "p1")))
|
||||||
|
repository.move(snapshot, from = 3, to = 1)
|
||||||
|
repository.setCursor(2)
|
||||||
|
repository.setPosition(42_000L)
|
||||||
|
val point = repository.captureResetPoint()
|
||||||
|
|
||||||
|
setPlaylist("p2", "s0", "s4")
|
||||||
|
repository.resetChangedOrigins(setOf(QueueOrigin(QueueKind.Playlist, 1, "p2")), point)
|
||||||
|
|
||||||
|
val updated = repository.snapshot()
|
||||||
|
assertEquals(listOf("s0", "s4", "s1", "s1", "s2"), resolveAll(updated))
|
||||||
|
assertEquals(3L, repository.remapPosition(updated, point.current!!))
|
||||||
|
assertEquals(3L, repository.cursor())
|
||||||
|
assertEquals(42_000L, repository.cursorPositionMs())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun aRemovedDuplicateOccurrenceDoesNotLeaveItsOffsetOnTheSurvivor() =
|
fun aRemovedDuplicateOccurrenceDoesNotLeaveItsOffsetOnTheSurvivor() =
|
||||||
runTest {
|
runTest {
|
||||||
@@ -613,6 +636,26 @@ class QueueRepositoryTest {
|
|||||||
assertEquals(3L, repository.snapshot().upNextAnchor)
|
assertEquals(3L, repository.snapshot().upNextAnchor)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun aResetKeepsTheCapturedDuplicateGroupAfterReordering() =
|
||||||
|
runTest {
|
||||||
|
seedLibrary()
|
||||||
|
setPlaylist("p1", "s1", "s2")
|
||||||
|
repository.snapshotAfter(listOf(repository.playlistEntry(1, "p1"), repository.playlistEntry(1, "p1")))
|
||||||
|
repository.setCursor(3)
|
||||||
|
repository.setPosition(42_000L)
|
||||||
|
val point = repository.captureResetPoint()
|
||||||
|
repository.move(repository.snapshot(), from = 2, to = 0)
|
||||||
|
|
||||||
|
repository.resetChangedOrigins(setOf(QueueOrigin(QueueKind.Playlist, 1, "p1")), point)
|
||||||
|
|
||||||
|
val updated = repository.snapshot()
|
||||||
|
assertEquals(listOf("s1", "s2", "s1", "s2"), resolveAll(updated))
|
||||||
|
assertEquals(1L, repository.remapPosition(updated, point.current!!))
|
||||||
|
assertEquals(1L, repository.cursor())
|
||||||
|
assertEquals(42_000L, repository.cursorPositionMs())
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun aChangedOriginResetRestoresFullyFragmentedDuplicateEntries() =
|
fun aChangedOriginResetRestoresFullyFragmentedDuplicateEntries() =
|
||||||
runTest {
|
runTest {
|
||||||
|
|||||||
Reference in New Issue
Block a user