summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt29
-rw-r--r--java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt72
-rw-r--r--java/src/com/android/intentresolver/contentpreview/shareousel/ui/composable/ShareouselComposable.kt9
-rw-r--r--java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt16
4 files changed, 67 insertions, 59 deletions
diff --git a/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt b/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
index 8a34e6a9..003f6884 100644
--- a/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
+++ b/java/src/com/android/intentresolver/contentpreview/PayloadToggleInteractor.kt
@@ -118,7 +118,6 @@ class PayloadToggleInteractor(
fun start() {
scope.launch {
- publishInitialState()
val cursorReader = cursorReaderProvider()
val selectedItems =
initiallySharedUris.map { uri ->
@@ -148,31 +147,6 @@ class PayloadToggleInteractor(
}
}
- private suspend fun publishInitialState() {
- stateFlowSource.emit(
- State(
- if (0 <= focusedUriIdx && focusedUriIdx < initiallySharedUris.size) {
- val fileInfo = uriMetadataReader(initiallySharedUris[focusedUriIdx])
- listOf(
- Record(
- // a unique key that won't appear anywhere after more items are loaded
- -initiallySharedUris.size - 1,
- initiallySharedUris[focusedUriIdx],
- fileInfo.previewUri,
- fileInfo.mimeType,
- fileInfo.mimeType?.mimeTypeToItemType() ?: ItemType.File,
- ),
- )
- } else {
- emptyList()
- },
- hasMoreItemsBefore = true,
- hasMoreItemsAfter = true,
- allowSelectionChange = false,
- )
- )
- }
-
fun loadMorePreviousItems() {
invokeAsyncIfNotRunning(prevPageLoadingGate) {
doLoadMorePreviousItems()
@@ -194,7 +168,6 @@ class PayloadToggleInteractor(
val (_, selectionTracker) = waitForCursorData() ?: return@launch
selectionTracker.setItemSelection(record.key, record, isSelected)
val targetIntent = targetIntentModifier(selectionTracker.getSelection())
-
val newJob = scope.launch { notifySelectionChanged(targetIntent) }
notifySelectionJobRef.getAndSet(newJob)?.cancel()
}
@@ -390,8 +363,10 @@ class PayloadTogglePreviewInteractor(
val previewUri: Flow<Uri?>
get() = interactor.previewUri(item)
+
val selected: Flow<Boolean>
get() = interactor.selected(item)
+
val key
get() = item.key
}
diff --git a/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt b/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt
index 4dd0d3f5..cc89f5bf 100644
--- a/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt
+++ b/java/src/com/android/intentresolver/contentpreview/ShareouselContentPreviewUi.kt
@@ -21,16 +21,26 @@ import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.compose.foundation.isSystemInDarkTheme
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.height
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.material3.dynamicLightColorScheme
import androidx.compose.runtime.LaunchedEffect
+import androidx.compose.runtime.getValue
+import androidx.compose.runtime.mutableStateOf
+import androidx.compose.runtime.remember
+import androidx.compose.runtime.setValue
+import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ComposeView
import androidx.compose.ui.platform.LocalContext
+import androidx.compose.ui.res.dimensionResource
+import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel
import com.android.intentresolver.R
import com.android.intentresolver.contentpreview.ChooserContentPreviewUi.ActionFactory
import com.android.intentresolver.contentpreview.shareousel.ui.composable.Shareousel
+import com.android.intentresolver.contentpreview.shareousel.ui.viewmodel.ShareouselViewModel
import com.android.intentresolver.contentpreview.shareousel.ui.viewmodel.toShareouselViewModel
internal class ShareouselContentPreviewUi(
@@ -63,33 +73,55 @@ internal class ShareouselContentPreviewUi(
val vm: BasePreviewViewModel = viewModel()
val interactor =
requireNotNull(vm.payloadToggleInteractor) { "Should not be null" }
- val viewModel = interactor.toShareouselViewModel(vm.imageLoader, actionFactory)
- if (headlineViewParent != null) {
- LaunchedEffect(Unit) {
- viewModel.headline.collect { headline ->
- headlineViewParent.findViewById<TextView>(R.id.headline)?.apply {
- if (headline.isNotBlank()) {
- text = headline
- visibility = View.VISIBLE
- } else {
- visibility = View.GONE
- }
+ var viewModel by remember { mutableStateOf<ShareouselViewModel?>(null) }
+ LaunchedEffect(Unit) {
+ viewModel =
+ interactor.toShareouselViewModel(
+ vm.imageLoader,
+ actionFactory,
+ vm.viewModelScope
+ )
+ }
+
+ headlineViewParent?.let {
+ viewModel?.let { viewModel ->
+ LaunchedEffect(viewModel) {
+ viewModel.headline.collect { headline ->
+ headlineViewParent
+ .findViewById<TextView>(R.id.headline)
+ ?.apply {
+ if (headline.isNotBlank()) {
+ text = headline
+ visibility = View.VISIBLE
+ } else {
+ visibility = View.GONE
+ }
+ }
}
}
}
}
- MaterialTheme(
- colorScheme =
- if (isSystemInDarkTheme()) {
- dynamicDarkColorScheme(LocalContext.current)
- } else {
- dynamicLightColorScheme(LocalContext.current)
- },
- ) {
- Shareousel(viewModel = viewModel)
+ viewModel?.let { viewModel ->
+ MaterialTheme(
+ colorScheme =
+ if (isSystemInDarkTheme()) {
+ dynamicDarkColorScheme(LocalContext.current)
+ } else {
+ dynamicLightColorScheme(LocalContext.current)
+ },
+ ) {
+ Shareousel(viewModel = viewModel)
+ }
}
+ ?: run {
+ Spacer(
+ Modifier.height(
+ dimensionResource(R.dimen.chooser_preview_image_height_tall)
+ )
+ )
+ }
}
}
return composeView
diff --git a/java/src/com/android/intentresolver/contentpreview/shareousel/ui/composable/ShareouselComposable.kt b/java/src/com/android/intentresolver/contentpreview/shareousel/ui/composable/ShareouselComposable.kt
index 0e6e9d7e..5cf35297 100644
--- a/java/src/com/android/intentresolver/contentpreview/shareousel/ui/composable/ShareouselComposable.kt
+++ b/java/src/com/android/intentresolver/contentpreview/shareousel/ui/composable/ShareouselComposable.kt
@@ -47,15 +47,12 @@ import com.android.intentresolver.contentpreview.shareousel.ui.viewmodel.Shareou
@Composable
fun Shareousel(viewModel: ShareouselViewModel) {
- val previewKeys by viewModel.previewKeys.collectAsStateWithLifecycle(initialValue = emptyList())
- val centerIdx by viewModel.centerIndex.collectAsStateWithLifecycle(initialValue = 0)
+ val centerIdx = viewModel.centerIndex.value
+ val carouselState = rememberLazyListState(initialFirstVisibleItemIndex = centerIdx)
+ val previewKeys by viewModel.previewKeys.collectAsStateWithLifecycle()
Column {
// TODO: item needs to be centered, check out ScalingLazyColumn impl or see if
// HorizontalPager works for our use-case
- val carouselState =
- rememberLazyListState(
- initialFirstVisibleItemIndex = centerIdx,
- )
LazyRow(
state = carouselState,
horizontalArrangement = Arrangement.spacedBy(4.dp),
diff --git a/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt b/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt
index fae439e5..18ee2539 100644
--- a/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt
+++ b/java/src/com/android/intentresolver/contentpreview/shareousel/ui/viewmodel/ShareouselViewModel.kt
@@ -24,16 +24,19 @@ import com.android.intentresolver.contentpreview.PayloadToggleInteractor
import com.android.intentresolver.icon.BitmapIcon
import com.android.intentresolver.icon.ComposeIcon
import com.android.intentresolver.widget.ActionRow.Action
+import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
data class ShareouselViewModel(
val headline: Flow<String>,
- val previewKeys: Flow<List<Any>>,
+ val previewKeys: StateFlow<List<Any>>,
val actions: Flow<List<ActionChipViewModel>>,
- val centerIndex: Flow<Int>,
+ val centerIndex: StateFlow<Int>,
val previewForKey: (key: Any) -> ShareouselImageViewModel,
val previewRowKey: (Any) -> Any
)
@@ -47,13 +50,14 @@ data class ShareouselImageViewModel(
val setSelected: (Boolean) -> Unit,
)
-fun PayloadToggleInteractor.toShareouselViewModel(
+suspend fun PayloadToggleInteractor.toShareouselViewModel(
imageLoader: ImageLoader,
- actionFactory: ActionFactory
+ actionFactory: ActionFactory,
+ scope: CoroutineScope,
): ShareouselViewModel {
return ShareouselViewModel(
headline = MutableStateFlow("Shareousel"),
- previewKeys = previewKeys,
+ previewKeys = previewKeys.stateIn(scope),
actions =
if (actionFactory is MutableActionFactory) {
actionFactory.customActionsFlow.map { actions ->
@@ -64,7 +68,7 @@ fun PayloadToggleInteractor.toShareouselViewModel(
emit(actionFactory.createCustomActions().map { it.toActionChipViewModel() })
}
},
- centerIndex = targetPosition,
+ centerIndex = targetPosition.stateIn(scope),
previewForKey = { key ->
val previewInteractor = previewInteractor(key)
ShareouselImageViewModel(