jsdw_ios/QuickLocation/Section/Group/GroupViewController.swift

207 lines
7.2 KiB
Swift

//
// 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 func setupOpenIM() {
GroupIMService.shared.initSDK()
GroupIMService.shared.login { [weak self] success in
guard success else { return }
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
self?.requestIMGroups(retryCount: 3)
}
}
GroupIMService.shared.setConversationListener { [weak self] _ in
GroupIMService.shared.getConversationList { conversations in
self?.viewModel.updateConversations(conversations)
}
}
}
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
self?.viewModel.loadIMGroups(groups, conversations: conversations)
}
}
private func requestIMGroups(retryCount: Int = 3) {
GroupIMService.shared.getJoinedGroups { [weak self] groups in
guard let self = self else { return }
if groups.isEmpty && retryCount > 0 {
DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
self.requestIMGroups(retryCount: retryCount - 1)
}
} else {
self.refreshIMData()
}
}
}
// 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)
NotificationCenter.default.rx.notification(.RefreshGroupInfoNotification)
.subscribe(onNext: { [weak self] _ in
self?.requestIMGroups()
})
.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)
}
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.setupOpenIM()
}.disposed(by: disposeBag)
}
}