93 lines
2.5 KiB
Swift
93 lines
2.5 KiB
Swift
//
|
|
// RemoveMemberViewModel.swift
|
|
// QuickLocation
|
|
//
|
|
// Created by 八条 on 2026/6/12.
|
|
//
|
|
|
|
import RxSwift
|
|
import RxCocoa
|
|
import RxDataSources
|
|
import ObjectMapper
|
|
|
|
typealias RemoveMemberListSectionModel = SectionModel<String, GroupMemberModel>
|
|
|
|
class RemoveMemberViewModel {
|
|
|
|
let groupId: String
|
|
|
|
var groupModel: GroupInfoModel?
|
|
|
|
struct Output {
|
|
var sectionedItems: Observable<[ReviewMemberListSectionModel]>
|
|
}
|
|
|
|
let output: Output
|
|
|
|
private var disposeBag = DisposeBag()
|
|
private let sectionedItems = PublishSubject<[ReviewMemberListSectionModel]>()
|
|
private var list: [GroupMemberModel] = []
|
|
private var searchKeyword = ""
|
|
|
|
var selectedMembers = BehaviorRelay<[String]>(value: [])
|
|
|
|
lazy var cellAction: Action<GroupMemberModel, Void> = { this in
|
|
return Action { model in
|
|
let memberId = model.user_id
|
|
guard !GroupOwnerMatcher.matches(userId: memberId, groupKey: self.groupId) else {
|
|
return .empty()
|
|
}
|
|
|
|
var current = this.selectedMembers.value
|
|
if let idx = current.firstIndex(of: memberId) {
|
|
current.remove(at: idx)
|
|
} else {
|
|
current.append(memberId)
|
|
}
|
|
this.selectedMembers.accept(current)
|
|
self.emitItems()
|
|
return .empty()
|
|
}
|
|
}(self)
|
|
|
|
func isSelected(id: String) -> Bool {
|
|
(self.selectedMembers.value.first(where: { $0 == id }) != nil)
|
|
}
|
|
|
|
func loadData(_ list: [GroupMemberModel]) {
|
|
self.list = GroupMemberSorter.sorted(
|
|
list,
|
|
groupKey: groupId,
|
|
currentUserId: AppContextManager.shared.userId
|
|
)
|
|
selectedMembers.accept(selectedMembers.value.filter { selectedId in
|
|
list.contains(where: { $0.user_id == selectedId })
|
|
})
|
|
emitItems()
|
|
}
|
|
|
|
func updateSearchKeyword(_ keyword: String) {
|
|
searchKeyword = keyword.trimmingCharacters(in: .whitespacesAndNewlines)
|
|
emitItems()
|
|
}
|
|
|
|
private func emitItems() {
|
|
let items: [GroupMemberModel]
|
|
if searchKeyword.isEmpty {
|
|
items = list
|
|
} else {
|
|
items = list.filter {
|
|
$0.nick_name.localizedCaseInsensitiveContains(searchKeyword)
|
|
}
|
|
}
|
|
sectionedItems.onNext(items.mapSection())
|
|
}
|
|
|
|
init(groupId: String) {
|
|
self.groupId = groupId
|
|
output = Output(
|
|
sectionedItems: sectionedItems.asObservable()
|
|
)
|
|
}
|
|
}
|