Skip to content

Commit

Permalink
Merge pull request #643 from KovalevAndrey/2.x-appyx-component-unific…
Browse files Browse the repository at this point in the history
…ation

Unify AppyxComponent composables
  • Loading branch information
KovalevAndrey authored Dec 15, 2023
2 parents 6e4ffd0 + d5e1da5 commit 119020c
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 282 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### API breaking changes

- [#630](https://github.com/bumble-tech/appyx/pull/630) – Pass initial state into Spotlights visualisations
- [#643](https://github.com/bumble-tech/appyx/pull/643) – Unify AppyxComponent composable between appyx-navigation and appyx-interactions modules

### Fixed

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import androidx.compose.foundation.layout.offset
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.key
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.saveable.rememberSaveableStateHolder
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -34,6 +36,7 @@ import com.bumble.appyx.interactions.core.gesture.GestureValidator
import com.bumble.appyx.interactions.core.gesture.GestureValidator.Companion.defaultValidator
import com.bumble.appyx.interactions.core.gesture.detectDragGesturesOrCancellation
import com.bumble.appyx.interactions.core.model.BaseAppyxComponent
import com.bumble.appyx.interactions.core.model.removedElements
import com.bumble.appyx.interactions.core.modifiers.onPointerEvent
import com.bumble.appyx.interactions.core.ui.LocalBoxScope
import com.bumble.appyx.interactions.core.ui.LocalMotionProperties
Expand All @@ -45,7 +48,6 @@ import com.bumble.appyx.interactions.core.ui.property.motionPropertyRenderValue

private val defaultExtraTouch = 48f.dp


@Suppress("LongMethod")
@Composable
fun <InteractionTarget : Any, ModelState : Any> AppyxComponent(
Expand Down Expand Up @@ -74,6 +76,18 @@ fun <InteractionTarget : Any, ModelState : Any> AppyxComponent(
val gestureExtraTouchAreaPx = with(density) { gestureExtraTouchArea.toPx() }
var containerSize by remember { mutableStateOf(IntSize.Zero) }

val saveableStateHolder = rememberSaveableStateHolder()

LaunchedEffect(appyxComponent) {
appyxComponent
.removedElements()
.collect { deletedElements ->
deletedElements.forEach {
saveableStateHolder.removeState(it)
}
}
}

SideEffect {
appyxComponent.updateContext(
UiContext(
Expand Down Expand Up @@ -107,7 +121,6 @@ fun <InteractionTarget : Any, ModelState : Any> AppyxComponent(
CompositionLocalProvider(LocalBoxScope provides this) {
elementUiModels.forEach { elementUiModel ->
val id = elementUiModel.element.id

key(id) {
var transformedBoundingBox by remember(id) { mutableStateOf(Rect.Zero) }
var elementSize by remember(id) { mutableStateOf(IntSize.Zero) }
Expand All @@ -120,52 +133,59 @@ fun <InteractionTarget : Any, ModelState : Any> AppyxComponent(
CompositionLocalProvider(
LocalMotionProperties provides elementUiModel.motionProperties
) {
val elementOffset = offsetCenter.round() - elementOffset(elementSize, containerSize)
val elementOffset =
offsetCenter.round() - elementOffset(elementSize, containerSize)

element.invoke(
elementUiModel.copy(
modifier = Modifier
.offset { elementOffset }
.pointerInput(appyxComponent) {
detectDragGesturesOrCancellation(
onDragStart = { position ->
appyxComponent.onStartDrag(position)
},
onDrag = { change, dragAmount ->
if (gestureValidator.isGestureValid(
change.position,
transformedBoundingBox.translate(-offsetCenter)
)
) {
change.consume()
appyxComponent.onDrag(dragAmount, density)
true
} else {
saveableStateHolder.SaveableStateProvider(key = elementUiModel.element) {
element.invoke(
elementUiModel.copy(
modifier = Modifier
.offset { elementOffset }
.pointerInput(appyxComponent) {
detectDragGesturesOrCancellation(
onDragStart = { position ->
appyxComponent.onStartDrag(position)
},
onDrag = { change, dragAmount ->
if (gestureValidator.isGestureValid(
change.position,
transformedBoundingBox.translate(-offsetCenter)
)
) {
change.consume()
appyxComponent.onDrag(
dragAmount,
density
)
true
} else {
appyxComponent.onDragEnd()
false
}
},
onDragEnd = {
appyxComponent.onDragEnd()
false
}
},
onDragEnd = {
appyxComponent.onDragEnd()
},
)
}
.offset { -elementOffset }
.then(elementUiModel.modifier)
.onPlaced {
elementSize = it.size
val localCenter = Offset(
it.size.width.toFloat(),
it.size.height.toFloat()
) / 2f
},
)
}
.offset { -elementOffset }
.then(elementUiModel.modifier)
.onPlaced {
elementSize = it.size
val localCenter = Offset(
it.size.width.toFloat(),
it.size.height.toFloat()
) / 2f

transformedBoundingBox =
it.boundsInParent().inflate(gestureExtraTouchAreaPx)
offsetCenter =
transformedBoundingBox.center - localCenter
}
transformedBoundingBox =
it.boundsInParent()
.inflate(gestureExtraTouchAreaPx)
offsetCenter =
transformedBoundingBox.center - localCenter
}
)
)
)
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.bumble.appyx.interactions.core.ui.output

import androidx.compose.runtime.Composable
import androidx.compose.runtime.Immutable
import androidx.compose.ui.Modifier
import com.bumble.appyx.interactions.core.Element
import com.bumble.appyx.interactions.core.ui.property.MotionProperty
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.StateFlow

@Immutable
data class ElementUiModel<InteractionTarget>(
val element: Element<InteractionTarget>,
val visibleState: StateFlow<Boolean>,
Expand Down
Loading

0 comments on commit 119020c

Please sign in to comment.