Skip to content

Commit 5e97ce7

Browse files
authored
Small improvements (pointfreeco#67)
* wip * wip * wip * simplfiy * wip * wip * wip
1 parent 45a77a2 commit 5e97ce7

File tree

12 files changed

+139
-82
lines changed

12 files changed

+139
-82
lines changed

Examples/Examples.xcodeproj/project.pbxproj

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525
CA47383E272F0F9B0012CAC3 /* 10-CustomComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA47383D272F0F9B0012CAC3 /* 10-CustomComponents.swift */; };
2626
CA53F7F1295BBDB700DE68FE /* EditStandupTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA53F7F0295BBDB700DE68FE /* EditStandupTests.swift */; };
2727
CA53F806295BEE4F00DE68FE /* StandupsListUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA53F805295BEE4F00DE68FE /* StandupsListUITests.swift */; };
28-
CA53F80C295F8BE600DE68FE /* AsyncAlgorithms in Frameworks */ = {isa = PBXBuildFile; productRef = CA53F80B295F8BE600DE68FE /* AsyncAlgorithms */; };
2928
CA64539A2968A06E00802931 /* Dependencies in Frameworks */ = {isa = PBXBuildFile; productRef = CA6453992968A06E00802931 /* Dependencies */; };
3029
CA70FED7274B1907005A0D53 /* 08-NavigationLinkList.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA70FED6274B1907005A0D53 /* 08-NavigationLinkList.swift */; };
3130
CA93236B292BE733004B1130 /* 13-IfCaseLet.swift in Sources */ = {isa = PBXBuildFile; fileRef = CA93236A292BE733004B1130 /* 13-IfCaseLet.swift */; };
@@ -35,11 +34,13 @@
3534
CAAA74E82956A658009A25CA /* StandupDetailTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAAA74E72956A658009A25CA /* StandupDetailTests.swift */; };
3635
CAAC0072292BDE660083F2FF /* 12-IfLet.swift in Sources */ = {isa = PBXBuildFile; fileRef = CAAC0071292BDE660083F2FF /* 12-IfLet.swift */; };
3736
CABE9FC1272F2C0000AFC150 /* 09-Routing.swift in Sources */ = {isa = PBXBuildFile; fileRef = CABE9FC0272F2C0000AFC150 /* 09-Routing.swift */; };
37+
CADF861E2977652500B7695B /* SoundEffectClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = CADF861D2977652500B7695B /* SoundEffectClient.swift */; };
38+
CADF8621297765F000B7695B /* ding.wav in Resources */ = {isa = PBXBuildFile; fileRef = CADF8620297765F000B7695B /* ding.wav */; };
3839
DC5E07772947CCD700293F45 /* StandupsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5E07762947CCD700293F45 /* StandupsApp.swift */; };
3940
DC5E07792947CCD700293F45 /* StandupDetail.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5E07782947CCD700293F45 /* StandupDetail.swift */; };
4041
DC5E077B2947CCD800293F45 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC5E077A2947CCD800293F45 /* Assets.xcassets */; };
4142
DC5E077E2947CCD800293F45 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = DC5E077D2947CCD800293F45 /* Preview Assets.xcassets */; };
42-
DC5E07A52947CFA000293F45 /* EditStandup.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5E07A42947CFA000293F45 /* EditStandup.swift */; };
43+
DC5E07A52947CFA000293F45 /* StandupForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5E07A42947CFA000293F45 /* StandupForm.swift */; };
4344
DC5E07A72947CFA600293F45 /* StandupsList.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5E07A62947CFA600293F45 /* StandupsList.swift */; };
4445
DC5E07A92947CFB700293F45 /* SpeechClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5E07A82947CFB700293F45 /* SpeechClient.swift */; };
4546
DC5E07AB2947CFCA00293F45 /* Models.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC5E07AA2947CFCA00293F45 /* Models.swift */; };
@@ -104,13 +105,15 @@
104105
CAAA74E72956A658009A25CA /* StandupDetailTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandupDetailTests.swift; sourceTree = "<group>"; };
105106
CAAC0071292BDE660083F2FF /* 12-IfLet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "12-IfLet.swift"; sourceTree = "<group>"; };
106107
CABE9FC0272F2C0000AFC150 /* 09-Routing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "09-Routing.swift"; sourceTree = "<group>"; };
108+
CADF861D2977652500B7695B /* SoundEffectClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SoundEffectClient.swift; sourceTree = "<group>"; };
109+
CADF8620297765F000B7695B /* ding.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ding.wav; sourceTree = "<group>"; };
107110
DC5E07742947CCD700293F45 /* Standups.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Standups.app; sourceTree = BUILT_PRODUCTS_DIR; };
108111
DC5E07762947CCD700293F45 /* StandupsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandupsApp.swift; sourceTree = "<group>"; };
109112
DC5E07782947CCD700293F45 /* StandupDetail.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandupDetail.swift; sourceTree = "<group>"; };
110113
DC5E077A2947CCD800293F45 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
111114
DC5E077D2947CCD800293F45 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
112115
DC5E07832947CCD800293F45 /* StandupsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = StandupsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
113-
DC5E07A42947CFA000293F45 /* EditStandup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditStandup.swift; sourceTree = "<group>"; };
116+
DC5E07A42947CFA000293F45 /* StandupForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandupForm.swift; sourceTree = "<group>"; };
114117
DC5E07A62947CFA600293F45 /* StandupsList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandupsList.swift; sourceTree = "<group>"; };
115118
DC5E07A82947CFB700293F45 /* SpeechClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeechClient.swift; sourceTree = "<group>"; };
116119
DC5E07AA2947CFCA00293F45 /* Models.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Models.swift; sourceTree = "<group>"; };
@@ -163,7 +166,6 @@
163166
isa = PBXFrameworksBuildPhase;
164167
buildActionMask = 2147483647;
165168
files = (
166-
CA53F80C295F8BE600DE68FE /* AsyncAlgorithms in Frameworks */,
167169
);
168170
runOnlyForDeploymentPostprocessing = 0;
169171
};
@@ -250,6 +252,7 @@
250252
isa = PBXGroup;
251253
children = (
252254
CA53F808295CCA2E00DE68FE /* Readme.md */,
255+
CADF861F297765F000B7695B /* Resources */,
253256
DC5E07752947CCD700293F45 /* Standups */,
254257
DC5E07862947CCD800293F45 /* StandupsTests */,
255258
CA53F7FB295BEDBE00DE68FE /* StandupsUITests */,
@@ -262,15 +265,24 @@
262265
children = (
263266
DCE73E0B2947D163004EE92E /* DataManager.swift */,
264267
CAAA74DF2956956B009A25CA /* OpenSettings.swift */,
268+
CADF861D2977652500B7695B /* SoundEffectClient.swift */,
265269
DC5E07A82947CFB700293F45 /* SpeechClient.swift */,
266270
);
267271
path = Dependencies;
268272
sourceTree = "<group>";
269273
};
274+
CADF861F297765F000B7695B /* Resources */ = {
275+
isa = PBXGroup;
276+
children = (
277+
CADF8620297765F000B7695B /* ding.wav */,
278+
);
279+
path = Resources;
280+
sourceTree = "<group>";
281+
};
270282
DC5E07752947CCD700293F45 /* Standups */ = {
271283
isa = PBXGroup;
272284
children = (
273-
DC5E07A42947CFA000293F45 /* EditStandup.swift */,
285+
DC5E07A42947CFA000293F45 /* StandupForm.swift */,
274286
DC5E07AA2947CFCA00293F45 /* Models.swift */,
275287
DC5E07AC2947CFD300293F45 /* RecordMeeting.swift */,
276288
DC5E07782947CCD700293F45 /* StandupDetail.swift */,
@@ -403,7 +415,6 @@
403415
);
404416
name = StandupsTests;
405417
packageProductDependencies = (
406-
CA53F80B295F8BE600DE68FE /* AsyncAlgorithms */,
407418
);
408419
productName = StandupsTests;
409420
productReference = DC5E07832947CCD800293F45 /* StandupsTests.xctest */;
@@ -452,7 +463,6 @@
452463
packageReferences = (
453464
DCE73E032947D063004EE92E /* XCRemoteSwiftPackageReference "swift-tagged" */,
454465
DCE73E062947D082004EE92E /* XCRemoteSwiftPackageReference "swift-identified-collections" */,
455-
CA53F80A295F8BE600DE68FE /* XCRemoteSwiftPackageReference "swift-async-algorithms" */,
456466
CA6453982968A06E00802931 /* XCRemoteSwiftPackageReference "swift-dependencies" */,
457467
);
458468
productRefGroup = CA473795272F08EF0012CAC3 /* Products */;
@@ -496,6 +506,7 @@
496506
isa = PBXResourcesBuildPhase;
497507
buildActionMask = 2147483647;
498508
files = (
509+
CADF8621297765F000B7695B /* ding.wav in Resources */,
499510
DC5E077E2947CCD800293F45 /* Preview Assets.xcassets in Resources */,
500511
DC5E077B2947CCD800293F45 /* Assets.xcassets in Resources */,
501512
);
@@ -560,8 +571,9 @@
560571
DC5E07792947CCD700293F45 /* StandupDetail.swift in Sources */,
561572
DCE73E0C2947D163004EE92E /* DataManager.swift in Sources */,
562573
DC5E07772947CCD700293F45 /* StandupsApp.swift in Sources */,
574+
CADF861E2977652500B7695B /* SoundEffectClient.swift in Sources */,
563575
CA22CCC22967799600F52F6D /* Helpers.swift in Sources */,
564-
DC5E07A52947CFA000293F45 /* EditStandup.swift in Sources */,
576+
DC5E07A52947CFA000293F45 /* StandupForm.swift in Sources */,
565577
DC5E07AB2947CFCA00293F45 /* Models.swift in Sources */,
566578
DC5E07AD2947CFD300293F45 /* RecordMeeting.swift in Sources */,
567579
DC5E07A92947CFB700293F45 /* SpeechClient.swift in Sources */,
@@ -1039,14 +1051,6 @@
10391051
/* End XCConfigurationList section */
10401052

10411053
/* Begin XCRemoteSwiftPackageReference section */
1042-
CA53F80A295F8BE600DE68FE /* XCRemoteSwiftPackageReference "swift-async-algorithms" */ = {
1043-
isa = XCRemoteSwiftPackageReference;
1044-
repositoryURL = "https://github.com/apple/swift-async-algorithms";
1045-
requirement = {
1046-
kind = upToNextMajorVersion;
1047-
minimumVersion = 0.0.3;
1048-
};
1049-
};
10501054
CA6453982968A06E00802931 /* XCRemoteSwiftPackageReference "swift-dependencies" */ = {
10511055
isa = XCRemoteSwiftPackageReference;
10521056
repositoryURL = "http://github.com/pointfreeco/swift-dependencies";
@@ -1082,11 +1086,6 @@
10821086
isa = XCSwiftPackageProductDependency;
10831087
productName = SwiftUINavigation;
10841088
};
1085-
CA53F80B295F8BE600DE68FE /* AsyncAlgorithms */ = {
1086-
isa = XCSwiftPackageProductDependency;
1087-
package = CA53F80A295F8BE600DE68FE /* XCRemoteSwiftPackageReference "swift-async-algorithms" */;
1088-
productName = AsyncAlgorithms;
1089-
};
10901089
CA6453992968A06E00802931 /* Dependencies */ = {
10911090
isa = XCSwiftPackageProductDependency;
10921091
package = CA6453982968A06E00802931 /* XCRemoteSwiftPackageReference "swift-dependencies" */;

Examples/Standups/Resources/ding.wav

523 KB
Binary file not shown.
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import AVFoundation
2+
import Dependencies
3+
4+
struct SoundEffectClient {
5+
var load: @Sendable (String) -> Void
6+
var play: @Sendable () -> Void
7+
}
8+
9+
extension SoundEffectClient: DependencyKey {
10+
static var liveValue: Self {
11+
let player = LockIsolated(AVPlayer())
12+
return Self(
13+
load: { fileName in
14+
player.withValue {
15+
guard let url = Bundle.main.url(forResource: fileName, withExtension: "")
16+
else { return }
17+
$0.replaceCurrentItem(with: AVPlayerItem(url: url))
18+
}
19+
},
20+
play: {
21+
player.withValue {
22+
$0.seek(to: .zero)
23+
$0.play()
24+
}
25+
}
26+
)
27+
}
28+
29+
static let testValue = Self(
30+
load: unimplemented("SoundEffectClient.load"),
31+
play: unimplemented("SoundEffectClient.play")
32+
)
33+
34+
static let noop = Self(
35+
load: { _ in },
36+
play: { }
37+
)
38+
}
39+
40+
extension DependencyValues {
41+
var soundEffectClient: SoundEffectClient {
42+
get { self[SoundEffectClient.self] }
43+
set { self[SoundEffectClient.self] = newValue }
44+
}
45+
}

Examples/Standups/Standups/RecordMeeting.swift

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ class RecordMeetingModel: ObservableObject {
1515
private var transcript = ""
1616

1717
@Dependency(\.continuousClock) var clock
18+
@Dependency(\.soundEffectClient) var soundEffectClient
1819
@Dependency(\.speechClient) var speechClient
1920

2021
var onMeetingFinished: (String) async -> Void = unimplemented(
@@ -58,6 +59,7 @@ class RecordMeetingModel: ObservableObject {
5859
}
5960

6061
self.speakerIndex += 1
62+
self.soundEffectClient.play()
6163
self.secondsElapsed =
6264
self.speakerIndex * Int(self.standup.durationPerAttendee.components.seconds)
6365
}
@@ -77,6 +79,8 @@ class RecordMeetingModel: ObservableObject {
7779
}
7880

7981
func task() async {
82+
self.soundEffectClient.load("ding.wav")
83+
8084
let authorization =
8185
await self.speechClient.authorizationStatus() == .notDetermined
8286
? self.speechClient.requestAuthorization()
@@ -127,6 +131,7 @@ class RecordMeetingModel: ObservableObject {
127131
break
128132
}
129133
self.speakerIndex += 1
134+
self.soundEffectClient.play()
130135
}
131136
}
132137
}
@@ -230,13 +235,16 @@ struct MeetingHeaderView: View {
230235
.progressViewStyle(MeetingProgressViewStyle(theme: self.theme))
231236
HStack {
232237
VStack(alignment: .leading) {
233-
Text("Seconds Elapsed")
238+
Text("Time Elapsed")
234239
.font(.caption)
235-
Label("\(self.secondsElapsed)", systemImage: "hourglass.bottomhalf.fill")
240+
Label(
241+
Duration.seconds(self.secondsElapsed).formatted(.units()),
242+
systemImage: "hourglass.bottomhalf.fill"
243+
)
236244
}
237245
Spacer()
238246
VStack(alignment: .trailing) {
239-
Text("Seconds Remaining")
247+
Text("Time Remaining")
240248
.font(.caption)
241249
Label(self.durationRemaining.formatted(.units()), systemImage: "hourglass.tophalf.fill")
242250
.font(.body.monospacedDigit())

Examples/Standups/Standups/StandupDetail.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class StandupDetailModel: ObservableObject {
2323

2424
enum Destination {
2525
case alert(AlertState<AlertAction>)
26-
case edit(EditStandupModel)
26+
case edit(StandupFormModel)
2727
case meeting(Meeting)
2828
case record(RecordMeetingModel)
2929
}
@@ -46,7 +46,7 @@ class StandupDetailModel: ObservableObject {
4646
self.standup.meetings.remove(atOffsets: indices)
4747
}
4848

49-
func meetingTapping(_ meeting: Meeting) {
49+
func meetingTapped(_ meeting: Meeting) {
5050
self.destination = .meeting(meeting)
5151
}
5252

@@ -75,7 +75,7 @@ class StandupDetailModel: ObservableObject {
7575
func editButtonTapped() {
7676
self.destination = .edit(
7777
withDependencies(from: self) {
78-
EditStandupModel(standup: self.standup)
78+
StandupFormModel(standup: self.standup)
7979
}
8080
)
8181
}
@@ -175,7 +175,7 @@ struct StandupDetailView: View {
175175
Section {
176176
ForEach(self.model.standup.meetings) { meeting in
177177
Button {
178-
self.model.meetingTapping(meeting)
178+
self.model.meetingTapped(meeting)
179179
} label: {
180180
HStack {
181181
Image(systemName: "calendar")
@@ -237,7 +237,7 @@ struct StandupDetailView: View {
237237
case: /StandupDetailModel.Destination.edit
238238
) { $editModel in
239239
NavigationStack {
240-
EditStandupView(model: editModel)
240+
StandupFormView(model: editModel)
241241
.navigationTitle(self.model.standup.title)
242242
.toolbar {
243243
ToolbarItem(placement: .cancellationAction) {

Examples/Standups/Standups/EditStandup.swift renamed to Examples/Standups/Standups/StandupForm.swift

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import Dependencies
22
import SwiftUI
33
import SwiftUINavigation
44

5-
class EditStandupModel: ObservableObject {
5+
class StandupFormModel: ObservableObject {
66
@Published var focus: Field?
77
@Published var standup: Standup
88

@@ -42,9 +42,9 @@ class EditStandupModel: ObservableObject {
4242
}
4343
}
4444

45-
struct EditStandupView: View {
46-
@FocusState var focus: EditStandupModel.Field?
47-
@ObservedObject var model: EditStandupModel
45+
struct StandupFormView: View {
46+
@FocusState var focus: StandupFormModel.Field?
47+
@ObservedObject var model: StandupFormModel
4848

4949
var body: some View {
5050
Form {
@@ -109,10 +109,10 @@ extension Duration {
109109
}
110110
}
111111

112-
struct EditStandup_Previews: PreviewProvider {
112+
struct StandupForm_Previews: PreviewProvider {
113113
static var previews: some View {
114114
NavigationStack {
115-
EditStandupView(model: EditStandupModel(standup: .mock))
115+
StandupFormView(model: StandupFormModel(standup: .mock))
116116
}
117117
.previewDisplayName("Edit")
118118

@@ -123,8 +123,8 @@ struct EditStandup_Previews: PreviewProvider {
123123
"""
124124
) {
125125
NavigationStack {
126-
EditStandupView(
127-
model: EditStandupModel(
126+
StandupFormView(
127+
model: StandupFormModel(
128128
focus: .attendee(Standup.mock.attendees[3].id),
129129
standup: .mock
130130
)

Examples/Standups/Standups/StandupsList.swift

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ final class StandupsListModel: ObservableObject {
1919
@Dependency(\.uuid) var uuid
2020

2121
enum Destination {
22-
case add(EditStandupModel)
22+
case add(StandupFormModel)
2323
case alert(AlertState<AlertAction>)
2424
case detail(StandupDetailModel)
2525
}
2626
enum AlertAction {
2727
case confirmLoadMockData
28-
case dismissFailedAlert
2928
}
3029

3130
init(
@@ -57,7 +56,7 @@ final class StandupsListModel: ObservableObject {
5756
func addStandupButtonTapped() {
5857
self.destination = .add(
5958
withDependencies(from: self) {
60-
EditStandupModel(standup: Standup(id: Standup.ID(self.uuid())))
59+
StandupFormModel(standup: Standup(id: Standup.ID(self.uuid())))
6160
}
6261
)
6362
}
@@ -69,9 +68,9 @@ final class StandupsListModel: ObservableObject {
6968
func confirmAddStandupButtonTapped() {
7069
defer { self.destination = nil }
7170

72-
guard case let .add(editStandupModel) = self.destination
71+
guard case let .add(standupFormModel) = self.destination
7372
else { return }
74-
var standup = editStandupModel.standup
73+
var standup = standupFormModel.standup
7574

7675
standup.attendees.removeAll { attendee in
7776
attendee.name.allSatisfy(\.isWhitespace)
@@ -120,9 +119,6 @@ final class StandupsListModel: ObservableObject {
120119
.engineeringMock,
121120
]
122121
}
123-
124-
case .dismissFailedAlert:
125-
self.standups = []
126122
}
127123
}
128124
}
@@ -174,7 +170,7 @@ struct StandupsList: View {
174170
case: /StandupsListModel.Destination.add
175171
) { $model in
176172
NavigationStack {
177-
EditStandupView(model: model)
173+
StandupFormView(model: model)
178174
.navigationTitle("New standup")
179175
.toolbar {
180176
ToolbarItem(placement: .cancellationAction) {
@@ -338,7 +334,7 @@ struct StandupsList_Previews: PreviewProvider {
338334
let _ = standup.attendees.append(lastAttendee)
339335
return StandupsListModel(
340336
destination: .add(
341-
EditStandupModel(
337+
StandupFormModel(
342338
focus: .attendee(lastAttendee.id),
343339
standup: standup
344340
)

0 commit comments

Comments
 (0)