Antidote/Antidote/ChatTypingHeaderView.swift
2024-02-22 21:43:11 +02:00

102 lines
2.9 KiB
Swift

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
import Foundation
import SnapKit
fileprivate struct Constants {
static let verticalOffset = 7.0
static let horizontalOffset = 20.0
static let animationStepDuration = 0.7
}
class ChatTypingHeaderView: UIView {
fileprivate let theme: Theme
fileprivate var bubbleView: BubbleView!
fileprivate var label: UILabel!
fileprivate var animationTimer: Timer?
fileprivate var animationStep: Int = 0
init(theme: Theme) {
self.theme = theme
super.init(frame: CGRect.zero)
createViews()
installConstraints()
}
required convenience init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func startAnimation() {
animationTimer = Timer.scheduledTimer(timeInterval: Constants.animationStepDuration, closure: {[weak self] _ -> Void in
guard let sself = self else {
return
}
sself.animationStep += 1
if sself.animationStep > 2 {
sself.animationStep = 0
}
sself.updateDotsString()
}, repeats: true)
}
func stopAnimation() {
animationTimer?.invalidate()
animationTimer = nil
}
}
private extension ChatTypingHeaderView {
func createViews() {
bubbleView = BubbleView()
bubbleView.text = " "
bubbleView.backgroundColor = theme.colorForType(.ChatIncomingBubble)
bubbleView.isUserInteractionEnabled = false
addSubview(bubbleView)
label = UILabel()
addSubview(label)
updateDotsString()
}
func installConstraints() {
bubbleView.snp.makeConstraints() {
$0.top.equalTo(self).offset(Constants.verticalOffset)
$0.bottom.equalTo(self).offset(-Constants.verticalOffset)
$0.leading.equalTo(self).offset(Constants.horizontalOffset)
}
label.snp.makeConstraints() {
$0.center.equalTo(bubbleView)
}
}
func updateDotsString() {
let mutable = NSMutableAttributedString()
let font = UIFont.systemFont(ofSize: 22.0)
let colorNormal = theme.colorForType(.ChatInformationText)
let colorSelected = colorNormal.darkerColor().darkerColor()
for i in 0..<3 {
let color = (i == animationStep) ? colorSelected : colorNormal
// HINT: u{2022} --> UTF-8 BULLET --> e2 80 a2
mutable.append(NSMutableAttributedString(string: "\u{2022}",
attributes: [NSAttributedStringKey.font : font,
NSAttributedStringKey.foregroundColor: color]))
}
label.attributedText = mutable
}
}