-
-
Notifications
You must be signed in to change notification settings - Fork 118
/
Copy pathSyncNavBarButton.swift
77 lines (65 loc) · 2.27 KB
/
SyncNavBarButton.swift
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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
//
// SyncNavBarButton.swift
// Strongbox
//
// Created by Strongbox on 02/08/2024.
// Copyright © 2024 Mark McGuill. All rights reserved.
//
import SwiftUI
struct SyncNavBarButton: View {
@State private var isAnimating = false
@State private var isError = false
var show: Bool {
if let syncStatus = model.syncStatus, syncStatus.state == .inProgress || syncStatus.state == .error {
return true
}
if model.isRunningAsyncUpdate {
return true
}
if let result = model.lastAsyncUpdateResult, !result.success {
return true
}
return false
}
var foreverAnimation: Animation {
Animation.linear(duration: 1.0)
.repeatForever(autoreverses: false)
}
@ObservedObject
var model: DatabaseHomeViewModel
func updateState() {
isAnimating = model.syncStatus?.state == .some(.inProgress) || model.isRunningAsyncUpdate
isError = model.syncStatus?.state == .some(.error) || !(model.lastAsyncUpdateResult?.success ?? true)
}
var body: some View {
Button(action: {}, label: {
if show {
Image(systemName: "arrow.triangle.2.circlepath")
.font(.caption)
.foregroundColor(isError ? .red : .blue)
.rotationEffect(Angle(degrees: isAnimating ? 360 : 0.0))
.animation(isAnimating ? foreverAnimation : .default, value: isAnimating)
}
})
.onAppear {
updateState()
}
.onReceive(NotificationCenter.default.publisher(for: .asyncUpdateDone, object: nil)) { _ in
updateState()
}
.onReceive(NotificationCenter.default.publisher(for: .asyncUpdateDone, object: nil)) { _ in
updateState()
}
.onReceive(NotificationCenter.default.publisher(for: .syncManagerDatabaseSyncStatusChanged, object: nil)) { _ in
updateState()
}
}
}
#Preview {
let model = DatabaseHomeViewModel(externalWorldAdaptor: DummyDatabaseActionsInterface(isRunningAsyncUpdate: true))
return NavigationView {
Text("Test")
.navigationTitle("Testing")
.navigationBarItems(leading: SyncNavBarButton(model: model))
}
}