170 lines
5.2 KiB
Swift
170 lines
5.2 KiB
Swift
//
|
|
// ChatBaseObject.swift
|
|
// yinmeng-ios
|
|
//
|
|
// Created by yinmeng on 2024/2/27.
|
|
//
|
|
|
|
import Foundation
|
|
import NIMSDK
|
|
|
|
public enum SessionType: Int {
|
|
case text = 1
|
|
case image
|
|
case time
|
|
case voice
|
|
}
|
|
|
|
|
|
public protocol ChatSessionProtocol: NSObjectProtocol {
|
|
var msg:NIMMessage? {get set}
|
|
// 气泡区域的大小 不包含气泡上下到cell上下的边距
|
|
var contentSize: CGSize { get set }
|
|
///高度
|
|
var height: Float { get set }
|
|
///用户的id
|
|
var userID: String? { get set }
|
|
///用户昵称
|
|
var name: String? { get set }
|
|
///头像
|
|
var avatar: String? { get set }
|
|
///消息的类型
|
|
var type:SessionType{get set}
|
|
|
|
init(msg: NIMMessage?)
|
|
}
|
|
|
|
|
|
open class ChatBaseObject:NSObject, ChatSessionProtocol {
|
|
|
|
public var msg: NIMMessage?
|
|
public var contentSize: CGSize
|
|
public var height: Float
|
|
public var userID: String?
|
|
public var name: String?
|
|
public var avatar: String?
|
|
public var type: SessionType = .text
|
|
|
|
public required init(msg: NIMMessage?) {
|
|
self.msg = msg
|
|
if let uid = msg?.from {
|
|
self.userID = uid
|
|
let user = NIMSDK.shared().userManager.userInfo(uid)
|
|
self.avatar = user?.userInfo?.avatarUrl
|
|
self.name = user?.userInfo?.nickName
|
|
}
|
|
contentSize = CGSize(width: 32.0, height: ChatUIConfig.layout.bubbleMinHeight)
|
|
height = Float(ChatUIConfig.layout.bubbleMinHeight + ChatUIConfig.layout.margin)
|
|
}
|
|
}
|
|
|
|
|
|
class ChatTextObject: ChatBaseObject {
|
|
public var attribute: NSMutableAttributedString?
|
|
required init(msg: NIMMessage?) {
|
|
super.init(msg: msg)
|
|
type = .text
|
|
|
|
let style = NSMutableParagraphStyle()
|
|
style.lineSpacing = 6
|
|
let attributeStr = NSMutableAttributedString(string: msg?.text ?? "", attributes: [NSAttributedString.Key.font: ChatUIConfig.ui.messageFont, NSAttributedString.Key.foregroundColor:ThemeColor(hexStr: "#2B2D33"), NSAttributedString.Key.paragraphStyle: style])
|
|
attribute = attributeStr
|
|
let textSize = ChatAttributeTool.boundingRect(attribute: attributeStr, font: ChatUIConfig.ui.messageFont, maxSize: CGSize(width: ChatUIConfig.layout.contentMaxWidth, height: CGFloat.greatestFiniteMagnitude))
|
|
|
|
var h = ChatUIConfig.layout.bubbleMinHeight
|
|
h = textSize.height + 1 + ChatUIConfig.layout.textInsets.top + ChatUIConfig.layout.textInsets.bottom
|
|
if h < 36 {
|
|
h = 36
|
|
}
|
|
contentSize = CGSize(width: textSize.width + ChatUIConfig.layout.textInsets.left + ChatUIConfig.layout.textInsets.right + 1, height: h)
|
|
|
|
height = Float(contentSize.height + ChatUIConfig.layout.cellContentInsets.bottom + ChatUIConfig.layout.cellContentInsets.top)
|
|
}
|
|
}
|
|
|
|
class ChatTimeObject: ChatBaseObject {
|
|
var text:String = ""
|
|
required init(msg: NIMMessage?) {
|
|
super.init(msg: msg)
|
|
type = .time
|
|
text = timestrToTimeSecond("\(msg?.timestamp ?? 0)")
|
|
contentSize = CGSize(width: ScreenWidth, height: 30)
|
|
height = Float(50)
|
|
}
|
|
}
|
|
|
|
class ChatImageObject: ChatBaseObject {
|
|
var url:String = ""
|
|
required init(msg: NIMMessage?) {
|
|
super.init(msg: msg)
|
|
type = .image
|
|
if let content = msg?.messageObject as? NIMImageObject {
|
|
url = content.url ?? content.thumbUrl ?? ""
|
|
}
|
|
contentSize = CGSize(width: 200 , height: 200)
|
|
height = Float(200 + ChatUIConfig.layout.cellContentInsets.bottom + ChatUIConfig.layout.cellContentInsets.top)
|
|
}
|
|
}
|
|
|
|
class ChatVoiceObject: ChatBaseObject {
|
|
var filPath:String = ""
|
|
var duartion:Int = 0
|
|
required init(msg: NIMMessage?) {
|
|
super.init(msg: msg)
|
|
type = .voice
|
|
let voiceHeight = 40.0
|
|
if let content = msg?.messageObject as? NIMAudioObject {
|
|
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 {
|
|
filPath = path
|
|
}
|
|
duartion = content.duration
|
|
contentSize = CGSize(width: width, height: voiceHeight)
|
|
height = Float(voiceHeight + ChatUIConfig.layout.cellContentInsets.bottom + ChatUIConfig.layout.cellContentInsets.top)
|
|
} else {
|
|
let low = (ChatUIConfig.layout.contentMaxWidth - 160)
|
|
contentSize = CGSize(width: low , height: voiceHeight)
|
|
height = Float(voiceHeight + ChatUIConfig.layout.cellContentInsets.bottom + ChatUIConfig.layout.cellContentInsets.top)
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
func timestrToTimeSecond(_ timeStr: String) -> String {
|
|
let interval = TimeInterval(timeStr) ?? 0
|
|
let date = Date(timeIntervalSince1970: interval)
|
|
return stringFromDate(date)
|
|
}
|
|
|
|
func stringFromDate(_ date: Date) -> String {
|
|
let currentFormatter = DateFormatter()
|
|
if isDateInToday(date) {
|
|
currentFormatter.dateFormat = "HH:mm"
|
|
} else {
|
|
if date.timeIntervalSince1970 > 0 {
|
|
currentFormatter.dateFormat = "MM月dd日 HH:mm"
|
|
} else {
|
|
currentFormatter.dateFormat = "yyyy年MM月dd日 HH:mm"
|
|
}
|
|
}
|
|
let dateString = currentFormatter.string(from: date)
|
|
return dateString
|
|
}
|
|
|
|
func isDateInToday(_ date: Date) -> Bool {
|
|
let secondsPerDay: TimeInterval = 24 * 60 * 60
|
|
let today = Date()
|
|
let tomorrow = today.addingTimeInterval(secondsPerDay)
|
|
let yesterday = today.addingTimeInterval(-secondsPerDay)
|
|
|
|
let todayString = String(describing: today).prefix(10)
|
|
let yesterdayString = String(describing: yesterday).prefix(10)
|
|
let tomorrowString = String(describing: tomorrow).prefix(10)
|
|
let dateString = String(describing: date).prefix(10)
|
|
|
|
return dateString == todayString
|
|
}
|