RaiseHandApplicationNotificationView.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //
  2. // RaiseHandApplicationNotificationView.swift
  3. // TUIRoomKit
  4. //
  5. // Created by janejntang on 2024/5/8.
  6. //
  7. import Foundation
  8. protocol RaiseHandApplicationNotificationViewListener: AnyObject {
  9. func onHidden()
  10. func onShown()
  11. }
  12. class RaiseHandApplicationNotificationView: UIView {
  13. let viewModel: RaiseHandApplicationNotificationViewModel
  14. weak var delegate: RaiseHandApplicationNotificationViewListener?
  15. private let imageView: UIImageView = {
  16. let image = UIImage(named: "room_raise_hand_notification", in: tuiRoomKitBundle(), compatibleWith: nil)
  17. return UIImageView(image: image)
  18. }()
  19. private let label: UILabel = {
  20. let label = UILabel()
  21. label.textAlignment = isRTL ? .right : .left
  22. label.font = UIFont.systemFont(ofSize: 14, weight: .regular)
  23. label.textColor = UIColor(0x181820)
  24. label.adjustsFontSizeToFitWidth = false
  25. return label
  26. }()
  27. private let checkButton: UIButton = {
  28. let button = UIButton()
  29. button.backgroundColor = .clear
  30. button.setTitle(.checkText, for: .normal)
  31. button.setTitleColor(UIColor(0x1C66E5), for: .normal)
  32. button.titleLabel?.font = UIFont.systemFont(ofSize: 14, weight: .medium)
  33. button.titleLabel?.textAlignment = .center
  34. return button
  35. }()
  36. init(viewModel: RaiseHandApplicationNotificationViewModel) {
  37. self.viewModel = viewModel
  38. super.init(frame: .zero)
  39. self.viewModel.responder = self
  40. }
  41. required init?(coder: NSCoder) {
  42. fatalError("init(coder:) has not been implemented")
  43. }
  44. // MARK: - view layout
  45. private var isViewReady: Bool = false
  46. override func didMoveToWindow() {
  47. super.didMoveToWindow()
  48. guard !isViewReady else { return }
  49. constructViewHierarchy()
  50. activateConstraints()
  51. bindInteraction()
  52. isViewReady = true
  53. }
  54. func constructViewHierarchy() {
  55. addSubview(imageView)
  56. addSubview(label)
  57. addSubview(checkButton)
  58. }
  59. func activateConstraints() {
  60. imageView.snp.makeConstraints { make in
  61. make.centerY.equalToSuperview()
  62. make.leading.equalToSuperview().offset(8.scale375Height())
  63. make.width.height.equalTo(24.scale375())
  64. }
  65. checkButton.snp.makeConstraints { make in
  66. make.centerY.equalToSuperview()
  67. make.trailing.equalToSuperview().offset(-6.scale375())
  68. make.height.equalTo(22.scale375Height())
  69. make.width.equalTo(48.scale375())
  70. }
  71. label.snp.makeConstraints { make in
  72. make.leading.equalTo(imageView.snp.trailing).offset(10.scale375())
  73. make.trailing.equalTo(checkButton.snp.leading).offset(-10.scale375())
  74. make.centerY.equalToSuperview()
  75. make.height.equalTo(22.scale375Height())
  76. }
  77. }
  78. func bindInteraction() {
  79. isHidden = true
  80. backgroundColor = UIColor(0xFFFFFF)
  81. layer.cornerRadius = 6
  82. checkButton.addTarget(self, action: #selector(checkAction(sender:)), for: .touchUpInside)
  83. guard viewModel.isShownRaiseHandApplicationNotificationView else { return }
  84. guard let userId = viewModel.userId, let userName = viewModel.userName, let count = viewModel.applicationCount else { return }
  85. show(userId: userId, userName: userName, count: count)
  86. }
  87. @objc private func checkAction(sender: UIButton) {
  88. hide()
  89. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(hide), object: nil)
  90. viewModel.checkRaiseHandApplicationAction()
  91. }
  92. func show(userId: String, userName: String, count: Int) {
  93. isHidden = false
  94. let nameText = userName ?? userId
  95. let title = count > 1 ?
  96. .multiApplyingOnStageText.replacingOccurrences(of: "xx", with: nameText).replacingOccurrences(of: "yy", with: String(count))
  97. : localizedReplace(.singleApplyingOnStageText, replace: nameText)
  98. label.text = title
  99. delegate?.onShown()
  100. NSObject.cancelPreviousPerformRequests(withTarget: self, selector: #selector(hide), object: nil)
  101. guard viewModel.delayDisappearanceTime > 0 else { return }
  102. perform(#selector(hide), with: nil, afterDelay: viewModel.delayDisappearanceTime)
  103. }
  104. @objc func hide() {
  105. isHidden = true
  106. delegate?.onHidden()
  107. }
  108. deinit {
  109. NSObject.cancelPreviousPerformRequests(withTarget: self)
  110. }
  111. }
  112. extension RaiseHandApplicationNotificationView: RaiseHandApplicationNotificationViewModelResponder {
  113. func showRaiseHandApplicationNotificationView(userId: String, userName: String, count: Int) {
  114. show(userId: userId, userName: userName, count: count)
  115. }
  116. func hideRaiseHandApplicationNotificationView() {
  117. hide()
  118. }
  119. }
  120. private extension String {
  121. static var checkText: String {
  122. localized("Check")
  123. }
  124. static var singleApplyingOnStageText: String {
  125. localized("xx is applying to be on stage.")
  126. }
  127. static var multiApplyingOnStageText: String {
  128. localized("Including xx, yy people are applying to be on stage.")
  129. }
  130. }