mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-24 20:26:02 +10:00
Merge branch 'feature/resend_message' into develop
This commit is contained in:
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "icon_dot_failed.pdf"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -238,6 +238,15 @@ class Draft: Object {
|
||||
enum ConversationType: Int {
|
||||
case OneToOne = 0 // 一对一对话
|
||||
case Group = 1 // 群组对话
|
||||
|
||||
var nameForServer: String {
|
||||
switch self {
|
||||
case .OneToOne:
|
||||
return "User"
|
||||
case .Group:
|
||||
return "Circle"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class Conversation: Object {
|
||||
|
||||
+209
-130
@@ -1042,22 +1042,22 @@ func sendText(text: String, toRecipient recipientID: String, #recipientType: Str
|
||||
moreInfo["text_content"] = text
|
||||
return moreInfo
|
||||
}
|
||||
sendMessageWithMediaType(.Text, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
createAndSendMessageWithMediaType(.Text, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
func sendImageInFilePath(filePath: String?, orFileData fileData: NSData?, #metaData: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
|
||||
sendMessageWithMediaType(.Image, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
createAndSendMessageWithMediaType(.Image, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
func sendAudioInFilePath(filePath: String?, orFileData fileData: NSData?, #metaData: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
|
||||
sendMessageWithMediaType(.Audio, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
createAndSendMessageWithMediaType(.Audio, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
func sendVideoInFilePath(filePath: String?, orFileData fileData: NSData?, #metaData: String?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
|
||||
sendMessageWithMediaType(.Video, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
createAndSendMessageWithMediaType(.Video, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
func sendLocationWithCoordinate(coordinate: CLLocationCoordinate2D, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
@@ -1069,11 +1069,10 @@ func sendLocationWithCoordinate(coordinate: CLLocationCoordinate2D, toRecipient
|
||||
return moreInfo
|
||||
}
|
||||
|
||||
sendMessageWithMediaType(.Location, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
createAndSendMessageWithMediaType(.Location, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, afterCreatedMessage: afterCreatedMessage, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
|
||||
func sendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: String?, orFileData fileData: NSData?, #metaData: String?, #fillMoreInfo: (JSONDictionary -> JSONDictionary)?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
func createAndSendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath: String?, orFileData fileData: NSData?, #metaData: String?, #fillMoreInfo: (JSONDictionary -> JSONDictionary)?, toRecipient recipientID: String, #recipientType: String, #afterCreatedMessage: (Message) -> Void, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
// 因为 message_id 必须来自远端,线程无法切换,所以这里暂时没用 realmQueue // TOOD: 也许有办法
|
||||
|
||||
let realm = Realm()
|
||||
@@ -1148,12 +1147,6 @@ func sendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath:
|
||||
realm.commitWrite()
|
||||
|
||||
|
||||
// 发出之前就显示 Message
|
||||
afterCreatedMessage(message)
|
||||
|
||||
|
||||
// 下面开始真正的消息发送
|
||||
|
||||
var messageInfo: JSONDictionary = [
|
||||
"recipient_id": recipientID,
|
||||
"recipient_type": recipientType,
|
||||
@@ -1182,149 +1175,235 @@ func sendMessageWithMediaType(mediaType: MessageMediaType, inFilePath filePath:
|
||||
|
||||
realm.commitWrite()
|
||||
|
||||
switch mediaType {
|
||||
|
||||
case .Text, .Location:
|
||||
createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in
|
||||
if let failureHandler = failureHandler {
|
||||
failureHandler(reason, errorMessage)
|
||||
}
|
||||
// 发出之前就显示 Message
|
||||
afterCreatedMessage(message)
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
realm.beginWrite()
|
||||
message.sendState = MessageSendState.Failed.rawValue
|
||||
realm.commitWrite()
|
||||
}
|
||||
// 下面开始真正的消息发送
|
||||
sendMessage(message, inFilePath: filePath, orFileData: fileData, metaData: metaData, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
}, completion: { messageID in
|
||||
func sendMessage(message: Message, inFilePath filePath: String?, orFileData fileData: NSData?, #metaData: String?, #fillMoreInfo: (JSONDictionary -> JSONDictionary)?, toRecipient recipientID: String, #recipientType: String, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
//Add to queue
|
||||
|
||||
// var operation = MessageStateOperation(type: .Sent, messageID: messageID)
|
||||
//
|
||||
// ConversationOperationQueue.sharedManager.addNewQperationQueue(operation)
|
||||
|
||||
realm.beginWrite()
|
||||
message.messageID = messageID
|
||||
message.sendState = MessageSendState.Successed.rawValue
|
||||
realm.commitWrite()
|
||||
|
||||
completion(success: true)
|
||||
if let mediaType = MessageMediaType(rawValue: message.mediaType) {
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
})
|
||||
var messageInfo: JSONDictionary = [
|
||||
"recipient_id": recipientID,
|
||||
"recipient_type": recipientType,
|
||||
"media_type": mediaType.description,
|
||||
]
|
||||
|
||||
default:
|
||||
if let fillMoreInfo = fillMoreInfo {
|
||||
messageInfo = fillMoreInfo(messageInfo)
|
||||
}
|
||||
|
||||
s3PrivateUploadParams(failureHandler: nil) { s3UploadParams in
|
||||
uploadFileToS3(inFilePath: filePath, orFileData: fileData, mimeType: mediaType.mineType(), s3UploadParams: s3UploadParams) { (result, error) in
|
||||
switch mediaType {
|
||||
|
||||
// TODO: attachments
|
||||
switch mediaType {
|
||||
case .Image:
|
||||
if let metaData = metaData {
|
||||
let attachments = ["image": [["file": s3UploadParams.key, "metadata": metaData]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
|
||||
} else {
|
||||
let attachments = ["image": [["file": s3UploadParams.key]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
}
|
||||
|
||||
case .Audio:
|
||||
if let metaData = metaData {
|
||||
let attachments = ["audio": [["file": s3UploadParams.key, "metadata": metaData]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
|
||||
} else {
|
||||
let attachments = ["audio": [["file": s3UploadParams.key]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
case .Text, .Location:
|
||||
createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in
|
||||
if let failureHandler = failureHandler {
|
||||
failureHandler(reason, errorMessage)
|
||||
}
|
||||
|
||||
let doCreateMessage = {
|
||||
createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in
|
||||
if let failureHandler = failureHandler {
|
||||
failureHandler(reason, errorMessage)
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
realm.beginWrite()
|
||||
message.sendState = MessageSendState.Failed.rawValue
|
||||
realm.commitWrite()
|
||||
}
|
||||
let realm = message.realm
|
||||
|
||||
}, completion: { messageID in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
realm.beginWrite()
|
||||
message.messageID = messageID
|
||||
message.sendState = MessageSendState.Successed.rawValue
|
||||
realm.commitWrite()
|
||||
|
||||
// var operation = MessageStateOperation(type: .Sent, messageID: messageID)
|
||||
//
|
||||
// ConversationOperationQueue.sharedManager.addNewQperationQueue(operation)
|
||||
|
||||
completion(success: true)
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
// 对于 Video 还要再传 thumbnail,……
|
||||
if mediaType == .Video {
|
||||
|
||||
var thumbnailData: NSData?
|
||||
|
||||
if
|
||||
let filePath = filePath,
|
||||
let image = thumbnailImageOfVideoInVideoURL(NSURL(fileURLWithPath: filePath)!) {
|
||||
thumbnailData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality())
|
||||
realm?.write {
|
||||
message.sendState = MessageSendState.Failed.rawValue
|
||||
}
|
||||
|
||||
s3PrivateUploadParams(failureHandler: nil) { thumbnailS3UploadParams in
|
||||
uploadFileToS3(inFilePath: nil, orFileData: thumbnailData, mimeType: MessageMediaType.Image.mineType(), s3UploadParams: thumbnailS3UploadParams) { (result, error) in
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
|
||||
if let metaData = metaData {
|
||||
let attachments = [
|
||||
"video": [
|
||||
["file": s3UploadParams.key, "metadata": metaData]
|
||||
],
|
||||
"thumbnail": [["file": thumbnailS3UploadParams.key]]
|
||||
]
|
||||
messageInfo["attachments"] = attachments
|
||||
}, completion: { messageID in
|
||||
|
||||
} else {
|
||||
let attachments = [
|
||||
"video": [
|
||||
["file": s3UploadParams.key]
|
||||
],
|
||||
"thumbnail": [["file": thumbnailS3UploadParams.key]]
|
||||
]
|
||||
messageInfo["attachments"] = attachments
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = message.realm
|
||||
realm?.write {
|
||||
message.messageID = messageID
|
||||
message.sendState = MessageSendState.Successed.rawValue
|
||||
}
|
||||
|
||||
completion(success: true)
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
})
|
||||
|
||||
default:
|
||||
|
||||
s3PrivateUploadParams(failureHandler: nil) { s3UploadParams in
|
||||
uploadFileToS3(inFilePath: filePath, orFileData: fileData, mimeType: mediaType.mineType(), s3UploadParams: s3UploadParams) { (result, error) in
|
||||
|
||||
// TODO: attachments
|
||||
switch mediaType {
|
||||
case .Image:
|
||||
if let metaData = metaData {
|
||||
let attachments = ["image": [["file": s3UploadParams.key, "metadata": metaData]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
|
||||
} else {
|
||||
let attachments = ["image": [["file": s3UploadParams.key]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
}
|
||||
|
||||
case .Audio:
|
||||
if let metaData = metaData {
|
||||
let attachments = ["audio": [["file": s3UploadParams.key, "metadata": metaData]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
|
||||
} else {
|
||||
let attachments = ["audio": [["file": s3UploadParams.key]]]
|
||||
messageInfo["attachments"] = attachments
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
|
||||
let doCreateMessage = {
|
||||
createMessageWithMessageInfo(messageInfo, failureHandler: { (reason, errorMessage) in
|
||||
if let failureHandler = failureHandler {
|
||||
failureHandler(reason, errorMessage)
|
||||
}
|
||||
|
||||
doCreateMessage()
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = message.realm
|
||||
realm?.write {
|
||||
message.sendState = MessageSendState.Failed.rawValue
|
||||
}
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
|
||||
}, completion: { messageID in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
let realm = message.realm
|
||||
realm?.write {
|
||||
message.messageID = messageID
|
||||
message.sendState = MessageSendState.Successed.rawValue
|
||||
}
|
||||
|
||||
completion(success: true)
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
} else {
|
||||
doCreateMessage()
|
||||
// 对于 Video 还要再传 thumbnail,……
|
||||
if mediaType == .Video {
|
||||
|
||||
var thumbnailData: NSData?
|
||||
|
||||
if
|
||||
let filePath = filePath,
|
||||
let image = thumbnailImageOfVideoInVideoURL(NSURL(fileURLWithPath: filePath)!) {
|
||||
thumbnailData = UIImageJPEGRepresentation(image, YepConfig.messageImageCompressionQuality())
|
||||
}
|
||||
|
||||
s3PrivateUploadParams(failureHandler: nil) { thumbnailS3UploadParams in
|
||||
uploadFileToS3(inFilePath: nil, orFileData: thumbnailData, mimeType: MessageMediaType.Image.mineType(), s3UploadParams: thumbnailS3UploadParams) { (result, error) in
|
||||
|
||||
if let metaData = metaData {
|
||||
let attachments = [
|
||||
"video": [
|
||||
["file": s3UploadParams.key, "metadata": metaData]
|
||||
],
|
||||
"thumbnail": [["file": thumbnailS3UploadParams.key]]
|
||||
]
|
||||
messageInfo["attachments"] = attachments
|
||||
|
||||
} else {
|
||||
let attachments = [
|
||||
"video": [
|
||||
["file": s3UploadParams.key]
|
||||
],
|
||||
"thumbnail": [["file": thumbnailS3UploadParams.key]]
|
||||
]
|
||||
messageInfo["attachments"] = attachments
|
||||
}
|
||||
|
||||
doCreateMessage()
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
doCreateMessage()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func resendMessage(message: Message, #failureHandler: ((Reason, String?) -> Void)?, #completion: (success: Bool) -> Void) {
|
||||
|
||||
var recipientID: String?
|
||||
var recipientType: String?
|
||||
|
||||
if let conversation = message.conversation {
|
||||
if conversation.type == ConversationType.OneToOne.rawValue {
|
||||
recipientID = conversation.withFriend?.userID
|
||||
recipientType = ConversationType.OneToOne.nameForServer
|
||||
|
||||
} else if conversation.type == ConversationType.Group.rawValue {
|
||||
recipientID = conversation.withGroup?.groupID
|
||||
recipientType = ConversationType.Group.nameForServer
|
||||
}
|
||||
}
|
||||
|
||||
if let
|
||||
recipientID = recipientID,
|
||||
recipientType = recipientType,
|
||||
messageMediaType = MessageMediaType(rawValue: message.mediaType) {
|
||||
|
||||
switch messageMediaType {
|
||||
|
||||
case .Text:
|
||||
|
||||
let fillMoreInfo: JSONDictionary -> JSONDictionary = { info in
|
||||
var moreInfo = info
|
||||
moreInfo["text_content"] = message.textContent
|
||||
return moreInfo
|
||||
}
|
||||
|
||||
sendMessage(message, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion)
|
||||
|
||||
case .Image:
|
||||
let filePath = NSFileManager.yepMessageImageURLWithName(message.localAttachmentName)?.path
|
||||
|
||||
sendMessage(message, inFilePath: filePath, orFileData: nil, metaData: message.metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion)
|
||||
|
||||
case .Video:
|
||||
let filePath = NSFileManager.yepMessageVideoURLWithName(message.localAttachmentName)?.path
|
||||
|
||||
sendMessage(message, inFilePath: filePath, orFileData: nil, metaData: message.metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion)
|
||||
|
||||
case .Audio:
|
||||
let filePath = NSFileManager.yepMessageAudioURLWithName(message.localAttachmentName)?.path
|
||||
|
||||
sendMessage(message, inFilePath: filePath, orFileData: nil, metaData: message.metaData, fillMoreInfo: nil, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion)
|
||||
|
||||
case .Location:
|
||||
if let coordinate = message.coordinate {
|
||||
let fillMoreInfo: JSONDictionary -> JSONDictionary = { info in
|
||||
var moreInfo = info
|
||||
moreInfo["longitude"] = coordinate.longitude
|
||||
moreInfo["latitude"] = coordinate.latitude
|
||||
return moreInfo
|
||||
}
|
||||
|
||||
sendMessage(message, inFilePath: nil, orFileData: nil, metaData: nil, fillMoreInfo: fillMoreInfo, toRecipient: recipientID, recipientType: recipientType, failureHandler: failureHandler, completion: completion)
|
||||
}
|
||||
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func markAsReadMessage(message: Message ,#failureHandler: ((Reason, String?) -> Void)?, #completion: (Bool) -> Void) {
|
||||
|
||||
if message.readed || message.messageID.isEmpty {
|
||||
|
||||
@@ -14,8 +14,6 @@ import MapKit
|
||||
|
||||
|
||||
struct MessageNotification {
|
||||
static let MessageSent = "MessageSentNotification"
|
||||
static let MessageRead = "MessageReadNotification"
|
||||
static let MessageStateChanged = "MessageStateChangedNotification"
|
||||
}
|
||||
|
||||
@@ -1640,7 +1638,24 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
|
||||
cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: {
|
||||
|
||||
self.performSegueWithIdentifier("showMessageMedia", sender: message)
|
||||
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: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: resendImage 错误提醒
|
||||
|
||||
}, completion: { success in
|
||||
println("resendImage: \(success)")
|
||||
})
|
||||
|
||||
}, cancelAction: {
|
||||
})
|
||||
|
||||
} else {
|
||||
self.performSegueWithIdentifier("showMessageMedia", sender: message)
|
||||
}
|
||||
})
|
||||
|
||||
return cell
|
||||
@@ -1652,6 +1667,26 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
|
||||
cell.configureWithMessage(message, audioPlayedDuration: audioPlayedDuration, audioBubbleTapAction: { message in
|
||||
|
||||
if let message = message {
|
||||
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: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: resendAudio 错误提醒
|
||||
|
||||
}, completion: { success in
|
||||
println("resendAudio: \(success)")
|
||||
})
|
||||
|
||||
}, cancelAction: {
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
self.playMessageAudioWithMessage(message)
|
||||
})
|
||||
|
||||
@@ -1662,7 +1697,24 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
|
||||
cell.configureWithMessage(message, messageImagePreferredWidth: messageImagePreferredWidth, messageImagePreferredHeight: messageImagePreferredHeight, messageImagePreferredAspectRatio: messageImagePreferredAspectRatio, mediaTapAction: {
|
||||
|
||||
self.performSegueWithIdentifier("showMessageMedia", sender: message)
|
||||
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: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: resendVideo 错误提醒
|
||||
|
||||
}, completion: { success in
|
||||
println("resendVideo: \(success)")
|
||||
})
|
||||
|
||||
}, cancelAction: {
|
||||
})
|
||||
|
||||
} else {
|
||||
self.performSegueWithIdentifier("showMessageMedia", sender: message)
|
||||
}
|
||||
})
|
||||
|
||||
return cell
|
||||
@@ -1671,14 +1723,32 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightLocationCellIdentifier, forIndexPath: indexPath) as! ChatRightLocationCell
|
||||
|
||||
cell.configureWithMessage(message, mediaTapAction: {
|
||||
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)
|
||||
|
||||
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: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: resendLocation 错误提醒
|
||||
|
||||
}, 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)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
@@ -1687,7 +1757,24 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi
|
||||
default:
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatRightTextCellIdentifier, forIndexPath: indexPath) as! ChatRightTextCell
|
||||
|
||||
cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message))
|
||||
cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), mediaTapAction: {
|
||||
|
||||
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: { (reason, errorMessage) in
|
||||
defaultFailureHandler(reason, errorMessage)
|
||||
// TODO: resendText 错误提醒
|
||||
|
||||
}, completion: { success in
|
||||
println("resendText: \(success)")
|
||||
})
|
||||
|
||||
}, cancelAction: {
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
return cell
|
||||
}
|
||||
|
||||
@@ -35,7 +35,8 @@ class ChatRightBaseCell: UICollectionViewCell {
|
||||
removeSendingAnimation()
|
||||
|
||||
case MessageSendState.Failed:
|
||||
dotImageView.hidden = true
|
||||
dotImageView.image = UIImage(named: "icon_dot_failed")
|
||||
dotImageView.hidden = false
|
||||
|
||||
removeSendingAnimation()
|
||||
|
||||
|
||||
@@ -22,6 +22,9 @@ class ChatRightTextCell: ChatRightBaseCell {
|
||||
@IBOutlet weak var textContentLabelTrailingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var textContentLabelLeadingConstraint: NSLayoutConstraint!
|
||||
@IBOutlet weak var textContentLabelWidthConstraint: NSLayoutConstraint!
|
||||
|
||||
typealias MediaTapAction = () -> Void
|
||||
var mediaTapAction: MediaTapAction?
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
@@ -48,11 +51,22 @@ class ChatRightTextCell: ChatRightBaseCell {
|
||||
|
||||
bubbleBodyImageView.tintColor = UIColor.rightBubbleTintColor()
|
||||
bubbleTailImageView.tintColor = UIColor.rightBubbleTintColor()
|
||||
|
||||
bubbleBodyImageView.userInteractionEnabled = true
|
||||
let tap = UITapGestureRecognizer(target: self, action: "tapMediaView")
|
||||
bubbleBodyImageView.addGestureRecognizer(tap)
|
||||
}
|
||||
|
||||
func tapMediaView() {
|
||||
mediaTapAction?()
|
||||
}
|
||||
|
||||
func configureWithMessage(message: Message, textContentLabelWidth: CGFloat) {
|
||||
func configureWithMessage(message: Message, textContentLabelWidth: CGFloat, mediaTapAction: MediaTapAction?) {
|
||||
|
||||
self.message = message
|
||||
|
||||
|
||||
self.mediaTapAction = mediaTapAction
|
||||
|
||||
textContentLabel.text = message.textContent
|
||||
|
||||
textContentLabelWidthConstraint.constant = max(YepConfig.minMessageTextLabelWidth, textContentLabelWidth)
|
||||
|
||||
Reference in New Issue
Block a user