Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(iOS): Elevator alerts on nearby & unfiltered #673

Merged
merged 3 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions iosApp/iosApp.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@
9A320F962CD3E4CF0096D7B1 /* UpcomingTripAccessibilityFormatters.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A320F952CD3E4CF0096D7B1 /* UpcomingTripAccessibilityFormatters.swift */; };
9A3739942D3AD67200BBE127 /* InfoIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3739932D3AD67200BBE127 /* InfoIcon.swift */; };
9A3739962D3AEC4500BBE127 /* AlertCardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3739952D3AEC4500BBE127 /* AlertCardTests.swift */; };
9A3739982D41450100BBE127 /* SettingsExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A3739972D41450100BBE127 /* SettingsExtension.swift */; };
9A37F3052BACCC40001714FE /* DoubleRoundedExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37F3042BACCC40001714FE /* DoubleRoundedExtension.swift */; };
9A37F3072BACCCA5001714FE /* CoordinateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A37F3062BACCCA5001714FE /* CoordinateExtension.swift */; };
9A392C972CC0497C00DE1FBE /* ErrorBannerViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9A392C962CC0497C00DE1FBE /* ErrorBannerViewModel.swift */; };
Expand Down Expand Up @@ -435,6 +436,7 @@
9A320F952CD3E4CF0096D7B1 /* UpcomingTripAccessibilityFormatters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UpcomingTripAccessibilityFormatters.swift; sourceTree = "<group>"; };
9A3739932D3AD67200BBE127 /* InfoIcon.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoIcon.swift; sourceTree = "<group>"; };
9A3739952D3AEC4500BBE127 /* AlertCardTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertCardTests.swift; sourceTree = "<group>"; };
9A3739972D41450100BBE127 /* SettingsExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsExtension.swift; sourceTree = "<group>"; };
9A37F3042BACCC40001714FE /* DoubleRoundedExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoubleRoundedExtension.swift; sourceTree = "<group>"; };
9A37F3062BACCCA5001714FE /* CoordinateExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoordinateExtension.swift; sourceTree = "<group>"; };
9A392C962CC0497C00DE1FBE /* ErrorBannerViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorBannerViewModel.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1116,6 +1118,7 @@
9A18DEAC2D07DDC800DA0A3B /* RouteExtension.swift */,
9A4850562CB56A1500F50EE7 /* RouteTypeExtension.swift */,
6EFEE42C2BED0FA800810319 /* ScenePhaseChangeModifier.swift */,
9A3739972D41450100BBE127 /* SettingsExtension.swift */,
8CE0141A2BBF059A00918FAE /* SheetNavigationStackEntry.swift */,
9ADB84A12BAE37C0006581CE /* StopExtension.swift */,
8C0923A62C210C8C00813454 /* Typography.swift */,
Expand Down Expand Up @@ -1544,6 +1547,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9A3739982D41450100BBE127 /* SettingsExtension.swift in Sources */,
6EC6F18F2CE665DB0022799F /* StopDetailsDownstreamAlert.swift in Sources */,
9A6A51EF2C652BB100E3AC13 /* AlertActivePeriodFormattingExtension.swift in Sources */,
9AF29DF82CF5454E005AA4A3 /* StopDetailsFilteredView.swift in Sources */,
Expand Down
4 changes: 4 additions & 0 deletions iosApp/iosApp/ComponentViews/AlertCard.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ enum AlertCardSpec {
case major
case downstream
case secondary
case elevator
}

struct AlertCard: View {
Expand Down Expand Up @@ -44,6 +45,7 @@ struct AlertCard: View {
ex. "[Detour] ahead", "[Shuttle buses] ahead"
"""
), effectName)
case .elevator: alert.header ?? effectName
default: effectName
}
}
Expand All @@ -54,8 +56,10 @@ struct AlertCard: View {
HStack(spacing: 16) {
AlertIcon(alertState: alert.alertState, color: color)
.frame(width: iconSize, height: iconSize)
.frame(maxHeight: spec == .elevator ? .infinity : iconSize, alignment: .top)
Text(headerString)
.font(spec == .major ? Typography.title2Bold : Typography.bodySemibold)
.multilineTextAlignment(.leading)
if spec != .major {
Spacer()
InfoIcon(size: infoIconSize)
Expand Down
1 change: 1 addition & 0 deletions iosApp/iosApp/ComponentViews/AlertIcon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ struct AlertIcon: View {
}

private static let iconNames: [StopAlertState: String] = [
.elevator: "accessibility-icon-inaccessible",
.issue: "alert-borderless-issue",
.shuttle: "alert-borderless-shuttle",
.suspension: "alert-borderless-suspension",
Expand Down
8 changes: 4 additions & 4 deletions iosApp/iosApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
.onAppear {
Task { await contentVM.loadFeaturePromos() }
Task { await contentVM.loadOnboardingScreens() }
Task { await nearbyVM.loadDebugSetting() }
Task { await nearbyVM.loadSettings() }
analytics.recordSession(colorScheme: colorScheme)
analytics.recordSession(voiceOver: voiceOver)
analytics.recordSession(hideMaps: contentVM.hideMaps)
Expand All @@ -69,7 +69,7 @@
} catch {}
}
.onChange(of: selectedTab) { _ in
Task { await nearbyVM.loadDebugSetting() }
Task { await nearbyVM.loadSettings() }
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
Expand Down Expand Up @@ -369,7 +369,7 @@
}
}

private func recenterOnVehicleButtonInfo() -> (RouteType, Vehicle, Stop)? {

Check notice on line 372 in iosApp/iosApp/ContentView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/ContentView.swift#L372

Large Tuple Violation: Tuples should have at most 2 members (large_tuple)
guard case let .stopDetails(stopId: _, stopFilter: stopFilter, tripFilter: tripFilter) = nearbyVM
.navigationStack.lastSafe(),
let selectedVehicle = mapVM.selectedVehicle, tripFilter?.vehicleId == selectedVehicle.id,
Expand All @@ -384,8 +384,8 @@
let entry = coverIdentityEntry.stackEntry
return NavigationStack {
switch entry {
case let .alertDetails(alertId, line, routes):
AlertDetailsPage(alertId: alertId, line: line, routes: routes, nearbyVM: nearbyVM)
case let .alertDetails(alertId, line, routes, stop):
AlertDetailsPage(alertId: alertId, line: line, routes: routes, stop: stop, nearbyVM: nearbyVM)
default:
EmptyView()
}
Expand All @@ -406,4 +406,4 @@
content.presentationBackgroundInteraction(.enabled(upThrough: .halfScreen))
}
}
}

Check notice on line 409 in iosApp/iosApp/ContentView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/ContentView.swift#L409

File Length Violation: File should contain 400 lines or less: currently contains 409 (file_length)
41 changes: 41 additions & 0 deletions iosApp/iosApp/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -3524,6 +3524,47 @@
}
}
},
"Elevator Closure" : {
"comment" : "Possible alert effect",
"localizations" : {
"es" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Cierre del Ascensor"
}
},
"ht" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Fèmti Asansè"
}
},
"pt-BR" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Fechamento de elevador"
}
},
"vi" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "Đóng thang máy"
}
},
"zh-Hans-CN" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "电梯关闭"
}
},
"zh-Hant-TW" : {
"stringUnit" : {
"state" : "needs_review",
"value" : "電梯關閉"
}
}
}
},
"End" : {
"comment" : "Label for the end date of a disruption",
"localizations" : {
Expand Down
29 changes: 22 additions & 7 deletions iosApp/iosApp/Pages/AlertDetails/AlertDetails.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
import shared
import SwiftUI

struct AlertDetails: View {

Check notice on line 12 in iosApp/iosApp/Pages/AlertDetails/AlertDetails.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Pages/AlertDetails/AlertDetails.swift#L12

Type Body Length Violation: Type body should span 250 lines or less excluding comments and whitespace: currently spans 253 lines (type_body_length)
var analytics: Analytics = AnalyticsProvider.shared
var alert: shared.Alert
var line: Line?
var routes: [Route]?
var stop: Stop?
var affectedStops: [Stop]
var stopId: String?
var now: Date
Expand All @@ -23,8 +24,12 @@

@State var areStopsExpanded = false

private var routeLabel: String {
line?.longName ?? routes?.first?.label ?? ""
private var routeLabel: String? {
line?.longName ?? routes?.first?.label
}

private var stopLabel: String? {
stop?.name
}

private var effectLabel: String? {
Expand Down Expand Up @@ -99,16 +104,26 @@
}
}

@ViewBuilder
private var alertTitle: some View {
VStack(alignment: .leading, spacing: 10) {
if let effectLabel {
@ViewBuilder var effectTitle: some View {
if let effectLabel {
if let routeLabel {
Text("\(routeLabel) \(effectLabel)",
comment: """
First value is the route label, second value is an alert effect, \
resulting in something like 'Red Line Suspension' or 'Green Line Shuttle'
""").font(.title2).bold()
""")
} else if let stopLabel {
Text("\(stopLabel) \(effectLabel)")
} else {
Text(effectLabel)
}
}
}

@ViewBuilder
private var alertTitle: some View {
VStack(alignment: .leading, spacing: 10) {
effectTitle.font(Typography.title2Bold)
if let causeLabel { Text(causeLabel).font(.body).bold() }
}
}
Expand Down
8 changes: 7 additions & 1 deletion iosApp/iosApp/Pages/AlertDetails/AlertDetailsPage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ struct AlertDetailsPage: View {
var alertId: String
var line: Line?
var routes: [Route]?
var stop: Stop?
var nearbyVM: NearbyViewModel
var errorBannerRepository: IErrorBannerStateRepository = RepositoryDI().errorBanner
var globalRepository: IGlobalRepository = RepositoryDI().global
Expand Down Expand Up @@ -73,6 +74,10 @@ struct AlertDetailsPage: View {
.aspectRatio(contentMode: .fit)
.scaledToFit()
.frame(maxHeight: modeIconHeight, alignment: .topLeading)
} else if alert?.effect == .elevatorClosure {
AlertIcon(alertState: .elevator)
.scaledToFit()
.frame(maxHeight: modeIconHeight, alignment: .topLeading)
}
Text("Alert Details", comment: "Header on the alert details page").font(.headline)
Spacer()
Expand All @@ -93,6 +98,7 @@ struct AlertDetailsPage: View {
alert: alert,
line: line,
routes: routes,
stop: stop,
affectedStops: affectedStops,
stopId: nearbyVM.navigationStack.lastStopId,
now: now
Expand Down Expand Up @@ -140,7 +146,7 @@ struct AlertDetailsPage: View {
// navigate back to the previous page.
if alert == nil, nextAlert == nil {
nearbyVM.navigationStack.removeAll { nav in
if case let .alertDetails(alertId, _, _) = nav {
if case let .alertDetails(alertId, _, _, _) = nav {
alertId == self.alertId
} else {
false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,8 @@
pushNavEntry(.alertDetails(
alertId: alert.id,
line: patternsByStop.line,
routes: patternsByStop.routes
routes: patternsByStop.routes,
stop: patternsByStop.stop
))
analytics.tappedAlertDetailsLegacy(
routeId: patternsByStop.routeIdentifier,
Expand All @@ -197,7 +198,8 @@
pushNavEntry(.alertDetails(
alertId: alert.id,
line: patternsByStop.line,
routes: patternsByStop.routes
routes: patternsByStop.routes,
stop: patternsByStop.stop
))
analytics.tappedAlertDetailsLegacy(
routeId: patternsByStop.routeIdentifier,
Expand Down Expand Up @@ -227,7 +229,7 @@
routeType: patternsByStop.representativeRoute.type,
noTrips: noTrips
)
}) {

Check notice on line 232 in iosApp/iosApp/Pages/LegacyStopDetails/StopDetailsFilteredRouteView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Pages/LegacyStopDetails/StopDetailsFilteredRouteView.swift#L232

Multiple Closures with Trailing Closure Violation: Trailing closure syntax should not be used when passing more than one closure argument (multiple_closures_with_trailing_closure)
HeadsignRowView(
headsign: row.headsign,
predictions: row.formatted,
Expand Down
2 changes: 2 additions & 0 deletions iosApp/iosApp/Pages/NearbyTransit/NearbyRouteView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@ struct NearbyRouteView: View {
let onPin: (String) -> Void
let pushNavEntry: (SheetNavigationStackEntry) -> Void
let now: Instant
let showElevatorAccessibility: Bool

var body: some View {
RouteCard(route: nearbyRoute.route, pinned: pinned, onPin: onPin) {
ForEach(Array(nearbyRoute.patternsByStop.enumerated()), id: \.element.stop.id) { index, patternsAtStop in
VStack(spacing: 0) {
NearbyStopView(
patternsAtStop: patternsAtStop,
showElevatorAccessibility: showElevatorAccessibility,
now: now,
pushNavEntry: pushNavEntry,
pinned: pinned
Expand Down
39 changes: 32 additions & 7 deletions iosApp/iosApp/Pages/NearbyTransit/NearbyStopView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,57 @@ struct NearbyStopView: View {
var analytics: Analytics = AnalyticsProvider.shared
let patternsAtStop: PatternsByStop
let condenseHeadsignPredictions: Bool
let showElevatorAccessibility: Bool
let now: Instant
let pushNavEntry: (SheetNavigationStackEntry) -> Void
let pinned: Bool

init(
patternsAtStop: PatternsByStop,
condenseHeadsignPredictions: Bool = false,
showElevatorAccessibility: Bool = false,
now: Instant,
pushNavEntry: @escaping (SheetNavigationStackEntry) -> Void,
pinned: Bool
) {
self.patternsAtStop = patternsAtStop
self.condenseHeadsignPredictions = condenseHeadsignPredictions
self.showElevatorAccessibility = showElevatorAccessibility
self.now = now
self.pushNavEntry = pushNavEntry
self.pinned = pinned
}

var elevatorAlerts: Int {
patternsAtStop.elevatorAlerts.count
}

var hasElevatorAlerts: Bool {
elevatorAlerts > 0
}

var body: some View {
Text(patternsAtStop.stop.name)
.font(Typography.callout)
.foregroundStyle(Color.text)
.padding(.horizontal, 16)
.padding(.vertical, 10)
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.fill2)
VStack(alignment: .leading, spacing: 8) {
HStack(spacing: 8) {
if showElevatorAccessibility, hasElevatorAlerts {
Image(.accessibilityIconInaccessible)
.accessibilityHidden(true)
}
Text(patternsAtStop.stop.name)
.font(Typography.callout)
.foregroundStyle(Color.text)
}
if showElevatorAccessibility, hasElevatorAlerts {
Text(
"\(elevatorAlerts, specifier: "%ld") elevator closures",
comment: "Header displayed when elevators are not working at a station"
)
}
}
.padding(.horizontal, 16)
.padding(.vertical, 12)
.frame(maxWidth: .infinity, alignment: .leading)
.background(Color.fill2)
StopDeparturesSummaryList(
patternsByStop: patternsAtStop,
condenseHeadsignPredictions: condenseHeadsignPredictions,
Expand Down
15 changes: 10 additions & 5 deletions iosApp/iosApp/Pages/NearbyTransit/NearbyTransitView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import shared
import SwiftUI

struct NearbyTransitView: View {

Check notice on line 16 in iosApp/iosApp/Pages/NearbyTransit/NearbyTransitView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Pages/NearbyTransit/NearbyTransitView.swift#L16

Type Body Length Violation: Type body should span 250 lines or less excluding comments and whitespace: currently spans 318 lines (type_body_length)
var analytics: Analytics = AnalyticsProvider.shared
var togglePinnedUsecase = UsecaseDI().toggledPinnedRouteUsecase
var pinnedRouteRepository = RepositoryDI().pinnedRoutes
Expand Down Expand Up @@ -125,15 +125,17 @@
pinned: pinnedRoutes.contains(nearbyRoute.route.id),
onPin: { id in toggledPinnedRoute(id) },
pushNavEntry: { entry in nearbyVM.pushNavEntry(entry) },
now: now.toKotlinInstant()
now: now.toKotlinInstant(),
showElevatorAccessibility: nearbyVM.showElevatorAccessibility
)
case let .withLine(nearbyLine):
NearbyLineView(
nearbyLine: nearbyLine,
pinned: pinnedRoutes.contains(nearbyLine.line.id),
onPin: { id in toggledPinnedRoute(id) },
pushNavEntry: { entry in nearbyVM.pushNavEntry(entry) },
now: now.toKotlinInstant()
now: now.toKotlinInstant(),
showElevatorAccessibility: nearbyVM.showElevatorAccessibility
)
}
}
Expand All @@ -157,7 +159,8 @@
pinned: false,
onPin: { _ in },
pushNavEntry: { _ in },
now: now.toKotlinInstant()
now: now.toKotlinInstant(),
showElevatorAccessibility: false
)
.loadingPlaceholder()
}
Expand Down Expand Up @@ -530,7 +533,8 @@
pinned: false,
onPin: { _ in },
pushNavEntry: { _ in },
now: Date.now.toKotlinInstant()
now: Date.now.toKotlinInstant(),
showElevatorAccessibility: true
)
NearbyRouteView(
nearbyRoute: StopsAssociated.WithRoute(
Expand Down Expand Up @@ -558,8 +562,9 @@
pinned: true,
onPin: { _ in },
pushNavEntry: { _ in },
now: Date.now.toKotlinInstant()
now: Date.now.toKotlinInstant(),
showElevatorAccessibility: true
)
}.font(Typography.body).previewDisplayName("NearbyRouteView")
}
}

Check notice on line 570 in iosApp/iosApp/Pages/NearbyTransit/NearbyTransitView.swift

View check run for this annotation

Xcode Cloud / MBTA Transit Staging | PR Branch Workflow | iosAppRetries - iOS

iosApp/iosApp/Pages/NearbyTransit/NearbyTransitView.swift#L570

File Length Violation: File should contain 400 lines or less: currently contains 570 (file_length)
Loading
Loading