Skip to content

Commit

Permalink
Merge pull request #630 from bumble-tech/fix_spotlights_visualisation…
Browse files Browse the repository at this point in the history
…s_with_initial_state

Pass initial state into Spotlights visualisations
  • Loading branch information
mapm14 authored Nov 9, 2023
2 parents c50a14b + 9988a6c commit 1901caf
Show file tree
Hide file tree
Showing 20 changed files with 109 additions and 70 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

## Pending changes

### API breaking changes

- [#630](https://github.com/bumble-tech/appyx/pull/630) – Pass initial state into Spotlights visualisations

---

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,20 @@ class SpotlightTest(private val testParam: TestParam) {
disableAnimations: Boolean = false,
initialActiveIndex: Float = 0f,
) {
spotlight = Spotlight(
model = SpotlightModel(
items = listOf(
InteractionTarget.Child1,
InteractionTarget.Child2,
InteractionTarget.Child3,
InteractionTarget.Child4,
InteractionTarget.Child5
),
initialActiveIndex = initialActiveIndex,
savedStateMap = null
val model = SpotlightModel(
items = listOf(
InteractionTarget.Child1,
InteractionTarget.Child2,
InteractionTarget.Child3,
InteractionTarget.Child4,
InteractionTarget.Child5
),
visualisation = { SpotlightSlider(uiContext = it) },
initialActiveIndex = initialActiveIndex,
savedStateMap = null
)
spotlight = Spotlight(
model = model,
visualisation = { SpotlightSlider(uiContext = it, initialState = model.currentState) },
scope = CoroutineScope(Dispatchers.Unconfined),
disableAnimations = disableAnimations,
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ fun ComposeContentTestRule.createSpotlight(
return Spotlight(
scope = CoroutineScope(Dispatchers.Unconfined),
model = model,
visualisation = { SpotlightSlider(it) },
visualisation = { SpotlightSlider(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) },
animationSpec = animationSpec
).also { setupSpotlight(it) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ class SpotlightModel<InteractionTarget : Any>(
activeIndex = initialActiveIndex
)

val currentState: State<InteractionTarget>
get() = output.value.currentTargetState

override fun State<InteractionTarget>.removeDestroyedElement(
element: Element<InteractionTarget>
): State<InteractionTarget> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,16 @@ import com.bumble.appyx.transitionmodel.BaseVisualisation

class SpotlightSlider<InteractionTarget : Any>(
uiContext: UiContext,
initialState: State<InteractionTarget>,
@Suppress("UnusedPrivateMember")
private val orientation: Orientation = Orientation.Horizontal, // TODO support RTL
) : BaseVisualisation<InteractionTarget, State<InteractionTarget>, MutableUiState, TargetUiState>(
uiContext = uiContext
) {
private val scrollX = GenericFloatProperty(uiContext.coroutineScope, Target(0f))
private val scrollX = GenericFloatProperty(
coroutineScope = uiContext.coroutineScope,
target = Target(initialState.activeIndex),
)
override val viewpointDimensions: List<Pair<(State<InteractionTarget>) -> Float, GenericFloatProperty>> =
listOf(
{ state: State<InteractionTarget> -> state.activeIndex } to scrollX
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,16 @@ import com.bumble.appyx.transitionmodel.BaseVisualisation

class SpotlightSliderRotation<InteractionTarget : Any>(
uiContext: UiContext,
initialState: State<InteractionTarget>,
@Suppress("UnusedPrivateMember")
private val orientation: Orientation = Orientation.Horizontal, // TODO support RTL
) : BaseVisualisation<InteractionTarget, State<InteractionTarget>, MutableUiState, TargetUiState>(
uiContext = uiContext
) {
private val scrollX = GenericFloatProperty(uiContext.coroutineScope, Target(0f))
private val scrollX = GenericFloatProperty(
coroutineScope = uiContext.coroutineScope,
target = Target(initialState.activeIndex),
)
override val viewpointDimensions: List<Pair<(State<InteractionTarget>) -> Float, GenericFloatProperty>> =
listOf(
{ state: State<InteractionTarget> -> state.activeIndex } to scrollX
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,17 @@ import com.bumble.appyx.transitionmodel.BaseVisualisation

class SpotlightSliderScale<InteractionTarget : Any>(
uiContext: UiContext,
initialState: State<InteractionTarget>,
@Suppress("UnusedPrivateMember")
private val orientation: Orientation = Orientation.Horizontal, // TODO support RTL
) : BaseVisualisation<InteractionTarget, State<InteractionTarget>, MutableUiState, TargetUiState>(
uiContext = uiContext
) {
@Suppress("MaxLineLength")
private val scrollX = GenericFloatProperty(uiContext.coroutineScope, Target(0f))
private val scrollX = GenericFloatProperty(
coroutineScope = uiContext.coroutineScope,
target = Target(initialState.activeIndex),
)
override val viewpointDimensions: List<Pair<(State<InteractionTarget>) -> Float, GenericFloatProperty>> =
listOf(
{ state: State<InteractionTarget> -> state.activeIndex } to scrollX
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import com.bumble.appyx.transitionmodel.BaseVisualisation
@Suppress("MagicNumber")
class SpotlightStack3D<InteractionTarget : Any>(
uiContext: UiContext,
initialState: State<InteractionTarget>,
) : BaseVisualisation<InteractionTarget, State<InteractionTarget>, MutableUiState, TargetUiState>(
uiContext = uiContext,
) {
Expand All @@ -37,7 +38,10 @@ class SpotlightStack3D<InteractionTarget : Any>(
height = transitionBounds.heightDp
}

private val scrollY = GenericFloatProperty(uiContext.coroutineScope, GenericFloatProperty.Target(0f))
private val scrollY = GenericFloatProperty(
coroutineScope = uiContext.coroutineScope,
target = GenericFloatProperty.Target(initialState.activeIndex),
)
override val viewpointDimensions: List<Pair<(State<InteractionTarget>) -> Float, GenericFloatProperty>> =
listOf(
{ state: State<InteractionTarget> -> state.activeIndex } to scrollY
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,12 @@ import androidx.compose.material.icons.filled.ViewCarousel
import androidx.compose.material.icons.outlined.Cake
import androidx.compose.material.icons.outlined.Extension
import androidx.compose.material.icons.outlined.GridView
import androidx.compose.material.icons.outlined.Style
import androidx.compose.material.icons.outlined.ViewCarousel
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import com.bumble.appyx.components.experimental.cards.android.DatingCards
import com.bumble.appyx.components.experimental.puzzle15.android.Puzzle15
import com.bumble.appyx.components.internal.testdrive.android.TestDriveExperiment
import com.bumble.appyx.components.spotlight.ui.sliderrotation.SpotlightSliderRotation
import com.bumble.appyx.interactions.sample.SpotlightExperiment
import com.bumble.appyx.navigation.node.node
import com.bumble.appyx.utils.material3.AppyxNavItem
Expand All @@ -41,7 +39,7 @@ enum class MainNavItem : Parcelable {
text = "Spotlight",
unselectedIcon = Outlined.ViewCarousel,
selectedIcon = Filled.ViewCarousel,
node = { node(it) { SpotlightExperiment { SpotlightSliderRotation(it) } } }
node = { node(it) { SpotlightExperiment() } }
)

TEST_DRIVE -> AppyxNavItem(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
Expand All @@ -27,13 +26,14 @@ import com.bumble.appyx.components.spotlight.operation.next
import com.bumble.appyx.components.spotlight.operation.previous
import com.bumble.appyx.components.spotlight.operation.updateElements
import com.bumble.appyx.components.spotlight.ui.slider.SpotlightSlider
import com.bumble.appyx.components.spotlight.ui.sliderrotation.SpotlightSliderRotation
import com.bumble.appyx.interactions.core.ui.context.UiContext
import com.bumble.appyx.interactions.core.ui.gesture.GestureSettleConfig
import com.bumble.appyx.interactions.core.ui.helper.AppyxComponentSetup
import com.bumble.appyx.interactions.sample.InteractionTarget
import com.bumble.appyx.interactions.sample.android.Element
import com.bumble.appyx.interactions.sample.android.SampleChildren
import com.bumble.appyx.interactions.theme.appyx_dark
import com.bumble.appyx.transitionmodel.BaseVisualisation
import com.bumble.appyx.utils.multiplatform.AppyxLogger
import com.bumble.appyx.interactions.sample.InteractionTarget as Target

Expand All @@ -43,7 +43,7 @@ fun SpotlightExperiment(
modifier: Modifier = Modifier,
orientation: Orientation = Orientation.Horizontal,
reverseOrientation: Boolean = false,
visualisation: (UiContext) -> BaseVisualisation<Target, SpotlightModel.State<Target>, *, *>
visualisationType: SpotlightVisualisationType = SpotlightVisualisationType.SLIDER_ROTATION,
) {
val items = listOf(
Target.Child1,
Expand All @@ -68,12 +68,13 @@ fun SpotlightExperiment(
Target.Child6,
Target.Child7,
)
val model = SpotlightModel(
items = items,
savedStateMap = null,
)
val spotlight = Spotlight(
model = SpotlightModel(
items = items,
savedStateMap = null
),
visualisation = visualisation,
model = model,
visualisation = { visualisationType.toVisualisation(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it, orientation, reverseOrientation) },
animationSpec = spring(stiffness = Spring.StiffnessVeryLow / 4),
gestureSettleConfig = GestureSettleConfig(
Expand Down Expand Up @@ -166,13 +167,10 @@ fun <InteractionTarget : Any> SpotlightUi(
}

@Composable
fun SpotlightExperimentInVertical(
visualisation: (UiContext) -> BaseVisualisation<Target, SpotlightModel.State<Target>, *, *>
) {
fun SpotlightExperimentInVertical() {
SpotlightExperiment(
orientation = Orientation.Vertical,
reverseOrientation = true,
visualisation = visualisation
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,21 +26,24 @@ import com.bumble.appyx.interactions.theme.appyx_dark
@ExperimentalMaterialApi
@Composable
fun SpotlightExperimentDebug(modifier: Modifier = Modifier) {
val model = remember {
SpotlightModel(
items = listOf(
InteractionTarget.Child1,
InteractionTarget.Child2,
InteractionTarget.Child3,
InteractionTarget.Child4,
InteractionTarget.Child5,
InteractionTarget.Child6,
InteractionTarget.Child7
),
savedStateMap = null
)
}
val spotlight = remember {
Spotlight(
model = SpotlightModel(
items = listOf(
InteractionTarget.Child1,
InteractionTarget.Child2,
InteractionTarget.Child3,
InteractionTarget.Child4,
InteractionTarget.Child5,
InteractionTarget.Child6,
InteractionTarget.Child7
),
savedStateMap = null
),
visualisation = { SpotlightSlider(it) },
model = model,
visualisation = { SpotlightSlider(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) },
isDebug = true
)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.bumble.appyx.interactions.sample

import com.bumble.appyx.components.spotlight.SpotlightModel
import com.bumble.appyx.components.spotlight.ui.sliderrotation.SpotlightSliderRotation
import com.bumble.appyx.interactions.core.ui.context.UiContext

enum class SpotlightVisualisationType {
SLIDER_ROTATION;

fun toVisualisation(
uiContext: UiContext,
state: SpotlightModel.State<InteractionTarget>,
) = when (this) {
SLIDER_ROTATION -> SpotlightSliderRotation(uiContext, state)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ fun SpotlightSliderSample(
Spotlight(
scope = coroutineScope,
model = model,
visualisation = { SpotlightSlider(it) },
visualisation = { SpotlightSlider(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) }
)
val actions = mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fun SpotlightSliderRotationSample(
Spotlight(
scope = coroutineScope,
model = model,
visualisation = { SpotlightSliderRotation(it) },
visualisation = { SpotlightSliderRotation(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) }
)
val actions = mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ fun SpotlightSliderScaleSample(
Spotlight(
scope = coroutineScope,
model = model,
visualisation = { SpotlightSliderScale(it) },
visualisation = { SpotlightSliderScale(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) }
)
val actions = mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ fun SpotlightStack3DSample(
Spotlight(
scope = coroutineScope,
model = model,
visualisation = { SpotlightStack3D(it) },
visualisation = { SpotlightStack3D(it, model.currentState) },
gestureFactory = {
SpotlightSlider.Gestures(
transitionBounds = it,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextAlign.Companion
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.bumble.appyx.components.spotlight.Spotlight
Expand Down Expand Up @@ -52,7 +51,7 @@ fun ObserveMotionPropertiesSample(
Spotlight(
scope = coroutineScope,
model = model,
visualisation = { SpotlightSliderRotation(it) },
visualisation = { SpotlightSliderRotation(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) }
)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,14 @@ import com.bumble.appyx.utils.multiplatform.Parcelize

class SpotlightNode(
buildContext: BuildContext,
private val model: SpotlightModel<InteractionTarget> = SpotlightModel(
items = List(7) { InteractionTarget.Child(it) },
initialActiveIndex = 0f,
savedStateMap = buildContext.savedStateMap,
),
private val spotlight: Spotlight<InteractionTarget> = Spotlight(
model = SpotlightModel(
items = List(7) { InteractionTarget.Child(it) },
initialActiveIndex = 0f,
savedStateMap = buildContext.savedStateMap
),
visualisation = { SpotlightSlider(it) },
model = model,
visualisation = { SpotlightSlider(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) }
)
) : ParentNode<InteractionTarget>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,14 @@ import com.bumble.appyx.utils.multiplatform.Parcelize

class SpotlightObserveTransitionsExampleNode(
buildContext: BuildContext,
private val model: SpotlightModel<InteractionTarget> = SpotlightModel(
items = List(7) { InteractionTarget.Child(it) },
initialActiveIndex = 0f,
savedStateMap = buildContext.savedStateMap
),
private val spotlight: Spotlight<InteractionTarget> = Spotlight(
model = SpotlightModel(
items = List(7) { InteractionTarget.Child(it) },
initialActiveIndex = 0f,
savedStateMap = buildContext.savedStateMap
),
visualisation = { SpotlightSliderRotation(it) },
model = model,
visualisation = { SpotlightSliderRotation(it, model.currentState) },
gestureFactory = { SpotlightSlider.Gestures(it) }
)
) : ParentNode<InteractionTarget>(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,14 @@ import com.bumble.appyx.utils.multiplatform.Parcelize

class SpotlightDebugNode(
buildContext: BuildContext,
private val model: SpotlightModel<InteractionTarget> = SpotlightModel(
items = List(7) { InteractionTarget.Child(it + 1) },
initialActiveIndex = 0f,
savedStateMap = buildContext.savedStateMap
),
private val spotlight: Spotlight<InteractionTarget> = Spotlight(
model = SpotlightModel(
items = List(7) { InteractionTarget.Child(it + 1) },
initialActiveIndex = 0f,
savedStateMap = buildContext.savedStateMap
),
visualisation = { SpotlightSlider(it) },
model = model,
visualisation = { SpotlightSlider(it, model.currentState) },
isDebug = true
)
) : ParentNode<InteractionTarget>(
Expand Down

0 comments on commit 1901caf

Please sign in to comment.