session-ios/Session/Components/FakeChatView.swift

127 lines
6.0 KiB
Swift
Raw Normal View History

2019-12-06 04:42:43 +01:00
final class FakeChatView : UIView {
private let spacing = Values.mediumSpacing
2019-12-09 01:50:45 +01:00
var contentOffset: CGPoint {
get { return scrollView.contentOffset }
set { scrollView.contentOffset = newValue }
}
2019-12-06 04:42:43 +01:00
private lazy var chatBubbles = [
getChatBubble(withText: NSLocalizedString("view_fake_chat_bubble_1", comment: ""), wasSentByCurrentUser: true),
getChatBubble(withText: NSLocalizedString("view_fake_chat_bubble_2", comment: ""), wasSentByCurrentUser: false),
getChatBubble(withText: NSLocalizedString("view_fake_chat_bubble_3", comment: ""), wasSentByCurrentUser: true),
getChatBubble(withText: NSLocalizedString("view_fake_chat_bubble_4", comment: ""), wasSentByCurrentUser: false),
getChatBubble(withText: NSLocalizedString("view_fake_chat_bubble_5", comment: ""), wasSentByCurrentUser: false)
2019-12-06 04:42:43 +01:00
]
private lazy var scrollView: UIScrollView = {
let result = UIScrollView()
2019-12-09 00:01:10 +01:00
result.showsHorizontalScrollIndicator = false
2019-12-06 04:42:43 +01:00
result.showsVerticalScrollIndicator = false
return result
}()
override init(frame: CGRect) {
super.init(frame: frame)
setUpViewHierarchy()
animate()
}
required init?(coder: NSCoder) {
super.init(coder: coder)
setUpViewHierarchy()
animate()
}
private func setUpViewHierarchy() {
let stackView = UIStackView(arrangedSubviews: chatBubbles)
stackView.axis = .vertical
stackView.spacing = spacing
stackView.alignment = .fill
stackView.set(.width, to: UIScreen.main.bounds.width)
stackView.layoutMargins = UIEdgeInsets(top: 8, leading: Values.veryLargeSpacing, bottom: 8, trailing: Values.veryLargeSpacing)
stackView.isLayoutMarginsRelativeArrangement = true
scrollView.addSubview(stackView)
stackView.pin(to: scrollView)
addSubview(scrollView)
scrollView.pin(to: self)
}
private func getChatBubble(withText text: String, wasSentByCurrentUser: Bool) -> UIView {
let result = UIView()
let bubbleView = UIView()
bubbleView.set(.width, to: Values.fakeChatBubbleWidth)
bubbleView.layer.cornerRadius = Values.fakeChatBubbleCornerRadius
2019-12-06 06:42:28 +01:00
bubbleView.layer.shadowColor = UIColor.black.cgColor
2020-09-09 03:24:39 +02:00
bubbleView.layer.shadowRadius = isLightMode ? 4 : 8
bubbleView.layer.shadowOpacity = isLightMode ? 0.16 : 0.24
2020-02-17 02:08:46 +01:00
bubbleView.layer.shadowOffset = CGSize.zero
2019-12-13 05:02:05 +01:00
let backgroundColor = wasSentByCurrentUser ? Colors.fakeChatBubbleBackground : Colors.accent
2019-12-06 04:42:43 +01:00
bubbleView.backgroundColor = backgroundColor
let label = UILabel()
2019-12-13 05:02:05 +01:00
let textColor = wasSentByCurrentUser ? Colors.text : Colors.fakeChatBubbleText
2019-12-06 04:42:43 +01:00
label.textColor = textColor
label.font = .boldSystemFont(ofSize: Values.mediumFontSize)
label.numberOfLines = 0
label.lineBreakMode = .byWordWrapping
label.text = text
bubbleView.addSubview(label)
2019-12-06 06:42:28 +01:00
label.pin(to: bubbleView, withInset: 12)
2019-12-06 04:42:43 +01:00
result.addSubview(bubbleView)
bubbleView.pin(.top, to: .top, of: result)
result.pin(.bottom, to: .bottom, of: bubbleView)
if wasSentByCurrentUser {
2019-12-13 05:02:05 +01:00
bubbleView.pin(.trailing, to: .trailing, of: result)
2019-12-06 04:42:43 +01:00
} else {
2019-12-13 05:02:05 +01:00
result.pin(.leading, to: .leading, of: bubbleView)
2019-12-06 04:42:43 +01:00
}
return result
}
private func animate() {
let animationDuration = Values.fakeChatAnimationDuration
let delayBetweenMessages = Values.fakeChatDelay
chatBubbles.forEach { $0.alpha = 0 }
Timer.scheduledTimer(withTimeInterval: Values.fakeChatStartDelay, repeats: false) { [weak self] _ in
self?.showChatBubble(at: 0)
2019-12-13 05:02:05 +01:00
Timer.scheduledTimer(withTimeInterval: 1.5 * delayBetweenMessages, repeats: false) { _ in
2019-12-06 04:42:43 +01:00
self?.showChatBubble(at: 1)
2019-12-09 00:01:10 +01:00
Timer.scheduledTimer(withTimeInterval: 1.5 * delayBetweenMessages, repeats: false) { _ in
2019-12-06 04:42:43 +01:00
self?.showChatBubble(at: 2)
UIView.animate(withDuration: animationDuration) {
guard let self = self else { return }
self.scrollView.contentOffset = CGPoint(x: 0, y: self.chatBubbles[0].height() + self.spacing)
}
2019-12-13 05:02:05 +01:00
Timer.scheduledTimer(withTimeInterval: 1.5 * delayBetweenMessages, repeats: false) { _ in
2019-12-06 04:42:43 +01:00
self?.showChatBubble(at: 3)
UIView.animate(withDuration: animationDuration) {
guard let self = self else { return }
self.scrollView.contentOffset = CGPoint(x: 0, y: self.chatBubbles[0].height() + self.spacing + self.chatBubbles[1].height() + self.spacing)
}
2019-12-13 05:02:05 +01:00
Timer.scheduledTimer(withTimeInterval: delayBetweenMessages, repeats: false) { _ in
self?.showChatBubble(at: 4)
UIView.animate(withDuration: animationDuration) {
guard let self = self else { return }
self.scrollView.contentOffset = CGPoint(x: 0, y: self.chatBubbles[0].height() + self.spacing + self.chatBubbles[1].height() + self.spacing + self.chatBubbles[2].height() + self.spacing)
}
}
2019-12-06 04:42:43 +01:00
}
}
}
}
}
private func showChatBubble(at index: Int) {
let chatBubble = chatBubbles[index]
UIView.animate(withDuration: Values.fakeChatAnimationDuration) {
chatBubble.alpha = 1
}
let scale = Values.fakeChatMessagePopAnimationStartScale
chatBubble.transform = CGAffineTransform(scaleX: scale, y: scale)
UIView.animate(withDuration: Values.fakeChatAnimationDuration, delay: 0, usingSpringWithDamping: 0.68, initialSpringVelocity: 4, options: .curveEaseInOut, animations: {
chatBubble.transform = CGAffineTransform(scaleX: 1, y: 1)
}, completion: nil)
}
}