Skip to content

Commit

Permalink
Merge branch 'main' into es-gl-stop-details-vehicles
Browse files Browse the repository at this point in the history
  • Loading branch information
EmmaSimon committed Oct 15, 2024
2 parents 731a4eb + 14bce93 commit 57361f5
Show file tree
Hide file tree
Showing 25 changed files with 516 additions and 402 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,8 @@ class NearbyTransitPageTest : KoinTest {

override var lastUpdated: Instant? = null

override fun shouldForgetPredictions(predictionCount: Int) = false

override fun disconnect() {
/* no-op */
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,8 @@ class NearbyTransitViewTest : KoinTest {

override var lastUpdated: Instant? = null

override fun shouldForgetPredictions(predictionCount: Int) = false

override fun disconnect() {
/* no-op */
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class StopDetailsViewTest {

override var lastUpdated: Instant? = null

override fun shouldForgetPredictions(predictionCount: Int) = false

override fun disconnect() {
/* no-op */
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class SubscribeToPredictionsTest {

override var lastUpdated: Instant? = null

override fun shouldForgetPredictions(predictionCount: Int) = false

override fun disconnect() {
check(isConnected) { "called disconnect when not connected" }
isConnected = false
Expand Down
12 changes: 6 additions & 6 deletions iosApp/Podfile.lock
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
PODS:
- Sentry (8.26.0):
- Sentry/Core (= 8.26.0)
- Sentry/Core (8.26.0)
- Sentry (8.36.0):
- Sentry/Core (= 8.36.0)
- Sentry/Core (8.36.0)
- shared (1.0):
- Sentry (~> 8.26.0)
- Sentry (~> 8.36.0)

DEPENDENCIES:
- shared (from `../shared/`)
Expand All @@ -17,8 +17,8 @@ EXTERNAL SOURCES:
:path: "../shared/"

SPEC CHECKSUMS:
Sentry: 74a073c71c998117edb08f56f443c83570a31bed
shared: 3feb3c866b91cde11fd8e459d237a2cc925cd032
Sentry: f8374b5415bc38dfb5645941b3ae31230fbeae57
shared: 19e2aa6dcc6627fddba6b8c32232f932ea8b8cc2

PODFILE CHECKSUM: 32413a7fdb16d40c9f57cf8da0c74d4507ff5f90

Expand Down
3 changes: 3 additions & 0 deletions iosApp/iosApp/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -350,6 +350,9 @@
},
"select location" : {

},
"Service Change" : {
"comment" : "Possible alert effect"
},
"Service ended" : {

Expand Down
1 change: 1 addition & 0 deletions iosApp/iosApp/Pages/AlertDetails/AlertDetails.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct AlertDetails: View {
switch alert.effect {
case .detour: NSLocalizedString("Detour", comment: "Possible alert effect")
case .dockClosure: NSLocalizedString("Dock Closure", comment: "Possible alert effect")
case .serviceChange: NSLocalizedString("Service Change", comment: "Possible alert effect")
case .shuttle: NSLocalizedString("Shuttle", comment: "Possible alert effect")
case .stationClosure: NSLocalizedString("Station Closure", comment: "Possible alert effect")
case .stopClosure: NSLocalizedString("Stop Closure", comment: "Possible alert effect")
Expand Down
9 changes: 8 additions & 1 deletion iosApp/iosApp/Pages/NearbyTransit/NearbyTransitView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,14 @@ struct NearbyTransitView: View {
}
}
.withScenePhaseHandlers(
onActive: { joinPredictions(state.nearbyByRouteAndStop?.stopIds()) },
onActive: {
if let predictionsByStop,
predictionsRepository
.shouldForgetPredictions(predictionCount: predictionsByStop.predictionQuantity()) {
self.predictionsByStop = nil
}
joinPredictions(state.nearbyByRouteAndStop?.stopIds())
},
onInactive: leavePredictions,
onBackground: {
leavePredictions()
Expand Down
19 changes: 14 additions & 5 deletions iosApp/iosApp/Pages/StopDetails/StopDetailsPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,20 @@ struct StopDetailsPage: View {
.onDisappear {
leavePredictions()
}
.withScenePhaseHandlers(onActive: { joinPredictions(stop) },
onInactive: leavePredictions,
onBackground: { leavePredictions()
isReturningFromBackground = true
})
.withScenePhaseHandlers(
onActive: {
if let predictionsByStop,
predictionsRepository
.shouldForgetPredictions(predictionCount: predictionsByStop.predictionQuantity()) {
self.predictionsByStop = nil
}
joinPredictions(stop)
},
onInactive: leavePredictions,
onBackground: { leavePredictions()
isReturningFromBackground = true
}
)
}
}

Expand Down
21 changes: 15 additions & 6 deletions iosApp/iosApp/Pages/TripDetails/TripDetailsPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -130,12 +130,21 @@ struct TripDetailsPage: View {
joinVehicle(vehicleId: vehicleId)
}
.onReceive(inspection.notice) { inspection.visit(self, $0) }
.withScenePhaseHandlers(onActive: joinRealtime,
onInactive: leaveRealtime,
onBackground: {
leaveRealtime()
isReturningFromBackground = true
})
.withScenePhaseHandlers(
onActive: {
if let tripPredictions,
tripPredictionsRepository
.shouldForgetPredictions(predictionCount: tripPredictions.predictionQuantity()) {
self.tripPredictions = nil
}
joinRealtime()
},
onInactive: leaveRealtime,
onBackground: {
leaveRealtime()
isReturningFromBackground = true
}
)
}

private func loadEverything() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -655,6 +655,10 @@ final class TripDetailsPageTests: XCTestCase {

var lastUpdated: Instant?

func shouldForgetPredictions(predictionCount _: Int32) -> Bool {
false
}

func disconnect() {
onDisconnect?()
}
Expand Down
2 changes: 1 addition & 1 deletion iosApp/iosAppTests/Views/ErrorBannerTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ final class ErrorBannerTests: XCTestCase {

let stateSetPublisher = PassthroughSubject<Void, Never>()

let showedState = sut.inspection.inspect(onReceive: stateSetPublisher, after: 0.2) { view in
let showedState = sut.inspection.inspect(onReceive: stateSetPublisher, after: 0.5) { view in
XCTAssertEqual(try view.find(ViewType.Text.self).string(), "Updated \(minutesAgo) minutes ago")

try view.find(ViewType.Button.self).tap()
Expand Down
4 changes: 2 additions & 2 deletions iosApp/iosAppTests/Views/NearbyTransitViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ final class NearbyTransitViewTests: XCTestCase {
nearbyVM: .init()
)

let exp = sut.inspection.inspect(onReceive: globalLoadedPublisher, after: 0.2) { view in
let exp = sut.inspection.inspect(onReceive: globalLoadedPublisher, after: 0.5) { view in
let stops = view.findAll(NearbyStopView.self)
XCTAssertEqual(stops[0].findAll(DestinationRowView.self).count, 3)

Expand Down Expand Up @@ -710,7 +710,7 @@ final class NearbyTransitViewTests: XCTestCase {
nearbyVM: .init()
)

sut.inspection.inspect(after: 0.2) { view in
sut.inspection.inspect(after: 0.5) { view in
XCTAssertNotNil(try view.view(NearbyTransitView.self)
.find(text: "Error loading data"))
}
Expand Down
2 changes: 1 addition & 1 deletion shared/shared.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Pod::Spec.new do |spec|
spec.vendored_frameworks = 'build/cocoapods/framework/shared.framework'
spec.libraries = 'c++'
spec.ios.deployment_target = '15.0'
spec.dependency 'Sentry', '~> 8.26.0'
spec.dependency 'Sentry', '~> 8.36.0'

if !Dir.exist?('build/cocoapods/framework/shared.framework') || Dir.empty?('build/cocoapods/framework/shared.framework')
raise "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ fun endToEndModule(): Module {

override var lastUpdated: Instant? = null

override fun shouldForgetPredictions(predictionCount: Int) = false

override fun connectV2(
stopIds: List<String>,
onJoin: (ApiResult<PredictionsByStopJoinResponse>) -> Unit,
Expand Down Expand Up @@ -199,6 +201,8 @@ fun endToEndModule(): Module {

override var lastUpdated: Instant? = null

override fun shouldForgetPredictions(predictionCount: Int) = false

override fun disconnect() {
TODO("Not yet implemented")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import com.mbta.tid.mbta_app.model.response.PredictionsStreamDataResponse
import com.mbta.tid.mbta_app.model.response.ScheduleResponse
import com.mbta.tid.mbta_app.utils.resolveParentId
import io.github.dellisd.spatialk.geojson.Position
import kotlin.time.Duration
import kotlin.time.Duration.Companion.minutes
import kotlinx.datetime.Instant

Expand Down Expand Up @@ -449,19 +450,22 @@ data class NearbyStaticData(val data: List<TransitWithStops>) {

/**
* Attaches [schedules] and [predictions] to the route, stop, and routePattern to which they apply.
* Removes non-typical route patterns which are not predicted within 90 minutes of [filterAtTime].
* Sorts routes by subway first then nearest stop, stops by distance, and headsigns by route pattern
* sort order.
* Removes non-typical route patterns which are not happening either at all or between
* [filterAtTime] and [filterAtTime] + [hideNonTypicalPatternsBeyondNext]. Sorts routes by subway
* first then nearest stop, stops by distance, and headsigns by route pattern sort order.
*
* Runs static data and predictions through [TemporaryTerminalRewriter].
*/
fun NearbyStaticData.withRealtimeInfo(
globalData: GlobalResponse?,
sortByDistanceFrom: Position,
sortByDistanceFrom: Position?,
schedules: ScheduleResponse?,
predictions: PredictionsStreamDataResponse?,
alerts: AlertsStreamDataResponse?,
filterAtTime: Instant,
showAllPatternsWhileLoading: Boolean,
hideNonTypicalPatternsBeyondNext: Duration?,
filterCancellations: Boolean,
pinnedRoutes: Set<String>
): List<StopsAssociated> {
val activeRelevantAlerts =
Expand Down Expand Up @@ -543,11 +547,26 @@ fun NearbyStaticData.withRealtimeInfo(
)
.orEmpty()

val cutoffTime = filterAtTime.plus(90.minutes)
val cutoffTime = hideNonTypicalPatternsBeyondNext?.let { filterAtTime + it }
val hasSchedulesTodayByPattern = NearbyStaticData.getSchedulesTodayByPattern(schedules)

val upcomingTripsMap: UpcomingTripsMap =
(upcomingTripsByRoutePatternAndStop + upcomingTripsByDirectionAndStop)
val upcomingTripsMap: UpcomingTripsMap? =
(upcomingTripsByRoutePatternAndStop + upcomingTripsByDirectionAndStop).takeUnless {
schedules == null && predictions == null
}

fun UpcomingTripsMap.maybeFilterCancellations(isSubway: Boolean) =
if (filterCancellations) this.filterCancellations(isSubway) else this

fun RealtimePatterns.shouldShow(): Boolean {
if (!allDataLoaded && showAllPatternsWhileLoading) return true
val isUpcoming =
when (cutoffTime) {
null -> this.isUpcoming()
else -> this.isUpcomingWithin(filterAtTime, cutoffTime)
}
return (isTypical() || isUpcoming) && !isArrivalOnly()
}

fun List<PatternsByStop>.filterEmptyAndSort(): List<PatternsByStop> {
return this.filterNot { it.patterns.isEmpty() }
Expand All @@ -562,14 +581,13 @@ fun NearbyStaticData.withRealtimeInfo(
StopsAssociated.WithRoute(
transit.route,
transit.patternsByStop
.map {
.map { stopPatterns ->
PatternsByStop(
it,
upcomingTripsMap.filterCancellations(
stopPatterns,
upcomingTripsMap?.maybeFilterCancellations(
transit.route.type.isSubway()
),
filterAtTime,
cutoffTime,
{ it.shouldShow() },
activeRelevantAlerts,
hasSchedulesTodayByPattern,
allDataLoaded
Expand All @@ -582,14 +600,13 @@ fun NearbyStaticData.withRealtimeInfo(
transit.line,
transit.routes,
transit.patternsByStop
.map {
.map { stopPatterns ->
PatternsByStop(
it,
upcomingTripsMap.filterCancellations(
stopPatterns,
upcomingTripsMap?.maybeFilterCancellations(
transit.routes.min().type.isSubway()
),
filterAtTime,
cutoffTime,
{ it.shouldShow() },
activeRelevantAlerts,
hasSchedulesTodayByPattern,
allDataLoaded
Expand All @@ -604,6 +621,29 @@ fun NearbyStaticData.withRealtimeInfo(
.sortedWith(PatternSorting.compareStopsAssociated(pinnedRoutes, sortByDistanceFrom))
}

fun NearbyStaticData.withRealtimeInfo(
globalData: GlobalResponse?,
sortByDistanceFrom: Position,
schedules: ScheduleResponse?,
predictions: PredictionsStreamDataResponse?,
alerts: AlertsStreamDataResponse?,
filterAtTime: Instant,
pinnedRoutes: Set<String>
): List<StopsAssociated> {
return this.withRealtimeInfo(
globalData,
sortByDistanceFrom,
schedules,
predictions,
alerts,
filterAtTime,
showAllPatternsWhileLoading = false,
hideNonTypicalPatternsBeyondNext = 90.minutes,
filterCancellations = true,
pinnedRoutes
)
}

class NearbyStaticDataBuilder {
val data = mutableListOf<NearbyStaticData.TransitWithStops>()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,17 @@ object PatternSorting {

fun compareStopsAssociated(
pinnedRoutes: Set<String>,
sortByDistanceFrom: Position
sortByDistanceFrom: Position?
): Comparator<StopsAssociated> =
compareBy(
{ pinnedRouteBucket(it.sortRoute(), pinnedRoutes) },
{ patternServiceBucket(it.patternsByStop.first().patterns.first()) },
{ subwayBucket(it.sortRoute()) },
{ it.distanceFrom(sortByDistanceFrom) },
if (sortByDistanceFrom != null) {
{ it.distanceFrom(sortByDistanceFrom) }
} else {
{ 0 }
},
{ it.sortRoute() },
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.mbta.tid.mbta_app.model.response.GlobalResponse
import io.github.dellisd.spatialk.geojson.Position
import io.github.dellisd.spatialk.turf.ExperimentalTurfApi
import io.github.dellisd.spatialk.turf.distance
import kotlinx.datetime.Instant

/**
* @property patterns [RealtimePatterns]s serving the stop grouped by headsign or direction. The
Expand All @@ -24,8 +23,7 @@ data class PatternsByStop(
constructor(
staticData: NearbyStaticData.StopPatterns,
upcomingTripsMap: UpcomingTripsMap?,
filterTime: Instant,
cutoffTime: Instant,
patternsPredicate: (RealtimePatterns) -> Boolean,
alerts: Collection<Alert>?,
hasSchedulesTodayByPattern: Map<String, Boolean>?,
allDataLoaded: Boolean,
Expand Down Expand Up @@ -62,10 +60,7 @@ data class PatternsByStop(
)
}
}
.filter {
(it.isTypical() || it.isUpcomingWithin(filterTime, cutoffTime)) &&
!it.isArrivalOnly()
}
.filter(patternsPredicate)
.sortedWith(PatternSorting.compareRealtimePatterns()),
staticData.directions
)
Expand Down
Loading

0 comments on commit 57361f5

Please sign in to comment.