113 lines
3.8 KiB
Swift
113 lines
3.8 KiB
Swift
//
|
||
// GroupViewModel.swift
|
||
// QuickLocation
|
||
//
|
||
|
||
import Foundation
|
||
import RxSwift
|
||
import RxCocoa
|
||
import RxDataSources
|
||
import OpenIMSDK
|
||
|
||
typealias HotGroupListSectionModel = SectionModel<String, GroupInfoModel>
|
||
typealias CircleListSectionModel = SectionModel<String, GroupCellData>
|
||
|
||
/// 群聊 cell 数据(融合群信息 + 会话信息)
|
||
struct GroupCellData {
|
||
let groupInfo: OIMGroupInfo
|
||
let unreadCount: Int
|
||
let lastMsgTime: Int // ms timestamp
|
||
let localIcon: UIImage
|
||
}
|
||
|
||
final class GroupViewModel {
|
||
|
||
struct Output {
|
||
let hotGroups: Observable<[HotGroupListSectionModel]>
|
||
let createdSections: Observable<[CircleListSectionModel]>
|
||
let joinedSections: Observable<[CircleListSectionModel]>
|
||
let segmentTitles: Driver<[String]>
|
||
}
|
||
|
||
let output: Output
|
||
|
||
private let hotGroupSectionedItems = PublishSubject<[HotGroupListSectionModel]>()
|
||
private let createdSectionsSubject = PublishSubject<[CircleListSectionModel]>()
|
||
private let joinedSectionsSubject = PublishSubject<[CircleListSectionModel]>()
|
||
|
||
let segmentTitles = BehaviorRelay<[String]>(value: ["我创建的圈子", "我加入的圈子"])
|
||
|
||
var groupList: [GroupInfoModel] = []
|
||
|
||
private var cachedGroups: [OIMGroupInfo] = []
|
||
private var cachedConversations: [OIMConversationInfo] = []
|
||
|
||
/// 当前群的本地图标
|
||
func getLocalIcon(groupId: String) -> UIImage {
|
||
groupList.first { groupId == $0.group_key }?.groupIcon ?? UIImage(named: "GroupIcon/1")!
|
||
}
|
||
|
||
/// 热门酷圈
|
||
func loadHotGroupData(_ list: [GroupInfoModel]) {
|
||
hotGroupSectionedItems.onNext(list.mapSection())
|
||
}
|
||
|
||
/// 加载群列表(全量刷新)
|
||
func loadIMGroups(_ groups: [OIMGroupInfo], conversations: [OIMConversationInfo] = []) {
|
||
if !groups.isEmpty { cachedGroups = groups }
|
||
if !conversations.isEmpty { cachedConversations = conversations }
|
||
reloadData()
|
||
}
|
||
|
||
/// 仅更新会话元数据(未读、时间)- 消息监听回调(只返回变更的会话,需合并)
|
||
func updateConversations(_ conversations: [OIMConversationInfo]) {
|
||
var merged: [String: OIMConversationInfo] = [:]
|
||
for c in cachedConversations { if let gid = c.groupID { merged[gid] = c } }
|
||
for c in conversations { if let gid = c.groupID { merged[gid] = c } }
|
||
cachedConversations = Array(merged.values)
|
||
reloadData()
|
||
}
|
||
|
||
private func reloadData() {
|
||
let currentUserId = AppContextManager.shared.userId
|
||
let convMap: [String: OIMConversationInfo] = {
|
||
var m: [String: OIMConversationInfo] = [:]
|
||
for c in cachedConversations where c.groupID != nil && !(c.groupID?.isEmpty ?? true) {
|
||
m[c.groupID!] = c
|
||
}
|
||
return m
|
||
}()
|
||
|
||
var created: [GroupCellData] = []
|
||
var joined: [GroupCellData] = []
|
||
|
||
for g in cachedGroups {
|
||
let conv = convMap[g.groupID ?? ""]
|
||
let data = GroupCellData(
|
||
groupInfo: g,
|
||
unreadCount: Int(conv?.unreadCount ?? 0),
|
||
lastMsgTime: Int(conv?.latestMsgSendTime ?? 0),
|
||
localIcon: getLocalIcon(groupId: g.groupID ?? "")
|
||
)
|
||
if g.ownerUserID == currentUserId || g.creatorUserID == currentUserId {
|
||
created.append(data)
|
||
} else {
|
||
joined.append(data)
|
||
}
|
||
}
|
||
|
||
createdSectionsSubject.onNext(created.mapSection())
|
||
joinedSectionsSubject.onNext(joined.mapSection())
|
||
}
|
||
|
||
// MARK: - Init
|
||
init() {
|
||
output = Output(
|
||
hotGroups: hotGroupSectionedItems.asObservable(),
|
||
createdSections: createdSectionsSubject.asObservable(),
|
||
joinedSections: joinedSectionsSubject.asObservable(),
|
||
segmentTitles: segmentTitles.asDriver()
|
||
)
|
||
}
|
||
}
|