diff options
| author | 2024-03-11 11:11:52 -0700 | |
|---|---|---|
| committer | 2024-03-13 17:52:00 +0000 | |
| commit | cac2753cd3e5c777548b802982c1b6eca1f2fbc7 (patch) | |
| tree | 01e66145971579fdeda7ce33beae7a6a44a77b7b | |
| parent | cd407d193c116eeb3fd80e09830a5b84d068951c (diff) | |
Automatic scroll when live content is updated
Bug: 328617832
Test: manual; see a video in bug
Flag: ACONFIG com.android.systemui.communal_hub TEAMFOOD
Change-Id: I6546562d850bd475e5d553de6db05db9863550ad
2 files changed, 26 insertions, 23 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt index 6a510bd13f7c..e1608c4d548c 100644 --- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt +++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/CommunalHub.kt @@ -76,7 +76,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue -import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -159,7 +158,9 @@ fun CommunalHub( val contentPadding = gridContentPadding(viewModel.isEditMode, toolbarSize) val contentOffset = beforeContentPadding(contentPadding).toOffset() - ScrollOnNewSmartspaceEffect(viewModel, gridState) + if (!viewModel.isEditMode) { + ScrollOnUpdatedLiveContentEffect(communalContent, gridState) + } Box( modifier = @@ -331,31 +332,33 @@ private fun onMotionEvent(viewModel: BaseCommunalViewModel) { viewModel.signalUserInteraction() } +/** + * Observes communal content and scrolls to any added or updated live content, e.g. a new media + * session is started, or a paused timer is resumed. + */ @Composable -private fun ScrollOnNewSmartspaceEffect( - viewModel: BaseCommunalViewModel, - gridState: LazyGridState +private fun ScrollOnUpdatedLiveContentEffect( + communalContent: List<CommunalContentModel>, + gridState: LazyGridState, ) { - val communalContent by viewModel.communalContent.collectAsState(initial = emptyList()) - var smartspaceCount by remember { mutableStateOf(0) } + val coroutineScope = rememberCoroutineScope() + val liveContentKeys = remember { mutableListOf<String>() } LaunchedEffect(communalContent) { - snapshotFlow { gridState.firstVisibleItemIndex } - .collect { index -> - val existingSmartspaceCount = smartspaceCount - smartspaceCount = communalContent.count { it.isSmartspace() } - val firstIndex = communalContent.indexOfFirst { it.isSmartspace() } + val prevLiveContentKeys = liveContentKeys.toList() + liveContentKeys.clear() + liveContentKeys.addAll(communalContent.filter { it.isLiveContent() }.map { it.key }) - // Scroll to the beginning of the smartspace area whenever the number of - // smartspace elements grows - if ( - existingSmartspaceCount < smartspaceCount && - !viewModel.isEditMode && - index > firstIndex - ) { - gridState.animateScrollToItem(firstIndex) - } - } + // Find the first updated content + val indexOfFirstUpdatedContent = + liveContentKeys.indexOfFirst { !prevLiveContentKeys.contains(it) } + + // Scroll if current position is behind the first updated content + if (indexOfFirstUpdatedContent in 0..<gridState.firstVisibleItemIndex) { + // Launching with a scope to prevent the job from being canceled in the case of a + // recomposition during scrolling + coroutineScope.launch { gridState.animateScrollToItem(indexOfFirstUpdatedContent) } + } } } diff --git a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt index 5fabd3c9bed8..fc8d6588c3d4 100644 --- a/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt +++ b/packages/SystemUI/src/com/android/systemui/communal/domain/model/CommunalContentModel.kt @@ -154,5 +154,5 @@ sealed interface CommunalContentModel { fun isWidgetContent() = this is WidgetContent - fun isSmartspace() = this is Smartspace + fun isLiveContent() = this is Smartspace || this is Umo } |