ScheduleConferenceStore.swift 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. //
  2. // ScheduleConferenceStore.swift
  3. // TUIRoomKit
  4. //
  5. // Created by aby on 2024/6/27.
  6. //
  7. import Combine
  8. protocol ScheduleConferenceStore {
  9. func update(conference info: ConferenceInfo)
  10. func fetchAttendees(cursor: String)
  11. func fetchRoomPassword(roomId: String)
  12. func reportViewShow(dataReport: DataReport)
  13. func select<Value:Equatable>(_ selector: Selector<ConferenceInfo, Value>) -> AnyPublisher<Value, Never>
  14. var conferenceInfo: ConferenceInfo { get }
  15. }
  16. class ScheduleConferenceStoreProvider {
  17. static let updateConferenceInfo = ActionTemplate(id: "updateConferenceInfo", payloadType: ConferenceInfo.self)
  18. static let fetchAttendeeList = ActionTemplate(id: "fetchAttendeeList", payloadType: (String, String, Int).self)
  19. static let updateAttendeeList = ActionTemplate(id: "updateAttendeeList", payloadType: ([UserInfo], String, UInt).self)
  20. static let fetchRoomPassword = ActionTemplate(id: ".fetchRoomPassword", payloadType: String.self)
  21. static let updateRoomPassword = ActionTemplate(id: "updateRoomPassword", payloadType: String.self)
  22. static let attendeesPerFetch = 20
  23. // MARK: - private property.
  24. private lazy var store: Store<ConferenceInfo, ServiceCenter> = {
  25. let store = Store.init(initialState: ConferenceInfo(), environment: ServiceCenter(), reducers: [self.conferenceReducer])
  26. store.register(effects: scheduleConferenceEffects())
  27. return store
  28. }()
  29. private let conferenceReducer = Reducer<ConferenceInfo>(
  30. ReduceOn(updateConferenceInfo, reduce: { state, action in
  31. state = action.payload
  32. }),
  33. ReduceOn(updateAttendeeList, reduce: { state, action in
  34. state.attendeeListResult.attendeeList.append(contentsOf: action.payload.0)
  35. state.attendeeListResult.fetchCursor = action.payload.1
  36. state.attendeeListResult.totalCount = action.payload.2
  37. }),
  38. ReduceOn(updateRoomPassword, reduce: { state, action in
  39. state.basicInfo.password = action.payload
  40. state.basicInfo.isPasswordEnabled = !action.payload.isEmpty
  41. })
  42. )
  43. deinit {
  44. store.unregister(reducer: conferenceReducer)
  45. store.unregisterEffects(withId: scheduleConferenceEffects.id)
  46. }
  47. }
  48. extension ScheduleConferenceStoreProvider: ScheduleConferenceStore {
  49. func reportViewShow(dataReport: DataReport) {
  50. RoomKitReport.reportData(dataReport)
  51. }
  52. func update(conference info: ConferenceInfo) {
  53. store.dispatch(action: ScheduleConferenceStoreProvider.updateConferenceInfo(payload: info))
  54. }
  55. func fetchAttendees(cursor: String) {
  56. let conferenceId = conferenceInfo.basicInfo.roomId
  57. store.dispatch(action: ScheduleConferenceStoreProvider.fetchAttendeeList(payload: (conferenceId, cursor, ScheduleConferenceStoreProvider.attendeesPerFetch)))
  58. }
  59. func fetchRoomPassword(roomId: String) {
  60. store.dispatch(action: ScheduleConferenceStoreProvider.fetchRoomPassword(payload: roomId))
  61. }
  62. func select<Value>(_ selector: Selector<ConferenceInfo, Value>) -> AnyPublisher<Value, Never> where Value : Equatable {
  63. return store.select(selector)
  64. }
  65. var conferenceInfo: ConferenceInfo {
  66. return store.state
  67. }
  68. }
  69. class scheduleConferenceEffects: Effects {
  70. typealias Environment = ServiceCenter
  71. let fetchAttendeeList = Effect<Environment>.dispatchingOne { actions, environment in
  72. actions.wasCreated(from: ScheduleConferenceStoreProvider.fetchAttendeeList)
  73. .flatMap { action in
  74. environment.conferenceListService.fetchAttendeeList(conferenceId: action.payload.0,
  75. cursor: action.payload.1,
  76. count: action.payload.2)
  77. .map { (userInfoList, cursor, totalCount) in
  78. ScheduleConferenceStoreProvider.updateAttendeeList(payload: (userInfoList, cursor, totalCount))
  79. }
  80. .catch { error -> Just<Action> in
  81. Just(ErrorActions.throwError(payload: error))
  82. }
  83. }
  84. .eraseToAnyPublisher()
  85. }
  86. let fetchRoomPassword = Effect<Environment>.dispatchingOne { actions, environment in
  87. actions.wasCreated(from: ScheduleConferenceStoreProvider.fetchRoomPassword)
  88. .flatMap { action in
  89. environment.conferenceListService.fetchConferenceInfo(roomId: action.payload)
  90. .map { conferenceInfo in
  91. ScheduleConferenceStoreProvider.updateRoomPassword(payload: conferenceInfo.basicInfo.password)
  92. }
  93. .catch { error -> Just<Action> in
  94. Just(ErrorActions.throwError(payload: error))
  95. }
  96. }
  97. .eraseToAnyPublisher()
  98. }
  99. }