Skip to content

Commit

Permalink
Merge pull request #18 from zjc19891106/main
Browse files Browse the repository at this point in the history
single chat pin message support&add readme
  • Loading branch information
lixm1988 authored Aug 29, 2024
2 parents 61106a0 + 17c7523 commit a59e634
Show file tree
Hide file tree
Showing 22 changed files with 140 additions and 39 deletions.
Binary file modified Documentation/IndicatorImages/contactInfo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Documentation/IndicatorImages/groupInfo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion EaseChatUIKit.podspec
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

Pod::Spec.new do |s|
s.name = 'EaseChatUIKit'
s.version = '4.8.0'
s.version = '4.9.0'
s.summary = 'A easy for use ChatUIKit.'

# This description is used to generate tags and improve search results.
Expand Down
50 changes: 50 additions & 0 deletions EaseChatUIKitChangeLog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# EaseChatUIKit change log

## 4.8.0
1.消息页面新增功能
- 消息置顶
- 文本消息URL预览
- 消息输入中状态

2.联系人
- 黑名单

## 4.6.0

1.会话列表界面
- 会话置顶
- 会话删除
- 会话免打扰
- 会话已读
- 更多扩展操作菜单

2.联系人列表界面
- 联系人列表
- 好友请求
- 群组列表及其后续

3.聊天界面

- 消息内容的显示可配置
- 消息扩展功能复制、删除、多选合并转发、单条转发、撤回、创建话题(群内消息)、表情回应、消息回复、消息翻译、消息举报、消息编辑。
- 发送文本、音频、视频、文件、联系人名片、表情、图片。
- 各种消息的预览。
- 消息气泡两种样式切换。
- 后续消息搜索等。

4.公共UI组件
- 导航栏
- 弹窗
- 底部弹层
- Loading页面
- Toast工具
- 图片加载存储组件
- 换肤协议工具
- 字体工具类
- 主题颜色工具类

5.工具类
- 国际化工具
- 音频amr格式转换工具
- 各种扩展工具

Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import Foundation

public let EaseChatUIKit_VERSION = "4.8.0"
public let EaseChatUIKit_VERSION = "4.9.0"

public let cache_update_notification = "EaseChatUIKitContextUpdateCache"

Expand Down Expand Up @@ -74,7 +74,13 @@ public let cache_update_notification = "EaseChatUIKitContextUpdateCache"
EaseChatUIKitContext.shared?.currentUser = user
EaseChatUIKitContext.shared?.chatCache?[user.id] = user
EaseChatUIKitContext.shared?.userCache?[user.id] = user
self.userService = UserServiceImplement(userInfo: user, token: token, completion: completion)
if self.userService != nil {
self.userService?.login(userId: user.id, token: token, completion: { success, error in
completion(error)
})
} else {
self.userService = UserServiceImplement(userInfo: user, token: token, completion: completion)
}
}

/// Logout user
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -450,7 +450,7 @@ extension ConversationServiceImplement: ChatEventsListener {
}

@objc open func onConversationReadCallback(conversation: ChatConversation ) {
conversation.markAllMessages(asRead: nil)
// conversation.markAllMessages(asRead: nil)
if let info = self.mapper(objects: [conversation]).first{
info.unreadCount = 0
for listener in self.responseDelegates.allObjects {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@ extension MessageListController: MessageListDriverEventsListener {
self.messageContainer.editMode = !$0
self.navigation.editMode = !$0
}

UIViewController.currentController?.present(vc, animated: true)
}

Expand Down Expand Up @@ -499,7 +500,7 @@ extension MessageListController: MessageListDriverEventsListener {
messageActions.removeAll { $0.tag == "OriginalText" }
}
}
if !Appearance.chat.enablePinMessage,self.chatType != .chat {
if !Appearance.chat.enablePinMessage {
messageActions.removeAll { $0.tag == "Pin" }
}
if !Appearance.chat.contentStyle.contains(.withReply) {
Expand All @@ -516,9 +517,7 @@ extension MessageListController: MessageListDriverEventsListener {
messageActions.removeAll { $0.tag == "Recall" }
}
}
if self.chatType == .chat {
messageActions.removeAll { $0.tag == "Pin" }
}

return messageActions
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ import UIKit
}

@objc open func fetchPinnedMessages() {
if Appearance.chat.enablePinMessage,self.chatType != .chat {
if Appearance.chat.enablePinMessage {
self.chatService?.pinnedMessages(conversationId: self.to, completion: { [weak self] messages,error in
guard let `self` = self else { return }
if error == nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,15 @@ extension MessageInputBar: UITextViewDelegate {
}

@objc private func keyboardWillHide(notification: Notification) {
if notification.object is MessageInputBar {
if self.rightView.isSelected {
let frame = notification.chat.keyboardEndFrame
let duration = notification.chat.keyboardAnimationDuration
self.hiddenDuration = duration ?? 0
self.keyboardHeight = frame!.height
self.showEmojiKeyboard()
self.textViewFirstResponder?(true)
} else {
self.hiddenInputBar()
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -807,7 +807,7 @@ extension MessageListView: IMessageListViewDriver {

public func reloadReaction(message: ChatMessage) {
if let index = self.messages.firstIndex(where: { $0.message.messageId == message.messageId }) {
if let indexPath = self.messageList.indexPathsForVisibleRows?.first(where: { $0.row == index }),indexPath.row > 0 {
if let indexPath = self.messageList.indexPathsForVisibleRows?.first(where: { $0.row == index }),indexPath.row >= 0 {
let entity = self.convertMessage(message: message)
let reactionWidth = entity.reactionMenuWidth()
if reactionWidth < reactionMaxWidth-30 {
Expand Down Expand Up @@ -836,7 +836,7 @@ extension MessageListView: IMessageListViewDriver {

public func reloadTopic(message: ChatMessage) {
if let index = self.messages.firstIndex(where: { $0.message.messageId == message.messageId }) {
if let indexPath = self.messageList.indexPathsForVisibleRows?.first(where: { $0.row == index }),indexPath.row > 0 {
if let indexPath = self.messageList.indexPathsForVisibleRows?.first(where: { $0.row == index }),indexPath.row >= 0 {
self.messages.replaceSubrange(index...index, with: [self.convertMessage(message: message)])
self.messageList.reloadData()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,18 @@ import UIKit
self.nickName.frame = CGRect(x: self.avatar.frame.maxX+12, y: self.avatar.frame.minX+4, width: self.contentView.frame.width-self.avatar.frame.maxX-12-16-50, height: 16)
self.date.frame = CGRect(x: self.contentView.frame.width-66, y: self.nickName.frame.minY+2, width: 50, height: 16)
self.content.frame = CGRect(x: self.avatar.frame.maxX+12, y: self.nickName.frame.maxY+2, width: self.contentView.frame.width-12-12-16-80, height: 20)
// self.badge.frame = CGRect(x: self.contentView.frame.width-48, y: self.nickName.frame.maxY+5, width: 32, height: 18)
var badgeWidth: CGFloat = 18
if let badgeText = self.badge.text {
if badgeText.count > 2 {
badgeWidth = 32
} else if badgeText.count > 1 {
badgeWidth = 24
}
}
self.badge.frame = CGRect(x: self.contentView.frame.width - badgeWidth - 16,
y: self.nickName.frame.maxY + 5,
width: badgeWidth,
height: 18)
self.dot.frame = CGRect(x: self.date.frame.maxX-12, y: self.nickName.frame.maxY+10, width: 8, height: 8)
self.separatorLine.frame = CGRect(x: self.nickName.frame.minX, y: self.contentView.frame.height-0.5, width: self.contentView.frame.width-self.nickName.frame.minX, height: 0.5)
}
Expand Down Expand Up @@ -124,15 +135,8 @@ import UIKit
} else {
self.badge.isHidden = info.unreadCount <= 0
self.dot.isHidden = true
var badgeWidth = 18
if info.unreadCount > 9 {
badgeWidth = 24
if info.unreadCount > 99 {
badgeWidth = 32
}
}
self.badge.frame = CGRect(x: Int(ScreenWidth)-16-badgeWidth, y: Int(self.nickName.frame.maxY)+5, width: badgeWidth, height: 18)
}
self.setNeedsLayout()
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ extension ConversationListController {
}

extension ConversationListController: ThemeSwitchProtocol {
public func switchTheme(style: ThemeStyle) {
open func switchTheme(style: ThemeStyle) {
self.view.backgroundColor = style == .dark ? UIColor.theme.neutralColor1:UIColor.theme.neutralColor98
self.search.backgroundColor = style == .dark ? UIColor.theme.neutralColor2:UIColor.theme.neutralColor95
self.navigation.backgroundColor = style == .dark ? UIColor.theme.neutralColor1:UIColor.theme.neutralColor98
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ public let disturb_change = "EaseUIKit_do_not_disturb_changed"
deinit {
destroyed()
}

}

//MARK: - ConversationListActionEventsDelegate
Expand Down Expand Up @@ -447,7 +448,15 @@ extension ConversationViewModel: ConversationServiceListener {

@objc open func conversationMessageAlreadyReadOnOtherDevice(info: ConversationInfo) {
info.unreadCount = 0
self.service?.markAllMessagesAsRead(conversationId: info.id)
if let infos = ChatClient.shared().chatManager?.getAllConversations(true) {
let items = self.mapper(objects: infos)
var count = UInt(0)
for item in items where item.doNotDisturb == false {
count += item.unreadCount
}
self.service?.notifyUnreadCount(count: count)
}
// self.service?.markAllMessagesAsRead(conversationId: info.id)
self.driver?.swipeMenuOperation(info: info, type: .read)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ private func consoleLog<T> (
debugPrint("\(timeString) \(type.rawValue) \(fileName):\(line) EaseChatUIKit Log:\(message) function Name:\(functionName)")
#else
if type == .error {
Log.saveLog(" EaseChatUIKit Log:\(message)",file: file,function: function,line: line)
Log.saveLog(" EaseChatUIKit Log:\(message) \n",file: file,function: function,line: line)
}
#endif
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public let edgeZero: UIEdgeInsets = .zero
public let BottomBarHeight = UIApplication.shared.windows.first?.safeAreaInsets.bottom ?? 0

/// The height of the status bar.
public let StatusBarHeight :CGFloat = BottomBarHeight > 0 ? 43:20
public let StatusBarHeight :CGFloat = UIApplication.shared.statusBarFrame.height

/// The height of the navigation bar, which includes the status bar.
public let NavigationHeight :CGFloat = StatusBarHeight + 44
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ import UIKit
}

public private(set) lazy var titleLabel: UILabel = {
UILabel(frame: CGRect(x: self.avatar.frame.maxX+4, y: StatusBarHeight+2, width: ScreenWidth-self.avatar.frame.maxX*2-8*3, height: 22)).font(UIFont.theme.headlineSmall).textColor(UIColor.theme.neutralColor1).backgroundColor(.clear).tag(2)
UILabel(frame: CGRect(x: self.avatar.frame.maxX+4, y: (nearStatusBar ? StatusBarHeight:0)+2, width: ScreenWidth-self.avatar.frame.maxX*2-8*3, height: 22)).font(UIFont.theme.headlineSmall).textColor(UIColor.theme.neutralColor1).backgroundColor(.clear).tag(2)
}()

public private(set) lazy var detail: UILabel = {
Expand Down Expand Up @@ -141,6 +141,10 @@ import UIKit
public private(set) lazy var cancel: UIButton = {
UIButton(type: .custom).frame(CGRect(x: ScreenWidth-58, y: self.frame.height-36, width: 50, height: 28)).backgroundColor(.clear).title("barrage_long_press_menu_cancel".chat.localize, .normal).font(UIFont.theme.labelMedium).textColor(UIColor.theme.primaryColor5, .normal).tag(4).addTargetFor(self, action: #selector(buttonAction(sender:)), for: .touchUpInside)
}()

private var originalRenderRightImage = false

private var nearStatusBar = true

internal override init(frame: CGRect) {
super.init(frame: frame)
Expand All @@ -154,9 +158,10 @@ import UIKit
/// - avatarURL: Avatar url.
/// - rightImages: Right buttons kind of `[UIImage]`.
/// - hiddenAvatar: Whether hide avatar or not.
@objc required public convenience init(frame: CGRect = CGRect(x: 0, y: 0, width: ScreenWidth, height: NavigationHeight),showLeftItem: Bool, textAlignment: NSTextAlignment = .center, placeHolder: UIImage? = nil,avatarURL: String? = nil,rightImages: [UIImage] = [],hiddenAvatar: Bool = false) {
@objc required public convenience init(frame: CGRect = CGRect(x: 0, y: 0, width: ScreenWidth, height: NavigationHeight),showLeftItem: Bool, textAlignment: NSTextAlignment = .center, placeHolder: UIImage? = nil,avatarURL: String? = nil,rightImages: [UIImage] = [],hiddenAvatar: Bool = false,nearStatusBar: Bool = true) {
self.init(frame: frame)
self.showLeft = showLeftItem
self.nearStatusBar = nearStatusBar
if showLeftItem {
var width = CGFloat(self.rightImages.count*36)
if self.avatar.frame.maxX+4 > width {
Expand All @@ -167,7 +172,7 @@ import UIKit
} else {
self.addSubViews([self.leftItem,self.avatar,self.status,self.titleLabel,self.detail,self.rightItems,self.separateLine,self.cancel])
}
self.titleLabel.frame = CGRect(x: (hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8, y: StatusBarHeight+4, width: ScreenWidth - width*2 - 4, height: 22)
self.titleLabel.frame = CGRect(x: (hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8, y: (nearStatusBar ? StatusBarHeight:0)+4, width: ScreenWidth - width*2 - 4, height: 22)
if textAlignment == .center {
self.titleLabel.center = CGPoint(x: self.center.x, y: self.titleLabel.center.y)
}
Expand All @@ -180,7 +185,7 @@ import UIKit
}
self.bringSubviewToFront(self.avatar)
self.bringSubviewToFront(self.status)
self.titleLabel.frame = CGRect(x: (hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8, y: StatusBarHeight+4, width: ScreenWidth - CGFloat(self.rightImages.count*36)*2, height: 22)
self.titleLabel.frame = CGRect(x: (hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8, y: (nearStatusBar ? StatusBarHeight:0), width: ScreenWidth - CGFloat(self.rightImages.count*36)*2, height: 22)
if textAlignment == .center {
self.titleLabel.center = CGPoint(x: self.center.x, y: self.titleLabel.center.y)
}
Expand All @@ -198,8 +203,9 @@ import UIKit
self.addGesture()
self.cancel.isHidden = true
self.leftItem.center = CGPoint(x: self.leftItem.center.x, y: self.leftItem.center.y-2)
self.avatar.frame = CGRect(x: self.showLeft ? self.leftItem.frame.maxX:CGFloat(10), y: self.frame.height-38, width: 32, height: 32)
self.updateRightItems(images: rightImages)
self.titleLabel.frame = CGRect(x: (hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8, y: StatusBarHeight+4, width: ScreenWidth - self.rightItems.frame.width - 8 - ((hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8), height: 22)
self.titleLabel.frame = CGRect(x: (hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8, y: (nearStatusBar ? StatusBarHeight:0)+4, width: ScreenWidth - self.rightItems.frame.width - 8 - ((hiddenAvatar ? self.leftItem.frame.maxX:self.avatar.frame.maxX)+8), height: 22)
self.detail.frame = CGRect(x: self.titleLabel.frame.minX, y: self.titleLabel.frame.maxY, width: self.titleLabel.frame.width, height: 14)
self.status.isHidden = Appearance.hiddenPresence
Theme.registerSwitchThemeViews(view: self)
Expand Down Expand Up @@ -269,27 +275,33 @@ import UIKit
}
}

@objc public func updateRightItems(images: [UIImage]) {
@objc public func updateRightItems(images: [UIImage],original: Bool = false) {
self.originalRenderRightImage = original
self.rightImages.removeAll()
if images.count > 3 {
self.rightImages = Array(images.prefix(3))
} else {
self.rightImages.append(contentsOf: images)
}
self.rightItems.frame = CGRect(x: ScreenWidth-CGFloat(images.count*36)-8, y: StatusBarHeight+8, width: CGFloat(images.count*36), height: 36)
self.rightItems.frame = CGRect(x: ScreenWidth-CGFloat(images.count*36)-8, y: (nearStatusBar ? StatusBarHeight:0)+8, width: CGFloat(images.count*36), height: 36)
self.rightItems.reloadData()
}

}

extension EaseChatNavigationBar: UICollectionViewDataSource,UICollectionViewDelegate {

public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
self.rightImages.count
}

public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "EaseChatNavigationBarRightCell", for: indexPath) as? EaseChatNavigationBarRightCell
cell?.imageView.image = self.rightImages[safe: indexPath.row]?.withTintColor(Theme.style == .dark ? UIColor.theme.neutralColor98:UIColor.theme.neutralColor3)
if self.originalRenderRightImage {
cell?.imageView.image = self.rightImages[safe: indexPath.row]?.withRenderingMode(.alwaysOriginal)
} else {
cell?.imageView.image = self.rightImages[safe: indexPath.row]?.withTintColor(Theme.style == .dark ? UIColor.theme.neutralColor98:UIColor.theme.neutralColor3)
}
return cell ?? UICollectionViewCell()
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,12 @@ import Combine
/// - placeHolder: An optional placeholder image to display while the image is being loaded.
@MainActor public func image(with url: String,placeHolder: UIImage?) {
self.image = placeHolder
var urlString = url.lowercased()
var urlString = ""
if url.hasSuffix(".png") || url.hasSuffix(".jpg") || url.hasSuffix(".jpeg") {
urlString = url
} else {
urlString = url.lowercased()
}
if !url.hasPrefix("http://"), !url.hasPrefix("https://") {
urlString = "https://" + url
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import UIKit

public var presentedViewComponent: PresentedViewComponent? = PresentedViewComponent(contentSize: Appearance.pageContainerConstraintsSize,destination: .bottomBaseline,canTapBGDismiss: true)

var customView: UIView?
public var customView: UIView?

override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import UIKit
private var pageTitles = [String]()

private var childControllers = [UIViewController]()

public var willRemoveClosure: (() -> ())?

lazy var container: PageContainer = {
PageContainer(frame: CGRect(x: 0, y: 0, width: self.presentedViewComponent?.contentSize.width ?? 0, height: self.presentedViewComponent?.contentSize.height ?? 0), viewControllers: self.childControllers, indicators: self.pageTitles).cornerRadius(.medium, [.topLeft,.topRight], .clear, 0).backgroundColor(UIColor.theme.neutralColor98)
Expand Down Expand Up @@ -63,6 +65,11 @@ import UIKit
self.view.backgroundColor(.clear)
self.view.addSubview(self.container)
}

public override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
self.willRemoveClosure?()
}
}


Expand Down
Loading

0 comments on commit a59e634

Please sign in to comment.