summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt25
-rw-r--r--packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt21
-rw-r--r--packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt23
3 files changed, 47 insertions, 22 deletions
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt
index fda46b855a65..ef62eb726e2b 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/communal/ui/compose/ResizeableItemFrame.kt
@@ -30,6 +30,8 @@ import androidx.compose.foundation.layout.height
import androidx.compose.foundation.lazy.grid.LazyGridState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.rememberUpdatedState
import androidx.compose.runtime.snapshotFlow
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@@ -52,12 +54,11 @@ import com.android.systemui.communal.ui.viewmodel.ResizeableItemFrameViewModel
import com.android.systemui.lifecycle.rememberViewModel
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.filterNotNull
@Composable
private fun UpdateGridLayoutInfo(
viewModel: ResizeableItemFrameViewModel,
- index: Int,
+ key: String,
gridState: LazyGridState,
minItemSpan: Int,
gridContentPadding: PaddingValues,
@@ -67,7 +68,7 @@ private fun UpdateGridLayoutInfo(
LaunchedEffect(
density,
viewModel,
- index,
+ key,
gridState,
minItemSpan,
gridContentPadding,
@@ -85,9 +86,8 @@ private fun UpdateGridLayoutInfo(
snapshotFlow { gridState.layoutInfo.maxSpan },
snapshotFlow { gridState.layoutInfo.viewportSize.height },
snapshotFlow {
- gridState.layoutInfo.visibleItemsInfo.firstOrNull { it.index == index }
- }
- .filterNotNull(),
+ gridState.layoutInfo.visibleItemsInfo.firstOrNull { it.key == key }
+ },
::Triple,
)
.collectLatest { (maxItemSpan, viewportHeightPx, itemInfo) ->
@@ -97,8 +97,8 @@ private fun UpdateGridLayoutInfo(
viewportHeightPx,
maxItemSpan,
minItemSpan,
- itemInfo.row,
- itemInfo.span,
+ itemInfo?.row,
+ itemInfo?.span,
)
}
}
@@ -161,7 +161,7 @@ private fun BoxScope.DragHandle(
*/
@Composable
fun ResizableItemFrame(
- index: Int,
+ key: String,
gridState: LazyGridState,
minItemSpan: Int,
gridContentPadding: PaddingValues,
@@ -177,6 +177,7 @@ fun ResizableItemFrame(
content: @Composable () -> Unit,
) {
val brush = SolidColor(outlineColor)
+ val onResizeUpdated by rememberUpdatedState(onResize)
val viewModel =
rememberViewModel(traceName = "ResizeableItemFrame.viewModel") {
ResizeableItemFrameViewModel()
@@ -230,13 +231,15 @@ fun ResizableItemFrame(
UpdateGridLayoutInfo(
viewModel,
- index,
+ key,
gridState,
minItemSpan,
gridContentPadding,
verticalArrangement,
)
- LaunchedEffect(viewModel) { viewModel.resizeInfo.collectLatest(onResize) }
+ LaunchedEffect(viewModel) {
+ viewModel.resizeInfo.collectLatest { info -> onResizeUpdated(info) }
+ }
}
}
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt
index e1946fc7bc6f..f0d88ab41ad4 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModelTest.kt
@@ -254,6 +254,23 @@ class ResizeableItemFrameViewModelTest : SysuiTestCase() {
assertThat(resizeInfo).isEqualTo(ResizeInfo(-1, DragHandle.BOTTOM))
}
+ @Test
+ fun testRowInfoBecomesNull_revertsBackToDefault() =
+ testScope.runTest {
+ val gridLayout = singleSpanGrid.copy(maxItemSpan = 3, currentRow = 1)
+ updateGridLayout(gridLayout)
+
+ val topState = underTest.topDragState
+ assertThat(topState.anchors.toList()).containsExactly(0 to 0f, -1 to -30f)
+
+ val bottomState = underTest.bottomDragState
+ assertThat(bottomState.anchors.toList()).containsExactly(0 to 0f, 1 to 30f)
+
+ updateGridLayout(gridLayout.copy(currentRow = null))
+ assertThat(topState.anchors.toList()).containsExactly(0 to 0f)
+ assertThat(bottomState.anchors.toList()).containsExactly(0 to 0f)
+ }
+
@Test(expected = IllegalArgumentException::class)
fun testIllegalState_maxSpanSmallerThanMinSpan() =
testScope.runTest {
@@ -317,7 +334,7 @@ class ResizeableItemFrameViewModelTest : SysuiTestCase() {
val viewportHeightPx: Int,
val maxItemSpan: Int,
val minItemSpan: Int,
- val currentRow: Int,
- val currentSpan: Int,
+ val currentRow: Int?,
+ val currentSpan: Int?,
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt
index 7aad33da97b6..87fcdd7b97ee 100644
--- a/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/communal/ui/viewmodel/ResizeableItemFrameViewModel.kt
@@ -25,8 +25,7 @@ import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged
-import kotlinx.coroutines.flow.dropWhile
-import kotlinx.coroutines.flow.filterNotNull
+import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
@@ -45,7 +44,10 @@ data class ResizeInfo(
val spans: Int,
/** The drag handle which was used to resize the element. */
val fromHandle: DragHandle,
-)
+) {
+ /** Whether we are expanding. If false, then we are shrinking. */
+ val isExpanding = spans > 0
+}
class ResizeableItemFrameViewModel : ExclusiveActivatable() {
private data class GridLayoutInfo(
@@ -73,7 +75,7 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() {
snapshotFlow { bottomDragState.settledValue }
.map { ResizeInfo(it, DragHandle.BOTTOM) },
)
- .dropWhile { it.spans == 0 }
+ .filter { it.spans != 0 }
.distinctUntilChanged()
/**
@@ -86,9 +88,13 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() {
viewportHeightPx: Int,
maxItemSpan: Int,
minItemSpan: Int,
- currentRow: Int,
- currentSpan: Int,
+ currentRow: Int?,
+ currentSpan: Int?,
) {
+ if (currentSpan == null || currentRow == null) {
+ gridLayoutInfo.value = null
+ return
+ }
require(maxItemSpan >= minItemSpan) {
"Maximum item span of $maxItemSpan cannot be less than the minimum span of $minItemSpan"
}
@@ -114,10 +120,10 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() {
private fun calculateAnchorsForHandle(
handle: DragHandle,
- layoutInfo: GridLayoutInfo,
+ layoutInfo: GridLayoutInfo?,
): DraggableAnchors<Int> {
- if (!isDragAllowed(handle, layoutInfo)) {
+ if (layoutInfo == null || !isDragAllowed(handle, layoutInfo)) {
return DraggableAnchors { 0 at 0f }
}
@@ -188,7 +194,6 @@ class ResizeableItemFrameViewModel : ExclusiveActivatable() {
override suspend fun onActivated(): Nothing {
coroutineScope("ResizeableItemFrameViewModel.onActivated") {
gridLayoutInfo
- .filterNotNull()
.onEach { layoutInfo ->
topDragState.updateAnchors(
calculateAnchorsForHandle(DragHandle.TOP, layoutInfo)