Skip to content

Commit c1ad59c

Browse files
committed
refactor(app): bring back iOS17 support
1 parent 5890832 commit c1ad59c

File tree

7 files changed

+168
-57
lines changed

7 files changed

+168
-57
lines changed
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
2+
import Foundation
3+
import SwiftUI
4+
5+
@available(iOS 18.0, *)
6+
struct CountdownIOS18: View {
7+
let date: Date
8+
9+
init(_ date: Date) {
10+
self.date = date
11+
}
12+
13+
var body: some View {
14+
Text(
15+
.currentDate,
16+
format:
17+
.reference(
18+
to: date,
19+
allowedFields: [.second, .minute, .hour],
20+
maxFieldCount: 2
21+
)
22+
)
23+
}
24+
}
25+
26+
struct CountdownLegacy: View {
27+
let date: Date
28+
@State var countdownText: String = " - "
29+
30+
init(_ date: Date) {
31+
self.date = date
32+
}
33+
34+
func updateCountdownText() {
35+
let formatter = RelativeDateTimeFormatter()
36+
formatter.unitsStyle = .abbreviated
37+
countdownText = formatter.localizedString(for: date, relativeTo: .now)
38+
}
39+
40+
let timer = Timer.publish(every: 0.5, on: .main, in: .common).autoconnect()
41+
42+
var body: some View {
43+
Text(countdownText)
44+
.onAppear {
45+
updateCountdownText()
46+
}
47+
.onReceive(timer) { _ in
48+
updateCountdownText()
49+
}
50+
}
51+
}
52+
53+
struct Countdown: View {
54+
let date: Date
55+
56+
init(_ date: Date) {
57+
self.date = date
58+
}
59+
60+
var body: some View {
61+
Group {
62+
if #available(iOS 18.0, *) {
63+
CountdownIOS18(date)
64+
} else {
65+
CountdownLegacy(date)
66+
}
67+
}
68+
}
69+
}
70+
71+
#Preview("Seconds") {
72+
Countdown(Date(timeIntervalSinceNow: 59))
73+
}
74+
75+
#Preview("Seconds in past") {
76+
Countdown(Date(timeIntervalSinceNow: 0))
77+
}
78+
79+
#Preview("Minutes") {
80+
Countdown(Date(timeIntervalSinceNow: 59 * 60))
81+
}
82+
83+
#Preview("Minutes in past") {
84+
Countdown(Date(timeIntervalSinceNow: -1 * 60))
85+
}
86+
87+
#Preview("Hours") {
88+
Countdown(Date(timeIntervalSinceNow: 10 * 60 * 60))
89+
}
90+
91+
92+
#Preview("Hours in past") {
93+
Countdown(Date(timeIntervalSinceNow: -1 * 2 * 60 * 60))
94+
}

app/Common/Components/MetroDeparture/Card.swift

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -30,28 +30,32 @@ struct MetroDepartureCard<Content: View>: View {
3030
}
3131

3232
#Preview {
33-
MetroDepartureCard(
34-
backgroundColor: getMetroLineColor("A"))
35-
{
36-
HStack {
37-
MetroDepartureCardLabel(direction: "Nemocnice Motol", metroLine: "A")
38-
Spacer()
33+
VStack {
34+
MetroDepartureCard(
35+
backgroundColor: getMetroLineColor("A"))
36+
{
37+
HStack {
38+
MetroDepartureCardLabel(direction: "Nemocnice Motol", metroLine: "A")
39+
Spacer()
40+
}
3941
}
40-
}
41-
MetroDepartureCard(
42-
backgroundColor: getMetroLineColor("B"))
43-
{
44-
HStack {
45-
MetroDepartureCardLabel(direction: "Černý Most", metroLine: "B")
46-
Spacer()
42+
MetroDepartureCard(
43+
backgroundColor: getMetroLineColor("B"))
44+
{
45+
HStack {
46+
MetroDepartureCardLabel(direction: "Černý Most", metroLine: "B")
47+
Spacer()
48+
}
4749
}
48-
}
49-
MetroDepartureCard(
50-
backgroundColor: getMetroLineColor("C"))
51-
{
52-
HStack {
53-
MetroDepartureCardLabel(direction: "Haje", metroLine: "C")
54-
Spacer()
50+
MetroDepartureCard(
51+
backgroundColor: getMetroLineColor("C"))
52+
{
53+
HStack {
54+
MetroDepartureCardLabel(direction: "Haje", metroLine: "C")
55+
Spacer()
56+
}
5557
}
5658
}
59+
.padding(.horizontal, 10)
60+
Spacer()
5761
}

app/Common/Components/MetroDeparture/FirstDeparture.swift

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,9 @@ struct MetroDepartureCardFirstDeparture: View {
55
let departureDate: Date
66

77
var body: some View {
8-
Text(
9-
.currentDate, format: .reference(
10-
to: departureDate,
11-
allowedFields: [.second, .minute, .hour]
12-
)
13-
)
14-
.fontWeight(.bold)
15-
.foregroundStyle(.white)
16-
.foregroundStyle(.white)
8+
Countdown(departureDate)
9+
.fontWeight(.bold)
10+
.foregroundStyle(.white)
11+
.foregroundStyle(.white)
1712
}
1813
}

app/Common/Components/MetroDeparture/MetroDeparture.swift

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,22 @@ struct MetroDeparture: View {
1313

1414
var body: some View {
1515
MetroDepartureCard(backgroundColor: getMetroLineColor(metroLine)) {
16-
MetroDepartureCardLabel(direction: direction, metroLine: metroLine)
16+
HStack {
17+
MetroDepartureCardLabel(direction: direction, metroLine: metroLine)
1718

18-
Spacer()
19+
Spacer()
1920

20-
VStack {
21-
if departures.count >= 1 {
22-
MetroDepartureCardFirstDeparture(departureDate: departures[0].departure)
23-
}
24-
if departures.count >= 2 {
25-
MetroDepartureCardSecondDeparture(
26-
direction: departures[0].heading == departures[1].heading ? nil : departures[1].heading,
27-
departureDate: departures[1].departure
28-
)
21+
VStack(alignment: .trailing) {
22+
if departures.count >= 1 {
23+
MetroDepartureCardFirstDeparture(departureDate: departures[0].departure)
24+
}
25+
26+
if departures.count >= 2 {
27+
MetroDepartureCardSecondDeparture(
28+
direction: departures[0].heading == departures[1].heading ? nil : departures[1].heading,
29+
departureDate: departures[1].departure
30+
)
31+
}
2932
}
3033
}
3134
}

app/Common/Components/MetroDeparture/SecondDeparture.swift

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,24 @@ import SwiftUI
44
struct MetroDepartureCardSecondDeparture: View {
55
let direction: String?
66
let departureDate: Date
7+
let text: String
8+
9+
init(direction: String?, departureDate: Date) {
10+
self.direction = direction
11+
self.departureDate = departureDate
12+
13+
if let direction {
14+
text = "To \(direction) "
15+
} else {
16+
text = "Also "
17+
}
18+
}
719

820
var body: some View {
9-
Text(
10-
direction == nil ? "Also in " : "Also to \(String(describing: direction)) in"
11-
).font(.caption2)
12-
.fontWeight(.bold)
13-
.foregroundStyle(.white)
14-
.opacity(0.9)
15-
Text(
16-
.currentDate, format: .reference(to: departureDate, allowedFields: [.second, .minute, .hour])
17-
)
21+
HStack(spacing: 0) {
22+
Text(text)
23+
Countdown(departureDate)
24+
}
1825
.font(.caption2)
1926
.fontWeight(.bold)
2027
.foregroundStyle(.white)

app/metro-now.xcodeproj/project.pbxproj

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,13 @@
181181
);
182182
target = 2DC639D72BF3CCBA00A72C7F /* metro-now */;
183183
};
184+
2D6C8CE02C51488E003E09A8 /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
185+
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
186+
membershipExceptions = (
187+
Countdown.swift,
188+
);
189+
target = 2DC639D72BF3CCBA00A72C7F /* metro-now */;
190+
};
184191
2DFD2F2B2C4DC2EC009C81CC /* PBXFileSystemSynchronizedBuildFileExceptionSet */ = {
185192
isa = PBXFileSystemSynchronizedBuildFileExceptionSet;
186193
membershipExceptions = (
@@ -206,6 +213,7 @@
206213
/* Begin PBXFileSystemSynchronizedRootGroup section */
207214
2D5BA5DE2C382D6A0055F12A /* MetroDeparture */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (2D5BA5E22C382D8D0055F12A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MetroDeparture; sourceTree = "<group>"; };
208215
2D5BA5EA2C382FC30055F12A /* MapAnnotation */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (2D5BA5EB2C382FEA0055F12A /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = MapAnnotation; sourceTree = "<group>"; };
216+
2D6C8CDD2C514882003E09A8 /* Countdown */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (2D6C8CE02C51488E003E09A8 /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = Countdown; sourceTree = "<group>"; };
209217
2DFD2F272C4DC296009C81CC /* API */ = {isa = PBXFileSystemSynchronizedRootGroup; exceptions = (2DFD2F2B2C4DC2EC009C81CC /* PBXFileSystemSynchronizedBuildFileExceptionSet */, 2DFD2F432C4DCC37009C81CC /* PBXFileSystemSynchronizedBuildFileExceptionSet */, ); explicitFileTypes = {}; explicitFolders = (); path = API; sourceTree = "<group>"; };
210218
/* End PBXFileSystemSynchronizedRootGroup section */
211219

@@ -297,6 +305,7 @@
297305
2D1B2C5B2BFADAAA007ED5EB /* Components */ = {
298306
isa = PBXGroup;
299307
children = (
308+
2D6C8CDD2C514882003E09A8 /* Countdown */,
300309
2D5BA5EA2C382FC30055F12A /* MapAnnotation */,
301310
2D5BA5DE2C382D6A0055F12A /* MetroDeparture */,
302311
);
@@ -925,7 +934,7 @@
925934
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
926935
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
927936
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
928-
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
937+
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
929938
LD_RUNPATH_SEARCH_PATHS = (
930939
"$(inherited)",
931940
"@executable_path/Frameworks",
@@ -959,7 +968,7 @@
959968
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
960969
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
961970
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
962-
IPHONEOS_DEPLOYMENT_TARGET = 18.0;
971+
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
963972
LD_RUNPATH_SEARCH_PATHS = (
964973
"$(inherited)",
965974
"@executable_path/Frameworks",

app/metro-now/Core/Map/StationDetailView.swift

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,7 @@ struct StationDetailView: View {
2828
grouping: upcomingDeparturesArr,
2929
by: { $0.platform }
3030
)
31-
}
32-
catch {
31+
} catch {
3332
errorMessage = "Failed to fetch departures: \(error)"
3433
}
3534
}
@@ -47,10 +46,10 @@ struct StationDetailView: View {
4746

4847
mapUrl =
4948
showDirection
50-
? URL(
51-
string:
49+
? URL(
50+
string:
5251
"maps://?saddr=&daddr=\(stationCoordinate.latitude),\(stationCoordinate.longitude)"
53-
) : nil
52+
) : nil
5453
}
5554

5655
var body: some View {
@@ -131,7 +130,7 @@ struct StationDetailView: View {
131130
MetroDeparture(
132131
metroLine: d[0].line,
133132
direction: d[0].heading,
134-
departures: d
133+
departures: d
135134
)
136135
}
137136
}

0 commit comments

Comments
 (0)