Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e5e09e2a authored by Darrell Shi's avatar Darrell Shi
Browse files

Scroll to newly added widget if needed

This changes adds a launched effect in edit mode and scrolls when a new
widget is added and not visible.

Test: manual; see video in bug
Fix: 355215590
Flag: com.android.systemui.communal_hub
Change-Id: I7dd71229dde65497a8e3e939d64042a021c389c5
parent 325cdf65
Loading
Loading
Loading
Loading
+33 −1
Original line number Diff line number Diff line
@@ -216,7 +216,9 @@ fun CommunalHub(
    val screenWidth = windowMetrics.bounds.width()
    val layoutDirection = LocalLayoutDirection.current

    if (!viewModel.isEditMode) {
    if (viewModel.isEditMode) {
        ScrollOnNewWidgetAddedEffect(communalContent, gridState)
    } else {
        ScrollOnUpdatedLiveContentEffect(communalContent, gridState)
    }

@@ -547,6 +549,36 @@ private fun ScrollOnUpdatedLiveContentEffect(
    }
}

/** Observes communal content and scrolls to a newly added widget if any. */
@Composable
private fun ScrollOnNewWidgetAddedEffect(
    communalContent: List<CommunalContentModel>,
    gridState: LazyGridState,
) {
    val coroutineScope = rememberCoroutineScope()
    val widgetKeys = remember { mutableListOf<String>() }

    LaunchedEffect(communalContent) {
        val oldWidgetKeys = widgetKeys.toList()
        widgetKeys.clear()
        widgetKeys.addAll(communalContent.filter { it.isWidgetContent() }.map { it.key })

        // Do nothing if there is no new widget
        val indexOfFirstNewWidget = widgetKeys.indexOfFirst { !oldWidgetKeys.contains(it) }
        if (indexOfFirstNewWidget < 0) {
            return@LaunchedEffect
        }

        // Scroll if the new widget is not visible
        val lastVisibleItemIndex = gridState.layoutInfo.visibleItemsInfo.lastOrNull()?.index
        if (lastVisibleItemIndex != null && indexOfFirstNewWidget > lastVisibleItemIndex) {
            // Launching with a scope to prevent the job from being canceled in the case of a
            // recomposition during scrolling
            coroutineScope.launch { gridState.animateScrollToItem(indexOfFirstNewWidget) }
        }
    }
}

@OptIn(ExperimentalFoundationApi::class)
@Composable
private fun BoxScope.CommunalHubLazyGrid(