@@ -8,21 +8,30 @@ import androidx.compose.foundation.layout.fillMaxSize
88import androidx.compose.foundation.layout.fillMaxWidth
99import androidx.compose.runtime.Composable
1010import androidx.compose.runtime.Immutable
11+ import androidx.compose.runtime.LaunchedEffect
12+ import androidx.compose.runtime.Stable
1113import androidx.compose.runtime.State
12- import androidx.compose.runtime.collectAsState
1314import androidx.compose.runtime.derivedStateOf
15+ import androidx.compose.runtime.getValue
16+ import androidx.compose.runtime.mutableStateListOf
17+ import androidx.compose.runtime.mutableStateOf
18+ import androidx.compose.runtime.remember
1419import androidx.compose.runtime.rememberCoroutineScope
20+ import androidx.compose.runtime.setValue
1521import androidx.compose.runtime.structuralEqualityPolicy
1622import androidx.compose.ui.Modifier
1723import androidx.compose.ui.platform.LocalContext
1824import androidx.compose.ui.tooling.preview.Preview
1925import androidx.lifecycle.compose.collectAsStateWithLifecycle
26+ import com.urbanairship.android.layout.AirshipEmbeddedViewManager
2027import com.urbanairship.android.layout.EmbeddedDisplayRequest
2128import com.urbanairship.android.layout.ui.EmbeddedLayout
2229import com.urbanairship.embedded.AirshipEmbeddedInfo
2330import com.urbanairship.embedded.EmbeddedViewManager
31+ import kotlinx.coroutines.Dispatchers
2432import kotlinx.coroutines.flow.distinctUntilChanged
2533import kotlinx.coroutines.flow.map
34+ import kotlinx.coroutines.withContext
2635
2736/* *
2837 * A container that allows all embedded content for the given [embeddedId]
@@ -40,56 +49,37 @@ public fun AirshipEmbeddedViewGroup(
4049 comparator : Comparator <AirshipEmbeddedInfo >? = null,
4150 content : @Composable BoxScope .(embeddedViews: List <EmbeddedViewItem >) -> Unit
4251) {
43- val scope = rememberCoroutineScope()
44-
45- val displayRequests = EmbeddedViewManager .displayRequests(embeddedId, comparator, scope)
46- .map { it.list }
47- .distinctUntilChanged()
48- .collectAsStateWithLifecycle(emptyList())
49-
50- val items: State <List <EmbeddedViewItem >> = derivedStateOf(policy = structuralEqualityPolicy()) {
51- displayRequests.value.map { request -> EmbeddedViewItem (request = request) }
52- }
53-
54- Box (modifier) {
55- content(items.value)
56- }
52+ AirshipEmbeddedViewGroup (
53+ modifier = modifier,
54+ state = rememberAirshipEmbeddedViewGroupState(embeddedId, comparator),
55+ content = content
56+ )
5757}
5858
5959/* *
60- * An embedded view item, containing the [AirshipEmbeddedInfo] and the content to display.
60+ * A container that allows all embedded content for the `embeddedId` defined on the given
61+ * [AirshipEmbeddedViewGroupState] instance.
62+ *
63+ * This composable may be useful when access to the embedded view group state is needed outside of
64+ * the `AirshipEmbeddedViewGroup` composable, embedded view group state should be hoisted, and for
65+ * advanced custom logic that depends on the availability of embedded view content.
66+ *
67+ * When included inside of a lazy composable or scrolling list, state should be hoisted up, above
68+ * the lazy composable or scrolling list, in order to ensure that the embedded view group state is
69+ * maintained across recompositions.
70+ *
71+ * @param state The [AirshipEmbeddedViewGroupState] to be used by this embedded view group.
72+ * @param modifier The modifier to be applied to the layout.
73+ * @param content The `Composable` that will display the list of embedded view content.
6174 */
62- @Immutable
63- public data class EmbeddedViewItem internal constructor(
64- private val request : EmbeddedDisplayRequest
75+ @Composable
76+ public fun AirshipEmbeddedViewGroup (
77+ state : AirshipEmbeddedViewGroupState ,
78+ modifier : Modifier = Modifier ,
79+ content : @Composable BoxScope .(embeddedViews: List <EmbeddedViewItem >) -> Unit
6580) {
66- /* * The [AirshipEmbeddedInfo] for this embedded content. */
67- public val info: AirshipEmbeddedInfo = AirshipEmbeddedInfo (
68- embeddedId = request.embeddedViewId,
69- instanceId = request.viewInstanceId,
70- priority = request.priority,
71- extras = request.extras,
72- )
73-
74- /* * The content to display for this embedded view item. */
75- @Composable
76- public fun content () {
77- val layout = EmbeddedLayout (
78- context = LocalContext .current,
79- embeddedViewId = request.embeddedViewId,
80- viewInstanceId = request.viewInstanceId,
81- args = request.displayArgsProvider.invoke(),
82- embeddedViewManager = EmbeddedViewManager
83- )
84-
85- EmbeddedViewWrapper (
86- embeddedId = request.embeddedViewId,
87- embeddedLayout = layout,
88- embeddedSize = layout.getPlacement()?.size?.toEmbeddedSize(),
89- // Consumers provide their own placeholder, if desired.
90- placeholder = null ,
91- modifier = Modifier .fillMaxWidth()
92- )
81+ Box (modifier) {
82+ content(state.items.value)
9383 }
9484}
9585
0 commit comments