Skip to content

Commit 07aec80

Browse files
committed
Add TTFD to all screens
1 parent c7a032e commit 07aec80

File tree

10 files changed

+122
-5
lines changed

10 files changed

+122
-5
lines changed

Modules/Sources/AnnouncementFeature/AnnouncementFeature.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import TopicFeature
1212
import ParsingClient
1313
import Models
1414
import PersistenceKeys
15+
import AnalyticsClient
1516

1617
@Reducer
1718
public struct AnnouncementFeature: Reducer, Sendable {
@@ -28,6 +29,8 @@ public struct AnnouncementFeature: Reducer, Sendable {
2829
public var announcement: Announcement?
2930

3031
var types: [[TopicTypeUI]] = []
32+
33+
var didLoadOnce = false
3134

3235
public init(id: Int, name: String?) {
3336
self.announcementId = id
@@ -50,6 +53,7 @@ public struct AnnouncementFeature: Reducer, Sendable {
5053
// MARK: - Dependencies
5154

5255
@Dependency(\.apiClient) private var apiClient
56+
@Dependency(\.analyticsClient) private var analyticsClient
5357

5458
// MARK: - Body
5559

@@ -88,13 +92,23 @@ public struct AnnouncementFeature: Reducer, Sendable {
8892

8993
case let ._loadTypes(types):
9094
state.types = types
95+
reportFullyDisplayed(&state)
9196
return .none
9297

9398
case let ._announcementResponse(.failure(error)):
9499
// TODO: Handle error
95100
print(error)
101+
reportFullyDisplayed(&state)
96102
return .none
97103
}
98104
}
99105
}
106+
107+
// MARK: - Shared Logic
108+
109+
private func reportFullyDisplayed(_ state: inout State) {
110+
guard !state.didLoadOnce else { return }
111+
analyticsClient.reportFullyDisplayed()
112+
state.didLoadOnce = true
113+
}
100114
}

Modules/Sources/ArticleFeature/ArticleFeature.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import APIClient
1313
import CacheClient
1414
import PasteboardClient
1515
import HapticClient
16+
import AnalyticsClient
1617

1718
@Reducer
1819
public struct ArticleFeature: Reducer, Sendable {
@@ -64,6 +65,8 @@ public struct ArticleFeature: Reducer, Sendable {
6465
var refreshRequestFinished = false
6566
var refreshTimePassed = false
6667

68+
var didLoadOnce = false
69+
6770
public init(
6871
destination: Destination.State? = nil,
6972
articlePreview: ArticlePreview,
@@ -133,6 +136,7 @@ public struct ArticleFeature: Reducer, Sendable {
133136
@Dependency(\.cacheClient) var cacheClient
134137
@Dependency(\.hapticClient) var hapticClient
135138
@Dependency(\.parsingClient) var parsingClient
139+
@Dependency(\.analyticsClient) var analyticsClient
136140
@Dependency(\.pasteboardClient) var pasteboardClient
137141
@Dependency(\.openURL) var openURL
138142
@Dependency(\.dismiss) var dismiss
@@ -323,6 +327,7 @@ public struct ArticleFeature: Reducer, Sendable {
323327
case ._articleResponse(.failure):
324328
state.isLoading = false
325329
state.destination = .alert(.error)
330+
reportFullyDisplayed(&state)
326331
return .none
327332

328333
case let ._commentResponse(.success(type)):
@@ -355,6 +360,7 @@ public struct ArticleFeature: Reducer, Sendable {
355360
case ._parseArticleElements(.success(let elements)):
356361
state.elements = elements
357362
state.isLoading = false
363+
reportFullyDisplayed(&state)
358364
return .run { _ in
359365
var urls: [URL] = []
360366
for case let .image(image) in elements {
@@ -366,6 +372,7 @@ public struct ArticleFeature: Reducer, Sendable {
366372
case ._parseArticleElements(.failure):
367373
state.isLoading = false
368374
state.destination = .alert(.error)
375+
reportFullyDisplayed(&state)
369376
return .none
370377

371378
case ._pollVoteResponse(.success):
@@ -389,7 +396,13 @@ public struct ArticleFeature: Reducer, Sendable {
389396
Analytics()
390397
}
391398

392-
// MARK: - Effects
399+
// MARK: - Shared Logic
400+
401+
private func reportFullyDisplayed(_ state: inout State) {
402+
guard !state.didLoadOnce else { return }
403+
analyticsClient.reportFullyDisplayed()
404+
state.didLoadOnce = true
405+
}
393406

394407
private func loadingIndicator() -> EffectOf<Self> {
395408
return .run { send in

Modules/Sources/ArticlesListFeature/ArticlesListFeature.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,8 @@ public struct ArticlesListFeature: Reducer, Sendable {
186186
Analytics()
187187
}
188188

189+
// MARK: - Shared Logic
190+
189191
private func reportFullyDisplayed(_ state: inout State) {
190192
guard !state.didLoadOnce else { return }
191193
analyticsClient.reportFullyDisplayed()

Modules/Sources/ForumFeature/ForumFeature.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Models
1313
import PasteboardClient
1414
import PersistenceKeys
1515
import TCAExtensions
16+
import AnalyticsClient
1617

1718
@Reducer
1819
public struct ForumFeature: Reducer, Sendable {
@@ -42,6 +43,8 @@ public struct ForumFeature: Reducer, Sendable {
4243
return userSession != nil
4344
}
4445

46+
var didLoadOnce = false
47+
4548
public init(
4649
forumId: Int,
4750
forumName: String?
@@ -75,6 +78,7 @@ public struct ForumFeature: Reducer, Sendable {
7578
// MARK: - Dependencies
7679

7780
@Dependency(\.apiClient) private var apiClient
81+
@Dependency(\.analyticsClient) private var analyticsClient
7882
@Dependency(\.pasteboardClient) private var pasteboardClient
7983

8084
// MARK: - Body
@@ -208,13 +212,22 @@ public struct ForumFeature: Reducer, Sendable {
208212

209213
state.isLoadingTopics = false
210214
state.isRefreshing = false
211-
215+
reportFullyDisplayed(&state)
212216
return .none
213217

214218
case let ._forumResponse(.failure(error)):
215219
print(error)
220+
reportFullyDisplayed(&state)
216221
return .none
217222
}
218223
}
219224
}
225+
226+
// MARK: - Shared Logic
227+
228+
private func reportFullyDisplayed(_ state: inout State) {
229+
guard !state.didLoadOnce else { return }
230+
analyticsClient.reportFullyDisplayed()
231+
state.didLoadOnce = true
232+
}
220233
}

Modules/Sources/ForumsListFeature/ForumsListFeature.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import Foundation
99
import ComposableArchitecture
1010
import APIClient
1111
import Models
12+
import AnalyticsClient
1213

1314
@Reducer
1415
public struct ForumsListFeature: Reducer, Sendable {
@@ -20,6 +21,7 @@ public struct ForumsListFeature: Reducer, Sendable {
2021
@ObservableState
2122
public struct State: Equatable {
2223
public var forums: [ForumRow]?
24+
var didLoadOnce = false
2325

2426
public init(
2527
forums: [ForumRow]? = nil
@@ -42,6 +44,7 @@ public struct ForumsListFeature: Reducer, Sendable {
4244
// MARK: - Dependencies
4345

4446
@Dependency(\.apiClient) private var apiClient
47+
@Dependency(\.analyticsClient) private var analyticsClient
4548

4649
// MARK: - Body
4750

@@ -74,12 +77,22 @@ public struct ForumsListFeature: Reducer, Sendable {
7477
}
7578

7679
state.forums = rows
80+
reportFullyDisplayed(&state)
7781
return .none
7882

7983
case let ._forumsListResponse(.failure(error)):
8084
print(error)
85+
reportFullyDisplayed(&state)
8186
return .none
8287
}
8388
}
8489
}
90+
91+
// MARK: - Shared Logic
92+
93+
private func reportFullyDisplayed(_ state: inout State) {
94+
guard !state.didLoadOnce else { return }
95+
analyticsClient.reportFullyDisplayed()
96+
state.didLoadOnce = true
97+
}
8598
}

Modules/Sources/HistoryFeature/HistoryFeature.swift

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ComposableArchitecture
1010
import PageNavigationFeature
1111
import APIClient
1212
import Models
13+
import AnalyticsClient
1314

1415
@Reducer
1516
public struct HistoryFeature: Sendable {
@@ -23,11 +24,12 @@ public struct HistoryFeature: Sendable {
2324
@Shared(.appSettings) var appSettings: AppSettings
2425

2526
public var history: [HistoryRow] = []
26-
2727
public var isLoading = false
2828

2929
public var pageNavigation = PageNavigationFeature.State(type: .history)
3030

31+
var didLoadOnce = false
32+
3133
public init(
3234
history: [HistoryRow] = []
3335
) {
@@ -51,6 +53,7 @@ public struct HistoryFeature: Sendable {
5153
// MARK: - Dependencies
5254

5355
@Dependency(\.apiClient) private var apiClient
56+
@Dependency(\.analyticsClient) private var analyticsClient
5457

5558
// MARK: - Body
5659

@@ -112,14 +115,23 @@ public struct HistoryFeature: Sendable {
112115
state.pageNavigation.count = response.historiesCount
113116

114117
state.isLoading = false
115-
118+
reportFullyDisplayed(&state)
116119
return .none
117120

118121
case let ._historyResponse(.failure(error)):
119122
// TODO: Handle error
120123
print(error)
124+
reportFullyDisplayed(&state)
121125
return .none
122126
}
123127
}
124128
}
129+
130+
// MARK: - Shared Logic
131+
132+
private func reportFullyDisplayed(_ state: inout State) {
133+
guard !state.didLoadOnce else { return }
134+
analyticsClient.reportFullyDisplayed()
135+
state.didLoadOnce = true
136+
}
125137
}

Modules/Sources/ProfileFeature/ProfileFeature.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import ComposableArchitecture
1010
import APIClient
1111
import PersistenceKeys
1212
import Models
13+
import AnalyticsClient
1314

1415
@Reducer
1516
public struct ProfileFeature: Reducer, Sendable {
@@ -30,6 +31,8 @@ public struct ProfileFeature: Reducer, Sendable {
3031
return userSession != nil && user?.id == userSession?.userId
3132
}
3233

34+
var didLoadOnce = false
35+
3336
public init(
3437
alert: AlertState<Action.Alert>? = nil,
3538
userId: Int? = nil,
@@ -65,6 +68,7 @@ public struct ProfileFeature: Reducer, Sendable {
6568
// MARK: - Dependencies
6669

6770
@Dependency(\.apiClient) private var apiClient
71+
@Dependency(\.analyticsClient) private var analyticsClient
6872
@Dependency(\.dismiss) private var dismiss
6973

7074
// MARK: - Body
@@ -101,15 +105,25 @@ public struct ProfileFeature: Reducer, Sendable {
101105
case ._userResponse(.success(let user)):
102106
state.isLoading = false
103107
state.user = user
108+
reportFullyDisplayed(&state)
104109
return .none
105110

106111
case ._userResponse(.failure(let error)):
107112
state.isLoading = false
108113
print(error, #line)
114+
reportFullyDisplayed(&state)
109115
return .none
110116
}
111117
}
112118

113119
Analytics()
114120
}
121+
122+
// MARK: - Shared Logic
123+
124+
private func reportFullyDisplayed(_ state: inout State) {
125+
guard !state.didLoadOnce else { return }
126+
analyticsClient.reportFullyDisplayed()
127+
state.didLoadOnce = true
128+
}
115129
}

Modules/Sources/QMSFeature/QMSFeature.swift

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import APIClient
1111
import PersistenceKeys
1212
import Models
1313
import ExyteChat
14+
import AnalyticsClient
1415

1516
@Reducer
1617
public struct QMSFeature: Reducer, Sendable {
@@ -26,6 +27,8 @@ public struct QMSFeature: Reducer, Sendable {
2627
public var chat: QMSChat?
2728
public var messages: [Message] = []
2829

30+
var didLoadOnce = false
31+
2932
public var title: String {
3033
if let chat {
3134
return chat.partnerName + " - " + chat.name
@@ -57,6 +60,7 @@ public struct QMSFeature: Reducer, Sendable {
5760
// MARK: - Dependencies
5861

5962
@Dependency(\.apiClient) private var apiClient
63+
@Dependency(\.analyticsClient) private var analyticsClient
6064
@Dependency(\.continuousClock) private var clock
6165

6266
// MARK: - Cancellable
@@ -125,11 +129,20 @@ public struct QMSFeature: Reducer, Sendable {
125129
print(error)
126130
// TODO: Handle error
127131
}
132+
reportFullyDisplayed(&state)
128133
return .none
129134

130135
case .binding:
131136
return .none
132137
}
133138
}
134139
}
140+
141+
// MARK: - Shared Logic
142+
143+
private func reportFullyDisplayed(_ state: inout State) {
144+
guard !state.didLoadOnce else { return }
145+
analyticsClient.reportFullyDisplayed()
146+
state.didLoadOnce = true
147+
}
135148
}

0 commit comments

Comments
 (0)