Skip to content

Commit b89dd7b

Browse files
committed
use maneiver view height flow instead of navigation state
1 parent b6d4666 commit b89dd7b

13 files changed

Lines changed: 168 additions & 96 deletions

File tree

libnavui-dropin/src/main/java/com/mapbox/navigation/dropin/component/maneuver/ManeuverBehavior.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,16 @@ internal class ManeuverBehavior {
99
private val _maneuverBehavior = MutableStateFlow<MapboxManeuverViewState>(
1010
MapboxManeuverViewState.COLLAPSED
1111
)
12+
private val _maneuverViewHeight = MutableStateFlow(0)
13+
1214
val maneuverBehavior = _maneuverBehavior.asStateFlow()
15+
val maneuverViewHeight = _maneuverViewHeight.asStateFlow()
1316

1417
fun updateBehavior(newState: MapboxManeuverViewState) {
1518
_maneuverBehavior.value = newState
1619
}
20+
21+
fun updateViewHeight(newHeight: Int) {
22+
_maneuverViewHeight.value = newHeight
23+
}
1724
}

libnavui-dropin/src/main/java/com/mapbox/navigation/dropin/component/maneuver/ManeuverComponentContractImpl.kt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,8 @@ internal class ManeuverComponentContractImpl(
1313
override fun onManeuverViewStateChanged(state: MapboxManeuverViewState) {
1414
context.maneuverBehavior.updateBehavior(state)
1515
}
16+
17+
override fun onManeuverViewHeightChanged(newHeight: Int) {
18+
context.maneuverBehavior.updateViewHeight(newHeight)
19+
}
1620
}

libnavui-dropin/src/main/java/com/mapbox/navigation/dropin/component/map/ScalebarPlaceholderComponent.kt

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,7 @@ import android.view.View
44
import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
55
import com.mapbox.navigation.core.MapboxNavigation
66
import com.mapbox.navigation.dropin.MapboxMapScalebarParams
7-
import com.mapbox.navigation.ui.app.internal.State
8-
import com.mapbox.navigation.ui.app.internal.navigation.NavigationState
97
import com.mapbox.navigation.ui.base.lifecycle.UIComponent
10-
import kotlinx.coroutines.flow.Flow
118
import kotlinx.coroutines.flow.StateFlow
129
import kotlinx.coroutines.flow.collect
1310
import kotlinx.coroutines.flow.combine
@@ -17,15 +14,15 @@ import kotlinx.coroutines.launch
1714
internal class ScalebarPlaceholderComponent(
1815
private val scalebarPlaceholder: View,
1916
private val scalebarParams: StateFlow<MapboxMapScalebarParams>,
20-
private val navigationState: StateFlow<State>,
17+
private val maneuverHeight: StateFlow<Int>,
2118
) : UIComponent() {
2219

2320
override fun onAttached(mapboxNavigation: MapboxNavigation) {
2421
super.onAttached(mapboxNavigation)
2522
coroutineScope.launch {
26-
combine(scalebarParams, navigationState) { params, state ->
23+
combine(scalebarParams, maneuverHeight) { params, height ->
2724
scalebarPlaceholder.visibility =
28-
if (params.enabled && state.navigation !is NavigationState.ActiveNavigation) {
25+
if (params.enabled && height == 0) {
2926
View.VISIBLE
3027
} else {
3128
View.GONE

libnavui-dropin/src/main/java/com/mapbox/navigation/dropin/coordinator/ScalebarPlaceholderBinder.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,7 @@ import com.mapbox.navigation.dropin.NavigationViewContext
88
import com.mapbox.navigation.dropin.R
99
import com.mapbox.navigation.dropin.component.map.ScalebarPlaceholderComponent
1010
import com.mapbox.navigation.dropin.databinding.MapboxScalebarPlaceholderLayoutBinding
11-
import com.mapbox.navigation.ui.app.internal.extension.actionsFlowable
1211
import com.mapbox.navigation.ui.base.lifecycle.UIBinder
13-
import kotlinx.coroutines.flow.map
1412

1513
@OptIn(ExperimentalPreviewMapboxNavigationAPI::class)
1614
internal class ScalebarPlaceholderBinder(
@@ -22,7 +20,7 @@ internal class ScalebarPlaceholderBinder(
2220
return ScalebarPlaceholderComponent(
2321
binding.scalebarPlaceholder,
2422
context.styles.mapScalebarParams,
25-
context.store.state
23+
context.maneuverBehavior.maneuverViewHeight
2624
)
2725
}
2826

libnavui-dropin/src/test/java/com/mapbox/navigation/dropin/component/maneuver/ManeuverBehaviorTest.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,13 @@ class ManeuverBehaviorTest {
1414

1515
assertEquals(MapboxManeuverViewState.EXPANDED, sut.maneuverBehavior.value)
1616
}
17+
18+
@Test
19+
fun `when maneuver view height is updated`() {
20+
val sut = ManeuverBehavior()
21+
22+
sut.updateViewHeight(43)
23+
24+
assertEquals(43, sut.maneuverViewHeight.value)
25+
}
1726
}

libnavui-dropin/src/test/java/com/mapbox/navigation/dropin/component/maneuver/ManeuverComponentContractImplTest.kt

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,26 @@ import org.junit.Test
1313
@ExperimentalPreviewMapboxNavigationAPI
1414
class ManeuverComponentContractImplTest {
1515

16+
private val navigationViewContext: NavigationViewContext = mockk(relaxed = true) {
17+
every { maneuverBehavior.updateBehavior(any()) } just Runs
18+
}
19+
private val sut = ManeuverComponentContractImpl(navigationViewContext)
20+
1621
@Test
1722
fun `when maneuver view state is changed, contract is notified`() {
18-
val navigationViewContext: NavigationViewContext = mockk(relaxed = true) {
19-
every { maneuverBehavior.updateBehavior(any()) } just Runs
20-
}
21-
val sut = ManeuverComponentContractImpl(navigationViewContext)
22-
2323
sut.onManeuverViewStateChanged(MapboxManeuverViewState.EXPANDED)
2424

2525
verify {
2626
navigationViewContext.maneuverBehavior.updateBehavior(MapboxManeuverViewState.EXPANDED)
2727
}
2828
}
29+
30+
@Test
31+
fun `when maneuver view height is changed, contract is notified`() {
32+
sut.onManeuverViewHeightChanged(23)
33+
34+
verify {
35+
navigationViewContext.maneuverBehavior.updateViewHeight(23)
36+
}
37+
}
2938
}

libnavui-dropin/src/test/java/com/mapbox/navigation/dropin/component/map/ScalebarComponentTest.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ internal class ScalebarComponentTest {
4141
private val scalebarMock = mockk<ScaleBarPlugin>(relaxed = true) {
4242
every { marginTop } returns 14f
4343
every { marginLeft } returns 14f
44-
every { updateSettings(any()) } answers { (args[0] as ScaleBarSettings.() -> Unit)(settings) }
44+
every { updateSettings(any()) } answers {
45+
(args[0] as ScaleBarSettings.() -> Unit)(settings)
46+
}
4547
}
4648
private val mapView = mockk<MapView>(relaxed = true) {
4749
every { scalebar } returns scalebarMock
@@ -53,7 +55,9 @@ internal class ScalebarComponentTest {
5355
)
5456
private val initialInsetTop = 3
5557
private val initialInsetLeft = 5
56-
private val systemBarsFlow = MutableStateFlow(Insets.of(initialInsetLeft, initialInsetTop, 0, 0))
58+
private val systemBarsFlow = MutableStateFlow(
59+
Insets.of(initialInsetLeft, initialInsetTop, 0, 0)
60+
)
5761
private val mapboxNavigation = mockk<MapboxNavigation>()
5862
private val component = ScalebarComponent(mapView, scalebarParamsFlow, systemBarsFlow)
5963

@@ -75,7 +79,9 @@ internal class ScalebarComponentTest {
7579
val isMetricUnits = Random.nextBoolean()
7680
ScalebarComponent(
7781
mapView,
78-
MutableStateFlow(MapboxMapScalebarParams.Builder(context).isMetricsUnits(isMetricUnits).build()),
82+
MutableStateFlow(
83+
MapboxMapScalebarParams.Builder(context).isMetricsUnits(isMetricUnits).build()
84+
),
7985
MutableStateFlow(Insets.NONE)
8086
)
8187
verify { settings.isMetricUnits = isMetricUnits }

libnavui-dropin/src/test/java/com/mapbox/navigation/dropin/component/map/ScalebarPlaceholderComponentTest.kt

Lines changed: 23 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@ import com.mapbox.navigation.base.ExperimentalPreviewMapboxNavigationAPI
77
import com.mapbox.navigation.core.MapboxNavigation
88
import com.mapbox.navigation.dropin.MapboxMapScalebarParams
99
import com.mapbox.navigation.testing.MainCoroutineRule
10-
import com.mapbox.navigation.ui.app.internal.State
11-
import com.mapbox.navigation.ui.app.internal.navigation.NavigationState
12-
import com.mapbox.navigation.ui.app.internal.routefetch.RoutePreviewState
1310
import io.mockk.clearMocks
1411
import io.mockk.mockk
1512
import io.mockk.verify
@@ -30,39 +27,26 @@ class ScalebarPlaceholderComponentTest {
3027
private val context = ApplicationProvider.getApplicationContext<Context>()
3128
private val mapboxNavigation = mockk<MapboxNavigation>()
3229
private val scalebarPlaceholderView = mockk<View>(relaxed = true)
33-
private val stateFlow = MutableStateFlow(
34-
State(
35-
navigation = NavigationState.FreeDrive,
36-
previewRoutes = RoutePreviewState.Ready(emptyList())
37-
)
30+
private val initialHeight = 7
31+
private val heightFlow = MutableStateFlow(initialHeight)
32+
private val mapScalebarParams = MutableStateFlow(
33+
MapboxMapScalebarParams.Builder(context).build()
34+
)
35+
private val component = ScalebarPlaceholderComponent(
36+
scalebarPlaceholderView,
37+
mapScalebarParams,
38+
heightFlow
3839
)
39-
private val mapScalebarParams = MutableStateFlow(MapboxMapScalebarParams.Builder(context).build())
40-
private val component = ScalebarPlaceholderComponent(scalebarPlaceholderView, mapScalebarParams, stateFlow)
41-
42-
@Test
43-
fun visibilityIsChangedOnOnAttachedActiveGuidance() {
44-
stateFlow.tryEmit(State(navigation = NavigationState.FreeDrive))
45-
component.onAttached(mapboxNavigation)
46-
verify { scalebarPlaceholderView.visibility = View.GONE }
47-
}
48-
49-
@Test
50-
fun visibilityIsChangedOnOnAttachedFreeDrive() {
51-
stateFlow.tryEmit(State(navigation = NavigationState.FreeDrive))
52-
component.onAttached(mapboxNavigation)
53-
verify { scalebarPlaceholderView.visibility = View.GONE }
54-
}
5540

5641
@Test
57-
fun visibilityIsChangedOnOnAttachedRoutePreview() {
58-
stateFlow.tryEmit(State(navigation = NavigationState.RoutePreview))
42+
fun visibilityIsChangedOnOnAttachedHasHeight() {
5943
component.onAttached(mapboxNavigation)
6044
verify { scalebarPlaceholderView.visibility = View.GONE }
6145
}
6246

6347
@Test
64-
fun visibilityIsChangedOnOnAttachedDestinationPreview() {
65-
stateFlow.tryEmit(State(navigation = NavigationState.RoutePreview))
48+
fun visibilityIsChangedOnOnAttachedNoHeight() {
49+
heightFlow.tryEmit(0)
6650
component.onAttached(mapboxNavigation)
6751
verify { scalebarPlaceholderView.visibility = View.GONE }
6852
}
@@ -74,80 +58,43 @@ class ScalebarPlaceholderComponentTest {
7458
}
7559

7660
@Test
77-
fun stateChangeBeforeOnAttached() {
78-
stateFlow.tryEmit(State(navigation = NavigationState.RoutePreview))
61+
fun heightChangeBeforeOnAttached() {
62+
heightFlow.tryEmit(8)
7963
verify(exactly = 0) { scalebarPlaceholderView.visibility = any() }
8064
}
8165

8266
@Test
83-
fun mapScalebarParamsChangeAfterOnAttachedActiveGuidance() {
84-
stateFlow.tryEmit(State(navigation = NavigationState.ActiveNavigation))
85-
component.onAttached(mapboxNavigation)
86-
clearMocks(scalebarPlaceholderView)
87-
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
88-
verify { scalebarPlaceholderView.visibility = View.GONE }
89-
}
90-
91-
@Test
92-
fun mapScalebarParamsChangeAfterOnAttachedFreeDrive() {
93-
stateFlow.tryEmit(State(navigation = NavigationState.ActiveNavigation))
67+
fun mapScalebarParamsChangeAfterOnAttachedHasHeight() {
9468
component.onAttached(mapboxNavigation)
9569
clearMocks(scalebarPlaceholderView)
9670
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
9771
verify { scalebarPlaceholderView.visibility = View.GONE }
9872
}
9973

10074
@Test
101-
fun mapScalebarParamsChangeAfterOnAttachedRoutePreview() {
102-
stateFlow.tryEmit(State(navigation = NavigationState.RoutePreview))
75+
fun mapScalebarParamsChangeAfterOnAttachedNoHeight() {
76+
heightFlow.tryEmit(0)
10377
component.onAttached(mapboxNavigation)
10478
clearMocks(scalebarPlaceholderView)
10579
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
10680
verify { scalebarPlaceholderView.visibility = View.VISIBLE }
10781
}
10882

10983
@Test
110-
fun mapScalebarParamsChangeAfterOnAttachedDestinationPreview() {
111-
stateFlow.tryEmit(State(navigation = NavigationState.DestinationPreview))
112-
component.onAttached(mapboxNavigation)
113-
clearMocks(scalebarPlaceholderView)
114-
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
115-
verify { scalebarPlaceholderView.visibility = View.VISIBLE }
116-
}
117-
118-
@Test
119-
fun stateChangeAfterOnAttachedActiveGuidance() {
84+
fun heightChangeAfterOnAttachedHasHeight() {
12085
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
12186
component.onAttached(mapboxNavigation)
12287
clearMocks(scalebarPlaceholderView)
123-
stateFlow.tryEmit(State(navigation = NavigationState.ActiveNavigation))
88+
heightFlow.tryEmit(8)
12489
verify { scalebarPlaceholderView.visibility = View.GONE }
12590
}
12691

12792
@Test
128-
fun stateChangeAfterOnAttachedFreeDrive() {
129-
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
130-
component.onAttached(mapboxNavigation)
131-
clearMocks(scalebarPlaceholderView)
132-
stateFlow.tryEmit(State(navigation = NavigationState.FreeDrive))
133-
verify { scalebarPlaceholderView.visibility = View.VISIBLE }
134-
}
135-
136-
@Test
137-
fun stateChangeAfterOnAttachedRoutePreview() {
138-
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
139-
component.onAttached(mapboxNavigation)
140-
clearMocks(scalebarPlaceholderView)
141-
stateFlow.tryEmit(State(navigation = NavigationState.RoutePreview))
142-
verify { scalebarPlaceholderView.visibility = View.VISIBLE }
143-
}
144-
145-
@Test
146-
fun stateChangeAfterOnAttachedDestinationPreview() {
93+
fun heightChangeAfterOnAttachedNoHeight() {
14794
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
14895
component.onAttached(mapboxNavigation)
14996
clearMocks(scalebarPlaceholderView)
150-
stateFlow.tryEmit(State(navigation = NavigationState.DestinationPreview))
97+
heightFlow.tryEmit(0)
15198
verify { scalebarPlaceholderView.visibility = View.VISIBLE }
15299
}
153100

@@ -161,12 +108,12 @@ class ScalebarPlaceholderComponentTest {
161108
}
162109

163110
@Test
164-
fun stateChangeAfterOnDetached() {
111+
fun heightChangeAfterOnDetached() {
165112
mapScalebarParams.tryEmit(MapboxMapScalebarParams.Builder(context).enabled(true).build())
166113
component.onAttached(mapboxNavigation)
167114
clearMocks(scalebarPlaceholderView)
168115
component.onDetached(mapboxNavigation)
169-
stateFlow.tryEmit(State(navigation = NavigationState.FreeDrive))
116+
heightFlow.tryEmit(9)
170117
verify(exactly = 0) { scalebarPlaceholderView.visibility = any() }
171118
}
172119
}

libnavui-maneuver/src/main/java/com/mapbox/navigation/ui/maneuver/internal/ManeuverComponent.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import kotlinx.coroutines.launch
2020

2121
interface ManeuverComponentContract {
2222
fun onManeuverViewStateChanged(state: MapboxManeuverViewState)
23+
fun onManeuverViewHeightChanged(newHeight: Int)
2324
}
2425

2526
@ExperimentalPreviewMapboxNavigationAPI
@@ -42,6 +43,11 @@ class ManeuverComponent(
4243
contract?.get()?.onManeuverViewStateChanged(it)
4344
}
4445
}
46+
coroutineScope.launch {
47+
maneuverView.heightFlow.collect {
48+
contract?.get()?.onManeuverViewHeightChanged(it)
49+
}
50+
}
4551
coroutineScope.launch {
4652
combine(
4753
mapboxNavigation.flowRoutesUpdated(),
@@ -69,4 +75,9 @@ class ManeuverComponent(
6975
}.collect()
7076
}
7177
}
78+
79+
override fun onDetached(mapboxNavigation: MapboxNavigation) {
80+
super.onDetached(mapboxNavigation)
81+
contract?.get()?.onManeuverViewHeightChanged(0)
82+
}
7283
}

libnavui-maneuver/src/main/java/com/mapbox/navigation/ui/maneuver/view/MapboxManeuverView.kt

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ import kotlinx.coroutines.flow.asStateFlow
4545
*/
4646
class MapboxManeuverView : ConstraintLayout {
4747

48+
private val _heightFlow = MutableStateFlow(0)
4849
private val _maneuverViewState = MutableStateFlow<MapboxManeuverViewState>(
4950
MapboxManeuverViewState.COLLAPSED
5051
)
@@ -54,6 +55,8 @@ class MapboxManeuverView : ConstraintLayout {
5455
*/
5556
val maneuverViewState = _maneuverViewState.asStateFlow()
5657

58+
internal val heightFlow = _heightFlow.asStateFlow()
59+
5760
private var maneuverViewOptions = ManeuverViewOptions.Builder().build()
5861

5962
/**
@@ -319,8 +322,12 @@ class MapboxManeuverView : ConstraintLayout {
319322
*/
320323
fun updateUpcomingManeuversVisibility(visibility: Int) {
321324
when (visibility) {
322-
VISIBLE -> { _maneuverViewState.value = MapboxManeuverViewState.EXPANDED }
323-
else -> { _maneuverViewState.value = MapboxManeuverViewState.COLLAPSED }
325+
VISIBLE -> {
326+
_maneuverViewState.value = MapboxManeuverViewState.EXPANDED
327+
}
328+
else -> {
329+
_maneuverViewState.value = MapboxManeuverViewState.COLLAPSED
330+
}
324331
}
325332
binding.upcomingManeuverRecycler.visibility = visibility
326333
}
@@ -745,4 +752,11 @@ class MapboxManeuverView : ConstraintLayout {
745752
internal fun getUpcomingManeuverAdapter(): MapboxUpcomingManeuverAdapter {
746753
return upcomingManeuverAdapter
747754
}
755+
756+
override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int) {
757+
super.onSizeChanged(w, h, oldw, oldh)
758+
if (h != oldh) {
759+
_heightFlow.tryEmit(h)
760+
}
761+
}
748762
}

0 commit comments

Comments
 (0)