-
Notifications
You must be signed in to change notification settings - Fork 895
/
Copy pathCallStatusView.swift
123 lines (106 loc) · 3.85 KB
/
CallStatusView.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
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
//
// CallStatusView.swift
// Telegram
//
// Created by Mikhail Filimonov on 13/08/2020.
// Copyright © 2020 Telegram. All rights reserved.
//
import Cocoa
import TGUIKit
import SwiftSignalKit
enum CallControllerStatusValue: Equatable {
case text(String, Int32?)
case timer(Double, Int32?)
case startsIn(Int)
var hasTimer: Bool {
switch self {
case .timer, .startsIn:
return true
default:
return false
}
}
}
class CallStatusView: View {
private var statusTimer: SwiftSignalKit.Timer?
var status: CallControllerStatusValue = .text("", nil) {
didSet {
if self.status != oldValue {
self.statusTimer?.invalidate()
if case .timer = self.status {
self.statusTimer = SwiftSignalKit.Timer(timeout: 0.5, repeat: true, completion: { [weak self] in
self?.updateStatus()
}, queue: Queue.mainQueue())
self.statusTimer?.start()
self.updateStatus()
} else {
self.updateStatus()
}
}
}
}
private let statusTextView:TextView = TextView()
private let receptionView = CallReceptionControl(frame: NSMakeRect(0, 0, 24, 10))
required init(frame frameRect: NSRect) {
super.init(frame: frameRect)
statusTextView.userInteractionEnabled = false
statusTextView.isSelectable = false
statusTextView.disableBackgroundDrawing = true
addSubview(statusTextView)
addSubview(receptionView)
}
override func layout() {
super.layout()
if receptionView.isHidden {
statusTextView.center()
} else {
receptionView.centerY(x: 0)
statusTextView.centerY(x: receptionView.frame.maxX)
}
}
func sizeThatFits(_ size: NSSize) -> NSSize {
if let layout = self.statusTextView.textLayout {
layout.measure(width: size.width)
statusTextView.update(layout)
return NSMakeSize(max(layout.layoutSize.width, 60) + 28, size.height)
}
return size
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
deinit {
statusTimer?.invalidate()
}
func updateStatus() {
var statusText: String = ""
switch self.status {
case let .text(text, reception):
statusText = text
if let reception = reception {
self.receptionView.reception = reception
}
self.receptionView.isHidden = reception == nil
case let .timer(referenceTime, reception):
let duration = Int32(CFAbsoluteTimeGetCurrent() - referenceTime)
let durationString: String
if duration > 60 * 60 {
durationString = String(format: "%02d:%02d:%02d", arguments: [duration / 3600, (duration / 60) % 60, duration % 60])
} else {
durationString = String(format: "%02d:%02d", arguments: [(duration / 60) % 60, duration % 60])
}
statusText = durationString
if let reception = reception {
self.receptionView.reception = reception
}
self.receptionView.isHidden = reception == nil
case let .startsIn(time):
statusText = strings().chatHeaderVoiceChatStartsIn(timerText(time - Int(Date().timeIntervalSince1970)))
self.receptionView.isHidden = true
}
let layout = TextViewLayout.init(.initialize(string: statusText, color: .white, font: .normal(18)), alignment: .center)
layout.measure(width: .greatestFiniteMagnitude)
self.statusTextView.update(layout)
needsLayout = true
}
}