summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--aconfig/FeatureFlags.aconfig7
-rw-r--r--java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt40
2 files changed, 47 insertions, 0 deletions
diff --git a/aconfig/FeatureFlags.aconfig b/aconfig/FeatureFlags.aconfig
index 6f7e75d5..8396bc24 100644
--- a/aconfig/FeatureFlags.aconfig
+++ b/aconfig/FeatureFlags.aconfig
@@ -116,3 +116,10 @@ flag {
description: "Allow toggling of final Shareousel item"
bug: "349468879"
}
+
+flag {
+ name: "shareousel_scroll_offscreen_selections"
+ namespace: "intentresolver"
+ description: "Whether to scroll items onscreen when they are partially offscreen and selected/unselected."
+ bug: "351883537"
+}
diff --git a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt
index f8cf243d..4b87d227 100644
--- a/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt
+++ b/java/src/com/android/intentresolver/contentpreview/payloadtoggle/ui/composable/ShareouselComposable.kt
@@ -64,6 +64,7 @@ import androidx.compose.ui.semantics.contentDescription
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.unit.dp
import androidx.lifecycle.compose.collectAsStateWithLifecycle
+import com.android.intentresolver.Flags.shareouselScrollOffscreenSelections
import com.android.intentresolver.Flags.unselectFinalItem
import com.android.intentresolver.R
import com.android.intentresolver.contentpreview.payloadtoggle.domain.model.ValueUpdate
@@ -189,6 +190,45 @@ private fun PreviewCarousel(
firstSelectedIndex = min(index, firstSelectedIndex ?: Int.MAX_VALUE)
}
+ if (shareouselScrollOffscreenSelections()) {
+ LaunchedEffect(index, model.uri) {
+ var current: Boolean? = null
+ previewModel.isSelected.collect { selected ->
+ when {
+ // First update will always be the current state, so we just want to
+ // record the state and do nothing else.
+ current == null -> current = selected
+
+ // We only want to act when the state changes
+ current != selected -> {
+ current = selected
+ with(carouselState.layoutInfo) {
+ visibleItemsInfo
+ .firstOrNull { it.index == index }
+ ?.let { item ->
+ when {
+ // Item is partially past start of viewport
+ item.offset < viewportStartOffset ->
+ -viewportStartOffset
+ // Item is partially past end of viewport
+ (item.offset + item.size) > viewportEndOffset ->
+ item.size - viewportEndOffset
+ // Item is fully within viewport
+ else -> null
+ }?.let { scrollOffset ->
+ carouselState.animateScrollToItem(
+ index = index,
+ scrollOffset = scrollOffset,
+ )
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
ShareouselCard(
viewModel.preview(
model,