mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
107 lines
3.8 KiB
Swift
107 lines
3.8 KiB
Swift
3 years ago
|
import UIKit
|
||
|
|
||
|
final class ReactionListSheet : BaseVC {
|
||
|
private let reactions: [ReactMessage]
|
||
|
private var reactionMap: OrderedDictionary<String, [ReactMessage]> = OrderedDictionary()
|
||
|
|
||
|
// MARK: Components
|
||
|
|
||
|
lazy var contentView: UIView = {
|
||
|
let result = UIView()
|
||
|
result.layer.borderWidth = 0.5
|
||
|
result.layer.borderColor = Colors.border.withAlphaComponent(0.5).cgColor
|
||
|
result.backgroundColor = Colors.modalBackground
|
||
|
return result
|
||
|
}()
|
||
|
|
||
|
lazy var reactionContainer: UIStackView = {
|
||
|
let result = UIStackView()
|
||
|
let spacing = Values.smallSpacing
|
||
|
result.spacing = spacing
|
||
|
result.layoutMargins = UIEdgeInsets(top: spacing, leading: spacing, bottom: spacing, trailing: spacing)
|
||
|
result.isLayoutMarginsRelativeArrangement = true
|
||
|
return result
|
||
|
}()
|
||
|
|
||
|
// MARK: Lifecycle
|
||
|
|
||
|
init(for reactions: [ReactMessage]) {
|
||
|
self.reactions = reactions
|
||
|
super.init(nibName: nil, bundle: nil)
|
||
|
}
|
||
|
|
||
|
override init(nibName: String?, bundle: Bundle?) {
|
||
|
preconditionFailure("Use init(for:) instead.")
|
||
|
}
|
||
|
|
||
|
required init?(coder: NSCoder) {
|
||
|
preconditionFailure("Use init(for:) instead.")
|
||
|
}
|
||
|
|
||
|
override func viewDidLoad() {
|
||
|
super.viewDidLoad()
|
||
|
view.backgroundColor = .clear
|
||
|
let swipeGestureRecognizer = UISwipeGestureRecognizer(target: self, action: #selector(close))
|
||
|
swipeGestureRecognizer.direction = .down
|
||
|
view.addGestureRecognizer(swipeGestureRecognizer)
|
||
|
populateData()
|
||
|
setUpViewHierarchy()
|
||
|
}
|
||
|
|
||
|
private func setUpViewHierarchy() {
|
||
|
view.addSubview(contentView)
|
||
|
contentView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing, UIView.VerticalEdge.bottom ], to: view)
|
||
|
contentView.set(.height, to: 440)
|
||
|
populateContentView()
|
||
|
}
|
||
|
|
||
|
private func populateContentView() {
|
||
|
// Reactions container
|
||
|
let scrollableContainer = UIScrollView(wrapping: reactionContainer, withInsets: .zero)
|
||
|
scrollableContainer.showsVerticalScrollIndicator = false
|
||
|
scrollableContainer.showsHorizontalScrollIndicator = false
|
||
|
scrollableContainer.set(.height, to: 48)
|
||
|
for reaction in reactionMap.orderedItems {
|
||
|
let reactionView = ReactionButton(emoji: reaction.0, value: reaction.1.count, largeSize: true)
|
||
|
reactionContainer.addArrangedSubview(reactionView)
|
||
|
}
|
||
|
contentView.addSubview(scrollableContainer)
|
||
|
scrollableContainer.pin([ UIView.VerticalEdge.top, UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing ], to: contentView)
|
||
|
// Line
|
||
|
let lineView = UIView()
|
||
|
lineView.backgroundColor = Colors.border.withAlphaComponent(0.5)
|
||
|
lineView.set(.height, to: 0.5)
|
||
|
contentView.addSubview(lineView)
|
||
|
lineView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing ], to: contentView)
|
||
|
lineView.pin(.top, to: .bottom, of: scrollableContainer)
|
||
|
|
||
|
}
|
||
|
|
||
|
private func populateData() {
|
||
|
for reaction in reactions {
|
||
|
if let emoji = reaction.emoji {
|
||
|
if !reactionMap.hasValue(forKey: emoji) { reactionMap.append(key: emoji, value: []) }
|
||
|
var value = reactionMap.value(forKey: emoji)!
|
||
|
value.append(reaction)
|
||
|
reactionMap.replace(key: emoji, value: value)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// MARK: Interaction
|
||
|
|
||
|
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||
|
let touch = touches.first!
|
||
|
let location = touch.location(in: view)
|
||
|
if contentView.frame.contains(location) {
|
||
|
super.touchesBegan(touches, with: event)
|
||
|
} else {
|
||
|
close()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@objc func close() {
|
||
|
dismiss(animated: true, completion: nil)
|
||
|
}
|
||
|
}
|