Skip to content

Commit

Permalink
Cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
ianthetechie committed Oct 22, 2024
1 parent 7510aa8 commit 56cb38f
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,11 @@ import androidx.lifecycle.viewModelScope
import com.stadiamaps.ferrostar.core.extensions.deviation
import com.stadiamaps.ferrostar.core.extensions.progress
import com.stadiamaps.ferrostar.core.extensions.visualInstruction
import java.util.concurrent.Executors
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import uniffi.ferrostar.GeographicCoordinate
import uniffi.ferrostar.Heading
import uniffi.ferrostar.RouteDeviation
import uniffi.ferrostar.SpokenInstruction
import uniffi.ferrostar.TripProgress
Expand Down Expand Up @@ -87,57 +83,6 @@ interface NavigationViewModel {
// to be a very big refactor (maybe even crossing into the MapLibre Compose project)
}

class IdleNavigationViewModel(locationProvider: LocationProvider) :
ViewModel(), NavigationViewModel {
private val locationStateFlow = MutableStateFlow(locationProvider.lastLocation)
private val executor = Executors.newSingleThreadScheduledExecutor()

init {
locationProvider.addListener(
object : LocationUpdateListener {
override fun onLocationUpdated(location: UserLocation) {
locationStateFlow.update { location }
}

override fun onHeadingUpdated(heading: Heading) {
// TODO: Heading
}
},
executor)
}

override val uiState =
locationStateFlow
.map { userLocation ->
// TODO: Heading
NavigationUiState(userLocation, null, null, null, null, null, null, false, null, null)
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
// TODO: Heading
initialValue =
NavigationUiState(
locationProvider.lastLocation,
null,
null,
null,
null,
null,
null,
false,
null,
null))

override fun toggleMute() {
// Do nothing
}

override fun stopNavigation() {
// Do nothing
}
}

class DefaultNavigationViewModel(
private val ferrostarCore: FerrostarCore,
private val spokenInstructionObserver: SpokenInstructionObserver? = null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ object AppModule {
val core =
FerrostarCore(
valhallaEndpointURL = valhallaEndpointUrl,
profile = "low_speed_vehicle",
profile = "auto",
httpClient = httpClient,
locationProvider = locationProvider,
foregroundServiceManager = foregroundServiceManager,
Expand All @@ -87,6 +87,10 @@ object AppModule {
options =
mapOf(
"costingOptions" to
// Just an example... You can set multiple costing options for any profile
// in Valhalla.
// If your app uses multiple routing modes, you can have a master settings
// map, or construct a new one each time.
mapOf(
"low_speed_vehicle" to
mapOf(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import com.stadiamaps.autocomplete.center
import com.stadiamaps.ferrostar.composeui.runtime.KeepScreenOnDisposableEffect
import com.stadiamaps.ferrostar.composeui.views.gridviews.InnerGridView
import com.stadiamaps.ferrostar.core.AndroidSystemLocationProvider
import com.stadiamaps.ferrostar.core.IdleNavigationViewModel
import com.stadiamaps.ferrostar.core.LocationProvider
import com.stadiamaps.ferrostar.core.NavigationViewModel
import com.stadiamaps.ferrostar.core.SimulatedLocationProvider
Expand All @@ -53,9 +52,10 @@ fun DemoNavigationScene(
// Keeps the screen on at consistent brightness while this Composable is in the view hierarchy.
KeepScreenOnDisposableEffect()

var viewModel by remember {
mutableStateOf<NavigationViewModel>(IdleNavigationViewModel(locationProvider))
}
// NOTE: We are aware that this is not a particularly great pattern.
// We are working on improving this. See the discussion on
// https://github.com/stadiamaps/ferrostar/pull/295.
var viewModel by remember { mutableStateOf<NavigationViewModel>(DemoNavigationViewModel()) }
val scope = rememberCoroutineScope()

// Get location permissions.
Expand All @@ -73,43 +73,26 @@ fun DemoNavigationScene(
Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION)
}

// val locationUpdateListener = remember {
// object : LocationUpdateListener {
// private var _lastLocation: MutableStateFlow<UserLocation?> = MutableStateFlow(null)
// val userLocation = _lastLocation.asStateFlow()
//
// override fun onLocationUpdated(location: UserLocation) {
// _lastLocation.value = location
// }
//
// override fun onHeadingUpdated(heading: Heading) {
// // TODO
// }
// }
// }

// val lastLocation = locationUpdateListener.userLocation.collectAsState(scope.coroutineContext)
val vmState = viewModel.uiState.collectAsState(scope.coroutineContext)

val permissionsLauncher =
rememberLauncherForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
permissions ->
when {
permissions.getOrDefault(Manifest.permission.ACCESS_FINE_LOCATION, false) -> {
if (locationProvider is AndroidSystemLocationProvider ||
locationProvider is FusedLocationProvider) {
// FIXME
// locationProvider.addListener(locationUpdateListener, executor)
val vm = viewModel
if ((locationProvider is AndroidSystemLocationProvider ||
locationProvider is FusedLocationProvider) && vm is DemoNavigationViewModel) {
// Activate location updates in the view model
vm.startLocationUpdates(locationProvider)
}
}
permissions.getOrDefault(Manifest.permission.ACCESS_COARSE_LOCATION, false) -> {
// TODO: Probably alert the user that this is unusable for navigation
// onAccess()
}
// TODO: Foreground service permissions; we should block access until approved on API 34+
else -> {
// TODO
// onFailed()
}
}
}
Expand Down Expand Up @@ -141,7 +124,10 @@ fun DemoNavigationScene(
snapUserLocationToRoute = false,
onTapExit = {
viewModel.stopNavigation()
viewModel = IdleNavigationViewModel(locationProvider)
val vm = DemoNavigationViewModel()
viewModel = vm

vm.startLocationUpdates(locationProvider)
},
userContent = { modifier ->
if (!viewModel.isNavigating()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
package com.stadiamaps.ferrostar

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.stadiamaps.ferrostar.core.LocationProvider
import com.stadiamaps.ferrostar.core.LocationUpdateListener
import com.stadiamaps.ferrostar.core.NavigationUiState
import com.stadiamaps.ferrostar.core.NavigationViewModel
import java.util.concurrent.Executors
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.flow.update
import uniffi.ferrostar.Heading
import uniffi.ferrostar.UserLocation

// NOTE: We are aware that this is not a particularly great ViewModel.
// We are working on improving this. See the discussion on
// https://github.com/stadiamaps/ferrostar/pull/295.
class DemoNavigationViewModel : ViewModel(), NavigationViewModel {
private val locationStateFlow = MutableStateFlow<UserLocation?>(null)
private val executor = Executors.newSingleThreadScheduledExecutor()

fun startLocationUpdates(locationProvider: LocationProvider) {
locationStateFlow.update { locationProvider.lastLocation }
locationProvider.addListener(
object : LocationUpdateListener {
override fun onLocationUpdated(location: UserLocation) {
locationStateFlow.update { location }
}

override fun onHeadingUpdated(heading: Heading) {
// TODO: Heading
}
},
executor)
}

override val uiState =
locationStateFlow
.map { userLocation ->
// TODO: Heading
NavigationUiState(userLocation, null, null, null, null, null, null, false, null, null)
}
.stateIn(
scope = viewModelScope,
started = SharingStarted.WhileSubscribed(),
// TODO: Heading
initialValue =
NavigationUiState(null, null, null, null, null, null, null, false, null, null))

override fun toggleMute() {
// Do nothing
}

override fun stopNavigation() {
// Do nothing
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class MainActivity : ComponentActivity(), AndroidTtsStatusListener {
// TTS listener methods

override fun onTtsInitialized(tts: TextToSpeech?, status: Int) {
// Set this up as appropriate for your app
if (tts != null) {
tts.setLanguage(Locale.US)
android.util.Log.i(TAG, "setLanguage status: $status")
Expand Down

0 comments on commit 56cb38f

Please sign in to comment.