Skip to content

Commit

Permalink
added speed limit provider & updated testing
Browse files Browse the repository at this point in the history
  • Loading branch information
Archdoog committed Jun 28, 2024
1 parent 7be623d commit e49a1f9
Show file tree
Hide file tree
Showing 21 changed files with 148 additions and 54 deletions.
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import PackageDescription

let binaryTarget: Target
let maplibreSwiftUIDSLPackage: Package.Dependency
let useLocalFramework = false
let useLocalFramework = true
let useLocalMapLibreSwiftUIDSL = false

if useLocalFramework {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ public struct DynamicallyOrientingNavigationView<
useSnappedCamera: Binding<Bool>,
onTapExit: @escaping () -> Void = {},
@MapViewContentBuilder makeMapContent: () -> [StyleLayerDefinition] = { [] },
@ViewBuilder topCenter: () -> TopCenter = { InfiniteSpacer() },
@ViewBuilder topTrailing: () -> TopTrailing = { InfiniteSpacer() },
@ViewBuilder midLeading: () -> MidLeading = { InfiniteSpacer() },
@ViewBuilder bottomTrailing: () -> BottomTrailing = { InfiniteSpacer() }
@ViewBuilder topCenter: () -> TopCenter = { Spacer() },
@ViewBuilder topTrailing: () -> TopTrailing = { Spacer() },
@ViewBuilder midLeading: () -> MidLeading = { Spacer() },
@ViewBuilder bottomTrailing: () -> BottomTrailing = { Spacer() }
) {
self.styleURL = styleURL
self.navigationState = navigationState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,10 @@ public struct PortraitNavigationView<TopCenter: View, TopTrailing: View, MidLead
useSnappedCamera: Binding<Bool>,
onTapExit: @escaping () -> Void = {},
@MapViewContentBuilder makeMapContent: () -> [StyleLayerDefinition] = { [] },
@ViewBuilder topCenter: () -> TopCenter = { InfiniteSpacer() },
@ViewBuilder topTrailing: () -> TopTrailing = { InfiniteSpacer() },
@ViewBuilder midLeading: () -> MidLeading = { InfiniteSpacer() },
@ViewBuilder bottomTrailing: () -> BottomTrailing = { InfiniteSpacer() }
@ViewBuilder topCenter: () -> TopCenter = { Spacer() },
@ViewBuilder topTrailing: () -> TopTrailing = { Spacer() },
@ViewBuilder midLeading: () -> MidLeading = { Spacer() },
@ViewBuilder bottomTrailing: () -> BottomTrailing = { Spacer() }
) {
self.styleURL = styleURL
self.navigationState = navigationState
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ public class DefaultFormatters {

// MARK: Speed

/// The speed with units formatter is a measurement formatter used to format speed units for items like
/// the user's current speed, speed limit and other related measurements.
///
/// E.g. `50 mi/hr` or `100 km/hr`
public static var speedWithUnitsFormatter: MeasurementFormatter {
let formatter = MeasurementFormatter()
formatter.unitOptions = .naturalScale
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Foundation

/// Build a data provider that tells the UI whether to prefer a US style (MUTCD) or Vienna style speed limit sign.
protocol SpeedLimitStyleProvider {
func useUSStyle() -> Bool
}

// TODO: Create a location based Provider using:
// MUTCD Signage Regions: https://en.wikipedia.org/wiki/Manual_on_Uniform_Traffic_Control_Devices
// US, Canada, Mexico, Belize, Argentina, Bolivia, Brazil, Colombia, Equador, Guyana
// Paraguay, Peru, Venezuela, Austrialia, Thailand.
// Region Codes: https://en.wikipedia.org/wiki/IETF_language_tag

/// Always prefer US Style (MUTCD)
class SpeedLimitFixedToUSStyle: SpeedLimitStyleProvider {
func useUSStyle() -> Bool {
true
}
}

/// Always prefer Vienna Style
class SpeedLimitFixedToViennaConventionStyle: SpeedLimitStyleProvider {
func useUSStyle() -> Bool {
false
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@ public struct InnerGridView<
/// - bottomCenter: The bottom center corner view. Defaults to a Spacer()
/// - bottomTrailing: The bottom right corner view. Defaults to a Spacer()
public init(
@ViewBuilder topLeading: @escaping () -> TopLeading = { InfiniteSpacer() },
@ViewBuilder topCenter: @escaping () -> TopCenter = { InfiniteSpacer() },
@ViewBuilder topTrailing: @escaping () -> TopTrailing = { InfiniteSpacer() },
@ViewBuilder midLeading: @escaping () -> MidLeading = { InfiniteSpacer() },
@ViewBuilder midCenter: @escaping () -> MidCenter = { InfiniteSpacer() },
@ViewBuilder midTrailing: @escaping () -> MidTrailing = { InfiniteSpacer() },
@ViewBuilder bottomLeading: @escaping () -> BottomLeading = { InfiniteSpacer() },
@ViewBuilder bottomCenter: @escaping () -> BottomCenter = { InfiniteSpacer() },
@ViewBuilder bottomTrailing: @escaping () -> BottomTrailing = { InfiniteSpacer() }
@ViewBuilder topLeading: @escaping () -> TopLeading = { Spacer() },
@ViewBuilder topCenter: @escaping () -> TopCenter = { Spacer() },
@ViewBuilder topTrailing: @escaping () -> TopTrailing = { Spacer() },
@ViewBuilder midLeading: @escaping () -> MidLeading = { Spacer() },
@ViewBuilder midCenter: @escaping () -> MidCenter = { Spacer() },
@ViewBuilder midTrailing: @escaping () -> MidTrailing = { Spacer() },
@ViewBuilder bottomLeading: @escaping () -> BottomLeading = { Spacer() },
@ViewBuilder bottomCenter: @escaping () -> BottomCenter = { Spacer() },
@ViewBuilder bottomTrailing: @escaping () -> BottomTrailing = { Spacer() }
) {
self.topLeading = topLeading()
self.topCenter = topCenter()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,10 @@ public struct NavigatingInnerGridView<
onZoomOut: @escaping () -> Void = {},
showCentering: Bool = false,
onCenter: @escaping () -> Void = {},
@ViewBuilder topCenter: () -> TopCenter = { InfiniteSpacer() },
@ViewBuilder topTrailing: () -> TopTrailing = { InfiniteSpacer() },
@ViewBuilder midLeading: () -> MidLeading = { InfiniteSpacer() },
@ViewBuilder bottomTrailing: () -> BottomTrailing = { InfiniteSpacer() }
@ViewBuilder topCenter: () -> TopCenter = { Spacer() },
@ViewBuilder topTrailing: () -> TopTrailing = { Spacer() },
@ViewBuilder midLeading: () -> MidLeading = { Spacer() },
@ViewBuilder bottomTrailing: () -> BottomTrailing = { Spacer() }
) {
self.speedLimit = speedLimit
self.showZoom = showZoom
Expand Down Expand Up @@ -91,14 +91,14 @@ public struct NavigatingInnerGridView<
midLeading: { midLeading },
midCenter: {
// This view does not allow center content.
InfiniteSpacer()
Spacer()
},
midTrailing: {
if showZoom {
ZoomButton(onZoomIn: onZoomIn, onZoomOut: onZoomOut)
.shadow(radius: 8)
} else {
InfiniteSpacer()
Spacer()
}
},
bottomLeading: {
Expand All @@ -111,12 +111,12 @@ public struct NavigatingInnerGridView<
}
.shadow(radius: 8)
} else {
InfiniteSpacer()
Spacer()
}
},
bottomCenter: {
// This view does not allow center content to prevent overlaying the puck.
InfiniteSpacer()
Spacer()
},
bottomTrailing: { bottomTrailing }
)
Expand Down
14 changes: 0 additions & 14 deletions apple/Sources/FerrostarSwiftUI/Views/InfiniteSpacer.swift

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,38 +1,62 @@
import SwiftUI

public struct SpeedLimitView: View {

/// The speed limit sign style toggling method. This is used to
/// define the method for swapping between USStyle & ViennaConvention
public enum ToggleStyleBy {
// TODO: Add improved automatic methods (e.g. route admins, etc)

/// Only use the US Style
case usStyle

/// Only use the Vienna Convention Style
case viennaConvention
}

@Environment(\.locale) private var locale

var toggleStyleBy: ToggleStyleBy
var speedLimit: Measurement<UnitSpeed>
var valueFormatter: NumberFormatter
var unitFormatter: MeasurementFormatter

public init(
speedLimit: Measurement<UnitSpeed>,
toggleStyleBy: ToggleStyleBy = .viennaConvention, // Change the default once we have a better solution.
valueFormatter: NumberFormatter = DefaultFormatters.speedFormatter,
unitFormatter: MeasurementFormatter = DefaultFormatters.speedWithUnitsFormatter
) {
self.toggleStyleBy = toggleStyleBy
self.speedLimit = speedLimit
self.valueFormatter = valueFormatter
self.unitFormatter = unitFormatter
}

public var body: some View {
switch locale.identifier {
case "en_US":
if useUSStyle() {
USStyleSpeedLimitView(
speedLimit: speedLimit,
valueFormatter: valueFormatter,
unitFormatter: unitFormatter
)
default:
} else {
ViennaConventionStyleSpeedLimitView(
speedLimit: speedLimit,
valueFormatter: valueFormatter,
unitFormatter: unitFormatter
)
}
}

private func useUSStyle() -> Bool {
switch toggleStyleBy {
case .usStyle:
return SpeedLimitFixedToUSStyle().useUSStyle()
case .viennaConvention:
return SpeedLimitFixedToViennaConventionStyle().useUSStyle()
}
}
}

#Preview {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,19 @@ import XCTest
@testable import FerrostarSwiftUI

final class NavigatingInnerGridViewTests: XCTestCase {
func testUSView() {
assertView {
NavigatingInnerGridView(
speedLimit: .init(value: 55, unit: .milesPerHour),
showZoom: true,
showCentering: true
)
.padding()
}
}
// TODO: enable once we decide on a method to expose the speed limit sign provider within the view stack.
// func testUSView() {
// assertView {
// NavigatingInnerGridView(
// speedLimit: .init(value: 55, unit: .milesPerHour),
// showZoom: true,
// showCentering: true
// )
// .padding()
// }
// }

func testROWView() {
func testViennaStyleSpeedLimitInGridView() {
assertView {
NavigatingInnerGridView(
speedLimit: .init(value: 100, unit: .kilometersPerHour),
Expand Down
53 changes: 53 additions & 0 deletions apple/Tests/FerrostarSwiftUITests/Views/SpeedLimitViewTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,57 @@ final class SpeedLimitViewTests: XCTestCase {
.environment(\.locale, .init(identifier: "fr_FR"))
}
}

// MARK: Dark Mode

func testUSStyleSpeedLimitViews_darkMode() {
assertView(colorScheme: .dark) {
USStyleSpeedLimitView(speedLimit: .init(value: 50, unit: .milesPerHour))
}

assertView(colorScheme: .dark) {
USStyleSpeedLimitView(speedLimit: .init(value: 100, unit: .milesPerHour))
}

assertView(colorScheme: .dark) {
USStyleSpeedLimitView(speedLimit: .init(value: 10000, unit: .milesPerHour))
}

assertView(colorScheme: .dark) {
USStyleSpeedLimitView(speedLimit: .init(value: 50, unit: .milesPerHour),
units: .kilometersPerHour)
}
}

func testViennaConventionStyleSpeedLimitViews_darkMode() {
assertView(colorScheme: .dark) {
ViennaConventionStyleSpeedLimitView(speedLimit: .init(value: 50, unit: .kilometersPerHour))
}

assertView(colorScheme: .dark) {
ViennaConventionStyleSpeedLimitView(speedLimit: .init(value: 100, unit: .kilometersPerHour))
}

assertView(colorScheme: .dark) {
ViennaConventionStyleSpeedLimitView(speedLimit: .init(value: 1000, unit: .kilometersPerHour))
}

assertView(colorScheme: .dark) {
ViennaConventionStyleSpeedLimitView(
speedLimit: .init(value: 100, unit: .kilometersPerHour),
units: .milesPerHour
)
}
}

func assertLocalizedSpeedLimitViews_darkMode() {
assertView(colorScheme: .dark) {
SpeedLimitView(speedLimit: .init(value: 24.5, unit: .metersPerSecond))
}

assertView(colorScheme: .dark) {
SpeedLimitView(speedLimit: .init(value: 27.8, unit: .metersPerSecond))
.environment(\.locale, .init(identifier: "fr_FR"))
}
}
}
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.
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.
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.
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.
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.

0 comments on commit e49a1f9

Please sign in to comment.