rastrillo / native Public

Clone
git clone https://amadan.net/rastrillo/native

Plain git — no account needed to clone.

Download

Download this file

1import RastrilloNative
2import SwiftUI
3
4/// A compact save status for a toolbar or title bar. Silent when saved, but
5/// the accessibility element stays present while silent, so the first
6/// failure is announced from a region that already exists (estilo
7/// savestatus). Entering offline, needs-sign-in and failed is announced; a
8/// saving flicker never is.
9public struct NativeSyncStatusView: View {
10 private let status: SyncStatus
11 private let strings: NativeSyncStrings
12
13 public init(status: SyncStatus, strings: NativeSyncStrings = .kit) {
14 self.status = status
15 self.strings = strings
16 }
17
18 public var body: some View {
19 let text = strings.text(for: status) ?? ""
20 Text(text)
21 .font(.callout)
22 .fontWeight(status.saveState == .failed ? .semibold : .regular)
23 .foregroundStyle(status.saveState == .failed ? AnyShapeStyle(.red) : AnyShapeStyle(.secondary))
24 .lineLimit(2)
25 .frame(minWidth: 8)
26 .accessibilityElement(children: .ignore)
27 .accessibilityLabel(text)
28 .accessibilityAddTraits(.updatesFrequently)
29 .onChange(of: status) { old, new in
30 guard new.isAnnounced, !Self.sameKind(old, new), let text = strings.text(for: new) else { return }
31 AccessibilityNotification.Announcement(text).post()
32 }
33 }
34
35 /// A count changing inside the same state is not news.
36 static func sameKind(_ a: SyncStatus, _ b: SyncStatus) -> Bool {
37 switch (a, b) {
38 case (.offline, .offline), (.needsSignIn, .needsSignIn), (.retrying, .retrying): return true
39 case (.failed(_, let x), .failed(_, let y)): return x == y
40 default: return a == b
41 }
42 }
43}
44