mirror of
https://github.com/austinried/subtracks.git
synced 2026-11-11 15:29:15 +01:00
anchor the queue window at the playing track
This commit is contained in:
@@ -35,7 +35,6 @@ import androidx.compose.runtime.remember
|
|||||||
import androidx.compose.runtime.rememberCoroutineScope
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.runtime.snapshotFlow
|
import androidx.compose.runtime.snapshotFlow
|
||||||
import androidx.compose.runtime.withFrameNanos
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
@@ -102,7 +101,7 @@ class QueueViewModel(
|
|||||||
withTimeoutOrNull(POSITION_TIMEOUT_MS) {
|
withTimeoutOrNull(POSITION_TIMEOUT_MS) {
|
||||||
playbackController.state.first { it.position != null }.position
|
playbackController.state.first { it.position != null }.position
|
||||||
}?.coerceIn(0, size - 1) ?: 0L
|
}?.coerceIn(0, size - 1) ?: 0L
|
||||||
val start = (cursor - QUEUE_CHUNK / 2).coerceAtLeast(0)
|
val start = cursor
|
||||||
val end = (start + QUEUE_CHUNK - 1).coerceAtMost(size - 1)
|
val end = (start + QUEUE_CHUNK - 1).coerceAtMost(size - 1)
|
||||||
rows.addAll(queueRepository.range(snapshot, start, end).map(::newRow))
|
rows.addAll(queueRepository.range(snapshot, start, end).map(::newRow))
|
||||||
first = rows.first().position
|
first = rows.first().position
|
||||||
@@ -289,17 +288,6 @@ fun QueueScreen(
|
|||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
var dragFrom by remember { mutableStateOf<Long?>(null) }
|
var dragFrom by remember { mutableStateOf<Long?>(null) }
|
||||||
var dragTo by remember { mutableStateOf<Long?>(null) }
|
var dragTo by remember { mutableStateOf<Long?>(null) }
|
||||||
var centered by remember { mutableStateOf(false) }
|
|
||||||
|
|
||||||
LaunchedEffect(ready, rows.size, currentPosition) {
|
|
||||||
if (centered || !ready) return@LaunchedEffect
|
|
||||||
val position = currentPosition ?: return@LaunchedEffect
|
|
||||||
val index = rows.indexOfFirst { it.position == position }
|
|
||||||
if (index >= 0) {
|
|
||||||
listState.requestScrollToItem(index)
|
|
||||||
centered = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val reorderState =
|
val reorderState =
|
||||||
rememberReorderableLazyListState(listState) { from, to ->
|
rememberReorderableLazyListState(listState) { from, to ->
|
||||||
@@ -310,9 +298,8 @@ fun QueueScreen(
|
|||||||
dragTo = toPosition
|
dragTo = toPosition
|
||||||
}
|
}
|
||||||
|
|
||||||
LaunchedEffect(listState, centered) {
|
LaunchedEffect(listState, ready) {
|
||||||
if (!centered) return@LaunchedEffect
|
if (!ready) return@LaunchedEffect
|
||||||
withFrameNanos { }
|
|
||||||
snapshotFlow {
|
snapshotFlow {
|
||||||
val info = listState.layoutInfo
|
val info = listState.layoutInfo
|
||||||
val firstVisible = info.visibleItemsInfo.firstOrNull()?.index ?: -1
|
val firstVisible = info.visibleItemsInfo.firstOrNull()?.index ?: -1
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class QueueViewModelTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun openingLoadsAWindowAroundTheCursorAndExtendingGrowsIt() {
|
fun openingLoadsAWindowAtTheCursorAndExtendingGrowsIt() {
|
||||||
runBlocking { seedSongs(200) }
|
runBlocking { seedSongs(200) }
|
||||||
controller.playSongs(1, 100)
|
controller.playSongs(1, 100)
|
||||||
await { controller.state.value.position == 100L }
|
await { controller.state.value.position == 100L }
|
||||||
@@ -71,15 +71,15 @@ class QueueViewModelTest {
|
|||||||
viewModel.open()
|
viewModel.open()
|
||||||
await { viewModel.ready }
|
await { viewModel.ready }
|
||||||
|
|
||||||
assertEquals((70L..129L).toList(), viewModel.rows.map { it.position })
|
assertEquals((100L..159L).toList(), viewModel.rows.map { it.position })
|
||||||
|
|
||||||
viewModel.loadNewer()
|
viewModel.loadNewer()
|
||||||
await { viewModel.rows.lastOrNull()?.position == 189L }
|
await { viewModel.rows.lastOrNull()?.position == 199L }
|
||||||
assertEquals((70L..189L).toList(), viewModel.rows.map { it.position })
|
assertEquals((100L..199L).toList(), viewModel.rows.map { it.position })
|
||||||
|
|
||||||
viewModel.loadOlder()
|
viewModel.loadOlder()
|
||||||
await { viewModel.rows.firstOrNull()?.position == 10L }
|
await { viewModel.rows.firstOrNull()?.position == 40L }
|
||||||
assertEquals((10L..189L).toList(), viewModel.rows.map { it.position })
|
assertEquals((40L..199L).toList(), viewModel.rows.map { it.position })
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -94,7 +94,7 @@ class QueueViewModelTest {
|
|||||||
viewModel.reorder(fromIndex = 0, toIndex = 2)
|
viewModel.reorder(fromIndex = 0, toIndex = 2)
|
||||||
|
|
||||||
val positions = viewModel.rows.map { it.position }
|
val positions = viewModel.rows.map { it.position }
|
||||||
assertEquals(listOf(71L, 72L, 70L), positions.take(3))
|
assertEquals(listOf(101L, 102L, 100L), positions.take(3))
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun seedSongs(count: Int) {
|
private suspend fun seedSongs(count: Int) {
|
||||||
|
|||||||
Reference in New Issue
Block a user