mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-09 12:56:15 +10:00
Merge branch 'develop' of https://github.com/CatchChat/Yep into develop
This commit is contained in:
@@ -43,7 +43,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
let directory: NSURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier(YepConfig.appGroupID)!
|
||||
let realmPath = directory.URLByAppendingPathComponent("db.realm").path!
|
||||
|
||||
return Realm.Configuration(path: realmPath, schemaVersion: 17, migrationBlock: { migration, oldSchemaVersion in
|
||||
return Realm.Configuration(path: realmPath, schemaVersion: 18, migrationBlock: { migration, oldSchemaVersion in
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+60
-20
@@ -511,6 +511,14 @@ class Message: Object {
|
||||
dynamic var mediaType: Int = MessageMediaType.Text.rawValue
|
||||
|
||||
dynamic var textContent: String = ""
|
||||
var textContentToShow: String {
|
||||
if deletedByCreator {
|
||||
return NSLocalizedString("Deleted by creator.", comment: "")
|
||||
} else {
|
||||
return textContent
|
||||
}
|
||||
}
|
||||
|
||||
dynamic var coordinate: Coordinate?
|
||||
|
||||
dynamic var attachmentURLString: String = ""
|
||||
@@ -550,7 +558,8 @@ class Message: Object {
|
||||
dynamic var sendState: Int = MessageSendState.NotSend.rawValue
|
||||
dynamic var readed: Bool = false
|
||||
dynamic var mediaPlayed: Bool = false // 音频播放过,图片查看过等
|
||||
dynamic var deleted: Bool = false // 标记已被删除,删除对方消息,使之不再显示
|
||||
dynamic var hidden: Bool = false // 隐藏对方消息,使之不再显示
|
||||
dynamic var deletedByCreator: Bool = false
|
||||
|
||||
dynamic var fromFriend: User?
|
||||
dynamic var conversation: Conversation?
|
||||
@@ -611,6 +620,25 @@ class Message: Object {
|
||||
break // TODO: if have other message media need to delete
|
||||
}
|
||||
}
|
||||
|
||||
func deleteInRealm(realm: Realm) {
|
||||
deleteAttachmentInRealm(realm)
|
||||
realm.delete(self)
|
||||
}
|
||||
|
||||
func updateForDeletedFromServerInRealm(realm: Realm) {
|
||||
|
||||
deletedByCreator = true
|
||||
|
||||
// 删除附件
|
||||
deleteAttachmentInRealm(realm)
|
||||
|
||||
// 再将其变为文字消息
|
||||
sendState = MessageSendState.Read.rawValue
|
||||
readed = true
|
||||
textContent = ""
|
||||
mediaType = MessageMediaType.Text.rawValue
|
||||
}
|
||||
}
|
||||
|
||||
class Draft: Object {
|
||||
@@ -708,6 +736,10 @@ class Conversation: Object {
|
||||
}
|
||||
|
||||
dynamic var unreadMessagesCount: Int = 0
|
||||
|
||||
var latestValidMessage: Message? {
|
||||
return messages.filter({ ($0.hidden == false) && ($0.deletedByCreator == false && ($0.mediaType != MessageMediaType.SectionDate.rawValue)) }).sort({ $0.createdUnixTime > $1.createdUnixTime }).first
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Feed
|
||||
@@ -1007,7 +1039,7 @@ func countOfUnreadMessagesInConversation(conversation: Conversation) -> Int {
|
||||
}).count
|
||||
}
|
||||
|
||||
func latestMessageInRealm(realm: Realm, withConversationType conversationType: ConversationType) -> Message? {
|
||||
func latestValidMessageInRealm(realm: Realm, withConversationType conversationType: ConversationType) -> Message? {
|
||||
|
||||
// let predicate = NSPredicate(format: "fromFriend != nil AND conversation != nil AND conversation.type = %d", conversationType.rawValue)
|
||||
// return realm.objects(Message).filter(predicate).sorted("updatedUnixTime", ascending: false).first
|
||||
@@ -1015,26 +1047,30 @@ func latestMessageInRealm(realm: Realm, withConversationType conversationType: C
|
||||
switch conversationType {
|
||||
|
||||
case .OneToOne:
|
||||
let predicate = NSPredicate(format: "fromFriend != nil AND conversation != nil AND conversation.type = %d", conversationType.rawValue)
|
||||
let predicate = NSPredicate(format: "hidden = false AND deletedByCreator = false AND fromFriend != nil AND conversation != nil AND conversation.type = %d", conversationType.rawValue)
|
||||
return realm.objects(Message).filter(predicate).sorted("updatedUnixTime", ascending: false).first
|
||||
|
||||
case .Group:
|
||||
let predicate = NSPredicate(format: "withGroup != nil AND withGroup.includeMe = true")
|
||||
return realm.objects(Conversation).filter(predicate).sorted("updatedUnixTime", ascending: false).first?.messages.sort({ $0.createdUnixTime > $1.createdUnixTime }).first
|
||||
let messages: [Message]? = realm.objects(Conversation).filter(predicate).sorted("updatedUnixTime", ascending: false).first?.messages.sort({ $0.createdUnixTime > $1.createdUnixTime })
|
||||
|
||||
return messages?.filter({ ($0.hidden == false) && ($0.deletedByCreator == false) }).first
|
||||
}
|
||||
}
|
||||
|
||||
func latestUnreadMessageInRealm(realm: Realm, withConversationType conversationType: ConversationType) -> Message? {
|
||||
func latestUnreadValidMessageInRealm(realm: Realm, withConversationType conversationType: ConversationType) -> Message? {
|
||||
|
||||
switch conversationType {
|
||||
|
||||
case .OneToOne:
|
||||
let predicate = NSPredicate(format: "readed = false AND fromFriend != nil AND conversation != nil AND conversation.type = %d", conversationType.rawValue)
|
||||
let predicate = NSPredicate(format: "readed = false AND hidden = false AND deletedByCreator = false AND fromFriend != nil AND conversation != nil AND conversation.type = %d", conversationType.rawValue)
|
||||
return realm.objects(Message).filter(predicate).sorted("updatedUnixTime", ascending: false).first
|
||||
|
||||
case .Group:
|
||||
let predicate = NSPredicate(format: "withGroup != nil AND withGroup.includeMe = true")
|
||||
return realm.objects(Conversation).filter(predicate).sorted("updatedUnixTime", ascending: false).first?.messages.filter({ $0.readed == false && $0.fromFriend?.userID != YepUserDefaults.userID.value }).sort({ $0.createdUnixTime > $1.createdUnixTime }).first
|
||||
let messages: [Message]? = realm.objects(Conversation).filter(predicate).sorted("updatedUnixTime", ascending: false).first?.messages.filter({ $0.readed == false && $0.fromFriend?.userID != YepUserDefaults.userID.value }).sort({ $0.createdUnixTime > $1.createdUnixTime })
|
||||
|
||||
return messages?.filter({ ($0.hidden == false) && ($0.deletedByCreator == false) }).first
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1307,25 +1343,28 @@ func unReadMessagesOfConversation(conversation: Conversation, inRealm realm: Rea
|
||||
*/
|
||||
|
||||
func messagesOfConversation(conversation: Conversation, inRealm realm: Realm) -> Results<Message> {
|
||||
let predicate = NSPredicate(format: "conversation = %@ AND deleted = false", argumentArray: [conversation])
|
||||
let predicate = NSPredicate(format: "conversation = %@ AND hidden = false", argumentArray: [conversation])
|
||||
let messages = realm.objects(Message).filter(predicate).sorted("createdUnixTime", ascending: true)
|
||||
return messages
|
||||
}
|
||||
|
||||
func deleteMessage(message: Message, inRealm realm: Realm) {
|
||||
realm.delete(message)
|
||||
}
|
||||
|
||||
func handleMessageDeletedFromServer(messageID messageID: String) {
|
||||
|
||||
guard let
|
||||
realm = try? Realm(),
|
||||
message = messageWithMessageID(messageID, inRealm: realm),
|
||||
conversation = message.conversation
|
||||
message = messageWithMessageID(messageID, inRealm: realm)
|
||||
//conversation = message.conversation
|
||||
else {
|
||||
return
|
||||
}
|
||||
|
||||
let _ = try? realm.write {
|
||||
message.updateForDeletedFromServerInRealm(realm)
|
||||
}
|
||||
|
||||
let messageIDs: [String] = [message.messageID]
|
||||
|
||||
/*
|
||||
let messages = messagesOfConversation(conversation, inRealm: realm)
|
||||
|
||||
var sectionDateMessage: Message?
|
||||
@@ -1347,9 +1386,10 @@ func handleMessageDeletedFromServer(messageID messageID: String) {
|
||||
message.deleteAttachmentInRealm(realm)
|
||||
realm.delete(message)
|
||||
}
|
||||
*/
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(YepConfig.Notification.deletedMessages, object: nil)
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(YepConfig.Notification.deletedMessages, object: ["messageIDs": messageIDs])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1562,11 +1602,11 @@ func updateUserWithUserID(userID: String, useUserInfo userInfo: JSONDictionary,
|
||||
|
||||
// MARK: Delete
|
||||
|
||||
private func clearMessagesOfConversation(conversation: Conversation, inRealm realm: Realm, keepDeletedMessages: Bool) {
|
||||
private func clearMessagesOfConversation(conversation: Conversation, inRealm realm: Realm, keepHiddenMessages: Bool) {
|
||||
|
||||
let messages: [Message]
|
||||
if keepDeletedMessages {
|
||||
messages = conversation.messages.filter({ $0.deleted == false })
|
||||
if keepHiddenMessages {
|
||||
messages = conversation.messages.filter({ $0.hidden == false })
|
||||
} else {
|
||||
messages = conversation.messages
|
||||
}
|
||||
@@ -1582,7 +1622,7 @@ private func clearMessagesOfConversation(conversation: Conversation, inRealm rea
|
||||
|
||||
func deleteConversation(conversation: Conversation, inRealm realm: Realm, needLeaveGroup: Bool = true, afterLeaveGroup: (() -> Void)? = nil) {
|
||||
|
||||
clearMessagesOfConversation(conversation, inRealm: realm, keepDeletedMessages: false)
|
||||
clearMessagesOfConversation(conversation, inRealm: realm, keepHiddenMessages: false)
|
||||
|
||||
// delete conversation, finally
|
||||
|
||||
@@ -1623,7 +1663,7 @@ func tryDeleteOrClearHistoryOfConversation(conversation: Conversation, inViewCon
|
||||
|
||||
let clearMessages: () -> Void = {
|
||||
realm.beginWrite()
|
||||
clearMessagesOfConversation(conversation, inRealm: realm, keepDeletedMessages: true)
|
||||
clearMessagesOfConversation(conversation, inRealm: realm, keepHiddenMessages: true)
|
||||
let _ = try? realm.commitWrite()
|
||||
}
|
||||
|
||||
|
||||
@@ -449,7 +449,7 @@ func syncSocialWorksToMessagesForYepTeam() {
|
||||
return messageIDs
|
||||
|
||||
} else {
|
||||
deleteMessage(message, inRealm: realm)
|
||||
message.deleteInRealm(realm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -827,10 +827,17 @@ func syncMessagesReadStatus() {
|
||||
|
||||
func recordMessageWithMessageID(messageID: String, detailInfo messageInfo: JSONDictionary, inRealm realm: Realm) {
|
||||
|
||||
println("messageInfo: \(messageInfo)")
|
||||
//println("messageInfo: \(messageInfo)")
|
||||
|
||||
let deleted = (messageInfo["deleted"] as? Bool) ?? false
|
||||
|
||||
if let message = messageWithMessageID(messageID, inRealm: realm) {
|
||||
|
||||
guard !deleted else {
|
||||
message.updateForDeletedFromServerInRealm(realm)
|
||||
return
|
||||
}
|
||||
|
||||
if let user = message.fromFriend where user.userID == YepUserDefaults.userID.value {
|
||||
message.sendState = MessageSendState.Read.rawValue
|
||||
}
|
||||
@@ -910,11 +917,26 @@ func recordMessageWithMessageID(messageID: String, detailInfo messageInfo: JSOND
|
||||
}
|
||||
|
||||
func syncMessageWithMessageInfo(messageInfo: JSONDictionary, messageAge: MessageAge, inRealm realm: Realm, andDoFurtherAction furtherAction: ((messageIDs: [String]) -> Void)? ) {
|
||||
|
||||
|
||||
if let messageID = messageInfo["id"] as? String {
|
||||
|
||||
var message = messageWithMessageID(messageID, inRealm: realm)
|
||||
|
||||
// 如果消息被删除,且的发送者是自己,不同步且删除本地已有的
|
||||
let deleted = (messageInfo["deleted"] as? Bool) ?? false
|
||||
if deleted {
|
||||
if let senderInfo = messageInfo["sender"] as? JSONDictionary, senderID = senderInfo["id"] as? String {
|
||||
if senderID == YepUserDefaults.userID.value {
|
||||
if let message = message {
|
||||
message.deleteAttachmentInRealm(realm)
|
||||
realm.delete(message)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if message == nil {
|
||||
let newMessage = Message()
|
||||
newMessage.messageID = messageID
|
||||
@@ -1111,7 +1133,7 @@ func syncMessageWithMessageInfo(messageInfo: JSONDictionary, messageAge: Message
|
||||
}
|
||||
|
||||
} else {
|
||||
deleteMessage(message, inRealm: realm)
|
||||
message.deleteInRealm(realm)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1800,7 +1800,8 @@ class ConversationViewController: BaseViewController {
|
||||
switch message.mediaType {
|
||||
|
||||
case MessageMediaType.Text.rawValue:
|
||||
let rect = message.textContent.boundingRectWithSize(CGSize(width: messageTextLabelMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.ChatCell.textAttributes, context: nil)
|
||||
|
||||
let rect = message.textContentToShow.boundingRectWithSize(CGSize(width: messageTextLabelMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.ChatCell.textAttributes, context: nil)
|
||||
|
||||
height = max(ceil(rect.height) + (11 * 2), YepConfig.chatCellAvatarSize())
|
||||
|
||||
@@ -1871,6 +1872,9 @@ class ConversationViewController: BaseViewController {
|
||||
|
||||
return height
|
||||
}
|
||||
private func clearHeightOfMessageWithKey(key: String) {
|
||||
messageHeights[key] = nil
|
||||
}
|
||||
|
||||
private var textContentLabelWidths = [String: CGFloat]()
|
||||
private func textContentLabelWidthOfMessage(message: Message) -> CGFloat {
|
||||
@@ -2497,7 +2501,17 @@ class ConversationViewController: BaseViewController {
|
||||
|
||||
@objc private func handleDeletedMessagesNotification(notification: NSNotification) {
|
||||
|
||||
reloadConversationCollectionView()
|
||||
defer {
|
||||
reloadConversationCollectionView()
|
||||
}
|
||||
|
||||
guard let info = notification.object as? [String: AnyObject], messageIDs = info["messageIDs"] as? [String] else {
|
||||
return
|
||||
}
|
||||
|
||||
messageIDs.forEach {
|
||||
clearHeightOfMessageWithKey($0)
|
||||
}
|
||||
}
|
||||
|
||||
// App 进入前台时,根据通知插入处于后台状态时收到的消息
|
||||
@@ -3347,7 +3361,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
})
|
||||
|
||||
} else {
|
||||
message.deleted = true
|
||||
message.hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3375,7 +3389,7 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
})
|
||||
|
||||
} else {
|
||||
message.deleted = true
|
||||
message.hidden = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -369,9 +369,9 @@ extension ConversationsViewController: UITableViewDataSource, UITableViewDelegat
|
||||
cell.haveGroupUnreadMessages = countOfUnreadMessagesInRealm(realm, withConversationType: ConversationType.Group) > 0
|
||||
|
||||
// 先找最新且未读的消息
|
||||
let latestUnreadMessage = latestUnreadMessageInRealm(realm, withConversationType: ConversationType.Group)
|
||||
let latestUnreadMessage = latestUnreadValidMessageInRealm(realm, withConversationType: ConversationType.Group)
|
||||
// 找不到就找最新的消息
|
||||
if let latestMessage = (latestUnreadMessage ?? latestMessageInRealm(realm, withConversationType: ConversationType.Group)) {
|
||||
if let latestMessage = (latestUnreadMessage ?? latestValidMessageInRealm(realm, withConversationType: ConversationType.Group)) {
|
||||
|
||||
if let mediaType = MessageMediaType(rawValue: latestMessage.mediaType), placeholder = mediaType.placeholder {
|
||||
cell.chatLabel.text = placeholder
|
||||
|
||||
@@ -64,7 +64,14 @@ class ChatLeftTextCell: ChatBaseCell {
|
||||
|
||||
self.user = message.fromFriend
|
||||
|
||||
textContentTextView.text = message.textContent
|
||||
textContentTextView.text = message.textContentToShow
|
||||
|
||||
if message.deletedByCreator {
|
||||
textContentTextView.textColor = UIColor.lightGrayColor()
|
||||
} else {
|
||||
textContentTextView.textColor = UIColor.blackColor()
|
||||
}
|
||||
|
||||
//textContentTextView.attributedText = NSAttributedString(string: message.textContent, attributes: textAttributes)
|
||||
|
||||
//textContentTextView.textAlignment = textContentLabelWidth < YepConfig.minMessageTextLabelWidth ? .Center : .Left
|
||||
|
||||
@@ -69,15 +69,15 @@ class ConversationCell: UITableViewCell {
|
||||
|
||||
func updateInfoLabels() {
|
||||
|
||||
if let latestMessage = messagesInConversation(conversation).last {
|
||||
if let latestValidMessage = conversation.latestValidMessage {
|
||||
|
||||
if let mediaType = MessageMediaType(rawValue: latestMessage.mediaType), placeholder = mediaType.placeholder {
|
||||
if let mediaType = MessageMediaType(rawValue: latestValidMessage.mediaType), placeholder = mediaType.placeholder {
|
||||
self.chatLabel.text = placeholder
|
||||
} else {
|
||||
self.chatLabel.text = latestMessage.textContent
|
||||
self.chatLabel.text = latestValidMessage.textContent
|
||||
}
|
||||
|
||||
let createdAt = NSDate(timeIntervalSince1970: latestMessage.createdUnixTime)
|
||||
let createdAt = NSDate(timeIntervalSince1970: latestValidMessage.createdUnixTime)
|
||||
self.timeAgoLabel.text = createdAt.timeAgo
|
||||
|
||||
} else {
|
||||
|
||||
@@ -68,12 +68,12 @@ class FeedConversationCell: UITableViewCell {
|
||||
})
|
||||
mediaView.setImagesWithAttachments(attachments)
|
||||
|
||||
if let latestMessage = messagesInConversation(conversation).last {
|
||||
if let latestValidMessage = conversation.latestValidMessage {
|
||||
|
||||
if let mediaType = MessageMediaType(rawValue: latestMessage.mediaType), placeholder = mediaType.placeholder {
|
||||
if let mediaType = MessageMediaType(rawValue: latestValidMessage.mediaType), placeholder = mediaType.placeholder {
|
||||
self.chatLabel.text = placeholder
|
||||
} else {
|
||||
self.chatLabel.text = latestMessage.nicknameWithTextContent
|
||||
self.chatLabel.text = latestValidMessage.nicknameWithTextContent
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -726,3 +726,5 @@
|
||||
|
||||
"Hide" = "隐藏";
|
||||
|
||||
"Deleted by creator." = "被创建者删除。";
|
||||
|
||||
|
||||
Reference in New Issue
Block a user