Skip to content

Commit

Permalink
feat: Implement More page UI (#498)
Browse files Browse the repository at this point in the history
* feat: Update tab bar icons and more label

* feat: Implement More page UI

* test: Get existing tests passing

* fix: Add string localization comments

* test: Add test to ensure links exist
  • Loading branch information
EmmaSimon authored Oct 29, 2024
1 parent bd5167f commit ea168ae
Show file tree
Hide file tree
Showing 24 changed files with 646 additions and 201 deletions.
50 changes: 35 additions & 15 deletions iosApp/iosApp.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

23 changes: 23 additions & 0 deletions iosApp/iosApp/ComponentViews/TabLabel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//
// TabLabel.swift
// iosApp
//
// Created by esimon on 10/24/24.
// Copyright © 2024 MBTA. All rights reserved.
//

import SwiftUI

struct TabLabel: View {
var title: String
var image: ImageResource

init(_ title: String, image: ImageResource) {
self.title = title
self.image = image
}

var body: some View {
Label(title: { Text(title) }, icon: { Image(image) })
}
}
20 changes: 11 additions & 9 deletions iosApp/iosApp/ContentView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct ContentView: View {
@StateObject var nearbyVM = NearbyViewModel()
@StateObject var mapVM = MapViewModel()
@StateObject var searchVM = SearchViewModel()
@StateObject var settingsVM = SettingsViewModel()

let transition: AnyTransition = .asymmetric(insertion: .push(from: .bottom), removal: .opacity)
var screenTracker: ScreenTracker = AnalyticsProvider.shared
Expand All @@ -28,7 +29,7 @@ struct ContentView: View {

private enum SelectedTab: Hashable {
case nearby
case settings
case more
}

@State private var selectedTab = SelectedTab.nearby
Expand All @@ -47,14 +48,14 @@ struct ContentView: View {

@ViewBuilder
var contents: some View {
if selectedTab == .settings {
if selectedTab == .more {
TabView(selection: $selectedTab) {
nearbyTab
.tag(SelectedTab.nearby)
.tabItem { Label("Nearby", systemImage: "mappin") }
SettingsPage()
.tag(SelectedTab.settings)
.tabItem { Label("Settings", systemImage: "gear") }
.tabItem { TabLabel("Nearby", image: .tabIconNearby) }
MorePage(viewModel: settingsVM)
.tag(SelectedTab.more)
.tabItem { TabLabel("More", image: .tabIconMore) }
.onAppear {
screenTracker.track(screen: .settings)
}
Expand All @@ -78,12 +79,12 @@ struct ContentView: View {
viewportProvider: viewportProvider
)
.tag(SelectedTab.nearby)
.tabItem { Label("Nearby", systemImage: "mappin") }
.tabItem { TabLabel("Nearby", image: .tabIconNearby) }
// we want to show nothing in the sheet when the settings tab is open,
// but an EmptyView here causes the tab to not be listed
VStack {}
.tag(SelectedTab.settings)
.tabItem { Label("Settings", systemImage: "gear") }
.tag(SelectedTab.more)
.tabItem { TabLabel("More", image: .tabIconMore) }
}
}
}
Expand Down Expand Up @@ -134,6 +135,7 @@ struct ContentView: View {
Task { await errorBannerVM.activate() }
Task { await contentVM.loadConfig() }
Task { await contentVM.loadHideMaps() }
Task { await settingsVM.getSections() }
}
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
Expand Down
15 changes: 15 additions & 0 deletions iosApp/iosApp/Icons.xcassets/fa-phone.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images": [
{
"filename": "fa-phone.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.
12 changes: 12 additions & 0 deletions iosApp/iosApp/Icons.xcassets/mbta-logo.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"images": [
{
"filename": "mbta-logo.svg",
"idiom": "universal"
}
],
"info": {
"author": "xcode",
"version": 1
}
}
4 changes: 4 additions & 0 deletions iosApp/iosApp/Icons.xcassets/mbta-logo.imageset/mbta-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
15 changes: 15 additions & 0 deletions iosApp/iosApp/Icons.xcassets/tab-icon-more.imageset/Contents.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"images": [
{
"filename": "tab-icon-more.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,15 @@
{
"images": [
{
"filename": "tab-icon-nearby.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.
50 changes: 49 additions & 1 deletion iosApp/iosApp/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,9 @@
"Coast Guard Restriction" : {
"comment" : "Possible alert cause"
},
"Commuter Rail and Ferry tickets" : {
"comment" : "Label for a More page link to the MBTA mTicket app"
},
"Congestion" : {
"comment" : "Possible alert cause"
},
Expand Down Expand Up @@ -221,6 +224,12 @@
},
"Error loading data" : {

},
"Fare Information" : {
"comment" : "Label for a More page link to fare information on MBTA.com"
},
"Feature Flags" : {
"comment" : "More page section header, only displayed in the developer app for enabling in-progress features"
},
"ferries" : {
"comment" : "ferries"
Expand All @@ -246,12 +255,18 @@
"Full Description" : {
"comment" : "Header for the details of a disruption"
},
"General MBTA Information & Support" : {
"comment" : "More page section header, includes user support resources"
},
"Hazmat Condition" : {
"comment" : "Possible alert cause"
},
"Heavy Ridership" : {
"comment" : "Possible alert cause"
},
"Hide Maps" : {
"comment" : "A setting on the More page to remove the app component from the app"
},
"High Winds" : {
"comment" : "Possible alert cause"
},
Expand Down Expand Up @@ -300,16 +315,31 @@
},
"Location access state unknown" : {

},
"Made with ♥ in Boston, for Boston" : {

},
"Maintenance" : {
"comment" : "Possible alert cause"
},
"Map Debug" : {
"comment" : "A setting on the More page to display map debug information (only visible for developers)"
},
"MBTA Go" : {

},
"Mechanical Problem" : {
"comment" : "Possible alert cause"
},
"Medical Emergency" : {
"comment" : "Possible alert cause"
},
"Monday through Friday: 6:30 AM - 8 PM" : {
"comment" : "Footnote under the More page support header, these are the hours for the support call center"
},
"mTicket App" : {
"comment" : "Footnote underneath the \"Commuter Rail and Ferry tickets\" label on the More page link to the MBTA mTicket app"
},
"Next stop" : {
"comment" : "Label for a vehicle's next stop. For example: Next stop Alewife"
},
Expand Down Expand Up @@ -348,9 +378,18 @@
},
"Predictions unavailable" : {

},
"Privacy Policy" : {
"comment" : "Label for a More page link to the MBTA.com privacy policy"
},
"Recently Viewed" : {

},
"Resources" : {
"comment" : "More page section header, includes links to MBTA.com and mTicket app"
},
"Route Search" : {
"comment" : "A setting on the More page to display routes in search (only visible for developers)"
},
"Routes" : {

Expand All @@ -368,7 +407,7 @@

},
"Settings" : {

"comment" : "More page section header, includes settings that the user can configure"
},
"Severe Weather" : {
"comment" : "Possible alert cause"
Expand Down Expand Up @@ -421,6 +460,9 @@
"Technical Problem" : {
"comment" : "Possible alert cause"
},
"Terms of Use" : {
"comment" : "Label for a More page link to the MBTA.com terms of use"
},
"This vehicle is completing another trip." : {

},
Expand All @@ -445,6 +487,9 @@
"trains" : {
"comment" : "trains"
},
"Trip Planner" : {
"comment" : "Label for a More page link to the MBTA.com trip planner"
},
"Unable to connect" : {

},
Expand Down Expand Up @@ -479,6 +524,9 @@
"Updated: %@" : {
"comment" : "Interpolated value is a timestamp for when displayed alert details were last changed"
},
"version %@" : {
"comment" : "Version number label on the More page"
},
"Weather" : {
"comment" : "Possible alert cause"
},
Expand Down
48 changes: 48 additions & 0 deletions iosApp/iosApp/Pages/More/MoreItem.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// MoreItem.swift
// iosApp
//
// Created by esimon on 10/28/24.
// Copyright © 2024 MBTA. All rights reserved.
//

import Foundation
import shared

enum MoreItem: Identifiable, Equatable {
case toggle(setting: Setting)
case link(label: String, url: String, note: String? = nil)
case phone(label: String, phoneNumber: String)

var id: String {
switch self {
case let .toggle(setting: setting): setting.key.name
case let .link(label: _, url: url, note: _): url
case let .phone(label: _, phoneNumber: number): number
}
}

var label: String {
switch self {
case let .toggle(setting: setting):
switch setting.key {
case .hideMaps: NSLocalizedString(
"Hide Maps",
comment: "A setting on the More page to remove the app component from the app"
)
case .searchRouteResults: NSLocalizedString(
"Route Search",
comment: "A setting on the More page to display routes in search (only visible for developers)"
)
case .map: NSLocalizedString(
"Map Debug",
comment: "A setting on the More page to display map debug information (only visible for developers)"
)
}

case let .link(label: label, url: _, note: _): label

case let .phone(label: label, phoneNumber: _): label
}
}
}
46 changes: 46 additions & 0 deletions iosApp/iosApp/Pages/More/MoreLink.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
//
// MoreLink.swift
// iosApp
//
// Created by esimon on 10/28/24.
// Copyright © 2024 MBTA. All rights reserved.
//

import SwiftUI

struct MoreLink: View {
var label: String
var url: String
var note: String? = nil

@ScaledMetric
private var iconSize: CGFloat = 10.5

var body: some View {
Link(destination: URL(string: url)!) {
HStack(alignment: .center, spacing: 0) {
VStack(alignment: .leading, spacing: 0) {
Text(label)
.foregroundStyle(Color.text)
.font(Typography.body)
if let note {
Text(note)
.foregroundStyle(Color.text)
.font(Typography.footnote)
.opacity(0.6)
.padding(.top, 2)
}
}
Spacer()
Image(systemName: "arrow.up.right")
.resizable()
.frame(width: iconSize, height: iconSize, alignment: .center)
.foregroundStyle(Color.deemphasized)
.fontWeight(.bold)
}
}
.padding(.vertical, 10)
.padding(.horizontal, 16)
.frame(minHeight: 44)
}
}
Loading

0 comments on commit ea168ae

Please sign in to comment.