-
Notifications
You must be signed in to change notification settings - Fork 566
Expand file tree
/
Copy pathNotificationInstance.swift
More file actions
154 lines (129 loc) · 3.87 KB
/
NotificationInstance.swift
File metadata and controls
154 lines (129 loc) · 3.87 KB
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
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import Cocoa
class NotificationInstance {
let payload: NotificationPayload
let panel: NSPanel
let clickableView: ClickableView
let creationIndex: Int
private var timeoutSeconds: Double = 0
var key: String { payload.key }
var isExpanded: Bool = false
var isAnimating: Bool = false
var compactContentView: NSView?
var expandedContentView: NSView?
var countdownTimer: Timer?
var meetingStartTime: Date?
var compactTimerLabel: NSTextField?
var expandedTimerLabel: NSTextField?
weak var progressBar: NotificationBackgroundView? {
didSet {
progressBar?.onProgressComplete = { [weak self] in
self?.dismissWithTimeout()
}
}
}
init(
payload: NotificationPayload, panel: NSPanel, clickableView: ClickableView, creationIndex: Int
) {
self.payload = payload
self.panel = panel
self.clickableView = clickableView
self.creationIndex = creationIndex
if let startTime = payload.startTime, startTime > 0 {
self.meetingStartTime = Date(timeIntervalSince1970: TimeInterval(startTime))
}
}
func toggleExpansion() {
guard !isAnimating else { return }
isAnimating = true
isExpanded.toggle()
NotificationManager.shared.animateExpansion(notification: self, isExpanded: isExpanded)
}
func stopCountdown() {
countdownTimer?.invalidate()
countdownTimer = nil
}
func setCompactCountdownLabel(_ label: NSTextField) {
compactTimerLabel = label
startCountdownIfNeeded()
updateCountdown()
}
func setExpandedCountdownLabel(_ label: NSTextField) {
expandedTimerLabel = label
startCountdownIfNeeded()
updateCountdown()
}
func clearExpandedCountdownLabel() {
expandedTimerLabel = nil
}
private func startCountdownIfNeeded() {
guard meetingStartTime != nil else {
stopCountdown()
return
}
guard countdownTimer == nil else { return }
countdownTimer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { [weak self] _ in
self?.updateCountdown()
}
}
private func updateCountdown() {
guard let startTime = meetingStartTime else { return }
let remaining = startTime.timeIntervalSinceNow
if remaining <= 0 {
compactTimerLabel?.stringValue = "Started"
expandedTimerLabel?.stringValue = "Started"
countdownTimer?.invalidate()
countdownTimer = nil
if isExpanded {
RustBridge.onExpandedStartTimeReached(key: key)
dismiss()
}
} else {
let minutes = Int(remaining) / 60
let seconds = Int(remaining) % 60
let countdownText = "Begins in \(minutes):\(String(format: "%02d", seconds))"
compactTimerLabel?.stringValue = countdownText
expandedTimerLabel?.stringValue = countdownText
}
}
func startDismissTimer(timeoutSeconds: Double) {
self.timeoutSeconds = timeoutSeconds
progressBar?.startProgress(duration: timeoutSeconds)
}
func pauseDismissTimer() {
progressBar?.pauseProgress()
}
func resumeDismissTimer() {
progressBar?.resumeProgress()
}
func restartDismissTimer() {
guard timeoutSeconds > 0 else { return }
progressBar?.startProgress(duration: timeoutSeconds)
}
func dismiss() {
progressBar?.onProgressComplete = nil
progressBar?.resetProgress()
stopCountdown()
compactTimerLabel = nil
expandedTimerLabel = nil
NSAnimationContext.runAnimationGroup({ context in
context.duration = Timing.dismiss
context.timingFunction = CAMediaTimingFunction(name: .easeIn)
self.panel.animator().alphaValue = 0
}) {
self.panel.close()
NotificationManager.shared.removeNotification(self)
}
}
func dismissWithUserAction() {
RustBridge.onDismiss(key: key)
dismiss()
}
func dismissWithTimeout() {
RustBridge.onCollapsedTimeout(key: key)
dismiss()
}
deinit {
progressBar?.onProgressComplete = nil
countdownTimer?.invalidate()
}
}