210 lines
7.3 KiB
Swift
210 lines
7.3 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)
|
|
}
|
|
}
|
|
}
|
|
|
|
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)
|
|
|
|
// GroupIMService.shared.setConversationListener { [weak self] _ in
|
|
// GroupIMService.shared.getConversationList { conversations in
|
|
// self?.viewModel.updateConversations(conversations)
|
|
// }
|
|
// }
|
|
}
|
|
}
|
|
|
|
private func requestIMGroups(retryCount: Int = 3) {
|
|
DLToast.showLoading(text: "消息获取中...")
|
|
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)
|
|
}
|
|
}
|