jsdw_ios/QuickLocation/Section/Home/HomeViewModel.swift

165 lines
4.9 KiB
Swift
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

//
// HomeViewModel.swift
// QuickLocation
//
// Created by on 2026/5/30.
//
import RxSwift
import RxDataSources
import ObjectMapper
typealias GroupMemberListSectionModel = SectionModel<String, GroupMemberModel>
class HomeViewModel {
struct Output {
var sectionedItems: Observable<[GroupMemberListSectionModel]>
}
let output: Output
private var disposeBag = DisposeBag()
private let sectionedItems = PublishSubject<[GroupMemberListSectionModel]>()
lazy var cellAction: Action<GroupMemberModel, Void> = { this in
return Action { model in
return .empty()
}
}(self)
var targetUid: String = ""
var groupModel: GroupModel?
//
var groupInfo: [String: Any] {
get {
guard let model = groupModel,
let groupInfoModel = model.groups.first(where: { $0.group_key == model.default_group_key }) else { return [:] }
return groupInfoModel.toJSON()
}
}
//
var groupName: String {
get {
guard let model = groupModel else { return "我的圈子" }
return model.groups.first(where: { $0.group_key == model.default_group_key })?.name ?? ""
}
}
//
var memberCount: Int {
memberList.count
}
// 线
var memberOnlineCount: Int {
memberList.filter(\.is_online).count
}
//
func isCurrentUser(id: String) -> Bool {
id == AppContextManager.shared.userId
}
//
func isGroupOwn(id: String) -> Bool {
guard let model = groupModel else { return false }
return GroupOwnerMatcher.matches(userId: id, groupKey: model.default_group_key)
}
func getUserNickName(id: String) -> String {
memberList.first { $0.user_id == id }?.nick_name ?? ""
}
private(set) var memberList: [GroupMemberModel] = []
func markMemberInBubble(userId: String) {
updateMemberStatus(userId: userId, status: 2)
}
func isInBubble(userId: String) -> Bool {
let ids = canonicalUserIds(userId)
if let member = memberList.first(where: { ids.contains($0.user_id) }) {
return member.status == 2
}
if ids.contains(where: { $0 == "current" || isCurrentUser(id: $0) }) {
return AppContextManager.shared.status == 2
}
return false
}
func updateMembers(_ list: [GroupMemberModel]) {
memberList = GroupMemberSorter.sorted(
list,
groupKey: groupModel?.default_group_key ?? "",
currentUserId: AppContextManager.shared.userId
)
sectionedItems.onNext(memberList.mapSection())
}
func clearMembers() {
updateMembers([])
}
private func canonicalUserIds(_ userId: String) -> Set<String> {
var ids: Set<String> = [userId]
if userId == "current" || isCurrentUser(id: userId) {
ids.insert("current")
let mine = AppContextManager.shared.userId
if !mine.isEmpty {
ids.insert(mine)
}
}
return ids
}
/// 线 last_active_time "X"
func setMemberOffline(userId: String) {
guard let idx = memberList.firstIndex(where: { $0.user_id == userId }) else { return }
var updated = memberList
updated[idx].is_online = false
updateMembers(updated)
}
/// MQTT 线
func updateMemberLocation(userId: String, lat: Double, lon: Double, address: String, battery: String, isOnline: Bool, lastUpdateTime: Int64) {
guard let idx = memberList.firstIndex(where: { $0.user_id == userId }) else { return }
var updated = memberList
updated[idx].last_position = "\(lat):\(lon):\(address)"
updated[idx].battery = battery
updated[idx].is_online = isOnline
updated[idx].last_active_time = lastUpdateTime
updateMembers(updated)
}
///
func memberIsExist(userId: String) -> Bool {
(memberList.first(where: { $0.user_id == userId }) != nil)
}
///
func removeMember(userId: String) {
guard let idx = memberList.firstIndex(where: { $0.user_id == userId }) else { return }
var updated = memberList
updated.remove(at: idx)
updateMembers(updated)
}
func updateMemberStatus(userId: String, status: Int) {
guard let index = memberList.firstIndex(where: { $0.user_id == userId }) else { return }
memberList[index].status = status
sectionedItems.onNext(memberList.mapSection())
}
// MARK: - Init
init() {
output = Output(
sectionedItems: sectionedItems.asObservable()
)
}
}