SelectMemberViewController.swift 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. //
  2. // SelectMemberViewController.swift
  3. // TUIRoomKit
  4. //
  5. // Created by CY zhao on 2024/6/18.
  6. //
  7. import Foundation
  8. import UIKit
  9. import Combine
  10. import RTCRoomEngine
  11. import Factory
  12. class SelectMemberViewController: UIViewController, ContactViewProtocol {
  13. @Injected(\.selectMemberStore) var selectMemberStore: SelectMemberStore
  14. weak var delegate: ContactViewSelectDelegate?
  15. private var cancellableSet = Set<AnyCancellable>()
  16. init(participants: ConferenceParticipants) {
  17. super.init(nibName: nil, bundle: nil)
  18. selectMemberStore.setSelectedMembers(participants.selectedList)
  19. selectMemberStore.setLockSelectionMembers(participants.unSelectableList)
  20. }
  21. required init?(coder: NSCoder) {
  22. fatalError("init(coder:) has not been implemented")
  23. }
  24. func setDelegate(_ selector: ContactViewSelectDelegate) {
  25. self.delegate = selector
  26. }
  27. override func loadView() {
  28. let rootView = SelectMemberView()
  29. rootView.backgroundColor = .white
  30. rootView.delegate = self
  31. view = rootView
  32. }
  33. override func viewWillAppear(_ animated: Bool) {
  34. super.viewWillAppear(animated)
  35. self.navigationController?.setNavigationBarHidden(true, animated: animated)
  36. }
  37. override func viewDidLoad() {
  38. super.viewDidLoad()
  39. bindInteraction()
  40. }
  41. override func viewWillDisappear(_ animated: Bool) {
  42. super.viewWillDisappear(animated)
  43. self.navigationController?.setNavigationBarHidden(false, animated: animated)
  44. }
  45. func bindInteraction() {
  46. guard let selectMembersView = view as? SelectMemberView else {
  47. return
  48. }
  49. selectMembersView.tableView.delegate = self
  50. selectMembersView.tableView.dataSource = self
  51. selectMembersView.selectedUserView.delegate = self
  52. selectMembersView.selectedUserView.dataSource = self
  53. selectMemberStore.subscribe(Selector(keyPath: \SelectMemberState.selectedMembers))
  54. .receive(on: DispatchQueue.main)
  55. .sink { [weak self] selectedMembers in
  56. self?.updateSelectedView(with: selectedMembers)
  57. }
  58. .store(in: &cancellableSet)
  59. selectMemberStore.subscribe(Selector(keyPath: \SelectMemberState.members))
  60. .receive(on: DispatchQueue.main)
  61. .sink { _ in
  62. selectMembersView.tableView.reloadData()
  63. }
  64. .store(in: &cancellableSet)
  65. }
  66. private func updateSelectedView(with members: [User]) {
  67. guard let selectMembersView = view as? SelectMemberView else {
  68. return
  69. }
  70. selectMembersView.updateSelectedView(with: members.count)
  71. selectMembersView.updateConfirmButton(with: members.count)
  72. }
  73. }
  74. extension SelectMemberViewController: UITableViewDelegate {
  75. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  76. return 52
  77. }
  78. func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
  79. let headerView = UIView()
  80. headerView.backgroundColor = UIColor.white
  81. let headerLabel = UILabel()
  82. headerLabel.font = UIFont(name: "PingFangSC-Regular", size: 14)
  83. headerLabel.textColor = UIColor.tui_color(withHex: "#22262E")
  84. let count = selectMemberStore.getAllMembersCount()
  85. headerLabel.text = .allMemberText + "(" + "\(count)" + ")"
  86. headerView.addSubview(headerLabel)
  87. headerLabel.snp.makeConstraints { make in
  88. make.leading.equalToSuperview().offset(19)
  89. make.top.equalToSuperview()
  90. }
  91. return headerView
  92. }
  93. func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
  94. return 38
  95. }
  96. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  97. let member = selectMemberStore.selectMemberState.members[indexPath.row]
  98. if selectMemberStore.selectMemberState.selectedMembers.contains(where: { $0.userId == member.userId }) {
  99. selectMemberStore.deleteSelectedMember(member.userId)
  100. } else {
  101. selectMemberStore.addSelectedMember(member)
  102. }
  103. tableView.reloadRows(at: [indexPath], with: .none)
  104. }
  105. }
  106. extension SelectMemberViewController: UITableViewDataSource {
  107. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  108. return selectMemberStore.selectMemberState.members.count
  109. }
  110. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  111. guard let cell = tableView.dequeueReusableCell(withIdentifier: ContactCell.reuseIdentifier, for: indexPath)
  112. as? ContactCell else {
  113. return UITableViewCell()
  114. }
  115. let member = selectMemberStore.selectMemberState.members[indexPath.row]
  116. let isSelected = selectMemberStore.selectMemberState.selectedMembers.contains(where: { $0.userId == member.userId})
  117. let isDisabled = selectMemberStore.isLockSelection(userId: member.userId)
  118. cell.setupViewState(with: member, isSelected: isSelected, isDisaled: isDisabled)
  119. cell.isUserInteractionEnabled = !isDisabled
  120. return cell
  121. }
  122. }
  123. extension SelectMemberViewController: SelectMemberViewDelegate {
  124. func selectView(_ selectView: SelectMemberView, didSearchWith searchText: String) {
  125. selectMemberStore.filterMembers(with: searchText)
  126. }
  127. func didExpandButtonClicked(in selectView: SelectMemberView) {
  128. let listView = SelectedMembersViewController()
  129. listView.selectedMember = selectMemberStore.selectMemberState.selectedMembers.map{ $0.userInfo }
  130. listView.didDeselectMember = { [weak self] member in
  131. guard let self = self else {return}
  132. self.selectMemberStore.deleteSelectedMember(member.userId)
  133. let members = self.selectMemberStore.selectMemberState.members
  134. if let index = members.firstIndex(where: { $0.userId == member.userId }) {
  135. let indexPath = IndexPath(row: index, section: 0)
  136. selectView.tableView.reloadRows(at: [indexPath], with: .none)
  137. }
  138. }
  139. listView.modalPresentationStyle = .overCurrentContext
  140. present(listView, animated: true, completion: nil)
  141. }
  142. func didConfirmButtonClicked(in selectView: SelectMemberView) {
  143. delegate?.onMemberSelected(self, invitees: selectMemberStore.selectMemberState.selectedMembers)
  144. }
  145. func didBackButtonClicked(in selectView: SelectMemberView) {
  146. navigationController?.popViewController(animated: true)
  147. }
  148. }
  149. extension SelectMemberViewController: UICollectionViewDelegate {
  150. }
  151. extension SelectMemberViewController: UICollectionViewDataSource {
  152. func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
  153. return selectMemberStore.selectMemberState.selectedMembers.count
  154. }
  155. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
  156. guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AvatarCell.reuseIdentifier, for: indexPath)
  157. as? AvatarCell else {
  158. return UICollectionViewCell()
  159. }
  160. let member = selectMemberStore.selectMemberState.selectedMembers[indexPath.item]
  161. cell.setupViewState(with: member)
  162. return cell
  163. }
  164. }
  165. private extension String {
  166. static let allMemberText = localized("All members")
  167. }