diff --git a/Yep.xcodeproj/project.pbxproj b/Yep.xcodeproj/project.pbxproj index 56ac961d..0e977e62 100644 --- a/Yep.xcodeproj/project.pbxproj +++ b/Yep.xcodeproj/project.pbxproj @@ -122,6 +122,7 @@ 5039594F1B05E6E000797A3E /* ProfileSocialAccountGithubCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 5039594D1B05E6E000797A3E /* ProfileSocialAccountGithubCell.xib */; }; 503CAB431AC00CB100DFE830 /* ConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503CAB421AC00CB100DFE830 /* ConversationViewController.swift */; }; 503ED23A1B8ADCE70072187D /* BlackListViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 503ED2391B8ADCE70072187D /* BlackListViewController.swift */; }; + 50485BCE1C56062400431AC7 /* ChatLeftRecallCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 50485BCD1C56062400431AC7 /* ChatLeftRecallCell.swift */; }; 504BDC151B4528A500DBD35D /* Badges.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 504BDC141B4528A500DBD35D /* Badges.xcassets */; }; 504CBA3D1B3D04B800663A90 /* ChatTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504CBA3C1B3D04B800663A90 /* ChatTextView.swift */; }; 504F41251ACE2D1D00FBB19A /* SampleView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 504F41241ACE2D1D00FBB19A /* SampleView.swift */; }; @@ -494,6 +495,7 @@ 5039594D1B05E6E000797A3E /* ProfileSocialAccountGithubCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = ProfileSocialAccountGithubCell.xib; path = Views/Cells/ProfileSocialAccount/ProfileSocialAccountGithubCell.xib; sourceTree = ""; }; 503CAB421AC00CB100DFE830 /* ConversationViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ConversationViewController.swift; path = ViewControllers/Conversation/ConversationViewController.swift; sourceTree = ""; }; 503ED2391B8ADCE70072187D /* BlackListViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = BlackListViewController.swift; path = ViewControllers/BlackList/BlackListViewController.swift; sourceTree = ""; }; + 50485BCD1C56062400431AC7 /* ChatLeftRecallCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChatLeftRecallCell.swift; path = Views/Cells/ChatLeftRecall/ChatLeftRecallCell.swift; sourceTree = ""; }; 504BDC141B4528A500DBD35D /* Badges.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Badges.xcassets; sourceTree = ""; }; 504CBA3C1B3D04B800663A90 /* ChatTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ChatTextView.swift; path = Views/TextViews/ChatTextView.swift; sourceTree = ""; }; 504F41241ACE2D1D00FBB19A /* SampleView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SampleView.swift; path = Views/AudioWaves/SampleView.swift; sourceTree = ""; }; @@ -1228,6 +1230,7 @@ 508D174E1ACCF49F0092D666 /* ChatRightAudio */, 5053AD5C1AF83B4600B3CBFA /* ChatLeftLocation */, 5053AD571AF83B1600B3CBFA /* ChatRightLocation */, + 50485BCF1C56062900431AC7 /* ChatLeftRecall */, 5016901A1BFB18D70096C4F9 /* ChatLeftSocialWork */, 508C2AA61AD661B8002B8097 /* UserState */, 50553F911ADB8BA600F80B59 /* ChatSectionDate */, @@ -1523,6 +1526,14 @@ name = BlackList; sourceTree = ""; }; + 50485BCF1C56062900431AC7 /* ChatLeftRecall */ = { + isa = PBXGroup; + children = ( + 50485BCD1C56062400431AC7 /* ChatLeftRecallCell.swift */, + ); + name = ChatLeftRecall; + sourceTree = ""; + }; 504CBA3B1B3D048900663A90 /* TextViews */ = { isa = PBXGroup; children = ( @@ -2707,6 +2718,7 @@ 501690181BFB18D20096C4F9 /* ChatLeftSocialWorkCell.swift in Sources */, 50E114F41ABBF9CC00F13000 /* Models.swift in Sources */, 848806B01B789A2D000C5424 /* EditSkillCell.swift in Sources */, + 50485BCE1C56062400431AC7 /* ChatLeftRecallCell.swift in Sources */, 5018132C1BA3CFEF0025873C /* WeChatActivity.swift in Sources */, 5053AD551AF83B0F00B3CBFA /* ChatRightLocationCell.swift in Sources */, 50A9D4571ACD393A000B2599 /* YepWaverView.swift in Sources */, diff --git a/Yep/Realm/Models.swift b/Yep/Realm/Models.swift index 98f43bbf..d23a47fd 100644 --- a/Yep/Realm/Models.swift +++ b/Yep/Realm/Models.swift @@ -519,12 +519,10 @@ class Message: Object { dynamic var mediaType: Int = MessageMediaType.Text.rawValue dynamic var textContent: String = "" - var textContentToShow: String { - if deletedByCreator { - return NSLocalizedString("Recalled by creator.", comment: "") - } else { - return textContent - } + + var recalledTextContent: String { + let nickname = fromFriend?.nickname ?? "" + return String(format: NSLocalizedString("%@ recalled a message.", comment: ""), nickname) } dynamic var openGraphURLDetected: Bool = false diff --git a/Yep/ViewControllers/Conversation/ConversationViewController.swift b/Yep/ViewControllers/Conversation/ConversationViewController.swift index 2dfa3fd4..903f7f4a 100644 --- a/Yep/ViewControllers/Conversation/ConversationViewController.swift +++ b/Yep/ViewControllers/Conversation/ConversationViewController.swift @@ -614,6 +614,7 @@ class ConversationViewController: BaseViewController { private let chatRightVideoCellIdentifier = "ChatRightVideoCell" private let chatLeftLocationCellIdentifier = "ChatLeftLocationCell" private let chatRightLocationCellIdentifier = "ChatRightLocationCell" + private let chatLeftRecallCellIdentifier = "ChatLeftRecallCell" private let chatLeftSocialWorkCellIdentifier = "ChatLeftSocialWorkCell" private struct Listener { @@ -710,6 +711,7 @@ class ConversationViewController: BaseViewController { conversationCollectionView.registerClass(ChatLeftLocationCell.self, forCellWithReuseIdentifier: chatLeftLocationCellIdentifier) conversationCollectionView.registerClass(ChatRightLocationCell.self, forCellWithReuseIdentifier: chatRightLocationCellIdentifier) + conversationCollectionView.registerClass(ChatLeftRecallCell.self, forCellWithReuseIdentifier: chatLeftRecallCellIdentifier) /* conversationCollectionView.registerNib(UINib(nibName: chatLeftTextCellIdentifier, bundle: nil), forCellWithReuseIdentifier: chatLeftTextCellIdentifier) conversationCollectionView.registerNib(UINib(nibName: chatRightTextCellIdentifier, bundle: nil), forCellWithReuseIdentifier: chatRightTextCellIdentifier) @@ -1877,16 +1879,21 @@ class ConversationViewController: BaseViewController { case MessageMediaType.Text.rawValue: - let rect = message.textContentToShow.boundingRectWithSize(CGSize(width: messageTextLabelMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.ChatCell.textAttributes, context: nil) + if message.deletedByCreator { + height = 30 - height = max(ceil(rect.height) + (11 * 2), YepConfig.chatCellAvatarSize()) + } else { + let rect = message.textContent.boundingRectWithSize(CGSize(width: messageTextLabelMaxWidth, height: CGFloat(FLT_MAX)), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: YepConfig.ChatCell.textAttributes, context: nil) - if message.openGraphURLInfo != nil { - height += 100 + 10 - } + height = max(ceil(rect.height) + (11 * 2), YepConfig.chatCellAvatarSize()) - if !key.isEmpty { - textContentLabelWidths[key] = ceil(rect.width) + if message.openGraphURLInfo != nil { + height += 100 + 10 + } + + if !key.isEmpty { + textContentLabelWidths[key] = ceil(rect.width) + } } case MessageMediaType.Image.rawValue: @@ -3748,13 +3755,19 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi default: - if message.openGraphURLInfo != nil { - let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftTextURLCellIdentifier, forIndexPath: indexPath) as! ChatLeftTextURLCell + if message.deletedByCreator { + let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftRecallCellIdentifier, forIndexPath: indexPath) as! ChatLeftRecallCell return cell } else { - let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftTextCellIdentifier, forIndexPath: indexPath) as! ChatLeftTextCell - return cell + if message.openGraphURLInfo != nil { + let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftTextURLCellIdentifier, forIndexPath: indexPath) as! ChatLeftTextURLCell + return cell + + } else { + let cell = collectionView.dequeueReusableCellWithReuseIdentifier(chatLeftTextCellIdentifier, forIndexPath: indexPath) as! ChatLeftTextCell + return cell + } } } @@ -3968,36 +3981,43 @@ extension ConversationViewController: UICollectionViewDataSource, UICollectionVi default: - if message.openGraphURLInfo != nil { - - if let cell = cell as? ChatLeftTextURLCell { - - cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), collectionView: collectionView, indexPath: indexPath) - - cell.tapUsernameAction = { [weak self] username in - println("left textURL cell.tapUsernameAction: \(username)") - self?.tryShowProfileWithUsername(username) - } - - cell.tapOpenGraphURLAction = { [weak self] URL in - self?.yep_openURL(URL) - } + if message.deletedByCreator { + if let cell = cell as? ChatLeftRecallCell { + cell.configureWithMessage(message) } } else { - - if let cell = cell as? ChatLeftTextCell { - - cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), collectionView: collectionView, indexPath: indexPath) + if message.openGraphURLInfo != nil { - cell.tapUsernameAction = { [weak self] username in - println("left text cell.tapUsernameAction: \(username)") - self?.tryShowProfileWithUsername(username) + if let cell = cell as? ChatLeftTextURLCell { + + cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), collectionView: collectionView, indexPath: indexPath) + + cell.tapUsernameAction = { [weak self] username in + println("left textURL cell.tapUsernameAction: \(username)") + self?.tryShowProfileWithUsername(username) + } + + cell.tapOpenGraphURLAction = { [weak self] URL in + self?.yep_openURL(URL) + } + } + + } else { + + if let cell = cell as? ChatLeftTextCell { + + cell.configureWithMessage(message, textContentLabelWidth: textContentLabelWidthOfMessage(message), collectionView: collectionView, indexPath: indexPath) + + cell.tapUsernameAction = { [weak self] username in + println("left text cell.tapUsernameAction: \(username)") + self?.tryShowProfileWithUsername(username) + } } } - } - tryDetectOpenGraphForMessage(message) + tryDetectOpenGraphForMessage(message) + } } } else { // from Me diff --git a/Yep/Views/Cells/ChatLeftRecall/ChatLeftRecallCell.swift b/Yep/Views/Cells/ChatLeftRecall/ChatLeftRecallCell.swift new file mode 100644 index 00000000..968102f8 --- /dev/null +++ b/Yep/Views/Cells/ChatLeftRecall/ChatLeftRecallCell.swift @@ -0,0 +1,68 @@ +// +// ChatLeftRecallCell.swift +// Yep +// +// Created by nixzhu on 16/1/25. +// Copyright © 2016年 Catch Inc. All rights reserved. +// + +import UIKit + +class ChatLeftRecallCell: UICollectionViewCell { + + lazy var bubbleImageView: UIImageView = { + let imageView = UIImageView(image: UIImage(named: "skill_bubble")) + imageView.tintColor = UIColor(white: 0.95, alpha: 1.0) + imageView.tintAdjustmentMode = .Normal + return imageView + }() + + lazy var recallLabel: UILabel = { + let label = UILabel() + label.font = UIFont.systemFontOfSize(12) + label.textColor = UIColor(white: 0.75, alpha: 1.0) + return label + }() + + override init(frame: CGRect) { + super.init(frame: frame) + + contentView.addSubview(bubbleImageView) + contentView.addSubview(recallLabel) + bubbleImageView.translatesAutoresizingMaskIntoConstraints = false + recallLabel.translatesAutoresizingMaskIntoConstraints = false + + do { + let views = [ + "recallLabel": recallLabel, + ] + + let constraintsH = NSLayoutConstraint.constraintsWithVisualFormat("H:|-78-[recallLabel]-(>=10)-|", options: [], metrics: nil, views: views) + + let centerY = NSLayoutConstraint(item: recallLabel, attribute: .CenterY, relatedBy: .Equal, toItem: contentView, attribute: .CenterY, multiplier: 1.0, constant: 0) + + NSLayoutConstraint.activateConstraints(constraintsH) + NSLayoutConstraint.activateConstraints([centerY]) + } + + do { + let leading = NSLayoutConstraint(item: bubbleImageView, attribute: .Leading, relatedBy: .Equal, toItem: recallLabel, attribute: .Leading, multiplier: 1.0, constant: -10) + let trailing = NSLayoutConstraint(item: bubbleImageView, attribute: .Trailing, relatedBy: .Equal, toItem: recallLabel, attribute: .Trailing, multiplier: 1.0, constant: 10) + + let centerX = NSLayoutConstraint(item: bubbleImageView, attribute: .CenterX, relatedBy: .Equal, toItem: recallLabel, attribute: .CenterX, multiplier: 1.0, constant: 0) + let centerY = NSLayoutConstraint(item: bubbleImageView, attribute: .CenterY, relatedBy: .Equal, toItem: recallLabel, attribute: .CenterY, multiplier: 1.0, constant: 0) + + let height = NSLayoutConstraint(item: bubbleImageView, attribute: .Height, relatedBy: .Equal, toItem: nil, attribute: .NotAnAttribute, multiplier: 1.0, constant: 24) + + NSLayoutConstraint.activateConstraints([leading, trailing, centerX, centerY, height]) + } + } + + required init?(coder aDecoder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + func configureWithMessage(message: Message) { + recallLabel.text = message.recalledTextContent + } +} diff --git a/Yep/Views/Cells/ChatLeftText/ChatLeftTextCell.swift b/Yep/Views/Cells/ChatLeftText/ChatLeftTextCell.swift index d76e3446..289ea2c1 100644 --- a/Yep/Views/Cells/ChatLeftText/ChatLeftTextCell.swift +++ b/Yep/Views/Cells/ChatLeftText/ChatLeftTextCell.swift @@ -85,13 +85,7 @@ class ChatLeftTextCell: ChatBaseCell { self.user = message.fromFriend - textContentTextView.text = message.textContentToShow - - if message.deletedByCreator { - textContentTextView.textColor = UIColor.lightGrayColor() - } else { - textContentTextView.textColor = UIColor.blackColor() - } + textContentTextView.text = message.textContent //textContentTextView.attributedText = NSAttributedString(string: message.textContent, attributes: textAttributes) diff --git a/Yep/zh-Hans.lproj/Localizable.strings b/Yep/zh-Hans.lproj/Localizable.strings index c1a90e31..c06b5945 100644 --- a/Yep/zh-Hans.lproj/Localizable.strings +++ b/Yep/zh-Hans.lproj/Localizable.strings @@ -726,7 +726,7 @@ "Hide" = "隐藏"; -"Recalled by creator." = "消息已被撤回。"; +"%@ recalled a message." = "%@ 撤回了一条消息。"; "Retry" = "重试";