1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
import Foundation
@Observable
@MainActor
final class StoryStripViewModel {
var authors: [GrainStoryAuthor] = []
var isLoading = false
/// Bumped to trigger re-render without changing author order.
var version: Int = 0
private let client: XRPCClient
init(client: XRPCClient) {
self.client = client
}
func load(
auth: AuthContext? = nil,
storyStatusCache: StoryStatusCache? = nil,
viewedStories: ViewedStoryStorage? = nil
) async {
isLoading = true
do {
let response = try await client.getStoryAuthors(auth: auth)
authors = response.authors.filter { $0.storyCount > 0 }
storyStatusCache?.update(from: response.authors)
// What was watched on another device arrives with the list.
viewedStories?.absorb(authors: response.authors)
} catch {
// Silently fail — strip just won't show
}
isLoading = false
}
/// Signal that viewed state changed so views re-evaluate sort order.
func invalidate() {
version += 1
}
}