mirror of
https://github.com/wahyd4/Yep.git
synced 2026-08-25 04:36:24 +10:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
+8
-13
@@ -90,9 +90,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
let isLogined = YepUserDefaults.isLogined
|
||||
|
||||
if isLogined {
|
||||
sync()
|
||||
|
||||
startFaye()
|
||||
delay(1.0, work: {[weak self] () -> Void in
|
||||
self?.sync()
|
||||
self?.startFaye()
|
||||
})
|
||||
|
||||
// 记录启动通知类型
|
||||
if let
|
||||
@@ -238,15 +240,13 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
if application.applicationState != .Active {
|
||||
self.remoteNotificationType = remoteNotificationType
|
||||
}
|
||||
|
||||
completionHandler(UIBackgroundFetchResult.NoData)
|
||||
|
||||
} else {
|
||||
completionHandler(UIBackgroundFetchResult.NoData)
|
||||
}
|
||||
|
||||
} else {
|
||||
completionHandler(UIBackgroundFetchResult.NewData)
|
||||
completionHandler(UIBackgroundFetchResult.NoData)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,14 +292,9 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
}
|
||||
|
||||
func sync() {
|
||||
|
||||
syncMyInfoAndDoFurtherAction {
|
||||
syncFriendshipsAndDoFurtherAction {
|
||||
syncGroupsAndDoFurtherAction {
|
||||
syncUnreadMessagesAndDoFurtherAction { messageIDs in
|
||||
tryPostNewMessagesReceivedNotificationWithMessageIDs(messageIDs, withMessageAge: .New)
|
||||
}
|
||||
}
|
||||
syncGroupsAndDoFurtherAction {
|
||||
syncUnreadMessagesAndDoFurtherAction { messageIDs in
|
||||
tryPostNewMessagesReceivedNotificationWithMessageIDs(messageIDs, withMessageAge: .New)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="14F27" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="Ha4-ol-D2e">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="Ha4-ol-D2e">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
|
||||
@@ -38,7 +38,7 @@ class AvatarCache {
|
||||
}
|
||||
}
|
||||
|
||||
func avatarFromURL(url: NSURL, completion: (isFinish: Bool, image: UIImage) -> ()) {
|
||||
func avatarFromURL(url: NSURL, size: CGFloat, completion: (isFinish: Bool, image: UIImage) -> ()) {
|
||||
|
||||
completion(isFinish: false, image: UIImage(named: "default_avatar")!)
|
||||
|
||||
@@ -62,7 +62,7 @@ class AvatarCache {
|
||||
let avatarFileURL = NSFileManager.yepAvatarURLWithName(avatar.avatarFileName),
|
||||
let image = UIImage(contentsOfFile: avatarFileURL.path!) {
|
||||
|
||||
let image = image.decodedImage()
|
||||
let image = image.squareImageOfSize(size).decodedImage()
|
||||
|
||||
self.cache.setObject(image, forKey: normalImageKey)
|
||||
|
||||
|
||||
+6
-4
@@ -6,19 +6,21 @@
|
||||
"resizing" : {
|
||||
"mode" : "3-part-horizontal",
|
||||
"center" : {
|
||||
"mode" : "fill",
|
||||
"mode" : "tile",
|
||||
"width" : 1
|
||||
},
|
||||
"capInsets" : {
|
||||
"cap-insets" : {
|
||||
"right" : 12,
|
||||
"left" : 12
|
||||
"left" : 13
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode",
|
||||
"author" : "xcode"
|
||||
},
|
||||
"properties" : {
|
||||
"template-rendering-intent" : "template"
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>107</string>
|
||||
<string>113</string>
|
||||
<key>Fabric</key>
|
||||
<dict>
|
||||
<key>APIKey</key>
|
||||
|
||||
+10
-5
@@ -563,7 +563,7 @@ func latestMessageInRealm(realm: Realm, withConversationType conversationType: C
|
||||
return realm.objects(Message).filter(predicate).sorted("updatedUnixTime", ascending: false).first
|
||||
}
|
||||
|
||||
func saveFeedWithFeedData(feedData: DiscoveredFeed, group: Group, inRealm realm: Realm) {
|
||||
func saveFeedWithFeedDataWithoutFullGroup(feedData: DiscoveredFeed, group: Group, inRealm realm: Realm) {
|
||||
|
||||
// try sync group first
|
||||
|
||||
@@ -578,12 +578,17 @@ func saveFeedWithFeedData(feedData: DiscoveredFeed, group: Group, inRealm realm:
|
||||
syncGroupWithGroupInfo(groupInfo, inRealm: realm)
|
||||
})
|
||||
|
||||
// save feed
|
||||
saveFeedWithFeedDataWithFullGroup(feedData, group: group, inRealm: realm)
|
||||
|
||||
}
|
||||
|
||||
func saveFeedWithFeedDataWithFullGroup(feedData: DiscoveredFeed, group: Group, inRealm realm: Realm) {
|
||||
// save feed
|
||||
|
||||
if let feed = feedWithFeedID(feedData.id, inRealm: realm) {
|
||||
|
||||
print("Join Feed \(feed.feedID)")
|
||||
|
||||
|
||||
} else {
|
||||
let newFeed = Feed()
|
||||
newFeed.feedID = feedData.id
|
||||
@@ -607,9 +612,9 @@ func saveFeedWithFeedData(feedData: DiscoveredFeed, group: Group, inRealm realm:
|
||||
|
||||
let attachments = attachmentFromDiscoveredAttachment(feedData.attachments, inRealm: realm)
|
||||
newFeed.attachments.appendContentsOf(attachments)
|
||||
|
||||
|
||||
newFeed.group = group
|
||||
|
||||
|
||||
let _ = try? realm.write {
|
||||
realm.add(newFeed)
|
||||
}
|
||||
|
||||
@@ -125,7 +125,10 @@ class FayeService: NSObject, MZFayeClientDelegate {
|
||||
message.sendState = MessageSendState.Read.rawValue
|
||||
}
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,7 +198,9 @@ class FayeService: NSObject, MZFayeClientDelegate {
|
||||
message.sendState = MessageSendState.Read.rawValue
|
||||
}
|
||||
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
NSNotificationCenter.defaultCenter().postNotificationName(MessageNotification.MessageStateChanged, object: nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -546,7 +546,7 @@ func syncGroupsAndDoFurtherAction(furtherAction: () -> Void) {
|
||||
topic = groupInfo["topic"] as? JSONDictionary,
|
||||
feedData = DiscoveredFeed.fromJSONDictionary(topic),
|
||||
group = group {
|
||||
saveFeedWithFeedData(feedData, group: group, inRealm: realm)
|
||||
saveFeedWithFeedDataWithFullGroup(feedData, group: group, inRealm: realm)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,9 @@ class ContactsViewController: BaseViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
syncFriendshipsAndDoFurtherAction {
|
||||
}
|
||||
|
||||
title = NSLocalizedString("Contacts", comment: "")
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,6 +13,8 @@ enum DiscoverUserMode: Int {
|
||||
case Card
|
||||
}
|
||||
|
||||
var skillSizeCache = [String: CGRect]()
|
||||
|
||||
class DiscoverViewController: BaseViewController {
|
||||
|
||||
@IBOutlet weak var discoverCollectionView: UICollectionView!
|
||||
@@ -60,6 +62,27 @@ class DiscoverViewController: BaseViewController {
|
||||
}
|
||||
|
||||
}, completion: { discoveredUsers in
|
||||
|
||||
for user in discoveredUsers {
|
||||
|
||||
for skill in user.masterSkills {
|
||||
|
||||
let skillLocalName = skill.localName ?? ""
|
||||
|
||||
let skillID = skill.id
|
||||
|
||||
if let _ = skillSizeCache[skillID] {
|
||||
|
||||
} else {
|
||||
let rect = skillLocalName.boundingRectWithSize(CGSize(width: CGFloat(FLT_MAX), height: SkillCell.height), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: skillTextAttributes, context: nil)
|
||||
|
||||
skillSizeCache[skillID] = rect
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.discoveredUsers = discoveredUsers
|
||||
self?.activityIndicator.stopAnimating()
|
||||
@@ -182,22 +205,35 @@ extension DiscoverViewController: UICollectionViewDelegate, UICollectionViewData
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
|
||||
let discoveredUser = discoveredUsers[indexPath.row]
|
||||
// let discoveredUser = discoveredUsers[indexPath.row]
|
||||
|
||||
switch userMode! {
|
||||
case .Normal:
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(NormalUserIdentifier, forIndexPath: indexPath) as! DiscoverNormalUserCell
|
||||
|
||||
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
|
||||
// cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
|
||||
return cell
|
||||
|
||||
case .Card:
|
||||
let cell = collectionView.dequeueReusableCellWithReuseIdentifier(CardUserIdentifier, forIndexPath: indexPath) as! DiscoverCardUserCell
|
||||
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
|
||||
// cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, willDisplayCell cell: UICollectionViewCell, forItemAtIndexPath indexPath: NSIndexPath) {
|
||||
let discoveredUser = discoveredUsers[indexPath.row]
|
||||
|
||||
|
||||
switch userMode! {
|
||||
case .Normal:
|
||||
let cell = cell as! DiscoverNormalUserCell
|
||||
|
||||
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
|
||||
|
||||
case .Card:
|
||||
let cell = cell as! DiscoverCardUserCell
|
||||
cell.configureWithDiscoveredUser(discoveredUser, collectionView: collectionView, indexPath: indexPath)
|
||||
}
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
|
||||
|
||||
@@ -256,7 +256,7 @@ class FeedsViewController: UIViewController {
|
||||
vc.conversation = feedConversation
|
||||
|
||||
if let group = group {
|
||||
saveFeedWithFeedData(feedData, group: group, inRealm: realm)
|
||||
saveFeedWithFeedDataWithoutFullGroup(feedData, group: group, inRealm: realm)
|
||||
}
|
||||
|
||||
vc.conversationFeed = ConversationFeed.DiscoveredFeedType(feedData)
|
||||
|
||||
@@ -206,6 +206,9 @@ class LoginVerifyMobileViewController: UIViewController {
|
||||
dispatch_async(dispatch_get_main_queue(), { () -> Void in
|
||||
|
||||
saveTokenAndUserInfoOfLoginUser(loginUser)
|
||||
|
||||
syncMyInfoAndDoFurtherAction {
|
||||
}
|
||||
|
||||
if let appDelegate = UIApplication.sharedApplication().delegate as? AppDelegate {
|
||||
appDelegate.startMainStory()
|
||||
|
||||
@@ -480,6 +480,9 @@ class ProfileViewController: UIViewController {
|
||||
|
||||
override func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
|
||||
syncMyInfoAndDoFurtherAction {
|
||||
}
|
||||
|
||||
title = NSLocalizedString("Profile", comment: "")
|
||||
|
||||
|
||||
@@ -124,7 +124,9 @@ class ChatLeftAudioCell: ChatBaseCell {
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
updateAudioInfoViews()
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.updateAudioInfoViews()
|
||||
}
|
||||
}
|
||||
|
||||
func updateAudioInfoViews() {
|
||||
|
||||
@@ -97,7 +97,9 @@ class ChatLeftImageCell: ChatBaseCell {
|
||||
|
||||
loadingProgress = 0
|
||||
|
||||
messageImageView.alpha = 0.0
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.messageImageView.alpha = 0.0
|
||||
}
|
||||
|
||||
if let (imageWidth, imageHeight) = imageMetaOfMessage(message) {
|
||||
|
||||
@@ -109,8 +111,14 @@ class ChatLeftImageCell: ChatBaseCell {
|
||||
if aspectRatio >= 1 {
|
||||
|
||||
let width = messageImagePreferredWidth
|
||||
messageImageView.frame = CGRect(x: CGRectGetMaxX(avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: bounds.height)
|
||||
loadingProgressView.center = CGPoint(x: CGRectGetMidX(messageImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(messageImageView.frame))
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.messageImageView.frame = CGRect(x: CGRectGetMaxX(strongSelf.avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.loadingProgressView.center = CGPoint(x: CGRectGetMidX(strongSelf.messageImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.messageImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / aspectRatio)), tailDirection: .Left, completion: { [weak self] progress, image in
|
||||
|
||||
@@ -123,8 +131,13 @@ class ChatLeftImageCell: ChatBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredHeight * aspectRatio
|
||||
messageImageView.frame = CGRect(x: CGRectGetMaxX(avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: bounds.height)
|
||||
loadingProgressView.center = CGPoint(x: CGRectGetMidX(messageImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(messageImageView.frame))
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.messageImageView.frame = CGRect(x: CGRectGetMaxX(strongSelf.avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.loadingProgressView.center = CGPoint(x: CGRectGetMidX(strongSelf.messageImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.messageImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredHeight * aspectRatio, height: messageImagePreferredHeight), tailDirection: .Left, completion: { [weak self] progress, image in
|
||||
|
||||
@@ -138,8 +151,13 @@ class ChatLeftImageCell: ChatBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredWidth
|
||||
messageImageView.frame = CGRect(x: CGRectGetMaxX(avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: bounds.height)
|
||||
loadingProgressView.center = CGPoint(x: CGRectGetMidX(messageImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(messageImageView.frame))
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.messageImageView.frame = CGRect(x: CGRectGetMaxX(strongSelf.avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.loadingProgressView.center = CGPoint(x: CGRectGetMidX(strongSelf.messageImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.messageImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / messageImagePreferredAspectRatio)), tailDirection: .Left, completion: { [weak self] progress, image in
|
||||
|
||||
|
||||
@@ -40,10 +40,6 @@ class ChatLeftTextCell: ChatBaseCell {
|
||||
NSUnderlineStyleAttributeName: NSNumber(integer: NSUnderlineStyle.StyleSingle.rawValue),
|
||||
]
|
||||
|
||||
let longPress = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
|
||||
longPress.minimumPressDuration = 0.3
|
||||
longPress.delegate = self // 由 ChatBaseCell 负责
|
||||
textContainerView.addGestureRecognizer(longPress)
|
||||
|
||||
textContainerView.copyTextAction = { [weak self] in
|
||||
UIPasteboard.generalPasteboard().string = self?.textContentTextView.text
|
||||
@@ -52,20 +48,12 @@ class ChatLeftTextCell: ChatBaseCell {
|
||||
bubbleBodyImageView.tintColor = UIColor.leftBubbleTintColor()
|
||||
bubbleTailImageView.tintColor = UIColor.leftBubbleTintColor()
|
||||
}
|
||||
|
||||
func handleLongPress(longPress: UILongPressGestureRecognizer) {
|
||||
if longPress.state == .Began {
|
||||
|
||||
if let view = longPress.view, superview = view.superview {
|
||||
|
||||
view.becomeFirstResponder()
|
||||
|
||||
let menu = UIMenuController.sharedMenuController()
|
||||
let copyItem = UIMenuItem(title: NSLocalizedString("Copy", comment: ""), action:"copyText")
|
||||
menu.menuItems = [copyItem]
|
||||
menu.setTargetRect(view.frame, inView: superview)
|
||||
menu.setMenuVisible(true, animated: true)
|
||||
}
|
||||
|
||||
override func respondsToSelector(aSelector: Selector) -> Bool {
|
||||
if ["copy:"].contains(aSelector) {
|
||||
return true
|
||||
} else {
|
||||
return super.respondsToSelector(aSelector)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,27 +61,33 @@ class ChatLeftTextCell: ChatBaseCell {
|
||||
|
||||
self.user = message.fromFriend
|
||||
|
||||
textContentTextView.text = message.textContent
|
||||
//textContentTextView.attributedText = NSAttributedString(string: message.textContent, attributes: textAttributes)
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.textContentTextView.text = message.textContent
|
||||
//textContentTextView.attributedText = NSAttributedString(string: message.textContent, attributes: textAttributes)
|
||||
|
||||
//textContentTextView.textAlignment = textContentLabelWidth < YepConfig.minMessageTextLabelWidth ? .Center : .Left
|
||||
|
||||
// 用 sizeThatFits 来对比,不需要 magicWidth 的时候就可以避免了
|
||||
var textContentLabelWidth = textContentLabelWidth
|
||||
let size = strongSelf.textContentTextView.sizeThatFits(CGSize(width: textContentLabelWidth, height: CGFloat.max))
|
||||
|
||||
// lineHeight 19.088, size.height 35.5 (1 line) 54.5 (2 lines)
|
||||
strongSelf.textContentTextView.textAlignment = ((size.height - strongSelf.textContentTextView.font!.lineHeight) < 20) ? .Center : .Left
|
||||
|
||||
if size.width != textContentLabelWidth {
|
||||
textContentLabelWidth += YepConfig.ChatCell.magicWidth
|
||||
}
|
||||
|
||||
textContentLabelWidth = max(textContentLabelWidth, YepConfig.ChatCell.minTextWidth)
|
||||
|
||||
strongSelf.textContainerView.frame = CGRect(x: CGRectGetMaxX(strongSelf.avatarImageView.frame) + YepConfig.chatCellGapBetweenTextContentLabelAndAvatar(), y: 3, width: textContentLabelWidth, height: strongSelf.bounds.height - 3 * 2)
|
||||
strongSelf.bubbleBodyImageView.frame = CGRectInset(strongSelf.textContainerView.frame, -12, -3)
|
||||
strongSelf.bubbleTailImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.bubbleBodyImageView.frame), y: CGRectGetMidY(strongSelf.avatarImageView.frame))
|
||||
|
||||
//textContentTextView.textAlignment = textContentLabelWidth < YepConfig.minMessageTextLabelWidth ? .Center : .Left
|
||||
|
||||
// 用 sizeThatFits 来对比,不需要 magicWidth 的时候就可以避免了
|
||||
var textContentLabelWidth = textContentLabelWidth
|
||||
let size = textContentTextView.sizeThatFits(CGSize(width: textContentLabelWidth, height: CGFloat.max))
|
||||
|
||||
// lineHeight 19.088, size.height 35.5 (1 line) 54.5 (2 lines)
|
||||
textContentTextView.textAlignment = ((size.height - textContentTextView.font!.lineHeight) < 20) ? .Center : .Left
|
||||
|
||||
if size.width != textContentLabelWidth {
|
||||
textContentLabelWidth += YepConfig.ChatCell.magicWidth
|
||||
}
|
||||
}
|
||||
|
||||
textContentLabelWidth = max(textContentLabelWidth, YepConfig.ChatCell.minTextWidth)
|
||||
|
||||
textContainerView.frame = CGRect(x: CGRectGetMaxX(avatarImageView.frame) + YepConfig.chatCellGapBetweenTextContentLabelAndAvatar(), y: 3, width: textContentLabelWidth, height: bounds.height - 3 * 2)
|
||||
bubbleBodyImageView.frame = CGRectInset(textContainerView.frame, -12, -3)
|
||||
bubbleTailImageView.center = CGPoint(x: CGRectGetMinX(bubbleBodyImageView.frame), y: CGRectGetMidY(avatarImageView.frame))
|
||||
|
||||
if let sender = message.fromFriend {
|
||||
AvatarCache.sharedInstance.roundAvatarOfUser(sender, withRadius: YepConfig.chatCellAvatarSize() * 0.5) { [weak self] roundImage in
|
||||
|
||||
@@ -99,7 +99,12 @@ class ChatLeftVideoCell: ChatBaseCell {
|
||||
|
||||
loadingProgress = 0
|
||||
|
||||
thumbnailImageView.alpha = 0.0
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.thumbnailImageView.alpha = 0.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if let (videoWidth, videoHeight) = videoMetaOfMessage(message) {
|
||||
|
||||
@@ -111,9 +116,14 @@ class ChatLeftVideoCell: ChatBaseCell {
|
||||
if aspectRatio >= 1 {
|
||||
|
||||
let width = messageImagePreferredWidth
|
||||
thumbnailImageView.frame = CGRect(x: CGRectGetMaxX(avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: bounds.height)
|
||||
playImageView.center = CGPoint(x: CGRectGetMidX(thumbnailImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
loadingProgressView.center = playImageView.center
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.thumbnailImageView.frame = CGRect(x: CGRectGetMaxX(strongSelf.avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.playImageView.center = CGPoint(x: CGRectGetMidX(strongSelf.thumbnailImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
strongSelf.loadingProgressView.center = strongSelf.playImageView.center
|
||||
}
|
||||
}
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / aspectRatio)), tailDirection: .Left, completion: { [weak self] progress, image in
|
||||
|
||||
@@ -126,9 +136,15 @@ class ChatLeftVideoCell: ChatBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredHeight * aspectRatio
|
||||
thumbnailImageView.frame = CGRect(x: CGRectGetMaxX(avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: bounds.height)
|
||||
playImageView.center = CGPoint(x: CGRectGetMidX(thumbnailImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
loadingProgressView.center = playImageView.center
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.thumbnailImageView.frame = CGRect(x: CGRectGetMaxX(strongSelf.avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.playImageView.center = CGPoint(x: CGRectGetMidX(strongSelf.thumbnailImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
strongSelf.loadingProgressView.center = strongSelf.playImageView.center
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredHeight * aspectRatio, height: messageImagePreferredHeight), tailDirection: .Left, completion: { [weak self] progress, image in
|
||||
|
||||
@@ -142,9 +158,14 @@ class ChatLeftVideoCell: ChatBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredWidth
|
||||
thumbnailImageView.frame = CGRect(x: CGRectGetMaxX(avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: bounds.height)
|
||||
playImageView.center = CGPoint(x: CGRectGetMidX(thumbnailImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
loadingProgressView.center = playImageView.center
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.thumbnailImageView.frame = CGRect(x: CGRectGetMaxX(strongSelf.avatarImageView.frame) + YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.playImageView.center = CGPoint(x: CGRectGetMidX(strongSelf.thumbnailImageView.frame) + YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
strongSelf.loadingProgressView.center = strongSelf.playImageView.center
|
||||
}
|
||||
}
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / messageImagePreferredAspectRatio)), tailDirection: .Left, completion: { [weak self] progress, image in
|
||||
|
||||
|
||||
@@ -95,14 +95,18 @@ class ChatRightAudioCell: ChatRightBaseCell {
|
||||
}
|
||||
}
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.layoutIfNeeded()
|
||||
}
|
||||
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
override func layoutSubviews() {
|
||||
super.layoutSubviews()
|
||||
|
||||
updateAudioInfoViews()
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.updateAudioInfoViews()
|
||||
}
|
||||
}
|
||||
|
||||
func updateAudioInfoViews() {
|
||||
|
||||
@@ -87,11 +87,16 @@ class ChatRightBaseCell: ChatBaseCell {
|
||||
animation.toValue = 2 * M_PI
|
||||
animation.duration = 1.0
|
||||
animation.repeatCount = MAXFLOAT
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.dotImageView.layer.addAnimation(animation, forKey: sendingAnimationName)
|
||||
}
|
||||
|
||||
dotImageView.layer.addAnimation(animation, forKey: sendingAnimationName)
|
||||
}
|
||||
|
||||
func removeSendingAnimation() {
|
||||
dotImageView.layer.removeAnimationForKey(sendingAnimationName)
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.dotImageView.layer.removeAnimationForKey(sendingAnimationName)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,12 +54,12 @@ class ChatRightImageCell: ChatRightBaseCell {
|
||||
|
||||
if let image = image {
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
|
||||
self.messageImageView.image = image
|
||||
self?.messageImageView.image = image
|
||||
|
||||
UIView.animateWithDuration(YepConfig.ChatCell.imageAppearDuration, delay: 0.0, options: .CurveEaseInOut, animations: { () -> Void in
|
||||
self.messageImageView.alpha = 1.0
|
||||
self?.messageImageView.alpha = 1.0
|
||||
}, completion: { (finished) -> Void in
|
||||
})
|
||||
}
|
||||
@@ -85,8 +85,10 @@ class ChatRightImageCell: ChatRightBaseCell {
|
||||
}
|
||||
|
||||
loadingProgress = 0
|
||||
|
||||
messageImageView.alpha = 0.0
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.messageImageView.alpha = 0.0
|
||||
}
|
||||
|
||||
if let (imageWidth, imageHeight) = imageMetaOfMessage(message) {
|
||||
|
||||
@@ -97,9 +99,14 @@ class ChatRightImageCell: ChatRightBaseCell {
|
||||
|
||||
if aspectRatio >= 1 {
|
||||
let width = messageImagePreferredWidth
|
||||
messageImageView.frame = CGRect(x: CGRectGetMinX(avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: bounds.height)
|
||||
dotImageView.center = CGPoint(x: CGRectGetMinX(messageImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(messageImageView.frame))
|
||||
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.messageImageView.frame = CGRect(x: CGRectGetMinX(strongSelf.avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.dotImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.messageImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(strongSelf.messageImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / aspectRatio)), tailDirection: .Right, completion: { [weak self] progress, image in
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
@@ -111,8 +118,13 @@ class ChatRightImageCell: ChatRightBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredHeight * aspectRatio
|
||||
messageImageView.frame = CGRect(x: CGRectGetMinX(avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: bounds.height)
|
||||
dotImageView.center = CGPoint(x: CGRectGetMinX(messageImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(messageImageView.frame))
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.messageImageView.frame = CGRect(x: CGRectGetMinX(strongSelf.avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.dotImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.messageImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(strongSelf.messageImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredHeight * aspectRatio, height: messageImagePreferredHeight), tailDirection: .Right, completion: { [weak self] progress, image in
|
||||
|
||||
@@ -126,8 +138,14 @@ class ChatRightImageCell: ChatRightBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredWidth
|
||||
messageImageView.frame = CGRect(x: CGRectGetMinX(avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: bounds.height)
|
||||
dotImageView.center = CGPoint(x: CGRectGetMinX(messageImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(messageImageView.frame))
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.messageImageView.frame = CGRect(x: CGRectGetMinX(strongSelf.avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.dotImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.messageImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(strongSelf.messageImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / messageImagePreferredAspectRatio)), tailDirection: .Right, completion: { [weak self] progress, image in
|
||||
|
||||
|
||||
@@ -26,19 +26,35 @@ class ChatRightTextCell: ChatRightBaseCell {
|
||||
let fullWidth = UIScreen.mainScreen().bounds.width
|
||||
|
||||
let halfAvatarSize = YepConfig.chatCellAvatarSize() / 2
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.avatarImageView.center = CGPoint(x: fullWidth - halfAvatarSize - YepConfig.chatCellGapBetweenWallAndAvatar(), y: halfAvatarSize)
|
||||
}
|
||||
|
||||
avatarImageView.center = CGPoint(x: fullWidth - halfAvatarSize - YepConfig.chatCellGapBetweenWallAndAvatar(), y: halfAvatarSize)
|
||||
}
|
||||
|
||||
override func respondsToSelector(aSelector: Selector) -> Bool {
|
||||
if ["deleteMessage:" ,"copy:"].contains(aSelector) {
|
||||
return true
|
||||
} else {
|
||||
return super.respondsToSelector(aSelector)
|
||||
}
|
||||
}
|
||||
|
||||
func deleteMessage(object: UIMenuController?) {
|
||||
if let longPressAction = longPressAction {
|
||||
longPressAction()
|
||||
}
|
||||
}
|
||||
|
||||
override func awakeFromNib() {
|
||||
super.awakeFromNib()
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.makeUI()
|
||||
}
|
||||
makeUI()
|
||||
|
||||
textContentTextView.textContainer.lineFragmentPadding = 0
|
||||
textContentTextView.font = UIFont.chatTextFont()
|
||||
|
||||
|
||||
textContentTextView.backgroundColor = UIColor.clearColor()
|
||||
textContentTextView.textColor = UIColor.whiteColor()
|
||||
@@ -48,11 +64,6 @@ class ChatRightTextCell: ChatRightBaseCell {
|
||||
NSUnderlineStyleAttributeName: NSNumber(integer: NSUnderlineStyle.StyleSingle.rawValue),
|
||||
]
|
||||
|
||||
let longPress = UILongPressGestureRecognizer(target: self, action: "handleLongPress:")
|
||||
longPress.minimumPressDuration = 0.3
|
||||
longPress.delegate = self // 由 ChatBaseCell 负责
|
||||
textContainerView.addGestureRecognizer(longPress)
|
||||
|
||||
textContainerView.copyTextAction = { [weak self] in
|
||||
UIPasteboard.generalPasteboard().string = self?.textContentTextView.text
|
||||
}
|
||||
@@ -69,22 +80,6 @@ class ChatRightTextCell: ChatRightBaseCell {
|
||||
bubbleBodyImageView.addGestureRecognizer(tap)
|
||||
}
|
||||
|
||||
func handleLongPress(longPress: UILongPressGestureRecognizer) {
|
||||
if longPress.state == .Began {
|
||||
|
||||
if let view = longPress.view, superview = view.superview {
|
||||
|
||||
view.becomeFirstResponder()
|
||||
|
||||
let menu = UIMenuController.sharedMenuController()
|
||||
let copyItem = UIMenuItem(title: NSLocalizedString("Copy", comment: ""), action:"copyText")
|
||||
let deleteItem = UIMenuItem(title: NSLocalizedString("Delete", comment: ""), action:"deleteTextMessage")
|
||||
menu.menuItems = [copyItem, deleteItem]
|
||||
menu.setTargetRect(view.frame, inView: superview)
|
||||
menu.setMenuVisible(true, animated: true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func tapMediaView() {
|
||||
mediaTapAction?()
|
||||
@@ -96,30 +91,35 @@ class ChatRightTextCell: ChatRightBaseCell {
|
||||
self.user = message.fromFriend
|
||||
|
||||
self.mediaTapAction = mediaTapAction
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
|
||||
textContentTextView.text = message.textContent
|
||||
//textContentTextView.attributedText = NSAttributedString(string: message.textContent, attributes: textAttributes)
|
||||
|
||||
//textContentTextView.textAlignment = textContentLabelWidth < YepConfig.minMessageTextLabelWidth ? .Center : .Left
|
||||
|
||||
// 用 sizeThatFits 来对比,不需要 magicWidth 的时候就可以避免了
|
||||
var textContentLabelWidth = textContentLabelWidth
|
||||
let size = textContentTextView.sizeThatFits(CGSize(width: textContentLabelWidth, height: CGFloat.max))
|
||||
|
||||
// lineHeight 19.088, size.height 35.5 (1 line) 54.5 (2 lines)
|
||||
textContentTextView.textAlignment = ((size.height - textContentTextView.font!.lineHeight) < 20) ? .Center : .Left
|
||||
|
||||
if size.width != textContentLabelWidth {
|
||||
textContentLabelWidth += YepConfig.ChatCell.magicWidth
|
||||
if let strongSelf = self {
|
||||
strongSelf.textContentTextView.text = message.textContent
|
||||
//textContentTextView.attributedText = NSAttributedString(string: message.textContent, attributes: textAttributes)
|
||||
|
||||
//textContentTextView.textAlignment = textContentLabelWidth < YepConfig.minMessageTextLabelWidth ? .Center : .Left
|
||||
|
||||
// 用 sizeThatFits 来对比,不需要 magicWidth 的时候就可以避免了
|
||||
var textContentLabelWidth = textContentLabelWidth
|
||||
let size = strongSelf.textContentTextView.sizeThatFits(CGSize(width: textContentLabelWidth, height: CGFloat.max))
|
||||
|
||||
// lineHeight 19.088, size.height 35.5 (1 line) 54.5 (2 lines)
|
||||
strongSelf.textContentTextView.textAlignment = ((size.height - strongSelf.textContentTextView.font!.lineHeight) < 20) ? .Center : .Left
|
||||
|
||||
if size.width != textContentLabelWidth {
|
||||
textContentLabelWidth += YepConfig.ChatCell.magicWidth
|
||||
}
|
||||
|
||||
textContentLabelWidth = max(textContentLabelWidth, YepConfig.ChatCell.minTextWidth)
|
||||
|
||||
strongSelf.textContainerView.frame = CGRect(x: CGRectGetMinX(strongSelf.avatarImageView.frame) - YepConfig.chatCellGapBetweenTextContentLabelAndAvatar() - textContentLabelWidth, y: 3, width: textContentLabelWidth, height: strongSelf.bounds.height - 3 * 2)
|
||||
strongSelf.bubbleBodyImageView.frame = CGRectInset(strongSelf.textContainerView.frame, -12, -3)
|
||||
strongSelf.bubbleTailImageView.center = CGPoint(x: CGRectGetMaxX(strongSelf.bubbleBodyImageView.frame), y: CGRectGetMidY(strongSelf.avatarImageView.frame))
|
||||
strongSelf.dotImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.bubbleBodyImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(strongSelf.bubbleBodyImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
textContentLabelWidth = max(textContentLabelWidth, YepConfig.ChatCell.minTextWidth)
|
||||
|
||||
textContainerView.frame = CGRect(x: CGRectGetMinX(avatarImageView.frame) - YepConfig.chatCellGapBetweenTextContentLabelAndAvatar() - textContentLabelWidth, y: 3, width: textContentLabelWidth, height: bounds.height - 3 * 2)
|
||||
bubbleBodyImageView.frame = CGRectInset(textContainerView.frame, -12, -3)
|
||||
bubbleTailImageView.center = CGPoint(x: CGRectGetMaxX(bubbleBodyImageView.frame), y: CGRectGetMidY(avatarImageView.frame))
|
||||
dotImageView.center = CGPoint(x: CGRectGetMinX(bubbleBodyImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(bubbleBodyImageView.frame))
|
||||
|
||||
if let sender = message.fromFriend {
|
||||
AvatarCache.sharedInstance.roundAvatarOfUser(sender, withRadius: YepConfig.chatCellAvatarSize() * 0.5) { [weak self] roundImage in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
|
||||
@@ -86,7 +86,9 @@ class ChatRightVideoCell: ChatRightBaseCell {
|
||||
}
|
||||
}
|
||||
|
||||
thumbnailImageView.alpha = 0.0
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
self?.thumbnailImageView.alpha = 0.0
|
||||
}
|
||||
|
||||
if let (videoWidth, videoHeight) = videoMetaOfMessage(message) {
|
||||
|
||||
@@ -98,9 +100,13 @@ class ChatRightVideoCell: ChatRightBaseCell {
|
||||
if aspectRatio >= 1 {
|
||||
|
||||
let width = messageImagePreferredWidth
|
||||
thumbnailImageView.frame = CGRect(x: CGRectGetMinX(avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: bounds.height)
|
||||
playImageView.center = CGPoint(x: CGRectGetMidX(thumbnailImageView.frame) - YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
dotImageView.center = CGPoint(x: CGRectGetMinX(thumbnailImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.thumbnailImageView.frame = CGRect(x: CGRectGetMinX(strongSelf.avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.playImageView.center = CGPoint(x: CGRectGetMidX(strongSelf.thumbnailImageView.frame) - YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
strongSelf.dotImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.thumbnailImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / aspectRatio)), tailDirection: .Right, completion: { [weak self] progress, image in
|
||||
|
||||
@@ -113,9 +119,14 @@ class ChatRightVideoCell: ChatRightBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredHeight * aspectRatio
|
||||
thumbnailImageView.frame = CGRect(x: CGRectGetMinX(avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: bounds.height)
|
||||
playImageView.center = CGPoint(x: CGRectGetMidX(thumbnailImageView.frame) - YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
dotImageView.center = CGPoint(x: CGRectGetMinX(thumbnailImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.thumbnailImageView.frame = CGRect(x: CGRectGetMinX(strongSelf.avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.playImageView.center = CGPoint(x: CGRectGetMidX(strongSelf.thumbnailImageView.frame) - YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
strongSelf.dotImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.thumbnailImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredHeight * aspectRatio, height: messageImagePreferredHeight), tailDirection: .Right, completion: { [weak self] progress, image in
|
||||
|
||||
@@ -129,9 +140,15 @@ class ChatRightVideoCell: ChatRightBaseCell {
|
||||
|
||||
} else {
|
||||
let width = messageImagePreferredWidth
|
||||
thumbnailImageView.frame = CGRect(x: CGRectGetMinX(avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: bounds.height)
|
||||
playImageView.center = CGPoint(x: CGRectGetMidX(thumbnailImageView.frame) - YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
dotImageView.center = CGPoint(x: CGRectGetMinX(thumbnailImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(thumbnailImageView.frame))
|
||||
|
||||
dispatch_async(dispatch_get_main_queue()) { [weak self] in
|
||||
if let strongSelf = self {
|
||||
strongSelf.thumbnailImageView.frame = CGRect(x: CGRectGetMinX(strongSelf.avatarImageView.frame) - YepConfig.ChatCell.gapBetweenAvatarImageViewAndBubble - width, y: 0, width: width, height: strongSelf.bounds.height)
|
||||
strongSelf.playImageView.center = CGPoint(x: CGRectGetMidX(strongSelf.thumbnailImageView.frame) - YepConfig.ChatCell.playImageViewXOffset, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
strongSelf.dotImageView.center = CGPoint(x: CGRectGetMinX(strongSelf.thumbnailImageView.frame) - YepConfig.ChatCell.gapBetweenDotImageViewAndBubble, y: CGRectGetMidY(strongSelf.thumbnailImageView.frame))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ImageCache.sharedInstance.imageOfMessage(message, withSize: CGSize(width: messageImagePreferredWidth, height: ceil(messageImagePreferredWidth / messageImagePreferredAspectRatio)), tailDirection: .Right, completion: { [weak self] progress, image in
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="7706" systemVersion="14D136" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="8191" systemVersion="15A284" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="7703"/>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
@@ -12,15 +13,18 @@
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="298" height="50"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yestoday 14:55" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qeo-Lw-vBM">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Yesterday 14:55" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qeo-Lw-vBM">
|
||||
<rect key="frame" x="0.0" y="0.0" width="298" height="50"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="12"/>
|
||||
<color key="textColor" red="0.40000000596046448" green="0.40000000596046448" blue="0.40000000596046448" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<animations/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="bottom" secondItem="qeo-Lw-vBM" secondAttribute="bottom" id="53j-Kc-ZKN"/>
|
||||
<constraint firstAttribute="trailing" secondItem="qeo-Lw-vBM" secondAttribute="trailing" id="THI-Ef-cbo"/>
|
||||
|
||||
@@ -8,6 +8,8 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
let skillTextAttributes = [NSFontAttributeName: UIFont.skillDiscoverTextFont()]
|
||||
|
||||
class DiscoverCardUserCell: UICollectionViewCell {
|
||||
|
||||
@IBOutlet weak var serviceImageView: UIImageView!
|
||||
@@ -24,8 +26,6 @@ class DiscoverCardUserCell: UICollectionViewCell {
|
||||
|
||||
var discoveredUser: DiscoveredUser?
|
||||
|
||||
let skillTextAttributes = [NSFontAttributeName: UIFont.skillDiscoverTextFont()]
|
||||
|
||||
let discoverCellHeight: CGFloat = 16
|
||||
|
||||
override func awakeFromNib() {
|
||||
@@ -33,8 +33,8 @@ class DiscoverCardUserCell: UICollectionViewCell {
|
||||
// Initialization code
|
||||
userSkillsCollectionView.backgroundColor = UIColor.clearColor()
|
||||
contentView.backgroundColor = UIColor.whiteColor()
|
||||
contentView.layer.cornerRadius = 6
|
||||
contentView.layer.masksToBounds = true
|
||||
// contentView.layer.cornerRadius = 6
|
||||
// contentView.layer.masksToBounds = true
|
||||
|
||||
contentView.layer.borderColor = UIColor.yepCellSeparatorColor().CGColor
|
||||
contentView.layer.borderWidth = 1.0
|
||||
@@ -56,7 +56,7 @@ class DiscoverCardUserCell: UICollectionViewCell {
|
||||
|
||||
let avatarURLString = discoveredUser.avatarURLString
|
||||
|
||||
AvatarCache.sharedInstance.avatarFromURL(NSURL(string: avatarURLString)!) {[weak self] (isFinish, image) -> () in
|
||||
AvatarCache.sharedInstance.avatarFromURL(NSURL(string: avatarURLString)!, size: 170) {[weak self] (isFinish, image) -> () in
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
if let _ = collectionView.cellForItemAtIndexPath(indexPath) {
|
||||
self?.avatarImageView.image = image
|
||||
@@ -81,13 +81,16 @@ class DiscoverCardUserCell: UICollectionViewCell {
|
||||
usernameLabel.text = discoveredUser.nickname
|
||||
|
||||
userSkillsCollectionView.reloadData()
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension DiscoverCardUserCell: UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {
|
||||
|
||||
func numberOfSectionsInCollectionView(collectionView: UICollectionView) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
|
||||
if let discoveredUser = discoveredUser {
|
||||
if discoveredUser.masterSkills.count > 4 {
|
||||
@@ -106,7 +109,19 @@ extension DiscoverCardUserCell: UICollectionViewDelegate, UICollectionViewDataS
|
||||
|
||||
let skillLocalName = discoveredUser.masterSkills[indexPath.row].localName ?? ""
|
||||
|
||||
let rect = skillLocalName.boundingRectWithSize(CGSize(width: CGFloat(FLT_MAX), height: SkillCell.height), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: skillTextAttributes, context: nil)
|
||||
let skillID = discoveredUser.masterSkills[indexPath.row].id
|
||||
|
||||
// print(skillID)
|
||||
|
||||
var rect = CGRectZero
|
||||
|
||||
if let cacheRect = skillSizeCache[skillID] {
|
||||
rect = cacheRect
|
||||
} else {
|
||||
rect = skillLocalName.boundingRectWithSize(CGSize(width: CGFloat(FLT_MAX), height: SkillCell.height), options: [.UsesLineFragmentOrigin, .UsesFontLeading], attributes: skillTextAttributes, context: nil)
|
||||
|
||||
skillSizeCache[skillID] = rect
|
||||
}
|
||||
|
||||
return CGSize(width: rect.width + 12, height: discoverCellHeight)
|
||||
} else {
|
||||
|
||||
@@ -16,6 +16,8 @@ class ProfileHeaderCell: UICollectionViewCell {
|
||||
@IBOutlet weak var avatarImageView: UIImageView!
|
||||
@IBOutlet weak var avatarBlurImageView: UIImageView!
|
||||
@IBOutlet weak var locationLabel: UILabel!
|
||||
|
||||
var askedForPermission = false
|
||||
|
||||
struct Listener {
|
||||
static let Avatar = "ProfileHeaderCell.Avatar"
|
||||
@@ -89,9 +91,14 @@ class ProfileHeaderCell: UICollectionViewCell {
|
||||
}
|
||||
}
|
||||
|
||||
proposeToAccess(.Location(.WhenInUse), agreed: {
|
||||
|
||||
YepLocationService.turnOn()
|
||||
proposeToAccess(.Location(.WhenInUse), agreed: { [weak self] in
|
||||
|
||||
if let askedForPermission = self?.askedForPermission {
|
||||
if !askedForPermission {
|
||||
self?.askedForPermission = true
|
||||
YepLocationService.turnOn()
|
||||
}
|
||||
}
|
||||
|
||||
}, rejected: {
|
||||
println("Yep can NOT get Location. :[\n")
|
||||
@@ -124,7 +131,7 @@ class ProfileHeaderCell: UICollectionViewCell {
|
||||
avatarBlurImageView.alpha = 0
|
||||
}
|
||||
|
||||
AvatarCache.sharedInstance.avatarFromURL(NSURL(string: avatarURLString)!) { [weak self] isFinish, image in
|
||||
AvatarCache.sharedInstance.avatarFromURL(NSURL(string: avatarURLString)!, size: 375) {[weak self] (isFinish, image) -> () in
|
||||
|
||||
if isFinish {
|
||||
self?.blurImage(image) { blurredImage in
|
||||
|
||||
@@ -23,32 +23,44 @@ class ProfileSocialAccountImagesCell: UICollectionViewCell {
|
||||
|
||||
let shots = dribbbleWork.shots
|
||||
|
||||
if let shot = shots[safe: 0] {
|
||||
if let shot = shots[safe: 2] {
|
||||
imageView1.kf_setImageWithURL(NSURL(string: shot.images.teaser)!, placeholderImage: nil)
|
||||
} else {
|
||||
imageView1.image = nil
|
||||
}
|
||||
|
||||
if let shot = shots[safe: 1] {
|
||||
imageView2.kf_setImageWithURL(NSURL(string: shot.images.teaser)!, placeholderImage: nil)
|
||||
} else {
|
||||
imageView2.image = nil
|
||||
}
|
||||
|
||||
if let shot = shots[safe: 2] {
|
||||
if let shot = shots[safe: 0] {
|
||||
imageView3.kf_setImageWithURL(NSURL(string: shot.images.teaser)!, placeholderImage: nil)
|
||||
} else {
|
||||
imageView3.image = nil
|
||||
}
|
||||
|
||||
case .Instagram(let instagramWork):
|
||||
|
||||
let medias = instagramWork.medias
|
||||
|
||||
if let media = medias[safe: 0] {
|
||||
if let media = medias[safe: 2] {
|
||||
imageView1.kf_setImageWithURL(NSURL(string: media.images.thumbnail)!, placeholderImage: nil)
|
||||
} else {
|
||||
imageView1.image = nil
|
||||
}
|
||||
|
||||
if let media = medias[safe: 1] {
|
||||
imageView2.kf_setImageWithURL(NSURL(string: media.images.thumbnail)!, placeholderImage: nil)
|
||||
} else {
|
||||
imageView2.image = nil
|
||||
}
|
||||
|
||||
if let media = medias[safe: 2] {
|
||||
if let media = medias[safe: 0] {
|
||||
imageView3.kf_setImageWithURL(NSURL(string: media.images.thumbnail)!, placeholderImage: nil)
|
||||
} else {
|
||||
imageView3.image = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import UIKit
|
||||
class ChatTextContainerView: UIView {
|
||||
|
||||
override func canBecomeFirstResponder() -> Bool {
|
||||
return true
|
||||
return false
|
||||
}
|
||||
|
||||
override func canPerformAction(action: Selector, withSender sender: AnyObject?) -> Bool {
|
||||
|
||||
Reference in New Issue
Block a user