Browse Source

Merge pull request #592 from deltachat/system-message-layout

relayout message cells on screen orientation change
nayooti 5 years ago
parent
commit
3a700b47d3

+ 4 - 4
deltachat-ios.xcodeproj/project.pbxproj

@@ -105,7 +105,7 @@
 		78E45E3A21D3CFBC00D4B15E /* SettingsController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3921D3CFBC00D4B15E /* SettingsController.swift */; };
 		78E45E3C21D3D03700D4B15E /* TextFieldTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.swift */; };
 		78E45E4421D3F14A00D4B15E /* UIImage+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */; };
-		78E45E4C21D404AE00D4B15E /* CustomMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4B21D404AE00D4B15E /* CustomMessageCell.swift */; };
+		78E45E4C21D404AE00D4B15E /* InfoMessageCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78E45E4B21D404AE00D4B15E /* InfoMessageCell.swift */; };
 		78ED838321D5379000243125 /* TextFieldCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED838221D5379000243125 /* TextFieldCell.swift */; };
 		78ED838D21D577D000243125 /* events.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED838C21D577D000243125 /* events.swift */; };
 		78ED839421D5AF8A00243125 /* QrCodeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 78ED839321D5AF8A00243125 /* QrCodeView.swift */; };
@@ -332,7 +332,7 @@
 		78E45E3921D3CFBC00D4B15E /* SettingsController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsController.swift; sourceTree = "<group>"; };
 		78E45E3B21D3D03700D4B15E /* TextFieldTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldTableViewCell.swift; sourceTree = "<group>"; };
 		78E45E4321D3F14A00D4B15E /* UIImage+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Extension.swift"; sourceTree = "<group>"; };
-		78E45E4B21D404AE00D4B15E /* CustomMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CustomMessageCell.swift; sourceTree = "<group>"; };
+		78E45E4B21D404AE00D4B15E /* InfoMessageCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InfoMessageCell.swift; sourceTree = "<group>"; };
 		78ED838221D5379000243125 /* TextFieldCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextFieldCell.swift; sourceTree = "<group>"; };
 		78ED838C21D577D000243125 /* events.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = events.swift; sourceTree = "<group>"; };
 		78ED839321D5AF8A00243125 /* QrCodeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QrCodeView.swift; sourceTree = "<group>"; };
@@ -564,6 +564,7 @@
 			children = (
 				300C509C234B551900F8AE22 /* TextMediaMessageCell.swift */,
 				305961AE2346125100C80F33 /* ContactMessageCell.swift */,
+				78E45E4B21D404AE00D4B15E /* InfoMessageCell.swift */,
 				305961AF2346125100C80F33 /* LocationMessageCell.swift */,
 				305961B02346125100C80F33 /* MediaMessageCell.swift */,
 				305961B12346125100C80F33 /* TextMessageCell.swift */,
@@ -799,7 +800,6 @@
 			children = (
 				AE406EEE240FA454005F7022 /* Cell */,
 				B26B3BC6236DC3DC008ED35A /* SwitchCell.swift */,
-				78E45E4B21D404AE00D4B15E /* CustomMessageCell.swift */,
 				70B8882D2091B8550074812E /* ContactCell.swift */,
 				78ED839321D5AF8A00243125 /* QrCodeView.swift */,
 				78ED838221D5379000243125 /* TextFieldCell.swift */,
@@ -1225,7 +1225,7 @@
 				789E879D21D6DF86003ED1C5 /* ProgressHud.swift in Sources */,
 				305961F32346125100C80F33 /* MediaMessageCell.swift in Sources */,
 				305962102346154D00C80F33 /* String+Extension.swift in Sources */,
-				78E45E4C21D404AE00D4B15E /* CustomMessageCell.swift in Sources */,
+				78E45E4C21D404AE00D4B15E /* InfoMessageCell.swift in Sources */,
 				AE38B31A2267328200EC37A1 /* Colors.swift in Sources */,
 				789E879621D6CB58003ED1C5 /* QrCodeReaderController.swift in Sources */,
 				305961D22346125100C80F33 /* CGRect+Extensions.swift in Sources */,

+ 23 - 19
deltachat-ios/Controller/ChatViewController.swift

@@ -95,7 +95,7 @@ class ChatViewController: MessagesViewController {
     }
 
     override func viewDidLoad() {
-        messagesCollectionView.register(CustomMessageCell.self)
+        messagesCollectionView.register(InfoMessageCell.self)
         super.viewDidLoad()
         if !DcConfig.configured {
             // TODO: display message about nothing being configured
@@ -233,11 +233,21 @@ class ChatViewController: MessagesViewController {
     }
 
     override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
-        coordinator.animate(alongsideTransition: { (_) -> Void in
-            if self.showCustomNavBar, let titleView = self.navigationItem.titleView as? ChatTitleView {
-                titleView.hideLocationStreamingIndicator() }},
-                            completion: { (_) -> Void in
-                                self.updateTitle(chat: DcChat(id: self.chatId)) })
+        let lastSectionVisibleBeforeTransition = self.isLastSectionVisible()
+        coordinator.animate(
+            alongsideTransition: { _ in
+                if self.showCustomNavBar, let titleView = self.navigationItem.titleView as? ChatTitleView {
+                    titleView.hideLocationStreamingIndicator()
+                }
+            },
+            completion: { _ in
+                self.updateTitle(chat: DcChat(id: self.chatId))
+                self.messagesCollectionView.reloadDataAndKeepOffset()
+                if lastSectionVisibleBeforeTransition {
+                    self.messagesCollectionView.scrollToBottom(animated: false)
+                }
+            }
+        )
         super.viewWillTransition(to: size, with: coordinator)
     }
 
@@ -529,6 +539,10 @@ class ChatViewController: MessagesViewController {
             let cell = messagesCollectionView.dequeueReusableCell(TextMessageCell.self, for: indexPath)
             cell.configure(with: message, at: indexPath, and: messagesCollectionView)
             return cell
+        case .info:
+            let cell = messagesCollectionView.dequeueReusableCell(InfoMessageCell.self, for: indexPath)
+            cell.configure(with: message, at: indexPath, and: messagesCollectionView)
+            return cell
         case .photo, .video:
             let cell = messagesCollectionView.dequeueReusableCell(MediaMessageCell.self, for: indexPath)
             cell.configure(with: message, at: indexPath, and: messagesCollectionView)
@@ -546,7 +560,7 @@ class ChatViewController: MessagesViewController {
             cell.configure(with: message, at: indexPath, and: messagesCollectionView)
             return cell
         case .custom:
-            let cell = messagesCollectionView.dequeueReusableCell(CustomMessageCell.self, for: indexPath)
+            let cell = messagesCollectionView.dequeueReusableCell(InfoMessageCell.self, for: indexPath)
             cell.configure(with: message, at: indexPath, and: messagesCollectionView)
             return cell
         case .audio:
@@ -992,18 +1006,8 @@ extension ChatViewController: MessagesDisplayDelegate {
 
     func messageStyle(for message: MessageType, at indexPath: IndexPath, in _: MessagesCollectionView) -> MessageStyle {
         if isInfoMessage(at: indexPath) {
-            return .custom { view in
-                view.style = .none
-                view.backgroundColor = DcColors.systemMessageBackgroundColor
-                let radius: CGFloat = 16
-                let path = UIBezierPath(roundedRect: view.bounds,
-                                        byRoundingCorners: UIRectCorner.allCorners,
-                                        cornerRadii: CGSize(width: radius, height: radius))
-                let mask = CAShapeLayer()
-                mask.path = path.cgPath
-                view.layer.mask = mask
-                view.center.x = self.view.center.x
-            }
+            //styling is hard-coded in info cell
+            return .none
         }
 
         var corners: UIRectCorner = []

+ 1 - 1
deltachat-ios/DC/Wrapper.swift

@@ -661,7 +661,7 @@ class DcMsg: MessageType {
                 NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 12),
                 NSAttributedString.Key.foregroundColor: DcColors.grayTextColor,
                 ])
-            return MessageKind.attributedText(text)
+            return MessageKind.info(text)
         } else if isSetupMessage {
             return MessageKind.text(String.localized("autocrypt_asm_click_body"))
         }

+ 4 - 0
deltachat-ios/MessageKit/Controllers/MessagesViewController.swift

@@ -280,6 +280,10 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
             let cell = messagesCollectionView.dequeueReusableCell(TextMessageCell.self, for: indexPath)
             cell.configure(with: message, at: indexPath, and: messagesCollectionView)
             return cell
+        case .info:
+            let cell = messagesCollectionView.dequeueReusableCell(InfoMessageCell.self, for: indexPath)
+            cell.configure(with: message, at: indexPath, and: messagesCollectionView)
+            return cell
         case .photo, .video:
             let cell = messagesCollectionView.dequeueReusableCell(MediaMessageCell.self, for: indexPath)
             cell.configure(with: message, at: indexPath, and: messagesCollectionView)

+ 3 - 0
deltachat-ios/MessageKit/Layout/MessagesCollectionViewFlowLayout.swift

@@ -173,6 +173,7 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout {
     lazy open var audioMessageSizeCalculator = AudioMessageSizeCalculator(layout: self)
     lazy open var contactMessageSizeCalculator = ContactMessageSizeCalculator(layout: self)
     lazy open var typingIndicatorSizeCalculator = TypingCellSizeCalculator(layout: self)
+    lazy open var customMessageSizeCalculator = TextMessageSizeCalculator(layout: self)
 
     /// Note:
     /// - If you override this method, remember to call MessageLayoutDelegate's
@@ -203,6 +204,8 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout {
             return audioMessageSizeCalculator
         case .contact:
             return contactMessageSizeCalculator
+        case .info:
+            return customMessageSizeCalculator
         case .custom:
             return messagesLayoutDelegate.customCellSizeCalculator(for: message, at: indexPath, in: messagesCollectionView)
         }

+ 10 - 4
deltachat-ios/MessageKit/Layout/TextMessageSizeCalculator.swift

@@ -29,13 +29,19 @@ open class TextMessageSizeCalculator: MessageSizeCalculator {
 
     public var incomingMessageLabelInsets = UIEdgeInsets(top: 7, left: 18, bottom: 7, right: 14)
     public var outgoingMessageLabelInsets = UIEdgeInsets(top: 7, left: 14, bottom: 7, right: 18)
+    public var centeredMessageLabelInsets = UIEdgeInsets(top: 7, left: 16, bottom: 7, right: 16)
 
     public var messageLabelFont = UIFont.preferredFont(forTextStyle: .body)
 
     internal func messageLabelInsets(for message: MessageType) -> UIEdgeInsets {
-        let dataSource = messagesLayout.messagesDataSource
-        let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
-        return isFromCurrentSender ? outgoingMessageLabelInsets : incomingMessageLabelInsets
+        switch message.kind {
+        case .info:
+            return centeredMessageLabelInsets
+        default:
+            let dataSource = messagesLayout.messagesDataSource
+            let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
+            return isFromCurrentSender ? outgoingMessageLabelInsets : incomingMessageLabelInsets
+        }
     }
 
     open override func messageContainerMaxWidth(for message: MessageType) -> CGFloat {
@@ -51,7 +57,7 @@ open class TextMessageSizeCalculator: MessageSizeCalculator {
         let attributedText: NSAttributedString
 
         switch message.kind {
-        case .attributedText(let text):
+        case .attributedText(let text), .info(let text):
             attributedText = text
         case .text(let text), .emoji(let text):
             attributedText = NSAttributedString(string: text, attributes: [.font: messageLabelFont])

+ 2 - 0
deltachat-ios/MessageKit/Models/MessageKind.swift

@@ -39,6 +39,8 @@ public enum MessageKind {
     /// A message with attributed text.
     case attributedText(NSAttributedString)
 
+    case info(NSAttributedString)
+
     /// A photo message.
     case photo(MediaItem)
 

+ 52 - 0
deltachat-ios/MessageKit/Views/Cells/InfoMessageCell.swift

@@ -0,0 +1,52 @@
+import UIKit
+
+open class InfoMessageCell: UICollectionViewCell {
+    let label = MessageLabel()
+
+    public override init(frame: CGRect) {
+        super.init(frame: frame)
+        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        setupSubviews()
+    }
+
+    public required init?(coder aDecoder: NSCoder) {
+        super.init(coder: aDecoder)
+        contentView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+        setupSubviews()
+    }
+
+    open override func apply(_ layoutAttributes: UICollectionViewLayoutAttributes) {
+        super.apply(layoutAttributes)
+        if let attributes = layoutAttributes as? MessagesCollectionViewLayoutAttributes {
+            label.textInsets = attributes.messageLabelInsets
+            label.messageLabelFont = attributes.messageLabelFont
+            label.backgroundColor = DcColors.systemMessageBackgroundColor
+            let padding = (contentView.frame.width - attributes.messageContainerSize.width) / 2
+            label.frame = CGRect(origin: CGPoint(x: padding, y: .zero), size: attributes.messageContainerSize)
+        }
+    }
+
+    open override func prepareForReuse() {
+        super.prepareForReuse()
+        label.attributedText = nil
+        label.text = nil
+    }
+
+    open func setupSubviews() {
+        contentView.addSubview(label)
+        label.layer.cornerRadius = 16
+        label.layer.masksToBounds = true
+        label.textAlignment = .center
+    }
+
+    open func configure(with message: MessageType, at indexPath: IndexPath, and collectionView: MessagesCollectionView) {
+       label.configure {
+            switch message.kind {
+            case let .info(data):
+                label.attributedText = data
+            default:
+                break
+            }
+        }
+    }
+}

+ 0 - 37
deltachat-ios/View/CustomMessageCell.swift

@@ -1,37 +0,0 @@
-import UIKit
-
-open class CustomMessageCell: UICollectionViewCell {
-    let label = UILabel()
-
-    public override init(frame: CGRect) {
-        super.init(frame: frame)
-        setupSubviews()
-    }
-
-    public required init?(coder aDecoder: NSCoder) {
-        super.init(coder: aDecoder)
-        setupSubviews()
-    }
-
-    open func setupSubviews() {
-        contentView.addSubview(label)
-        label.textAlignment = .center
-        label.font = UIFont.italicSystemFont(ofSize: 13)
-    }
-
-    open override func layoutSubviews() {
-        super.layoutSubviews()
-        label.frame = contentView.bounds
-    }
-
-    open func configure(with message: MessageType, at _: IndexPath, and _: MessagesCollectionView) {
-        // Do stuff
-        switch message.kind {
-        case let .custom(data):
-            guard let systemMessage = data as? String else { return }
-            label.text = systemMessage
-        default:
-            break
-        }
-    }
-}