jsdw_ios/QuickLocation/Section/Group/GroupViewController.swift

217 lines
7.7 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.

//
// GroupViewController.swift
// QuickLocation
//
import UIKit
import RxSwift
import RxCocoa
import RxDataSources
import SDCycleScrollView
import OpenIMSDK
final class GroupViewController: BaseViewController {
override var isNavigationBarHidden: Bool { true }
fileprivate var rootView: GroupView!
private let viewModel = GroupViewModel()
override func loadView() {
rootView = GroupView(frame: UIScreen.main.bounds)
view = rootView
}
override func viewDidLoad() {
super.viewDidLoad()
bindViewModel()
reactiveAction()
observeTableViews()
requestRecommandGroup()
requestGroupInfo()
guard let config = AppContextManager.shared.systemConfig else { return }
rootView.cycleScrollView.imageURLStringsGroup = config.groupBannerList
}
// MARK: - OpenIM
private var hasSetupIMListeners = false
/// IM +
private func loadIMData() {
GroupIMService.shared.ensureLogin { [weak self] success in
guard let self = self else { return }
guard success else {
return
}
self.setupIMListenersIfNeeded()
self.refreshIMData()
}
}
/// IM /SDK /退
private func setupIMListenersIfNeeded() {
guard !hasSetupIMListeners else { return }
hasSetupIMListeners = true
GroupIMService.shared.setConversationListener { [weak self] _ in
GroupIMService.shared.getConversationList { conversations in
self?.viewModel.updateConversations(conversations)
}
}
// /SDK
GroupIMService.shared.setGroupListener { [weak self] in
GroupIMService.shared.getJoinedGroups { groups in
self?.viewModel.loadIMGroups(groups)
}
}
}
private func refreshIMData() {
let group = DispatchGroup()
var groups: [OIMGroupInfo] = []
var conversations: [OIMConversationInfo] = []
group.enter()
GroupIMService.shared.getJoinedGroups { g in
groups = g
group.leave()
}
group.enter()
GroupIMService.shared.getConversationList { c in
conversations = c
group.leave()
}
group.notify(queue: .main) { [weak self] in
DLToast.dismiss()
self?.viewModel.loadIMGroups(groups, conversations: conversations)
}
}
// MARK: - Bindings
private func bindViewModel() {
viewModel.output.hotGroups
.observe(on: MainScheduler.asyncInstance)
.bind(to: rootView.hotGroupsCollectionView.rx.items(dataSource: hotGroupDataSource))
.disposed(by: disposeBag)
viewModel.output.createdSections
.observe(on: MainScheduler.asyncInstance)
.bind(to: rootView.createdTableView.rx.items(dataSource: createdDataSource))
.disposed(by: disposeBag)
viewModel.output.joinedSections
.observe(on: MainScheduler.asyncInstance)
.bind(to: rootView.joinedTableView.rx.items(dataSource: joinedDataSource))
.disposed(by: disposeBag)
}
private func reactiveAction() {
rootView.createGroupBtn.rx.tapGesture
.subscribe(onNext: { _ in
AppRouter.push(Route.createGroup)
})
.disposed(by: disposeBag)
rootView.joinGroupBtn.rx.tapGesture
.subscribe(onNext: { _ in
AppRouter.push(Route.joinGroup)
})
.disposed(by: disposeBag)
rootView.createdTabLabel.rx.tapGesture
.subscribe(onNext: { [weak self] _ in self?.switchToSegment(0) })
.disposed(by: disposeBag)
rootView.joinedTabLabel.rx.tapGesture
.subscribe(onNext: { [weak self] _ in self?.switchToSegment(1) })
.disposed(by: disposeBag)
Observable.merge(
rootView.createdTableView.rx.modelSelected(GroupCellData.self).asObservable(),
rootView.joinedTableView.rx.modelSelected(GroupCellData.self).asObservable()
)
.subscribe(onNext: { data in
guard let groupId = data.groupInfo.groupID else { return }
AppRouter.push(Route.groupChat, userInfo: ["groupId": groupId])
})
.disposed(by: disposeBag)
NotificationCenter.default.rx.notification(.RefreshUserConfigNotification)
.subscribe(onNext: { [weak self] _ in
self?.requestRecommandGroup()
self?.requestGroupInfo()
guard let config = AppContextManager.shared.systemConfig else { return }
self?.rootView.cycleScrollView.imageURLStringsGroup = config.groupBannerList
})
.disposed(by: disposeBag)
}
private func switchToSegment(_ index: Int) {
rootView.selectSegment(at: index)
let offset = CGPoint(x: CGFloat(index) * rootView.segmentScrollView.bounds.width, y: 0)
rootView.segmentScrollView.setContentOffset(offset, animated: false)
}
// MARK: - tableView
private func observeTableViews() {
rootView.createdTableView.rx.didScroll
.observe(on: MainScheduler.asyncInstance)
.subscribe(onNext: { [weak self] in
guard let self = self else { return }
self.rootView.handleTableViewScroll(self.rootView.createdTableView)
})
.disposed(by: disposeBag)
rootView.joinedTableView.rx.didScroll
.observe(on: MainScheduler.asyncInstance)
.subscribe(onNext: { [weak self] in
guard let self = self else { return }
self.rootView.handleTableViewScroll(self.rootView.joinedTableView)
})
.disposed(by: disposeBag)
}
// MARK: - dataSource
private lazy var hotGroupDataSource: RxCollectionViewSectionedReloadDataSource<HotGroupListSectionModel> = {
RxCollectionViewSectionedReloadDataSource<HotGroupListSectionModel> { datasource, collectionView, indexPath, model in
let cell: HotGroupCell = collectionView.dequeueReusableCell(for: indexPath)
cell.configure(model)
return cell
}
}()
private lazy var createdDataSource: RxTableViewSectionedReloadDataSource<CircleListSectionModel> = {
RxTableViewSectionedReloadDataSource<CircleListSectionModel> { _, tableView, indexPath, model in
let cell: CircleGroupCell = tableView.dequeueReusableCell(for: indexPath)
cell.configure(model)
return cell
}
}()
private lazy var joinedDataSource: RxTableViewSectionedReloadDataSource<CircleListSectionModel> = {
RxTableViewSectionedReloadDataSource<CircleListSectionModel> { _, tableView, indexPath, model in
let cell: CircleGroupCell = tableView.dequeueReusableCell(for: indexPath)
cell.configure(model)
return cell
}
}()
// MARK: - API
private func requestRecommandGroup() {
GroupService.recommand(count: 5).subscribe(onNext: { response in
self.viewModel.loadHotGroupData(response.list)
}).disposed(by: disposeBag)
}
private func requestGroupInfo() {
GroupService.groupInfo().subscribe { response in
guard let model = response.model else { return }
self.viewModel.groupList = model.groups
self.loadIMData()
}.disposed(by: disposeBag)
}
}