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: Initial new stop page trip details UI #572

Merged
merged 15 commits into from
Dec 11, 2024
Merged
Show file tree
Hide file tree
Changes from 13 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
54 changes: 47 additions & 7 deletions iosApp/iosApp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"colors": [
{
"color": {
"color-space": "srgb",
"components": {
"alpha": "0.150",
"blue": "0x00",
"green": "0x00",
"red": "0x00"
}
},
"idiom": "universal"
},
{
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
],
"color": {
"color-space": "srgb",
"components": {
"alpha": "0.300",
"blue": "0xFF",
"green": "0xFF",
"red": "0xFF"
}
},
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
15 changes: 15 additions & 0 deletions iosApp/iosApp/ComponentViews/HaloSeparator.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
//
// HaloSeparator.swift
// iosApp
//
// Created by esimon on 12/5/24.
// Copyright © 2024 MBTA. All rights reserved.
//

import SwiftUI

struct HaloSeparator: View {
var body: some View {
Divider().frame(maxHeight: 1).foregroundStyle(Color.halo)
}
}
4 changes: 2 additions & 2 deletions iosApp/iosApp/ComponentViews/RouteHeader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ struct RouteHeader<Content: View>: View {
var body: some View {
TransitHeader(
name: route.label,
backgroundColor: Color(hex: route.color),
textColor: Color(hex: route.textColor),
backgroundColor: route.uiColor,
textColor: route.uiTextColor,
modeIcon: routeIcon(route),
rightContent: rightContent
)
Expand Down
13 changes: 7 additions & 6 deletions iosApp/iosApp/ComponentViews/UpcomingTripView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
struct UpcomingTripView: View {
let prediction: State
var routeType: RouteType?
var hideRealtimeIndicators: Bool = false
var isFirst: Bool = true
var isOnly: Bool = true

Expand Down Expand Up @@ -56,33 +57,33 @@
case .now:
Text("Now", comment: "Label for a trip that's arriving right now")
.font(Typography.headlineBold)
.realtime()
.realtime(hideIndicator: hideRealtimeIndicators)
.accessibilityLabel(isFirst
? accessibilityFormatters
.arrivingFirst(vehicleText: routeType?.typeText(isOnly: isOnly) ?? "")
: accessibilityFormatters.arrivingOther())
case .boarding:
Text("BRD", comment: "Shorthand for boarding")
.font(Typography.headlineBold)
.realtime()
.realtime(hideIndicator: hideRealtimeIndicators)
.accessibilityLabel(isFirst
? accessibilityFormatters
.boardingFirst(vehicleText: routeType?.typeText(isOnly: isOnly) ?? "")
: accessibilityFormatters.boardingOther())
case .arriving:
Text("ARR", comment: "Shorthand for arriving")
.font(Typography.headlineBold)
.realtime()
.realtime(hideIndicator: hideRealtimeIndicators)
.accessibilityLabel(isFirst
? accessibilityFormatters
.arrivingFirst(vehicleText: routeType?.typeText(isOnly: isOnly) ?? "")
: accessibilityFormatters.arrivingOther())
case .approaching:
PredictionText(minutes: 1).realtime()
PredictionText(minutes: 1).realtime(hideIndicator: hideRealtimeIndicators)
case let .time(format):
Text(Date(instant: format.predictionTime), style: .time)
.font(format.headline ? Typography.headlineSemibold : Typography.footnoteSemibold)
.realtime()
.realtime(hideIndicator: hideRealtimeIndicators)
.accessibilityLabel(isFirst
? accessibilityFormatters.distantFutureFirst(
date: format.predictionTime.toNSDate(),
Expand All @@ -92,7 +93,7 @@
.distantFutureOther(date: format.predictionTime.toNSDate()))
case let .minutes(format):
PredictionText(minutes: format.minutes)
.realtime()
.realtime(hideIndicator: hideRealtimeIndicators)
.accessibilityLabel(isFirst
? accessibilityFormatters.predictionMinutesFirst(
minutes: format.minutes,
Expand Down Expand Up @@ -146,7 +147,7 @@
case .serviceEndedToday:
Text(
"Service ended",
comment: "The status label for a route and direction when service was running earlier, but no more trips are running today"

Check notice on line 150 in iosApp/iosApp/ComponentViews/UpcomingTripView.swift

View check run for this annotation

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

iosApp/iosApp/ComponentViews/UpcomingTripView.swift#L150

Line Length Violation: Line should be 120 characters or less; currently it has 139 characters (line_length)
).font(Typography.footnote)
case .noSchedulesToday:
Text(
Expand Down
30 changes: 18 additions & 12 deletions iosApp/iosApp/ComponentViews/WithRealtimeIndicator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,37 +12,43 @@ struct WithRealtimeIndicator: View {
private static let subjectSpacing: CGFloat = 4
@ScaledMetric private var iconSize: CGFloat = 12
let prediction: any View
let hideIndicator: Bool

init(_ prediction: () -> any View) {
init(_ prediction: () -> any View, hideIndicator: Bool = false) {
self.prediction = prediction()
self.hideIndicator = hideIndicator
}

init(_ prediction: any View) {
init(_ prediction: any View, hideIndicator: Bool = false) {
self.prediction = prediction
self.hideIndicator = hideIndicator
}

var body: some View {
HStack(spacing: Self.subjectSpacing) {
Image(.liveData)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconSize, height: iconSize)
.padding(4)
.opacity(0.6)
.accessibilityHidden(true)
if !hideIndicator {
Image(.liveData)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: iconSize, height: iconSize)
.padding(4)
.opacity(0.6)
.accessibilityHidden(true)
}
AnyView(prediction)
}
}
}

struct WithRealtimeIndicatorModifier: ViewModifier {
var hideIndicator: Bool = false
func body(content: Content) -> some View {
WithRealtimeIndicator(content)
WithRealtimeIndicator(content, hideIndicator: hideIndicator)
}
}

extension View {
func realtime() -> some View {
modifier(WithRealtimeIndicatorModifier())
func realtime(hideIndicator: Bool = false) -> some View {
modifier(WithRealtimeIndicatorModifier(hideIndicator: hideIndicator))
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images": [
{
"filename": "fa-caret-right.svg",
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
},
"properties": {
"template-rendering-intent": "template"
}
}
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
@@ -0,0 +1,22 @@
{
"images": [
{
"filename": "stop-pin-indicator.svg",
"idiom": "universal"
},
{
"appearances": [
{
"appearance": "luminosity",
"value": "dark"
}
],
"filename": "stop-pin-indicator-dark.svg",
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
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
@@ -0,0 +1,12 @@
{
"images": [
{
"filename": "stop-trip-line-twist-shadow.svg",
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
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
@@ -0,0 +1,15 @@
{
"images": [
{
"filename": "stop-trip-line-twist.svg",
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
},
"properties": {
"template-rendering-intent": "template"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 2 additions & 2 deletions iosApp/iosApp/Pages/Map/VehicleMarkerView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct VehicleMarkerView: View {
ZStack {
ZStack {
Image(.vehicleHalo)
Image(.vehiclePuck).foregroundStyle(Color(hex: route.color))
Image(.vehiclePuck).foregroundStyle(route.uiColor)
}
.frame(width: 32, height: 32)
.rotationEffect(.degrees(45))
Expand All @@ -29,7 +29,7 @@ struct VehicleMarkerView: View {
.frame(height: 18)
}
.padding(10)
.modifier(PulsingHaloModifier(isSelected: isSelected, routeColor: Color(hex: route.color)))
.modifier(PulsingHaloModifier(isSelected: isSelected, routeColor: route.uiColor))
.onTapGesture { onTap() }
}

Expand Down
5 changes: 1 addition & 4 deletions iosApp/iosApp/Pages/More/MoreSectionView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,10 +51,7 @@ struct MoreSectionView: View {
MoreNavLink(label: label, destination: destination)
}
if index < section.items.count {
Rectangle()
.fill(Color.halo)
.frame(height: 1)
.frame(maxWidth: .infinity)
HaloSeparator().frame(maxWidth: .infinity)
}
}
}
Expand Down
23 changes: 23 additions & 0 deletions iosApp/iosApp/Pages/StopDetails/ColoredRouteLine.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// ColoredRouteLine.swift
// iosApp
//
// Created by esimon on 12/5/24.
// Copyright © 2024 MBTA. All rights reserved.
//

import SwiftUI

struct ColoredRouteLine: View {
var color: Color

init(_ color: Color) {
self.color = color
}

var body: some View {
Rectangle()
.frame(minWidth: 4, maxWidth: 4)
.foregroundStyle(color)
}
}
5 changes: 3 additions & 2 deletions iosApp/iosApp/Pages/StopDetails/DirectionPicker.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ struct DirectionPicker: View {
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
.accessibilityAddTraits(isSelected ? [.isSelected] : [])
.background(isSelected ? Color(hex: route.color) : deselectedBackroundColor)
.foregroundStyle(isSelected ? Color(hex: route.textColor) : .deselectedToggleText)
.background(isSelected ? route.uiColor : deselectedBackroundColor)
.foregroundStyle(isSelected ? route.uiTextColor : .deselectedToggleText)
.clipShape(.rect(cornerRadius: 6))
}
}
Expand All @@ -53,6 +53,7 @@ struct DirectionPicker: View {
.clipShape(.rect(cornerRadius: 8))
} else if availableDirections.count == 1, let direction = availableDirections.first {
DirectionLabel(direction: directions[Int(direction)])
.foregroundStyle(route.uiTextColor)
.padding(8)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ struct StopDetailsFilteredDepartureDetails: View {
var patternsByStop: PatternsByStop
var pinned: Bool

var now: Date

@ObservedObject var errorBannerVM: ErrorBannerViewModel
@ObservedObject var nearbyVM: NearbyViewModel
@ObservedObject var mapVM: MapViewModel
Expand Down Expand Up @@ -49,7 +51,7 @@ struct StopDetailsFilteredDepartureDetails: View {
// This unscrollable scroll view is necessary to prevent the sheet from messing up the layout
// of the contents and cutting off the header when not in large detent.
ScrollView([], showsIndicators: false) {
VStack(spacing: 14) {
VStack(spacing: 16) {
ScrollViewReader { view in
DirectionPicker(
patternsByStop: patternsByStop,
Expand All @@ -60,29 +62,25 @@ struct StopDetailsFilteredDepartureDetails: View {
}
)
.fixedSize(horizontal: false, vertical: true)
.padding(.horizontal, 16)
.padding(.top, 16)
.padding([.horizontal, .top], 16)
.padding(.bottom, 6)
.dynamicTypeSize(...DynamicTypeSize.accessibility1)

departureTiles(patternsByStop, view)
.dynamicTypeSize(...DynamicTypeSize.accessibility3)
EmmaSimon marked this conversation as resolved.
Show resolved Hide resolved
}
alertCards(patternsByStop, routeColor)
statusRows(patternsByStop)

if let tripFilter {
TripDetailsView(
tripId: tripFilter.tripId,
vehicleId: tripFilter.vehicleId,
routeId: stopFilter.routeId,
stopId: stopId,
stopSequence: tripFilter.stopSequence?.intValue,
global: stopDetailsVM.global,
errorBannerVM: errorBannerVM,
nearbyVM: nearbyVM,
mapVM: mapVM
)
.padding(.horizontal, 8)
.padding(.bottom, 48)
}
TripDetailsView(
tripFilter: tripFilter,
stopId: stopId,
now: now,
errorBannerVM: errorBannerVM,
nearbyVM: nearbyVM,
mapVM: mapVM,
stopDetailsVM: stopDetailsVM
)
}
}
}
Expand Down Expand Up @@ -120,6 +118,7 @@ struct StopDetailsFilteredDepartureDetails: View {
}
.padding(.horizontal, 12)
.padding(.vertical, 1)
.fixedSize(horizontal: false, vertical: true)
}
}

Expand Down
Loading
Loading