ConferenceStoreProvider.swift 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. //
  2. // ConferenceStoreProvider.swift
  3. // TUIRoomKit
  4. //
  5. // Created by CY zhao on 2024/6/12.
  6. //
  7. import Foundation
  8. import Combine
  9. class ConferenceStoreProvider {
  10. let errorSubject = PassthroughSubject<RoomError, Never>()
  11. let toastSubject = PassthroughSubject<ToastInfo, Never>()
  12. let scheduleActionSubject = PassthroughSubject<any IdentifiableAction, Never>()
  13. let roomActionSubject = PassthroughSubject<any IdentifiableAction, Never>()
  14. private(set) lazy var operation: Store<OperationState, ServiceCenter> = {
  15. return Store(initialState: OperationState(), environment: ServiceCenter())
  16. }()
  17. private(set) lazy var viewStore: Store<ViewState, Void> = Store(initialState: ViewState())
  18. private var cancellableSet: Set<AnyCancellable> = []
  19. init() {
  20. initializeStore()
  21. }
  22. private func initializeStore() {
  23. initializeUserStore()
  24. initializeConferenceListStore()
  25. initializeConferenceInvitationStore()
  26. initializeInvitationObserverStore()
  27. initializeRoomStore()
  28. initializeErrorEffect()
  29. initializedViewStore()
  30. }
  31. private func initializeUserStore() {
  32. operation.register(reducer: userReducer, for: \.userState)
  33. operation.register(effects: UserEffects())
  34. }
  35. private func initializeConferenceListStore() {
  36. operation.register(reducer: ConferenceListReducer, for: \.conferenceListState)
  37. operation.register(effects: ConferenceListEffects())
  38. }
  39. private func initializeConferenceInvitationStore() {
  40. operation.register(reducer: ConferenceInvitationReducer, for: \.conferenceInvitationState)
  41. operation.register(effects: ConferenceInvitationEffects())
  42. }
  43. private func initializeInvitationObserverStore() {
  44. operation.register(effects: InvitationObserverEffects())
  45. }
  46. private func initializeRoomStore() {
  47. operation.register(reducer: roomReducer, for: \.roomState)
  48. operation.register(effects: RoomEffects())
  49. }
  50. private func initializeErrorEffect() {
  51. operation.register(effects: ErrorEffects())
  52. errorSubject
  53. .sink { [weak self] error in
  54. guard let self = self else { return }
  55. self.handle(error: error)
  56. }
  57. .store(in: &cancellableSet)
  58. }
  59. private func initializedViewStore() {
  60. viewStore.register(reducer: scheduleViewReducer,for: \ViewState.scheduleViewState)
  61. viewStore.register(reducer: invitationViewReducer, for: \ViewState.invitationViewState)
  62. }
  63. deinit {
  64. operation.unregister(reducer: userReducer)
  65. operation.unregisterEffects(withId: UserEffects.id)
  66. operation.unregister(reducer: ConferenceListReducer)
  67. operation.unregisterEffects(withId: ConferenceListEffects.id)
  68. operation.unregister(reducer: ConferenceInvitationReducer)
  69. operation.unregisterEffects(withId: ConferenceInvitationEffects.id)
  70. operation.unregisterEffects(withId: InvitationObserverEffects.id)
  71. operation.unregister(reducer: roomReducer)
  72. operation.unregisterEffects(withId: RoomEffects.id)
  73. operation.unregisterEffects(withId: ErrorEffects.id)
  74. viewStore.unregister(reducer: scheduleViewReducer)
  75. viewStore.unregister(reducer: invitationViewReducer)
  76. }
  77. }
  78. extension ConferenceStoreProvider: ConferenceStore {
  79. func dispatch(action: Action) {
  80. guard let action = action as? IdentifiableAction else { return }
  81. if action.id.hasPrefix(ScheduleResponseActions.key) {
  82. scheduleActionSubject.send(action)
  83. }
  84. if action.id.hasPrefix(RoomResponseActions.key) {
  85. roomActionSubject.send(action)
  86. }
  87. if action.id.hasPrefix(ViewActions.toastActionKey) {
  88. handleToast(action: action)
  89. } else if action.id.hasPrefix(ViewActions.key) {
  90. viewStore.dispatch(action: action)
  91. } else {
  92. operation.dispatch(action: action)
  93. }
  94. }
  95. func select<Value: Equatable>(_ selector: Selector<OperationState, Value>) -> AnyPublisher<Value, Never> {
  96. return operation.select(selector)
  97. .removeDuplicates()
  98. .eraseToAnyPublisher()
  99. }
  100. func selectCurrent<Value>(_ selector: Selector<OperationState, Value>) -> Value {
  101. return operation.selectCurrent(selector)
  102. }
  103. func select<Value:Equatable>(_ selector: Selector<ViewState, Value>) -> AnyPublisher<Value, Never> {
  104. return viewStore.select(selector)
  105. }
  106. func selectCurrent<Value>(_ selector: Selector<ViewState, Value>) -> Value {
  107. return viewStore.selectCurrent(selector)
  108. }
  109. }
  110. extension ConferenceStoreProvider {
  111. private func handle(error: RoomError) {
  112. error.actions.forEach { action in
  113. guard let action = action as? IdentifiableAction else { return }
  114. dispatch(action: action)
  115. }
  116. }
  117. private func handleToast(action: Action) {
  118. if let viewAction = action as? AnonymousAction<ToastInfo> {
  119. toastSubject.send(viewAction.payload)
  120. }
  121. }
  122. }