FloatChatButton.swift 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. //
  2. // FloatChatButton.swift
  3. // TUIRoomKit
  4. //
  5. // Created by CY zhao on 2024/5/9.
  6. // Copyright © 2024 Tencent. All rights reserved.
  7. //
  8. import UIKit
  9. import Foundation
  10. #if USE_OPENCOMBINE
  11. import OpenCombine
  12. import OpenCombineDispatch
  13. #else
  14. import Combine
  15. #endif
  16. import Factory
  17. class FloatChatButton: UIView {
  18. @Injected(\.floatChatService) private var store: FloatChatStoreProvider
  19. private lazy var floatInputViewShowState = self.store.select(FloatChatSelectors.getShowFloatInputView)
  20. var cancellableSet = Set<AnyCancellable>()
  21. weak var inputController: UIViewController?
  22. var roomId = ""
  23. private let emojiLabelSpacing: CGFloat = 6
  24. private let horizonSpacing: CGFloat = 10
  25. func updateRoomId(roomId: String) {
  26. self.roomId = roomId
  27. store.dispatch(action: FloatChatActions.setRoomId(payload: roomId))
  28. }
  29. private let emojiView: UIImageView = {
  30. let emojiImage = UIImage(named: "room_emoji_icon", in: tuiRoomKitBundle(), compatibleWith: nil)
  31. let imageView = UIImageView(image: emojiImage)
  32. return imageView
  33. }()
  34. private let label: UILabel = {
  35. let view = UILabel()
  36. view.backgroundColor = .clear
  37. view.textColor = UIColor.tui_color(withHex: "D5E0F2")
  38. view.font = UIFont(name: "PingFangSC-Regular", size: 12)
  39. view.text = .placeHolderText
  40. view.sizeToFit()
  41. return view
  42. }()
  43. private let clickView: UIView = {
  44. let view = UIView()
  45. view.backgroundColor = .clear
  46. view.isUserInteractionEnabled = true
  47. return view
  48. }()
  49. private var isViewReady = false
  50. override func didMoveToWindow() {
  51. super.didMoveToWindow()
  52. guard !isViewReady else { return }
  53. constructViewHierarchy()
  54. activateConstraints()
  55. bindInteraction()
  56. isViewReady = true
  57. }
  58. private func constructViewHierarchy() {
  59. backgroundColor = UIColor.tui_color(withHex: "22262E80", alpha: 0.5)
  60. layer.cornerRadius = 15
  61. addSubview(emojiView)
  62. addSubview(label)
  63. addSubview(clickView)
  64. }
  65. private func activateConstraints() {
  66. emojiView.snp.makeConstraints { make in
  67. make.leading.equalToSuperview().offset(horizonSpacing)
  68. make.centerY.equalToSuperview()
  69. make.width.equalTo(24)
  70. make.height.equalTo(24)
  71. }
  72. label.snp.makeConstraints { make in
  73. make.leading.equalTo(emojiView.snp.trailing).offset(emojiLabelSpacing)
  74. make.centerY.equalToSuperview()
  75. make.trailing.equalToSuperview().offset(-horizonSpacing)
  76. make.height.equalTo(24)
  77. }
  78. clickView.snp.makeConstraints { make in
  79. make.edges.equalToSuperview()
  80. }
  81. }
  82. private func bindInteraction() {
  83. let tap = UITapGestureRecognizer(target: self, action: #selector(showInputView))
  84. clickView.addGestureRecognizer(tap)
  85. floatInputViewShowState
  86. .receive(on: DispatchQueue.mainQueue)
  87. .sink { [weak self] showFloatChatInput in
  88. guard let self = self else { return }
  89. if showFloatChatInput {
  90. let inputController = FloatChatInputController()
  91. inputController.view.backgroundColor = .clear
  92. let navController = UINavigationController(rootViewController: inputController)
  93. navController.isNavigationBarHidden = true
  94. navController.navigationBar.prefersLargeTitles = true
  95. navController.modalPresentationStyle = .overFullScreen
  96. RoomCommon.getCurrentWindowViewController()?.present(navController, animated: true, completion: nil)
  97. self.inputController = inputController
  98. } else {
  99. self.inputController?.dismiss(animated: true)
  100. }
  101. }
  102. .store(in: &cancellableSet)
  103. }
  104. @objc private func showInputView() {
  105. store.dispatch(action: FloatViewActions.showFloatInputView(payload: true))
  106. }
  107. }
  108. private extension String {
  109. static var placeHolderText: String {
  110. localized("Say something")
  111. }
  112. }