Fixed unfavorite list jump
This commit is contained in:
parent
02dd3c154a
commit
8baa347e81
2 changed files with 23 additions and 3 deletions
|
|
@ -4,10 +4,10 @@
|
||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-06-23T09:15:42.913635127Z">
|
<DropdownSelection timestamp="2026-06-23T09:36:00.583173984Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
<handle>
|
<handle>
|
||||||
<DeviceId pluginId="PhysicalDevice" identifier="serial=RFCY20YA30P" />
|
<DeviceId pluginId="LocalEmulator" identifier="path=/home/sylar/.android/avd/Medium_Phone.avd" />
|
||||||
</handle>
|
</handle>
|
||||||
</Target>
|
</Target>
|
||||||
</DropdownSelection>
|
</DropdownSelection>
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,10 @@ import androidx.compose.runtime.LaunchedEffect
|
||||||
import androidx.compose.runtime.getValue
|
import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.remember
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.rememberCoroutineScope
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
import androidx.compose.runtime.saveable.rememberSaveable
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
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.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
|
|
@ -56,6 +58,8 @@ import androidx.compose.ui.unit.dp
|
||||||
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
||||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||||
import com.keylightpiano.pianotimeline.R
|
import com.keylightpiano.pianotimeline.R
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import com.keylightpiano.pianotimeline.domain.Recording
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
|
||||||
@Composable
|
@Composable
|
||||||
|
|
@ -93,6 +97,22 @@ fun RecordingListScreen(
|
||||||
wasRefreshing = isRefreshing
|
wasRefreshing = isRefreshing
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Preserve scroll position across a favorite toggle (which reorders the list).
|
||||||
|
// When the user stars/unstars an item, we snapshot the current top item's
|
||||||
|
// index+offset, then restore it after the list settles so the viewport
|
||||||
|
// doesn't jump to follow the moved item.
|
||||||
|
val coroutineScope = rememberCoroutineScope()
|
||||||
|
val onFavoriteToggle: (Recording) -> Unit = { recording ->
|
||||||
|
val anchorIndex = listState.firstVisibleItemIndex
|
||||||
|
val anchorOffset = listState.firstVisibleItemScrollOffset
|
||||||
|
vm.toggleFavorite(recording)
|
||||||
|
coroutineScope.launch {
|
||||||
|
// Wait one frame for the reordered list to be applied, then restore.
|
||||||
|
withFrameNanos { }
|
||||||
|
listState.scrollToItem(anchorIndex, anchorOffset)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
|
val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior()
|
||||||
val hasActiveFilter = searchQuery.isNotEmpty() || hiddenArtists.isNotEmpty()
|
val hasActiveFilter = searchQuery.isNotEmpty() || hiddenArtists.isNotEmpty()
|
||||||
|
|
||||||
|
|
@ -269,7 +289,7 @@ fun RecordingListScreen(
|
||||||
RecordingItem(
|
RecordingItem(
|
||||||
recording = recording,
|
recording = recording,
|
||||||
onPlayClick = { vm.onPlay(recording) },
|
onPlayClick = { vm.onPlay(recording) },
|
||||||
onFavoriteClick = { vm.toggleFavorite(recording) },
|
onFavoriteClick = { onFavoriteToggle(recording) },
|
||||||
onNotesClick = if (recording.hasMidi) {
|
onNotesClick = if (recording.hasMidi) {
|
||||||
{ /* TODO: open falling notes */ }
|
{ /* TODO: open falling notes */ }
|
||||||
} else null
|
} else null
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue