Skip to content

Commit

Permalink
Merge branch 'main' into kb-schedule-vm-only
Browse files Browse the repository at this point in the history
  • Loading branch information
KaylaBrady authored Jan 10, 2025
2 parents 739a0e2 + e05b6c0 commit 9d1182c
Show file tree
Hide file tree
Showing 30 changed files with 205 additions and 68 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.mbta.tid.mbta_app.android.state

import androidx.activity.ComponentActivity
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand Down Expand Up @@ -52,7 +53,7 @@ class SubscribeToPredictionsTest {

composeTestRule.setContent {
var stopIds by remember { stopIds }
predictions =
val predictionsVM =
subscribeToPredictions(
stopIds,
predictionsRepo,
Expand All @@ -62,6 +63,7 @@ class SubscribeToPredictionsTest {
MockSettingsRepository()
)
)
predictions = predictionsVM.predictionsFlow.collectAsState(initial = null).value
}

composeTestRule.waitUntil { connectProps == listOf("place-a") }
Expand Down Expand Up @@ -102,7 +104,7 @@ class SubscribeToPredictionsTest {
composeTestRule.setContent {
CompositionLocalProvider(LocalLifecycleOwner provides lifecycleOwner) {
var stopIds by remember { stopIds }
predictions =
val predictionsVM =
subscribeToPredictions(
stopIds,
predictionsRepo,
Expand All @@ -112,6 +114,7 @@ class SubscribeToPredictionsTest {
MockSettingsRepository()
)
)
predictions = predictionsVM.predictionsFlow.collectAsState(initial = null).value
}
}

Expand Down Expand Up @@ -145,7 +148,7 @@ class SubscribeToPredictionsTest {
var predictions: PredictionsStreamDataResponse? = null

composeTestRule.setContent {
predictions =
val predictionsVM =
subscribeToPredictions(
emptyList(),
predictionsRepo,
Expand All @@ -155,6 +158,7 @@ class SubscribeToPredictionsTest {
MockSettingsRepository()
)
)
predictions = predictionsVM.predictionsFlow.collectAsState(initial = null).value
}

composeTestRule.waitUntil { predictions != null }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.mbta.tid.mbta_app.android.stopDetails
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithContentDescription
import androidx.compose.ui.test.onNodeWithText
import com.mbta.tid.mbta_app.model.LocationType
import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder
Expand Down Expand Up @@ -126,4 +127,44 @@ class StopDetailsRoutesViewTest {
composeTestRule.onNodeWithText("Sample Headsign").assertExists()
composeTestRule.onNodeWithText("1 min").assertExists()
}

@Test
fun testLoadingStateFiltered() {
composeTestRule.setContent {
val filterState = remember {
mutableStateOf<StopDetailsFilter?>(StopDetailsFilter("routeId", 1))
}

StopDetailsRoutesView(
departures = null,
global = globalResponse,
now = now,
pinRoute = {},
pinnedRoutes = emptySet(),
filter = filterState.value,
updateStopFilter = filterState::value::set
)
}

composeTestRule.onNodeWithContentDescription("Loading...").assertExists()
}

@Test
fun testLoadingStateUnfiltered() {
composeTestRule.setContent {
val filterState = remember { mutableStateOf<StopDetailsFilter?>(null) }

StopDetailsRoutesView(
departures = null,
global = globalResponse,
now = now,
pinRoute = {},
pinnedRoutes = emptySet(),
filter = filterState.value,
updateStopFilter = filterState::value::set
)
}

composeTestRule.onNodeWithContentDescription("Loading...").assertExists()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.sp
import com.mbta.tid.mbta_app.android.R
import com.mbta.tid.mbta_app.android.util.modifiers.placeholderIfLoading
import com.mbta.tid.mbta_app.model.Direction

private val localizedDirectionNames: Map<String, Int> =
Expand All @@ -35,14 +36,21 @@ fun DirectionLabel(direction: Direction, modifier: Modifier = Modifier) {
R.string.directionTo,
stringResource(directionNameFormatted(direction))
),
fontSize = 13.sp
fontSize = 13.sp,
modifier = Modifier.placeholderIfLoading()
)
Text(
destination,
fontSize = 17.sp,
fontWeight = FontWeight.SemiBold,
modifier = Modifier.placeholderIfLoading()
)
Text(destination, fontSize = 17.sp, fontWeight = FontWeight.SemiBold)
} else {
Text(
stringResource(directionNameFormatted(direction)),
fontSize = 17.sp,
fontWeight = FontWeight.SemiBold
fontWeight = FontWeight.SemiBold,
modifier = Modifier.placeholderIfLoading()
)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import com.mbta.tid.mbta_app.android.MyApplicationTheme
import com.mbta.tid.mbta_app.android.util.placeholderIfLoading
import com.mbta.tid.mbta_app.android.util.modifiers.placeholderIfLoading
import com.mbta.tid.mbta_app.model.Alert
import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder.Single.alert
import com.mbta.tid.mbta_app.model.ObjectCollectionBuilder.Single.route
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,15 @@ package com.mbta.tid.mbta_app.android.component
import androidx.compose.foundation.layout.Column
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.semantics.clearAndSetSemantics
import androidx.compose.ui.semantics.contentDescription
import com.mbta.tid.mbta_app.android.R
import com.mbta.tid.mbta_app.android.nearbyTransit.NearbyRouteView
import com.mbta.tid.mbta_app.android.util.modifiers.loadingShimmer
import com.mbta.tid.mbta_app.model.LoadingPlaceholders
import com.valentinilk.shimmer.shimmer
import kotlinx.datetime.Clock

@Composable
fun LoadingRouteCard() {
val placeholderRouteData = LoadingPlaceholders.nearbyRoute()

val contentDesc = stringResource(R.string.loading)

Column(
modifier = Modifier.shimmer().clearAndSetSemantics { contentDescription = contentDesc }
) {
Column(modifier = Modifier.loadingShimmer()) {
NearbyRouteView(placeholderRouteData, false, {}, Clock.System.now(), { _, _ -> })
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.mbta.tid.mbta_app.android.R
import com.mbta.tid.mbta_app.android.util.placeholderIfLoading
import com.mbta.tid.mbta_app.android.util.modifiers.placeholderIfLoading

@Composable
fun PinButton(pinned: Boolean, color: Color, action: () -> Unit) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import com.mbta.tid.mbta_app.android.R
import com.mbta.tid.mbta_app.android.generated.drawableByName
import com.mbta.tid.mbta_app.android.util.placeholderIfLoading
import com.mbta.tid.mbta_app.android.util.modifiers.placeholderIfLoading
import com.mbta.tid.mbta_app.model.RealtimePatterns
import com.mbta.tid.mbta_app.model.Route

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import androidx.compose.ui.semantics.semantics
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.mbta.tid.mbta_app.android.util.placeholderIfLoading
import com.mbta.tid.mbta_app.android.util.modifiers.placeholderIfLoading

@Composable
fun TransitHeader(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.mbta.tid.mbta_app.android.R
import com.mbta.tid.mbta_app.android.util.UpcomingTripAccessibilityFormatters
import com.mbta.tid.mbta_app.android.util.placeholderIfLoading
import com.mbta.tid.mbta_app.android.util.modifiers.placeholderIfLoading
import com.mbta.tid.mbta_app.android.util.typeText
import com.mbta.tid.mbta_app.model.Alert
import com.mbta.tid.mbta_app.model.RealtimePatterns
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import androidx.compose.ui.res.colorResource
import androidx.compose.ui.unit.dp
import com.mbta.tid.mbta_app.android.R
import com.mbta.tid.mbta_app.android.component.StopDeparturesSummaryList
import com.mbta.tid.mbta_app.android.util.placeholderIfLoading
import com.mbta.tid.mbta_app.android.util.modifiers.placeholderIfLoading
import com.mbta.tid.mbta_app.model.PatternsByStop
import com.mbta.tid.mbta_app.model.StopDetailsFilter
import com.mbta.tid.mbta_app.model.TripInstantDisplay
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.compositionLocalOf
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
Expand All @@ -26,6 +27,7 @@ import com.mbta.tid.mbta_app.android.component.ErrorBannerViewModel
import com.mbta.tid.mbta_app.android.component.LoadingRouteCard
import com.mbta.tid.mbta_app.android.state.getSchedule
import com.mbta.tid.mbta_app.android.state.subscribeToPredictions
import com.mbta.tid.mbta_app.android.util.IsLoadingSheetContents
import com.mbta.tid.mbta_app.android.util.managePinnedRoutes
import com.mbta.tid.mbta_app.android.util.rememberSuspend
import com.mbta.tid.mbta_app.android.util.timer
Expand All @@ -40,8 +42,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.koin.androidx.compose.koinViewModel

val IsLoadingSheetContents = compositionLocalOf { false }

@Composable
fun NearbyTransitView(
alertData: AlertsStreamDataResponse?,
Expand All @@ -67,7 +67,13 @@ fun NearbyTransitView(
val now = timer(updateInterval = 5.seconds)
val stopIds = remember(nearbyVM.nearby) { nearbyVM.nearby?.stopIds()?.toList() }
val schedules = getSchedule(stopIds)
val predictions = subscribeToPredictions(stopIds, errorBannerViewModel = errorBannerViewModel)
val predictionsVM = subscribeToPredictions(stopIds, errorBannerViewModel = errorBannerViewModel)
val predictions by predictionsVM.predictionsFlow.collectAsState(initial = null)
LaunchedEffect(targetLocation == null) {
if (targetLocation == null) {
predictionsVM.reset()
}
}

val (pinnedRoutes, togglePinnedRoute) = managePinnedRoutes()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import com.mbta.tid.mbta_app.android.map.IMapViewModel
import com.mbta.tid.mbta_app.android.map.MapViewModel
import com.mbta.tid.mbta_app.android.nearbyTransit.NearbyTransitTabViewModel
import com.mbta.tid.mbta_app.android.nearbyTransit.NearbyTransitView
import com.mbta.tid.mbta_app.android.nearbyTransit.NearbyTransitViewModel
import com.mbta.tid.mbta_app.android.nearbyTransit.NoNearbyStopsView
import com.mbta.tid.mbta_app.android.search.SearchBarOverlay
import com.mbta.tid.mbta_app.android.state.subscribeToVehicles
Expand All @@ -64,6 +65,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.FlowPreview
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch
import org.koin.androidx.compose.koinViewModel
import org.koin.compose.koinInject

@OptIn(ExperimentalMaterial3Api::class)
Expand Down Expand Up @@ -216,6 +218,8 @@ fun NearbyTransitPage(
}
}
composable<SheetRoutes.NearbyTransit> {
// for ViewModel reasons, must be within the `composable` to be the same instance
val nearbyViewModel: NearbyTransitViewModel = koinViewModel()
LaunchedEffect(true) {
if (!navBarVisible) {
showNavBar()
Expand All @@ -234,13 +238,13 @@ fun NearbyTransitPage(
}
LaunchedEffect(nearbyTransit.viewportProvider.isManuallyCentering) {
if (nearbyTransit.viewportProvider.isManuallyCentering) {
// TODO reset view model
nearbyViewModel.reset()
targetLocation = null
}
}
LaunchedEffect(nearbyTransit.viewportProvider.isFollowingPuck) {
if (nearbyTransit.viewportProvider.isFollowingPuck) {
// TODO reset view model
nearbyViewModel.reset()
targetLocation = null
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package com.mbta.tid.mbta_app.android.pages
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import com.mapbox.maps.MapboxExperimental
import com.mbta.tid.mbta_app.android.component.ErrorBannerViewModel
Expand Down Expand Up @@ -36,11 +38,12 @@ fun StopDetailsPage(
) {
val globalResponse = getGlobalData()

val predictionsResponse =
val predictionsVM =
subscribeToPredictions(
stopIds = listOf(stop.id),
errorBannerViewModel = errorBannerViewModel
)
val predictionsResponse by predictionsVM.predictionsFlow.collectAsState(initial = null)

val now = timer(updateInterval = 5.seconds)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ value class PhoenixSocketWrapper(private val socket: Socket) : PhoenixSocket {

fun attachLogging() {
socket.onMessage { message -> Log.i("Socket", message.toString()) }
socket.onError { throwable, response -> Log.e("Socket", response.toString(), throwable) }
socket.onError { throwable, response ->
Log.e("Socket", response?.toString() ?: throwable.toString(), throwable)
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.mbta.tid.mbta_app.android.state

import android.util.Log
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.compose.LifecycleResumeEffect
Expand All @@ -11,7 +10,6 @@ import com.mbta.tid.mbta_app.android.component.ErrorBannerViewModel
import com.mbta.tid.mbta_app.model.response.ApiResult
import com.mbta.tid.mbta_app.model.response.PredictionsByStopJoinResponse
import com.mbta.tid.mbta_app.model.response.PredictionsByStopMessageResponse
import com.mbta.tid.mbta_app.model.response.PredictionsStreamDataResponse
import com.mbta.tid.mbta_app.repositories.IPredictionsRepository
import kotlin.time.Duration.Companion.seconds
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -86,6 +84,10 @@ class PredictionsViewModel(
}
}

fun reset() {
_predictions.value = null
}

fun disconnect() {
predictionsRepository.disconnect()
errorBannerViewModel.loadingWhenPredictionsStale = true
Expand Down Expand Up @@ -119,7 +121,7 @@ fun subscribeToPredictions(
stopIds: List<String>?,
predictionsRepository: IPredictionsRepository = koinInject(),
errorBannerViewModel: ErrorBannerViewModel
): PredictionsStreamDataResponse? {
): PredictionsViewModel {
val viewModel: PredictionsViewModel =
viewModel(
factory = PredictionsViewModel.Factory(predictionsRepository, errorBannerViewModel)
Expand All @@ -133,5 +135,5 @@ fun subscribeToPredictions(

onPauseOrDispose { viewModel.disconnect() }
}
return viewModel.predictionsFlow.collectAsState(initial = null).value
return viewModel
}
Loading

0 comments on commit 9d1182c

Please sign in to comment.