Skip to content

Commit

Permalink
Merge branch 'main' into android_annotations
Browse files Browse the repository at this point in the history
  • Loading branch information
ahmedre committed Nov 7, 2024
2 parents 3ca1aa6 + fbbc52e commit 455a7c7
Show file tree
Hide file tree
Showing 64 changed files with 3,755 additions and 1,871 deletions.
7 changes: 3 additions & 4 deletions .github/workflows/android.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ on:

jobs:
build:
runs-on: macos-14
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-android-build
cancel-in-progress: true
Expand Down Expand Up @@ -52,8 +52,7 @@ jobs:
working-directory: android

test:

runs-on: macos-14
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-android-test
cancel-in-progress: true
Expand Down Expand Up @@ -99,7 +98,7 @@ jobs:

verify-snapshots:

runs-on: macos-14
runs-on: ubuntu-latest
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-android-snapshots
cancel-in-progress: true
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/typos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ jobs:
uses: actions/checkout@v4

- name: Run typos
uses: crate-ci/typos@v1.26.0
uses: crate-ci/typos@master
1 change: 1 addition & 0 deletions .swiftformat
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

--exclude apple/.build
--exclude apple/DemoApp/.build
--exclude apple/Sources/UniFFI/ferrostar.swift

# format options

Expand Down
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ if useLocalFramework {
path: "./common/target/ios/libferrostar-rs.xcframework"
)
} else {
let releaseTag = "0.20.0"
let releaseChecksum = "b3565c57b70ac72426e10e7d3c3020900c07548d0eede8200ef4d07edb617a22"
let releaseTag = "0.20.1"
let releaseChecksum = "a5d8ecc5b4d4b77e2e9fd237b3c6ffd62772606a996a0e34f0fc7ecadc19fb9c"
binaryTarget = .binaryTarget(
name: "FerrostarCoreRS",
url:
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@ ext {

allprojects {
group = "com.stadiamaps.ferrostar"
version = "0.20.0"
version = "0.20.1"
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,5 @@ object DefaultInstructionRowTheme : InstructionRowTheme {
@Composable get() = MaterialTheme.colorScheme.onSurface

override val backgroundColor: Color
@Composable get() = MaterialTheme.colorScheme.surface
@Composable get() = MaterialTheme.colorScheme.surfaceContainerLow
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,7 @@ interface RoadNameViewTheme {
*/
object DefaultRoadNameViewTheme : RoadNameViewTheme {
override val textStyle: TextStyle
@Composable
get() =
MaterialTheme.typography.labelSmall.copy(color = MaterialTheme.colorScheme.inverseOnSurface)
@Composable get() = MaterialTheme.typography.labelSmall.copy(color = Color.White)

override val backgroundColor: Color
@Composable get() = Color(0x35, 0x83, 0xdd)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,47 @@
package com.stadiamaps.ferrostar.composeui.views

import android.icu.util.ULocale
import androidx.compose.animation.animateContentSize
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.heightIn
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.shadow
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import com.stadiamaps.ferrostar.composeui.formatting.DistanceFormatter
import com.stadiamaps.ferrostar.composeui.formatting.LocalizedDistanceFormatter
import com.stadiamaps.ferrostar.composeui.theme.DefaultInstructionRowTheme
import com.stadiamaps.ferrostar.composeui.theme.InstructionRowTheme
import com.stadiamaps.ferrostar.composeui.views.controls.PillDragHandle
import com.stadiamaps.ferrostar.composeui.views.maneuver.ManeuverImage
import com.stadiamaps.ferrostar.composeui.views.maneuver.ManeuverInstructionView
import uniffi.ferrostar.ManeuverModifier
import uniffi.ferrostar.ManeuverType
import uniffi.ferrostar.RouteStep
import uniffi.ferrostar.VisualInstruction
import uniffi.ferrostar.VisualInstructionContent

Expand All @@ -36,23 +58,88 @@ fun InstructionsView(
distanceToNextManeuver: Double?,
distanceFormatter: DistanceFormatter = LocalizedDistanceFormatter(),
theme: InstructionRowTheme = DefaultInstructionRowTheme,
content: @Composable () -> Unit = {
ManeuverImage(instructions.primaryContent, tint = MaterialTheme.colorScheme.primary)
remainingSteps: List<RouteStep>? = null,
initExpanded: Boolean = false,
contentBuilder: @Composable (VisualInstruction) -> Unit = {
ManeuverImage(it.primaryContent, tint = MaterialTheme.colorScheme.primary)
}
) {
Column(
var isExpanded by remember { mutableStateOf(initExpanded) }
val screenHeight = LocalConfiguration.current.screenHeightDp.dp

Box(
modifier =
Modifier.fillMaxWidth()
.shadow(elevation = 5.dp, RoundedCornerShape(10.dp))
.heightIn(max = screenHeight)
.animateContentSize(animationSpec = spring(stiffness = Spring.StiffnessHigh))
.background(theme.backgroundColor, RoundedCornerShape(10.dp))
.padding(8.dp)) {
ManeuverInstructionView(
text = instructions.primaryContent.text,
distanceFormatter = distanceFormatter,
distanceToNextManeuver = distanceToNextManeuver,
theme = theme,
content = content)
// TODO: Secondary instructions
.clickable { isExpanded = true }) {
Column(modifier = Modifier.fillMaxWidth().padding(16.dp)) {
// Primary content
ManeuverInstructionView(
text = instructions.primaryContent.text,
distanceFormatter = distanceFormatter,
distanceToNextManeuver = distanceToNextManeuver,
theme = theme) {
contentBuilder(instructions)
}

// TODO: Secondary content

// Expanded content
val showMultipleRows = isExpanded && remainingSteps != null && remainingSteps.count() > 1
if (showMultipleRows) {
Spacer(modifier = Modifier.height(8.dp))
HorizontalDivider(thickness = 1.dp)
Spacer(modifier = Modifier.height(8.dp))
}

if (isExpanded) {
Box(modifier = Modifier.weight(1f)) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
verticalArrangement = Arrangement.spacedBy(8.dp)) {
if (remainingSteps != null) {
items(remainingSteps.drop(1)) { step ->
step.visualInstructions.firstOrNull()?.let { upcomingInstruction ->
ManeuverInstructionView(
text = upcomingInstruction.primaryContent.text,
distanceFormatter = distanceFormatter,
distanceToNextManeuver = step.distance,
theme = theme) {
contentBuilder(upcomingInstruction)
}
Spacer(modifier = Modifier.height(8.dp))
HorizontalDivider(thickness = 1.dp)
}
}
}
}
}
}

if (showMultipleRows) {
Spacer(modifier = Modifier.height(16.dp))
}
}

PillDragHandle(
isExpanded,
// The modifier here lets us keep the container as slim as possible
modifier =
Modifier.offset {
IntOffset(
0,
if (isExpanded) {
(-4 * density).toInt()
} else {
(-8 * density).toInt()
})
}
.align(Alignment.BottomCenter),
iconTintColor = theme.iconTintColor) {
isExpanded = !isExpanded
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package com.stadiamaps.ferrostar.composeui.views.controls

import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.KeyboardArrowUp
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.semantics.onClick
import androidx.compose.ui.semantics.role
import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp

@Composable
fun PillDragHandle(
isExpanded: Boolean,
modifier: Modifier = Modifier.fillMaxWidth(),
iconTintColor: Color = MaterialTheme.colorScheme.onSurface,
toggle: () -> Unit = {}
) {
val handleHeight = if (isExpanded) 36.dp else 4.dp
Box(modifier = modifier.height(handleHeight).clickable(onClick = toggle)) {
if (isExpanded) {
Icon(
Icons.Rounded.KeyboardArrowUp,
modifier = Modifier.align(Alignment.Center),
contentDescription = "Show upcoming maneuvers",
tint = iconTintColor)
} else {
Box(
modifier =
Modifier.align(Alignment.Center)
.height(handleHeight)
.width(24.dp)
.background(iconTintColor, RoundedCornerShape(6.dp))
.semantics {
role = Role.Button
onClick(label = "Hide upcoming maneuvers") {
toggle()
true
}
})
}
}
}

@Preview
@Composable
fun PreviewPillDragHandleCollapsed() {
PillDragHandle(isExpanded = false, iconTintColor = Color.White)
}

@Preview
@Composable
fun PreviewPillDragHandleExpanded() {
PillDragHandle(isExpanded = true, iconTintColor = Color.White)
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.stadiamaps.ferrostar.views

import com.stadiamaps.ferrostar.composeui.views.InstructionsView
import com.stadiamaps.ferrostar.core.NavigationUiState
import com.stadiamaps.ferrostar.core.mock.pedestrianExample
import com.stadiamaps.ferrostar.support.paparazziDefault
import com.stadiamaps.ferrostar.support.withSnapshotBackground
import org.junit.Rule
Expand Down Expand Up @@ -35,4 +37,19 @@ class InstructionViewTest {
}
}
}

@Test
fun testInstructionViewExpanded() {
val state = NavigationUiState.pedestrianExample()

paparazzi.snapshot {
withSnapshotBackground {
InstructionsView(
instructions = state.visualInstruction!!,
remainingSteps = state.remainingSteps,
distanceToNextManeuver = 42.0,
initExpanded = true)
}
}
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import kotlinx.coroutines.launch
import uniffi.ferrostar.CourseOverGround
import uniffi.ferrostar.GeographicCoordinate
import uniffi.ferrostar.Heading
import uniffi.ferrostar.LocationBias
import uniffi.ferrostar.LocationSimulationState
import uniffi.ferrostar.Route
import uniffi.ferrostar.Speed
Expand Down Expand Up @@ -155,7 +156,7 @@ class SimulatedLocationProvider : LocationProvider {
override fun addListener(listener: LocationUpdateListener, executor: Executor) {
listeners.add(listener to executor)

if (simulationJob == null) {
if (simulationJob?.isActive != true) {
simulationJob = scope.launch { startSimulation() }
}
}
Expand All @@ -168,11 +169,11 @@ class SimulatedLocationProvider : LocationProvider {
}
}

fun setSimulatedRoute(route: Route) {
simulationState = locationSimulationFromRoute(route, resampleDistance = 10.0)
fun setSimulatedRoute(route: Route, bias: LocationBias = LocationBias.None) {
simulationState = locationSimulationFromRoute(route, resampleDistance = 10.0, bias)
lastLocation = simulationState?.currentLocation

if (listeners.isNotEmpty() && simulationJob == null) {
if (listeners.isNotEmpty() && simulationJob?.isActive != true) {
simulationJob = scope.launch { startSimulation() }
}
}
Expand Down
Loading

0 comments on commit 455a7c7

Please sign in to comment.