ScheduleConferenceViewController.swift 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. //
  2. // ScheduleConferenceViewController.swift
  3. // TUIRoomKit
  4. //
  5. // Created by janejntang on 2024/6/5.
  6. //
  7. import Foundation
  8. import Factory
  9. import RTCRoomEngine
  10. import Combine
  11. import TUICore
  12. @objcMembers public class ScheduleConferenceViewController: UIViewController {
  13. private var cancellableSet = Set<AnyCancellable>()
  14. private let durationTime = 1800
  15. private let reminderSecondsBeforeStart = 600
  16. lazy var rootView: ScheduleConferenceTableView = {
  17. return ScheduleConferenceTableView(menus: ScheduleConferenceDataHelper.generateScheduleConferenceData(route: route, store: store, operation: operation, viewController: self))
  18. }()
  19. public override var shouldAutorotate: Bool {
  20. return false
  21. }
  22. public override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
  23. return .portrait
  24. }
  25. public override func loadView() {
  26. self.view = rootView
  27. }
  28. public override func viewDidLoad() {
  29. super.viewDidLoad()
  30. initializeView()
  31. initializeRoute()
  32. initializeData()
  33. reportSchedulePanelShow()
  34. subscribeScheduleSubject()
  35. subscribeToast()
  36. let selector = Selector(keyPath: \ConferenceInfo.basicInfo.isPasswordEnabled)
  37. store.select(selector)
  38. .removeDuplicates()
  39. .receive(on: RunLoop.main)
  40. .sink { [weak self] isPasswordEnabled in
  41. guard let self = self else { return }
  42. var conferenceInfo = store.conferenceInfo
  43. conferenceInfo.basicInfo.password = isPasswordEnabled ? getRandomNumber(numberOfDigits: 6) : ""
  44. store.update(conference: conferenceInfo)
  45. self.rootView.menus = ScheduleConferenceDataHelper.generateScheduleConferenceData(route: self.route, store: self.store, operation: self.operation, viewController: self)
  46. self.rootView.tableView.reloadData()
  47. }
  48. .store(in: &cancellableSet)
  49. }
  50. private func initializeView() {
  51. view.backgroundColor = UIColor(0xF8F9FB)
  52. navigationItem.title = .bookRoomText
  53. }
  54. private func initializeRoute() {
  55. let viewRoute = ConferenceRoute.init(viewController: self)
  56. route.initializeRoute(viewController: self, rootRoute: viewRoute)
  57. }
  58. private func initializeData() {
  59. operation.dispatch(action: UserActions.getSelfInfo())
  60. getConferenceInfo { [weak self] conferenceInfo in
  61. guard let self = self else { return }
  62. self.store.update(conference: conferenceInfo)
  63. self.store.fetchAttendees(cursor: "")
  64. }
  65. }
  66. private func getConferenceInfo(onGetConferenceInfo: @escaping (ConferenceInfo)->()) {
  67. FetchRoomId.getRoomId { [weak self] roomId in
  68. guard let self = self else { return }
  69. var info = ConferenceInfo()
  70. info.scheduleStartTime = self.getStartTime()
  71. info.durationTime = UInt(self.durationTime)
  72. info.reminderSecondsBeforeStart = self.reminderSecondsBeforeStart
  73. var basicInfo = RoomInfo()
  74. basicInfo.roomId = roomId
  75. basicInfo.name = localizedReplace(.temporaryRoomText, replace: self.operation.selectCurrent(UserSelectors.getSelfUserName))
  76. basicInfo.isCameraDisableForAllUser = false
  77. basicInfo.isMicrophoneDisableForAllUser = false
  78. info.basicInfo = basicInfo
  79. onGetConferenceInfo(info)
  80. }
  81. }
  82. private func getStartTime() -> UInt {
  83. let oneMinutesInterval = 60
  84. let fiveMinutesInterval = UInt(5 * oneMinutesInterval)
  85. var time = UInt(Date().timeIntervalSince1970)
  86. let remainder = time % fiveMinutesInterval
  87. if remainder > oneMinutesInterval {
  88. time = time - remainder
  89. }
  90. time = time + fiveMinutesInterval
  91. return time
  92. }
  93. private func getRandomNumber(numberOfDigits: Int) -> String {
  94. let minNumber = Int(truncating: NSDecimalNumber(decimal: pow(10, numberOfDigits - 1)))
  95. let maxNumber = Int(truncating: NSDecimalNumber(decimal: pow(10, numberOfDigits))) - 1
  96. let randomNumber = arc4random_uniform(UInt32(maxNumber - minNumber)) + UInt32(minNumber)
  97. return String(randomNumber)
  98. }
  99. private func reportSchedulePanelShow() {
  100. store.reportViewShow(dataReport: .metricsConferenceSchedulePanelShow)
  101. }
  102. deinit {
  103. debugPrint("deinit \(self)")
  104. }
  105. @Injected(\.navigation) private var route
  106. @Injected(\.modifyScheduleStore) private var store
  107. @Injected(\.conferenceStore) private var operation
  108. }
  109. extension ScheduleConferenceViewController {
  110. private func subscribeToast() {
  111. operation.toastSubject
  112. .receive(on: DispatchQueue.main)
  113. .sink { [weak self] toast in
  114. guard let self = self else { return }
  115. var position = TUICSToastPositionBottom
  116. switch toast.position {
  117. case .center:
  118. position = TUICSToastPositionCenter
  119. default:
  120. break
  121. }
  122. self.view.makeToast(toast.message, duration: toast.duration, position: position)
  123. }
  124. .store(in: &cancellableSet)
  125. }
  126. private func subscribeScheduleSubject() {
  127. operation.scheduleActionSubject
  128. .receive(on: RunLoop.main)
  129. .filter { $0.id == ScheduleResponseActions.onScheduleSuccess.id }
  130. .sink { [weak self] action in
  131. guard let self = self else { return }
  132. self.route.pop()
  133. }
  134. .store(in: &cancellableSet)
  135. }
  136. }
  137. extension ScheduleConferenceViewController: ContactViewSelectDelegate {
  138. public func onMemberSelected(_ viewController: ContactViewProtocol,
  139. invitees: [User]) {
  140. var conferenceInfo = store.conferenceInfo
  141. conferenceInfo.attendeeListResult.attendeeList = invitees.map { $0.userInfo }
  142. conferenceInfo.attendeeListResult.totalCount = UInt(invitees.count)
  143. store.update(conference: conferenceInfo)
  144. route.pop()
  145. }
  146. }
  147. private extension String {
  148. static var bookRoomText: String = localized("Schedule Room")
  149. static var temporaryRoomText: String = localized("xx's temporary room")
  150. }