Files
yingmeng-ios-switf/yinmeng-ios/Modules/Chat/ChatVC.swift
2024-03-01 14:22:06 +08:00

301 lines
7.5 KiB
Swift

//
// ChatVC.swift
// yinmeng-ios
//
// Created by MaiMang on 2024/2/25.
//
import UIKit
import NIMSDK
class ChatVC: BaseViewController, HiddenNavigationBarProtocol {
// /
private var isBecome: Bool = false
///
private var isSended: Bool = true
///
private let ToolBarLastH: CGFloat = (52 + SafeAraeBottomHeight)
public init(session: NIMSession) {
vm = ChatViewModel(session: session)
super.init(nibName: nil, bundle: nil)
vm.delegate = self
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
var vm:ChatViewModel
override var preferredStatusBarStyle: UIStatusBarStyle {
.darkContent
}
override open func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if NIMSDK.shared().mediaManager.isPlaying() {
NIMSDK.shared().mediaManager.stopPlay()
}
}
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = ThemeColor(hexStr: "#F8F8FB")
requestInfo()
loadChatList()
registerChatCell()
let height = ScreenHeight - (ToolBarLastH + NavHeight)
chatTableView.frame = CGRect(x: 0, y: NavHeight, width: ScreenWidth, height: height)
navView.frame = CGRect(x: 0, y: 0, width: ScreenWidth, height: NavHeight)
view.addSubview(chatTableView)
view.addSubview(keyboardView)
view.addSubview(navView)
}
///cell
private func registerChatCell() {
chatTableView.register(cellType: ChatTextCell.self)
chatTableView.register(cellType: ChatTimeCell.self)
}
private lazy var chatTableView: UITableView = {
let tableView = UITableView(frame: .zero, style: .plain)
tableView.delegate = self
tableView.dataSource = self
tableView.tableFooterView = UIView()
tableView.separatorStyle = .none
tableView.backgroundColor = .clear
if #available(iOS 11.0, *) {
tableView.contentInsetAdjustmentBehavior = .never
}
return tableView
}()
private lazy var keyboardView: ChatKeyboardView = {
let toolBarY = ScreenHeight - ToolBarLastH
let view = ChatKeyboardView(frame: CGRect(x: 0, y: toolBarY, width: ScreenWidth, height: ToolBarLastH))
view.backgroundColor = .white
view.delegate = self
return view
}()
private lazy var navView: ChatNavView = {
let view = ChatNavView(frame: .zero)
view.backgroundColor = .white
return view
}()
}
// MARK: - ChatKeyboardViewDelegate
extension ChatVC: ChatKeyboardViewDelegate {
func keyboard(_ keyboard: ChatKeyboardView, voiceDidFinish path: String) {
vm.sendAudioMessage(filePath: path) { error in
}
}
func keyboard(_ keyboard: ChatKeyboardView, DidFinish content: String) {
///
vm.sendTextMessage(text: content) { error in
}
}
func keyboard(_ keyboard: ChatKeyboardView, DidBecome isBecome: Bool) {
self.isSended = true
self.isBecome = isBecome
}
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType) {
//TODO:
}
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat) {
}
}
extension ChatVC {
func requestInfo() {
let params = ["uid": vm.session.sessionId]
RequestGet(path: "user/get", parma: params) { data in
if let info = Deserialized<UserObject>.toModel(with: data) {
self.navView.name = info.nick
}
} fail: { code, msg in
}
let par:[String : Any] = ["uid": AuthManager.userUid, "isLikeUid": vm.session.sessionId]
RequestGet(path: "fans/isLike", parma: par) { data in
if let isLike = data as? Bool {
self.navView.isLike = isLike
}
} fail: { code, msg in
}
}
func loadChatList() {
weak var weakSelf = self
vm.queryRoamMsgHasMoreTime_v2 { error, historyEnd, newEnd, models, index in
if let ms = models, ms.count > 0 {
weakSelf?.chatTableView.reloadData()
if weakSelf?.vm.isHistoryAnchorChat == true {
let indexPath = IndexPath(row: index, section: 0)
weakSelf?.chatTableView.scrollToRow(at: indexPath, at: .none, animated: false)
} else {
if let tempArrayJJom = weakSelf?.vm.messageObjects, tempArrayJJom.count > 0 {
DispatchQueue.main.async {
weakSelf?.chatTableView.scrollToRow(
at: IndexPath(row: tempArrayJJom.count - 1, section: 0),
at: .bottom,
animated: false
)
}
}
}
} else if let err = error {
HUDTool.show(with: err.localizedDescription)
}
}
}
private func insertRows() {
let oldRows = chatTableView.numberOfRows(inSection: 0)
if oldRows == 0 {
chatTableView.reloadData()
return
}
if oldRows == vm.messageObjects.count {
chatTableView.reloadData()
return
}
var indexs = [IndexPath]()
for (i, _) in vm.messageObjects.enumerated() {
if i >= oldRows {
indexs.append(IndexPath(row: i, section: 0))
}
}
if !indexs.isEmpty {
chatTableView.insertRows(at: indexs, with: .none)
chatTableView.scrollToRow(
at: IndexPath(row: vm.messageObjects.count - 1, section: 0),
at: .bottom,
animated: false
)
}
}
public func tableViewDeleteIndexs(_ indexs: [IndexPath]) {
chatTableView.beginUpdates()
chatTableView.deleteRows(at: indexs, with: .none)
chatTableView.endUpdates()
}
public func tableViewReloadIndexs(_ indexs: [IndexPath]) {
chatTableView.beginUpdates()
chatTableView.reloadRows(at: indexs, with: .none)
chatTableView.endUpdates()
}
}
extension ChatVC: ChatViewModelDelegate{
public func onRecvMessages(_ messages: [NIMMessage]) {
insertRows()
vm.markRead(messages: messages) { error in
}
}
public func willSend(_ message: NIMMessage) {
}
public func didAppend(_ message: NIMMessage) {
}
public func send(_ message: NIMMessage, progress: Float) {}
public func send(_ message: NIMMessage, didCompleteWithError error: Error?) {
}
private func indexPathsWithMessags(_ messages: [NIMMessage]) -> [IndexPath] {
var indexPaths = [IndexPath]()
for messageModel in messages {
for (i, model) in vm.messageObjects.enumerated() {
if model.msg?.messageId == messageModel.messageId {
indexPaths.append(IndexPath(row: i, section: 0))
}
}
}
return indexPaths
}
public func onDeleteMessage(_ message: NIMMessage, atIndexs: [IndexPath]) {
if atIndexs.isEmpty {
return
}
tableViewDeleteIndexs(atIndexs)
}
}
extension ChatVC: UITableViewDelegate, UITableViewDataSource, UIScrollViewDelegate {
public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return vm.messageObjects.count
}
public func tableView(_ tableView: UITableView,
cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let model = vm.messageObjects[safe: indexPath.row]
if model?.type == .text {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatTextCell.self)
cell.model = model
} else if model?.type == .time {
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatTimeCell.self)
cell.model = model
}
return UITableViewCell()
}
public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
public func tableView(_ tableView: UITableView,
heightForRowAt indexPath: IndexPath) -> CGFloat {
let m = vm.messageObjects[safe:indexPath.row]
return CGFloat(m?.height ?? 0)
}
func scrollViewWillBeginDragging(_ scrollView: UIScrollView) {
if isSended {
isSended = false
}
}
func scrollViewDidScroll(_ scrollView: UIScrollView) {
if isSended {
return
}
if chatTableView.y <= 0 && isBecome {
DispatchQueue.main.async {
NotificationCenter.default.post(name: .kChatTextKeyboardNeedHide, object: nil)
}
}
}
}