From 455e62f86210d564cf7bffca104fdbef6c9fab36 Mon Sep 17 00:00:00 2001 From: nixzhu Date: Sun, 6 Sep 2015 22:49:31 +0800 Subject: [PATCH] move cell configure in willDisplayCell --- .../ConversationViewController.swift | 676 ++++++++++-------- 1 file changed, 379 insertions(+), 297 deletions(-) diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index 7b1c04fe..139d0b59 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -1899,14 +1899,6 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatSectionDateCellIdentifier, forIndexPath: indexPath) as! ChatSectionDateCell - let createdAt = NSDate(timeIntervalSince1970: message.createdUnixTime) - - if createdAt.isInCurrentWeek() { - cell.sectionDateLabel.text = sectionDateInCurrentWeekFormatter.stringFromDate(createdAt) - } else { - cell.sectionDateLabel.text = sectionDateFormatter.stringFromDate(createdAt) - } - return cell } @@ -1922,88 +1914,24 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftImageCellIdentifier, forIndexPath: indexPath) as! ChatLeftImageCell - cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in - - if message.downloadState == MessageDownloadState.Downloaded.rawValue { - self?.performSegueWithIdentifier("showMessageMedia", sender: message) - - } else { - YepAlert.alertSorry(message: NSLocalizedString("Please wait while the image is not dready!", comment: ""), inViewController: self) - } - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell case MessageMediaType.Audio.rawValue: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftAudioCellIdentifier, forIndexPath: indexPath) as! ChatLeftAudioCell - let audioPlayedDuration = audioPlayedDurationOfMessage(message) - - cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { [weak self] in - - if message.downloadState == MessageDownloadState.Downloaded.rawValue { - self?.playMessageAudioWithMessage(message) - - } else { - YepAlert.alertSorry(message: NSLocalizedString("Please wait while the audio is not dready!", comment: ""), inViewController: self) - } - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell case MessageMediaType.Video.rawValue: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftVideoCellIdentifier, forIndexPath: indexPath) as! ChatLeftVideoCell - cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in - - if message.downloadState == MessageDownloadState.Downloaded.rawValue { - self?.performSegueWithIdentifier("showMessageMedia", sender: message) - - } else { - YepAlert.alertSorry(message: NSLocalizedString("Please wait while the video is not dready!", comment: ""), inViewController: self) - } - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell case MessageMediaType.Location.rawValue: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftLocationCellIdentifier, forIndexPath: indexPath) as! ChatLeftLocationCell - cell.configureWithMessage(message, mediaTapAction: { [weak self] in - if let coordinate = message.coordinate { - let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) - let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil)) - /* - let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] - mapItem.openInMapsWithLaunchOptions(launchOptions) - */ - mapItem.openInMapsWithLaunchOptions(nil) - } - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell default: @@ -2012,10 +1940,6 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), collectionView: collectionView, indexPath: indexPath) - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell } @@ -2027,251 +1951,30 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightImageCellIdentifier, forIndexPath: indexPath) as! ChatRightImageCell - cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in - - if message.sendState == MessageSendState.Failed.rawValue { - - YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend image?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { - - resendMessage(message, failureHandler: { [weak self] reason, errorMessage in - defaultFailureHandler(reason, errorMessage) - - YepAlert.alertSorry(message: NSLocalizedString("Failed to resend image!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) - - }, completion: { success in - println("resendImage: \(success)") - }) - - }, cancelAction: { - }) - - } else { - self?.performSegueWithIdentifier("showMessageMedia", sender: message) - } - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell case MessageMediaType.Audio.rawValue: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightAudioCellIdentifier, forIndexPath: indexPath) as! ChatRightAudioCell - let audioPlayedDuration = audioPlayedDurationOfMessage(message) - - cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { [weak self] in - - if message.sendState == MessageSendState.Failed.rawValue { - - YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend audio?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { - - resendMessage(message, failureHandler: { [weak self] reason, errorMessage in - defaultFailureHandler(reason, errorMessage) - - YepAlert.alertSorry(message: NSLocalizedString("Failed to resend audio!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) - - }, completion: { success in - println("resendAudio: \(success)") - }) - - }, cancelAction: { - }) - - return - } - - self?.playMessageAudioWithMessage(message) - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell case MessageMediaType.Video.rawValue: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightVideoCellIdentifier, forIndexPath: indexPath) as! ChatRightVideoCell - cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in - - if message.sendState == MessageSendState.Failed.rawValue { - - YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend video?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { - - resendMessage(message, failureHandler: { [weak self] reason, errorMessage in - defaultFailureHandler(reason, errorMessage) - - YepAlert.alertSorry(message: NSLocalizedString("Failed to resend video!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) - - }, completion: { success in - println("resendVideo: \(success)") - }) - - }, cancelAction: { - }) - - } else { - self?.performSegueWithIdentifier("showMessageMedia", sender: message) - } - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell case MessageMediaType.Location.rawValue: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightLocationCellIdentifier, forIndexPath: indexPath) as! ChatRightLocationCell - cell.configureWithMessage(message, mediaTapAction: { [weak self] in - - if message.sendState == MessageSendState.Failed.rawValue { - - YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend location?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { - - resendMessage(message, failureHandler: { [weak self] reason, errorMessage in - defaultFailureHandler(reason, errorMessage) - - YepAlert.alertSorry(message: NSLocalizedString("Failed to resend location!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) - - }, completion: { success in - println("resendLocation: \(success)") - }) - - }, cancelAction: { - }) - - } else { - if let coordinate = message.coordinate { - let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) - let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil)) - /* - let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] - mapItem.openInMapsWithLaunchOptions(launchOptions) - */ - mapItem.openInMapsWithLaunchOptions(nil) - } - } - - }, collectionView: collectionView, indexPath: indexPath) - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell default: let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightTextCellIdentifier, forIndexPath: indexPath) as! ChatRightTextCell - cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), mediaTapAction: { [weak self] in - - if message.sendState == MessageSendState.Failed.rawValue { - - YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { - - resendMessage(message, failureHandler: { [weak self] reason, errorMessage in - defaultFailureHandler(reason, errorMessage) - - YepAlert.alertSorry(message: NSLocalizedString("Failed to resend text!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) - - }, completion: { success in - println("resendText: \(success)") - }) - - }, cancelAction: { - }) - } - }, collectionView: collectionView, indexPath: indexPath) - - cell.longPressAction = { [weak self] in - dispatch_async(dispatch_get_main_queue()) { - if let strongSelf = self, realm = message.realm { - - var sectionDateMessage: Message? - - if let currentMessageIndex = strongSelf.messages.indexOf(message) { - - let previousMessageIndex = currentMessageIndex - 1 - - if let previousMessage = strongSelf.messages[safe: previousMessageIndex] { - - if previousMessage.mediaType == MessageMediaType.SectionDate.rawValue { - sectionDateMessage = previousMessage - } - } - } - - let currentIndexPath: NSIndexPath - if let index = strongSelf.messages.indexOf(message) { - currentIndexPath = NSIndexPath(forItem: index - strongSelf.displayedMessagesRange.location, inSection: indexPath.section) - } else { - currentIndexPath = indexPath - } - - if let sectionDateMessage = sectionDateMessage { - - var canDeleteTwoMessages = false // 考虑刚好的边界情况,例如消息为本束的最后一条,而 sectionDate 在上一束中 - if strongSelf.displayedMessagesRange.length >= 2 { - strongSelf.displayedMessagesRange.length -= 2 - canDeleteTwoMessages = true - - } else { - if strongSelf.displayedMessagesRange.location >= 1 { - strongSelf.displayedMessagesRange.location -= 1 - } - strongSelf.displayedMessagesRange.length -= 1 - } - - realm.write { - if let mediaMetaData = sectionDateMessage.mediaMetaData { - realm.delete(mediaMetaData) - } - if let mediaMetaData = message.mediaMetaData { - realm.delete(mediaMetaData) - } - realm.delete(sectionDateMessage) - realm.delete(message) - } - - if canDeleteTwoMessages { - let previousIndexPath = NSIndexPath(forItem: currentIndexPath.item - 1, inSection: currentIndexPath.section) - strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([previousIndexPath, currentIndexPath]) - } else { - strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([currentIndexPath]) - } - - } else { - strongSelf.displayedMessagesRange.length -= 1 - realm.write { - if let mediaMetaData = message.mediaMetaData { - realm.delete(mediaMetaData) - } - realm.delete(message) - } - strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([currentIndexPath]) - } - - // 必须更新,插入时需要 - strongSelf.lastTimeMessagesCount = strongSelf.messages.count - } - } - } - - cell.tapAvatarAction = { [weak self] user in - self?.performSegueWithIdentifier("showProfile", sender: user) - } - return cell } } @@ -2288,6 +1991,385 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi } + func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) { + + if let message = messages[safe: (displayedMessagesRange.location + indexPath.item)] { + + if message.mediaType == MessageMediaType.SectionDate.rawValue { + + if let cell = cell as? ChatSectionDateCell { + let createdAt = NSDate(timeIntervalSince1970: message.createdUnixTime) + + if createdAt.isInCurrentWeek() { + cell.sectionDateLabel.text = sectionDateInCurrentWeekFormatter.stringFromDate(createdAt) + } else { + cell.sectionDateLabel.text = sectionDateFormatter.stringFromDate(createdAt) + } + } + + return + } + + if let sender = message.fromFriend { + + if sender.friendState != UserFriendState.Me.rawValue { // from Friend + + markMessageAsReaded(message) + + switch message.mediaType { + + case MessageMediaType.Image.rawValue: + + if let cell = cell as? ChatLeftImageCell { + + cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in + + if message.downloadState == MessageDownloadState.Downloaded.rawValue { + self?.performSegueWithIdentifier("showMessageMedia", sender: message) + + } else { + YepAlert.alertSorry(message: NSLocalizedString("Please wait while the image is not dready!", comment: ""), inViewController: self) + } + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + case MessageMediaType.Audio.rawValue: + + if let cell = cell as? ChatLeftAudioCell { + + let audioPlayedDuration = audioPlayedDurationOfMessage(message) + + cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { [weak self] in + + if message.downloadState == MessageDownloadState.Downloaded.rawValue { + self?.playMessageAudioWithMessage(message) + + } else { + YepAlert.alertSorry(message: NSLocalizedString("Please wait while the audio is not dready!", comment: ""), inViewController: self) + } + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + case MessageMediaType.Video.rawValue: + + if let cell = cell as? ChatLeftVideoCell { + + cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in + + if message.downloadState == MessageDownloadState.Downloaded.rawValue { + self?.performSegueWithIdentifier("showMessageMedia", sender: message) + + } else { + YepAlert.alertSorry(message: NSLocalizedString("Please wait while the video is not dready!", comment: ""), inViewController: self) + } + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + + case MessageMediaType.Location.rawValue: + + if let cell = cell as? ChatLeftLocationCell { + + cell.configureWithMessage(message, mediaTapAction: { [weak self] in + if let coordinate = message.coordinate { + let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) + let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil)) + /* + let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] + mapItem.openInMapsWithLaunchOptions(launchOptions) + */ + mapItem.openInMapsWithLaunchOptions(nil) + } + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + default: + + if let cell = cell as? ChatLeftTextCell { + + cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + } + + } else { // from Me + + switch message.mediaType { + + case MessageMediaType.Image.rawValue: + + if let cell = cell as? ChatRightImageCell { + + cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in + + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend image?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { [weak self] reason, errorMessage in + defaultFailureHandler(reason, errorMessage) + + YepAlert.alertSorry(message: NSLocalizedString("Failed to resend image!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) + + }, completion: { success in + println("resendImage: \(success)") + }) + + }, cancelAction: { + }) + + } else { + self?.performSegueWithIdentifier("showMessageMedia", sender: message) + } + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + case MessageMediaType.Audio.rawValue: + + if let cell = cell as? ChatRightAudioCell { + + let audioPlayedDuration = audioPlayedDurationOfMessage(message) + + cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { [weak self] in + + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend audio?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { [weak self] reason, errorMessage in + defaultFailureHandler(reason, errorMessage) + + YepAlert.alertSorry(message: NSLocalizedString("Failed to resend audio!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) + + }, completion: { success in + println("resendAudio: \(success)") + }) + + }, cancelAction: { + }) + + return + } + + self?.playMessageAudioWithMessage(message) + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + case MessageMediaType.Video.rawValue: + + if let cell = cell as? ChatRightVideoCell { + + cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: { [weak self] in + + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend video?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { [weak self] reason, errorMessage in + defaultFailureHandler(reason, errorMessage) + + YepAlert.alertSorry(message: NSLocalizedString("Failed to resend video!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) + + }, completion: { success in + println("resendVideo: \(success)") + }) + + }, cancelAction: { + }) + + } else { + self?.performSegueWithIdentifier("showMessageMedia", sender: message) + } + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + case MessageMediaType.Location.rawValue: + + if let cell = cell as? ChatRightLocationCell { + + cell.configureWithMessage(message, mediaTapAction: { [weak self] in + + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend location?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { [weak self] reason, errorMessage in + defaultFailureHandler(reason, errorMessage) + + YepAlert.alertSorry(message: NSLocalizedString("Failed to resend location!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) + + }, completion: { success in + println("resendLocation: \(success)") + }) + + }, cancelAction: { + }) + + } else { + if let coordinate = message.coordinate { + let locationCoordinate = CLLocationCoordinate2D(latitude: coordinate.latitude, longitude: coordinate.longitude) + let mapItem = MKMapItem(placemark: MKPlacemark(coordinate: locationCoordinate, addressDictionary: nil)) + /* + let launchOptions = [MKLaunchOptionsDirectionsModeKey: MKLaunchOptionsDirectionsModeDriving] + mapItem.openInMapsWithLaunchOptions(launchOptions) + */ + mapItem.openInMapsWithLaunchOptions(nil) + } + } + + }, collectionView: collectionView, indexPath: indexPath) + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + + default: + + if let cell = cell as? ChatRightTextCell { + + cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), mediaTapAction: { [weak self] in + + if message.sendState == MessageSendState.Failed.rawValue { + + YepAlert.confirmOrCancel(title: NSLocalizedString("Action", comment: ""), message: NSLocalizedString("Resend text?", comment: ""), confirmTitle: NSLocalizedString("Resend", comment: ""), cancelTitle: NSLocalizedString("Cancel", comment: ""), inViewController: self, withConfirmAction: { + + resendMessage(message, failureHandler: { [weak self] reason, errorMessage in + defaultFailureHandler(reason, errorMessage) + + YepAlert.alertSorry(message: NSLocalizedString("Failed to resend text!\nPlease make sure your iPhone is connected to the Internet.", comment: ""), inViewController: self) + + }, completion: { success in + println("resendText: \(success)") + }) + + }, cancelAction: { + }) + } + }, collectionView: collectionView, indexPath: indexPath) + + cell.longPressAction = { [weak self] in + dispatch_async(dispatch_get_main_queue()) { + if let strongSelf = self, realm = message.realm { + + var sectionDateMessage: Message? + + if let currentMessageIndex = strongSelf.messages.indexOf(message) { + + let previousMessageIndex = currentMessageIndex - 1 + + if let previousMessage = strongSelf.messages[safe: previousMessageIndex] { + + if previousMessage.mediaType == MessageMediaType.SectionDate.rawValue { + sectionDateMessage = previousMessage + } + } + } + + let currentIndexPath: NSIndexPath + if let index = strongSelf.messages.indexOf(message) { + currentIndexPath = NSIndexPath(forItem: index - strongSelf.displayedMessagesRange.location, inSection: indexPath.section) + } else { + currentIndexPath = indexPath + } + + if let sectionDateMessage = sectionDateMessage { + + var canDeleteTwoMessages = false // 考虑刚好的边界情况,例如消息为本束的最后一条,而 sectionDate 在上一束中 + if strongSelf.displayedMessagesRange.length >= 2 { + strongSelf.displayedMessagesRange.length -= 2 + canDeleteTwoMessages = true + + } else { + if strongSelf.displayedMessagesRange.location >= 1 { + strongSelf.displayedMessagesRange.location -= 1 + } + strongSelf.displayedMessagesRange.length -= 1 + } + + realm.write { + if let mediaMetaData = sectionDateMessage.mediaMetaData { + realm.delete(mediaMetaData) + } + if let mediaMetaData = message.mediaMetaData { + realm.delete(mediaMetaData) + } + realm.delete(sectionDateMessage) + realm.delete(message) + } + + if canDeleteTwoMessages { + let previousIndexPath = NSIndexPath(forItem: currentIndexPath.item - 1, inSection: currentIndexPath.section) + strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([previousIndexPath, currentIndexPath]) + } else { + strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([currentIndexPath]) + } + + } else { + strongSelf.displayedMessagesRange.length -= 1 + realm.write { + if let mediaMetaData = message.mediaMetaData { + realm.delete(mediaMetaData) + } + realm.delete(message) + } + strongSelf.conversationCollectionView.deleteItemsAtIndexPaths([currentIndexPath]) + } + + // 必须更新,插入时需要 + strongSelf.lastTimeMessagesCount = strongSelf.messages.count + } + } + } + + cell.tapAvatarAction = { [weak self] user in + self?.performSegueWithIdentifier("showProfile", sender: user) + } + } + } + } + } + } + } + func collectionView(collectionView: UICollectionView!, layout collectionViewLayout: UICollectionViewLayout!, sizeForItemAtIndexPath indexPath: NSIndexPath!) -> CGSize { if let message = messages[safe: (displayedMessagesRange.location + indexPath.item)] {