Fixed unfavorite list jump

This commit is contained in:
OmniaX-Dev 2026-06-23 11:39:25 +02:00
parent 02dd3c154a
commit 8baa347e81
2 changed files with 23 additions and 3 deletions

View file

@ -4,10 +4,10 @@
<selectionStates>
<SelectionState runConfigName="app">
<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">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=RFCY20YA30P" />
<DeviceId pluginId="LocalEmulator" identifier="path=/home/sylar/.android/avd/Medium_Phone.avd" />
</handle>
</Target>
</DropdownSelection>

View file

@ -45,8 +45,10 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.runtime.withFrameNanos
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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.viewmodel.compose.viewModel
import com.keylightpiano.pianotimeline.R
import kotlinx.coroutines.launch
import com.keylightpiano.pianotimeline.domain.Recording
@OptIn(ExperimentalMaterial3Api::class, ExperimentalLayoutApi::class)
@Composable
@ -93,6 +97,22 @@ fun RecordingListScreen(
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 hasActiveFilter = searchQuery.isNotEmpty() || hiddenArtists.isNotEmpty()
@ -269,7 +289,7 @@ fun RecordingListScreen(
RecordingItem(
recording = recording,
onPlayClick = { vm.onPlay(recording) },
onFavoriteClick = { vm.toggleFavorite(recording) },
onFavoriteClick = { onFavoriteToggle(recording) },
onNotesClick = if (recording.hasMidi) {
{ /* TODO: open falling notes */ }
} else null