SelectMemberState.swift 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. //
  2. // SelectMemberState.swift
  3. // Pods
  4. //
  5. // Created by janejntang on 2024/12/31.
  6. //
  7. import Foundation
  8. import Combine
  9. import TUICore
  10. struct SelectMemberState {
  11. var members: [User] = []
  12. var selectedMembers: [User] = []
  13. }
  14. protocol SelectMemberStore {
  15. var selectMemberState: SelectMemberState { get }
  16. func subscribe<Value>(_ selector: Selector<SelectMemberState, Value>) -> AnyPublisher<Value, Never>
  17. func setSelectedMembers(_ members: [User])
  18. func setLockSelectionMembers(_ members: [User])
  19. func addSelectedMember(_ member: User)
  20. func deleteSelectedMember(_ userId: String)
  21. func filterMembers(with searchText: String)
  22. func getAllMembersCount() -> Int
  23. func isLockSelection(userId: String) -> Bool
  24. }
  25. class SelectMemberProvider: NSObject {
  26. var initialMembers: [User] = []
  27. var lockSelectionMembers: [User] = []
  28. private lazy var store: Store<SelectMemberState, Void> = {
  29. let store = Store(initialState: SelectMemberState(), reducers: [SelectMemberStateUpdater])
  30. return store
  31. }()
  32. private var cancellables = Set<AnyCancellable>()
  33. override init() {
  34. super.init()
  35. initMembers()
  36. }
  37. private func initMembers() {
  38. let users = ConferenceSession.sharedInstance.implementation.participants
  39. if !users.isEmpty {
  40. setMembers(users)
  41. } else {
  42. loadIMMembers()
  43. }
  44. }
  45. private func loadIMMembers() {
  46. V2TIMManager.sharedInstance()?.getFriendList { [weak self] list in
  47. guard let self = self else { return }
  48. let users = list?.map({ info in
  49. return User(userId: info.userID ?? "", userName: info.userFullInfo.nickName ?? "", avatarUrl: info.userFullInfo.faceURL ?? "")
  50. })
  51. self.setMembers(users ?? [])
  52. } fail: { _, _ in
  53. debugPrint("getFriendList falied")
  54. }
  55. }
  56. private func setMembers(_ users: [User]) {
  57. initialMembers = users
  58. store.dispatch(action: SelectMemberActions.updateMembers(payload: users))
  59. }
  60. deinit {
  61. store.unregister(reducer: SelectMemberStateUpdater)
  62. }
  63. }
  64. extension SelectMemberProvider: SelectMemberStore {
  65. var selectMemberState: SelectMemberState {
  66. return store.state
  67. }
  68. func subscribe<Value>(_ selector: Selector<SelectMemberState, Value>) -> AnyPublisher<Value, Never> {
  69. return store.select(selector)
  70. }
  71. func setSelectedMembers(_ members: [User]) {
  72. store.dispatch(action: SelectMemberActions.updateSelectedMembers(payload: members))
  73. }
  74. func setLockSelectionMembers(_ members: [User]) {
  75. lockSelectionMembers = members
  76. }
  77. func addSelectedMember(_ member: User) {
  78. var selectedMembers = store.state.selectedMembers
  79. guard !selectedMembers.contains(where: { $0.userId == member.userId }) else { return }
  80. selectedMembers.append(member)
  81. store.dispatch(action: SelectMemberActions.updateSelectedMembers(payload: selectedMembers))
  82. }
  83. func deleteSelectedMember(_ userId: String) {
  84. var selectedMembers = store.state.selectedMembers
  85. guard let index = selectedMembers.firstIndex(where: { $0.userId == userId }) else { return }
  86. selectedMembers.remove(at: index)
  87. store.dispatch(action: SelectMemberActions.updateSelectedMembers(payload: selectedMembers))
  88. }
  89. func filterMembers(with searchText: String) {
  90. if searchText.isEmpty {
  91. store.dispatch(action: SelectMemberActions.updateMembers(payload: initialMembers))
  92. } else {
  93. let lowercaseSearchText = searchText.lowercased()
  94. let members = initialMembers.filter {
  95. $0.userName.lowercased().contains(lowercaseSearchText) ||
  96. $0.userId.lowercased().contains(lowercaseSearchText)
  97. }
  98. store.dispatch(action: SelectMemberActions.updateMembers(payload: members))
  99. }
  100. }
  101. func isLockSelection(userId: String) -> Bool {
  102. return lockSelectionMembers.contains(where: { $0.userId == userId })
  103. }
  104. func getAllMembersCount() -> Int {
  105. return initialMembers.count
  106. }
  107. }
  108. enum SelectMemberActions {
  109. static let key = "select.member.action"
  110. static let updateMembers = ActionTemplate(id: key.appending(".updateMembers"), payloadType: [User].self)
  111. static let updateSelectedMembers = ActionTemplate(id: key.appending(".updateSelectedMembers"), payloadType: [User].self)
  112. }
  113. let SelectMemberStateUpdater = Reducer<SelectMemberState> (
  114. ReduceOn(SelectMemberActions.updateMembers, reduce: { state, action in
  115. state.members = action.payload
  116. }),
  117. ReduceOn(SelectMemberActions.updateSelectedMembers, reduce: { state, action in
  118. state.selectedMembers = action.payload
  119. })
  120. )