Skip to content

Commit cd4c3fd

Browse files
committed
Refactor TimelineContentFilter to use Snapshot struct
Introduces a Snapshot struct in TimelineContentFilter to capture filter state, and updates TimelineDatasource to use this snapshot for filtering. Refactors related methods and tests to use the new snapshot-based approach, improving clarity and thread safety.
1 parent 3fa1930 commit cd4c3fd

File tree

3 files changed

+55
-14
lines changed

3 files changed

+55
-14
lines changed

Packages/Timeline/Sources/Timeline/TimelineContentFilter.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,25 @@ import SwiftUI
33

44
@MainActor
55
@Observable public class TimelineContentFilter {
6+
public struct Snapshot: Sendable {
7+
public let showBoosts: Bool
8+
public let showReplies: Bool
9+
public let showThreads: Bool
10+
public let showQuotePosts: Bool
11+
12+
public init(
13+
showBoosts: Bool,
14+
showReplies: Bool,
15+
showThreads: Bool,
16+
showQuotePosts: Bool
17+
) {
18+
self.showBoosts = showBoosts
19+
self.showReplies = showReplies
20+
self.showThreads = showThreads
21+
self.showQuotePosts = showQuotePosts
22+
}
23+
}
24+
625
class Storage {
726
@AppStorage("timeline_show_boosts") var showBoosts: Bool = true
827
@AppStorage("timeline_show_replies") var showReplies: Bool = true
@@ -43,4 +62,13 @@ import SwiftUI
4362
showThreads = storage.showThreads
4463
showQuotePosts = storage.showQuotePosts
4564
}
65+
66+
public func snapshot() -> Snapshot {
67+
Snapshot(
68+
showBoosts: showBoosts,
69+
showReplies: showReplies,
70+
showThreads: showThreads,
71+
showQuotePosts: showQuotePosts
72+
)
73+
}
4674
}

Packages/Timeline/Sources/Timeline/actors/TimelineDatasource.swift

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,11 @@ actor TimelineDatasource {
2424

2525
func getFiltered() async -> [Status] {
2626
let contentFilter = await TimelineContentFilter.shared
27+
let snapshot = await contentFilter.snapshot()
2728
var filtered: [Status] = []
2829
for item in items {
2930
guard case .status(let status) = item else { continue }
30-
if await shouldShowStatus(status, filter: contentFilter) {
31+
if shouldShowStatus(status, filter: snapshot) {
3132
filtered.append(status)
3233
}
3334
}
@@ -36,20 +37,32 @@ actor TimelineDatasource {
3637

3738
func getFilteredItems() async -> [TimelineItem] {
3839
let contentFilter = await TimelineContentFilter.shared
40+
let snapshot = await contentFilter.snapshot()
3941
var filtered: [TimelineItem] = []
4042
for item in items {
4143
switch item {
4244
case .gap:
4345
filtered.append(item)
4446
case .status(let status):
45-
if await shouldShowStatus(status, filter: contentFilter) {
47+
if shouldShowStatus(status, filter: snapshot) {
4648
filtered.append(item)
4749
}
4850
}
4951
}
5052
return filtered
5153
}
5254

55+
func getFiltered(using snapshot: TimelineContentFilter.Snapshot) -> [Status] {
56+
var filtered: [Status] = []
57+
for item in items {
58+
guard case .status(let status) = item else { continue }
59+
if shouldShowStatus(status, filter: snapshot) {
60+
filtered.append(status)
61+
}
62+
}
63+
return filtered
64+
}
65+
5366
func count() -> Int {
5467
items.count
5568
}
@@ -155,11 +168,11 @@ actor TimelineDatasource {
155168

156169
// MARK: - Private Helpers
157170

158-
private func shouldShowStatus(_ status: Status, filter: TimelineContentFilter) async -> Bool {
159-
let showReplies = await filter.showReplies
160-
let showBoosts = await filter.showBoosts
161-
let showThreads = await filter.showThreads
162-
let showQuotePosts = await filter.showQuotePosts
171+
private func shouldShowStatus(_ status: Status, filter: TimelineContentFilter.Snapshot) -> Bool {
172+
let showReplies = filter.showReplies
173+
let showBoosts = filter.showBoosts
174+
let showThreads = filter.showThreads
175+
let showQuotePosts = filter.showQuotePosts
163176
let hasQuote = status.quote?.quotedStatusId != nil
164177
|| status.quote?.quotedStatus != nil
165178
|| status.reblog?.quote?.quotedStatusId != nil

Packages/Timeline/Tests/TimelineTests/TimelineViewModelTests.swift

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,6 @@ struct Tests {
136136

137137
@Test
138138
func hideQuotePostsFiltersLegacyAndNativeQuotes() async throws {
139-
let contentFilter = TimelineContentFilter.shared
140-
contentFilter.showBoosts = true
141-
contentFilter.showReplies = true
142-
contentFilter.showThreads = true
143-
contentFilter.showQuotePosts = false
144-
145139
let normalStatus = makeStatus(id: "normal", hidden: false)
146140
let legacyQuoteStatus = makeStatus(
147141
id: "legacy-quote",
@@ -157,7 +151,13 @@ struct Tests {
157151
let datasource = TimelineDatasource()
158152
await datasource.set([normalStatus, legacyQuoteStatus, nativeQuoteStatus])
159153

160-
let filtered = await datasource.getFiltered()
154+
let snapshot = TimelineContentFilter.Snapshot(
155+
showBoosts: true,
156+
showReplies: true,
157+
showThreads: true,
158+
showQuotePosts: false
159+
)
160+
let filtered = await datasource.getFiltered(using: snapshot)
161161
#expect(filtered.map(\.id) == ["normal"])
162162
}
163163
}

0 commit comments

Comments
 (0)