私聊完成
This commit is contained in:
Binary file not shown.
Before Width: | Height: | Size: 19 KiB After Width: | Height: | Size: 17 KiB |
Binary file not shown.
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 38 KiB |
@@ -7,7 +7,8 @@
|
||||
|
||||
import UIKit
|
||||
import NIMSDK
|
||||
class ChatVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
import TZImagePickerController
|
||||
class ChatVC: BaseViewController, HiddenNavigationBarProtocol, TZImagePickerControllerDelegate{
|
||||
|
||||
// 键盘收起/弹出 滚动的时候收起输入栏
|
||||
private var isBecome: Bool = false
|
||||
@@ -57,6 +58,8 @@ class ChatVC: BaseViewController, HiddenNavigationBarProtocol {
|
||||
private func registerChatCell() {
|
||||
chatTableView.register(cellType: ChatTextCell.self)
|
||||
chatTableView.register(cellType: ChatTimeCell.self)
|
||||
chatTableView.register(cellType: ChatVoiceCell.self)
|
||||
chatTableView.register(cellType: ChatImageCell.self)
|
||||
}
|
||||
|
||||
private lazy var chatTableView: UITableView = {
|
||||
@@ -111,8 +114,20 @@ extension ChatVC: ChatKeyboardViewDelegate {
|
||||
}
|
||||
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidMoreMenu type: ChatMoreMenuType) {
|
||||
|
||||
//TODO: 点击更多
|
||||
if type == .album {
|
||||
let imagePicker = TZImagePickerController(maxImagesCount: 1, columnNumber: 5, delegate: self)
|
||||
imagePicker?.allowPickingVideo = false
|
||||
imagePicker?.modalPresentationStyle = .fullScreen
|
||||
imagePicker?.didFinishPickingPhotosHandle = {(images: [UIImage]?, assets:[Any]?, isSelectOriginalPhoto: Bool) in
|
||||
if (type == .album) {
|
||||
if let image = images?[safe:0] {
|
||||
self.vm.sendImageMessage(image: image) { _ in}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.navigationController?.present(imagePicker!, animated: true)
|
||||
keyboard.hiddenMoreView()
|
||||
}
|
||||
}
|
||||
|
||||
func keyboard(_ keyboard: ChatKeyboardView, DidObserver offsetY: CGFloat) {
|
||||
@@ -123,6 +138,7 @@ extension ChatVC: ChatKeyboardViewDelegate {
|
||||
extension ChatVC {
|
||||
|
||||
func requestInfo() {
|
||||
self.navView.uid = vm.session.sessionId
|
||||
let params = ["uid": vm.session.sessionId]
|
||||
RequestGet(path: "user/get", parma: params) { data in
|
||||
if let info = Deserialized<UserObject>.toModel(with: data) {
|
||||
@@ -133,7 +149,7 @@ extension ChatVC {
|
||||
}
|
||||
|
||||
let par:[String : Any] = ["uid": AuthManager.userUid, "isLikeUid": vm.session.sessionId]
|
||||
RequestGet(path: "fans/isLike", parma: par) { data in
|
||||
RequestGet(path: "fans/islike", parma: par) { data in
|
||||
if let isLike = data as? Bool {
|
||||
self.navView.isLike = isLike
|
||||
}
|
||||
@@ -194,6 +210,7 @@ extension ChatVC {
|
||||
animated: false
|
||||
)
|
||||
}
|
||||
chatTableView.reloadData()
|
||||
}
|
||||
|
||||
public func tableViewDeleteIndexs(_ indexs: [IndexPath]) {
|
||||
@@ -211,7 +228,7 @@ extension ChatVC {
|
||||
}
|
||||
|
||||
extension ChatVC: ChatViewModelDelegate{
|
||||
public func onRecvMessages(_ messages: [NIMMessage]) {
|
||||
public func onRecvMessages1(_ messages: [NIMMessage]) {
|
||||
insertRows()
|
||||
vm.markRead(messages: messages) { error in
|
||||
|
||||
@@ -229,7 +246,9 @@ extension ChatVC: ChatViewModelDelegate{
|
||||
public func send(_ message: NIMMessage, progress: Float) {}
|
||||
|
||||
public func send(_ message: NIMMessage, didCompleteWithError error: Error?) {
|
||||
|
||||
if error == nil {
|
||||
insertRows()
|
||||
}
|
||||
}
|
||||
|
||||
private func indexPathsWithMessags(_ messages: [NIMMessage]) -> [IndexPath] {
|
||||
@@ -263,10 +282,21 @@ extension ChatVC: UITableViewDelegate, UITableViewDataSource, UIScrollViewDelega
|
||||
if model?.type == .text {
|
||||
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatTextCell.self)
|
||||
cell.model = model
|
||||
return cell
|
||||
} else if model?.type == .time {
|
||||
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatTimeCell.self)
|
||||
cell.model = model
|
||||
return cell
|
||||
} else if model?.type == .voice {
|
||||
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatVoiceCell.self)
|
||||
cell.model = model
|
||||
return cell
|
||||
} else if model?.type == .image {
|
||||
let cell = tableView.dequeueReusableCell(for: indexPath, cellType: ChatImageCell.self)
|
||||
cell.model = model
|
||||
return cell
|
||||
}
|
||||
|
||||
return UITableViewCell()
|
||||
}
|
||||
|
||||
|
@@ -33,7 +33,8 @@ class ChatKeyboardView: UIView {
|
||||
private let kLeft: CGFloat = 12.0
|
||||
private let kSpace: CGFloat = 12.0
|
||||
private let kViewWH: CGFloat = 26.0
|
||||
private let kLineHeight: CGFloat = 0.75
|
||||
private let kTextHeight: CGFloat = 36
|
||||
|
||||
|
||||
// MARK: - var lazy
|
||||
|
||||
@@ -69,7 +70,7 @@ class ChatKeyboardView: UIView {
|
||||
fileprivate lazy var changeButton : UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
let x: CGFloat = self.kLeft
|
||||
button.frame = CGRect(x: x, y: self.kSpace + 5, width: self.kViewWH, height: self.kViewWH)
|
||||
button.frame = CGRect(x: x, y: self.kSpace + (kTextHeight - kViewWH) / 2.0, width: self.kViewWH, height: self.kViewWH)
|
||||
button.setImage(UIImage(named: "chat_input_text"), for: .normal)
|
||||
button.setImage(UIImage(named: "chat_voice"), for: .highlighted)
|
||||
button.addTarget(self, action: #selector(changeDidAction(_:)), for: .touchUpInside)
|
||||
@@ -80,7 +81,7 @@ class ChatKeyboardView: UIView {
|
||||
fileprivate lazy var moreButton : UIButton = {
|
||||
let button = UIButton(type: .custom)
|
||||
let x: CGFloat = ScreenWidth - self.kViewWH - self.kSpace
|
||||
button.frame = CGRect(x: x, y: self.kSpace + 5, width: self.kViewWH, height: self.kViewWH)
|
||||
button.frame = CGRect(x: x, y: self.kSpace + (kTextHeight - kViewWH) / 2.0, width: self.kViewWH, height: self.kViewWH)
|
||||
button.setImage(UIImage(named: "chat_more"), for: .normal)
|
||||
button.setImage(UIImage(named: "chat_more"), for: .highlighted)
|
||||
button.addTarget(self, action: #selector(moreDidAction(_:)), for: .touchUpInside)
|
||||
@@ -90,7 +91,7 @@ class ChatKeyboardView: UIView {
|
||||
/// 文本输入框
|
||||
fileprivate lazy var chatTextView: ChatGrowingTextView = {
|
||||
let w: CGFloat = ScreenWidth - self.kViewWH * 2 - self.kSpace * 3 - self.kSpace
|
||||
let textView = ChatGrowingTextView(frame: CGRect(x: self.kSpace + self.kLeft + self.kViewWH, y: self.kSpace, width: w, height: 36))
|
||||
let textView = ChatGrowingTextView(frame: CGRect(x: self.kSpace + self.kLeft + self.kViewWH, y: self.kSpace, width: w, height: kTextHeight))
|
||||
textView.placeholder = "请输入..."
|
||||
textView.textColor = ThemeColor(hexStr: "#000000")
|
||||
textView.maxNumberOfLines = 5
|
||||
@@ -310,6 +311,7 @@ extension ChatKeyboardView {
|
||||
keyboardHeight = endFrame.height
|
||||
// 键盘弹出状态
|
||||
isShowKeyboard = false
|
||||
contentHeight = 0
|
||||
|
||||
let option = userInfo["UIKeyboardAnimationCurveUserInfoKey"] as! Int
|
||||
let changedY = ScreenHeight - self.toolBarHeight - self.contentHeight
|
||||
@@ -413,6 +415,14 @@ extension ChatKeyboardView {
|
||||
delegate?.keyboard(self, DidBecome: true)
|
||||
}
|
||||
|
||||
func hiddenMoreView() {
|
||||
contentView.isHidden = true
|
||||
moreMenuView.isHidden = true
|
||||
isShowMore = false
|
||||
contentHeight = 0.0
|
||||
restToolbarContentHeight()
|
||||
}
|
||||
|
||||
/// 更改容器高度
|
||||
func restToolbarContentHeight(_ isRest: Bool = false) {
|
||||
var changedY = ScreenHeight - self.toolBarHeight - contentHeight
|
||||
@@ -433,6 +443,8 @@ extension ChatKeyboardView {
|
||||
self.layoutIfNeeded()
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
// MARK: - 改变输入框高度位置
|
||||
@@ -446,7 +458,7 @@ extension ChatKeyboardView {
|
||||
toolBarView.frame = CGRect(x: toolBarView.x, y: 0, width: toolBarView.width, height: toolBarHeight)
|
||||
|
||||
let spaceY = toolBarView.height - kSpace - kViewWH
|
||||
chatTextView.frame = CGRect(x: chatTextView.x, y: chatTextView.x, width: chatTextView.width, height: textHeight)
|
||||
chatTextView.frame = CGRect(x: chatTextView.x, y: chatTextView.y, width: chatTextView.width, height: textHeight)
|
||||
moreButton.frame = CGRect(x: moreButton.x, y: spaceY, width: moreButton.width, height: moreButton.height)
|
||||
contentView.frame = CGRect(x: contentView.x, y: toolBarView.maxY, width: contentView.width, height: contentHeight)
|
||||
|
||||
|
@@ -112,10 +112,10 @@ class ChatVoiceObject: ChatBaseObject {
|
||||
required init(msg: NIMMessage?) {
|
||||
super.init(msg: msg)
|
||||
type = .voice
|
||||
let voiceHeight = 30.0
|
||||
let voiceHeight = 40.0
|
||||
if let content = msg?.messageObject as? NIMAudioObject {
|
||||
let scale = 2*atan((Double(content.duration)/1000.0-1)/10.0)/M_PI;
|
||||
let low = (ChatUIConfig.layout.contentMaxWidth - 180)
|
||||
let scale = 2*atan((Double(content.duration)/1000.0-1)/9.0)/M_PI;
|
||||
let low = (ChatUIConfig.layout.contentMaxWidth - 160)
|
||||
let max = (ChatUIConfig.layout.contentMaxWidth - 100)
|
||||
let width = (max - low) * scale + low
|
||||
if let path = content.path {
|
||||
@@ -125,7 +125,7 @@ class ChatVoiceObject: ChatBaseObject {
|
||||
contentSize = CGSize(width: width, height: voiceHeight)
|
||||
height = Float(voiceHeight + ChatUIConfig.layout.cellContentInsets.bottom + ChatUIConfig.layout.cellContentInsets.top)
|
||||
} else {
|
||||
let low = (ChatUIConfig.layout.contentMaxWidth - 180)
|
||||
let low = (ChatUIConfig.layout.contentMaxWidth - 160)
|
||||
contentSize = CGSize(width: low , height: voiceHeight)
|
||||
height = Float(voiceHeight + ChatUIConfig.layout.cellContentInsets.bottom + ChatUIConfig.layout.cellContentInsets.top)
|
||||
}
|
||||
|
@@ -25,13 +25,12 @@ public protocol ChatViewModelDelegate: NSObjectProtocol {
|
||||
|
||||
func send(_ message: NIMMessage, didCompleteWithError error: Error?)
|
||||
func send(_ message: NIMMessage, progress: Float)
|
||||
func onRecvMessages(_ messages: [NIMMessage])
|
||||
func onRecvMessages1(_ messages: [NIMMessage])
|
||||
func willSend(_ message: NIMMessage)
|
||||
}
|
||||
|
||||
|
||||
public class ChatViewModel: NSObject,
|
||||
NIMConversationManagerDelegate, NIMSystemNotificationManagerDelegate {
|
||||
public class ChatViewModel: NSObject, NIMChatManagerDelegate {
|
||||
private var userInfo = [String: NIMUser]()
|
||||
public let messagPageNum: UInt = 100
|
||||
|
||||
@@ -52,8 +51,6 @@ public class ChatViewModel: NSObject,
|
||||
|
||||
private func addMessageListener() {
|
||||
NIMSDK.shared().chatManager.add(self)
|
||||
NIMSDK.shared().conversationManager.add(self)
|
||||
NIMSDK.shared().systemNotificationManager.add(self)
|
||||
}
|
||||
|
||||
init(session: NIMSession) {
|
||||
@@ -316,6 +313,67 @@ public class ChatViewModel: NSObject,
|
||||
}
|
||||
}
|
||||
|
||||
public func send(_ message: NIMMessage, didCompleteWithError error: Error?) {
|
||||
for (i, msg) in messageObjects.enumerated() {
|
||||
if message.messageId == msg.msg?.messageId {
|
||||
messageObjects[i].msg = message
|
||||
break
|
||||
}
|
||||
}
|
||||
delegate?.send(message, didCompleteWithError: error)
|
||||
}
|
||||
|
||||
|
||||
// 收到消息
|
||||
public func onRecvMessages(_ messages: [NIMMessage]) {
|
||||
for msg in messages {
|
||||
if msg.session?.sessionId == session.sessionId {
|
||||
if let model = modelTransformMessage(message: msg) {
|
||||
newMsg = msg
|
||||
addTimeMessage(msg)
|
||||
self.messageObjects.append(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate?.onRecvMessages1(messages)
|
||||
}
|
||||
|
||||
public func willSend(_ message: NIMMessage) {
|
||||
if message.session?.sessionId != session.sessionId {
|
||||
return
|
||||
}
|
||||
guard let model = modelTransformMessage(message: message) else { return }
|
||||
|
||||
if newMsg == nil {
|
||||
newMsg = message
|
||||
}
|
||||
|
||||
var isResend = false
|
||||
for (i, msg) in messageObjects.enumerated() {
|
||||
if message.messageId == msg.msg?.messageId {
|
||||
messageObjects[i].msg = message
|
||||
isResend = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isResend {
|
||||
addTimeMessage(message)
|
||||
messageObjects.append(model)
|
||||
}
|
||||
delegate?.didAppend(message)
|
||||
|
||||
}
|
||||
|
||||
public func onReceive(_ notification: NIMCustomSystemNotification) {
|
||||
|
||||
}
|
||||
|
||||
public func send(_ message: NIMMessage, progress: Float) {
|
||||
delegate?.send(message, progress: progress)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@discardableResult
|
||||
public func resendMessage(message: NIMMessage) -> Error? {
|
||||
@@ -600,66 +658,3 @@ public class ChatViewModel: NSObject,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extension ChatViewModel: NIMChatManagerDelegate {
|
||||
// MARK: NIMChatManagerDelegate
|
||||
public func send(_ message: NIMMessage, didCompleteWithError error: Error?) {
|
||||
for (i, msg) in messageObjects.enumerated() {
|
||||
if message.messageId == msg.msg?.messageId {
|
||||
messageObjects[i].msg = message
|
||||
break
|
||||
}
|
||||
}
|
||||
delegate?.send(message, didCompleteWithError: error)
|
||||
}
|
||||
|
||||
// 收到消息
|
||||
public func onRecvMessages(_ messages: [NIMMessage]) {
|
||||
for msg in messages {
|
||||
if msg.session?.sessionId == session.sessionId {
|
||||
if let model = modelTransformMessage(message: msg) {
|
||||
newMsg = msg
|
||||
addTimeMessage(msg)
|
||||
self.messageObjects.append(model)
|
||||
}
|
||||
}
|
||||
}
|
||||
delegate?.onRecvMessages(messages)
|
||||
}
|
||||
|
||||
public func willSend(_ message: NIMMessage) {
|
||||
if message.session?.sessionId != session.sessionId {
|
||||
return
|
||||
}
|
||||
guard let model = modelTransformMessage(message: message) else { return }
|
||||
|
||||
if newMsg == nil {
|
||||
newMsg = message
|
||||
}
|
||||
|
||||
var isResend = false
|
||||
for (i, msg) in messageObjects.enumerated() {
|
||||
if message.messageId == msg.msg?.messageId {
|
||||
messageObjects[i].msg = message
|
||||
isResend = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if !isResend {
|
||||
addTimeMessage(message)
|
||||
messageObjects.append(model)
|
||||
}
|
||||
delegate?.didAppend(message)
|
||||
|
||||
}
|
||||
|
||||
public func onReceive(_ notification: NIMCustomSystemNotification) {
|
||||
|
||||
}
|
||||
|
||||
public func send(_ message: NIMMessage, progress: Float) {
|
||||
delegate?.send(message, progress: progress)
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -55,7 +55,7 @@ class ChatBaseCell: UITableViewCell, Reusable{
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
selectionStyle = .none
|
||||
backgroundColor = ThemeColor(hexStr: "#F8F8FB")
|
||||
backgroundColor = .clear
|
||||
contentView.addSubview(avatarImgView)
|
||||
contentView.addSubview(bubbleView)
|
||||
contentView.addSubview(activityIndicatorView)
|
||||
|
@@ -37,6 +37,11 @@ class ChatImageCell: ChatBaseCell {
|
||||
return imageView
|
||||
}()
|
||||
|
||||
override func layoutMessageCell() {
|
||||
super.layoutMessageCell()
|
||||
setupCellLayout()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension ChatImageCell {
|
||||
|
@@ -8,6 +8,7 @@
|
||||
import UIKit
|
||||
|
||||
class ChatNavView: BaseView {
|
||||
var uid:String = ""
|
||||
|
||||
var isLike:Bool? {
|
||||
didSet {
|
||||
@@ -54,6 +55,7 @@ class ChatNavView: BaseView {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "chat_back"), for: .normal)
|
||||
button.setImage(UIImage(named: "chat_back"), for: .selected)
|
||||
button.addTarget(self, action: #selector(backClick), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
@@ -82,10 +84,35 @@ class ChatNavView: BaseView {
|
||||
let button = UIButton(type: .custom)
|
||||
button.setImage(UIImage(named: "chat_opt"), for: .normal)
|
||||
button.setImage(UIImage(named: "chat_opt"), for: .selected)
|
||||
button.addTarget(self, action: #selector(optClick), for: .touchUpInside)
|
||||
return button
|
||||
}()
|
||||
|
||||
@objc func optClick() {
|
||||
let alertController = UIAlertController(title: nil,
|
||||
message: nil,
|
||||
preferredStyle: .actionSheet)
|
||||
|
||||
alertController.addAction(UIAlertAction(title: "举报", style: .default, handler: { action in
|
||||
HUDTool.show(with: "举报成功, 我们将尽快处理")
|
||||
}))
|
||||
|
||||
alertController.addAction(UIAlertAction(title: "取消", style: .cancel, handler: { action in
|
||||
|
||||
}))
|
||||
YMRequestX.topViewController()?.present(alertController, animated: true, completion: nil)
|
||||
}
|
||||
|
||||
@objc func likeClick() {
|
||||
//TODO: 关注
|
||||
let params:[String: Any] = ["uid": AuthManager.userUid, "ticket": AuthManager.ticket, "type":"1", "likedUid": uid]
|
||||
RequestPost(path: "fans/like", parma: params) { _ in
|
||||
self.likeBtn.isHidden = true
|
||||
} fail: { code, msg in
|
||||
HUDTool.show(with: msg)
|
||||
}
|
||||
}
|
||||
|
||||
@objc func backClick() {
|
||||
YMRequestX.topViewController()?.navigationController?.popViewController(animated: true)
|
||||
}
|
||||
}
|
||||
|
@@ -21,7 +21,7 @@ class ChatTimeCell: UITableViewCell, Reusable {
|
||||
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
selectionStyle = .none
|
||||
backgroundColor = ThemeColor(hexStr: "#F8F8FB")
|
||||
backgroundColor = .clear
|
||||
contentView.addSubview(timeLb)
|
||||
timeLb.snp.makeConstraints { make in
|
||||
make.edges.equalTo(contentView)
|
||||
|
@@ -12,7 +12,7 @@ class ChatVoiceCell: ChatBaseCell, NIMMediaManagerDelegate {
|
||||
override var model: ChatSessionProtocol? {
|
||||
didSet {
|
||||
if let model = model as? ChatVoiceObject {
|
||||
timeLabel.text = "\(model.duartion / 1000)"
|
||||
timeLabel.text = "\(model.duartion / 1000)s"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -28,8 +28,8 @@ class ChatVoiceCell: ChatBaseCell, NIMMediaManagerDelegate {
|
||||
let imageView = UIImageView()
|
||||
imageView.isUserInteractionEnabled = true
|
||||
let firstImage = UIImage(named:"chat_audio_playing_first")!
|
||||
let second = UIImage(named:"chat_audio_playing_first")!
|
||||
let third = UIImage(named:"chat_audio_playing_first")!
|
||||
let second = UIImage(named:"chat_audio_playing_second")!
|
||||
let third = UIImage(named:"chat_audio_playing_third")!
|
||||
imageView.animationImages = [firstImage, second, third];
|
||||
imageView.animationDuration = 1
|
||||
imageView.animationRepeatCount = 100
|
||||
@@ -42,6 +42,8 @@ class ChatVoiceCell: ChatBaseCell, NIMMediaManagerDelegate {
|
||||
NIMSDK.shared().mediaManager.setNeedProximityMonitor(false)
|
||||
NIMSDK.shared().mediaManager.add(self)
|
||||
loadSubViews()
|
||||
let tap = UITapGestureRecognizer(target: self, action: #selector(didTapBackRecognizer))
|
||||
addGestureRecognizer(tap)
|
||||
}
|
||||
|
||||
|
||||
@@ -89,6 +91,10 @@ class ChatVoiceCell: ChatBaseCell, NIMMediaManagerDelegate {
|
||||
}
|
||||
}
|
||||
|
||||
override func layoutMessageCell() {
|
||||
super.layoutMessageCell()
|
||||
setupCellLayout()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user