mirror of
https://github.com/MessageKit/MessageKit.git
synced 2026-02-06 19:03:19 +00:00
Merge branch 'v0.9.0' into v0.9.0
This commit is contained in:
@@ -0,0 +1,14 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
end_of_line = lf
|
||||
insert_final_newline = true
|
||||
|
||||
# Set default charset
|
||||
[*.{js,py,swift,m,json}]
|
||||
charset = utf-8
|
||||
|
||||
# 4 space indentation
|
||||
[*.swift]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
+2
-2
@@ -46,9 +46,9 @@ The more information you can provide, the easier it will be for us to resolve yo
|
||||
- This ensures the feature is in scope and no ones time is wasted.
|
||||
|
||||
- **Please DO NOT submit pull requests to the `master` branch**
|
||||
- This branch is always stable and represents a relase.
|
||||
- This branch is always stable and represents a release.
|
||||
|
||||
- **Please DO submit your pull request to the branch repersenting the next release version**
|
||||
- **Please DO submit your pull request to the branch representing the next release version**
|
||||
|
||||
1. Link to any issues the pull request resolves. If none exist, create one.
|
||||
2. Write unit tests for new functionality or fix any broken by your changes.
|
||||
|
||||
@@ -198,6 +198,3 @@ final class SampleData {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
171D5AB91F36712B0053DF69 /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171D5AB81F36712B0053DF69 /* InputTextView.swift */; };
|
||||
2EB618EF1F8462CA007FBA0E /* UICollectionView+Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EB618EE1F8462CA007FBA0E /* UICollectionView+Extensions.swift */; };
|
||||
372F6AEB1F36C15600B57FBD /* AvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372F6AEA1F36C15600B57FBD /* AvatarView.swift */; };
|
||||
372F6AEF1F36C61000B57FBD /* AvatarViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372F6AEE1F36C61000B57FBD /* AvatarViewTests.swift */; };
|
||||
376AD1821F4258D80083072A /* TestMessageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 376AD1811F4258D80083072A /* TestMessageModel.swift */; };
|
||||
@@ -74,6 +75,7 @@
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
171D5AB81F36712B0053DF69 /* InputTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = "<group>"; };
|
||||
2EB618EE1F8462CA007FBA0E /* UICollectionView+Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UICollectionView+Extensions.swift"; sourceTree = "<group>"; };
|
||||
372F6AEA1F36C15600B57FBD /* AvatarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarView.swift; sourceTree = "<group>"; };
|
||||
372F6AEE1F36C61000B57FBD /* AvatarViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarViewTests.swift; sourceTree = "<group>"; };
|
||||
376AD1811F4258D80083072A /* TestMessageModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TestMessageModel.swift; sourceTree = "<group>"; };
|
||||
@@ -150,6 +152,27 @@
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
2EB618F01F84676A007FBA0E /* Cells */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B01049111F6F86E8008DBA58 /* LocationMessageCell.swift */,
|
||||
B0D943BD1F6DC9AB008B7BFD /* MediaMessageCell.swift */,
|
||||
B0655A4C1F244C0600542A83 /* MessageCollectionViewCell.swift */,
|
||||
B0291DA81F6DBB9F00BEDF03 /* TextMessageCell.swift */,
|
||||
);
|
||||
name = Cells;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
2EB618F11F846899007FBA0E /* Headers & Footers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B074EE921F35587100ABB8C8 /* MessageHeaderView.swift */,
|
||||
B0147C8F1F5ED0810035B36E /* MessageDateHeaderView.swift */,
|
||||
B074EE941F35588A00ABB8C8 /* MessageFooterView.swift */,
|
||||
);
|
||||
name = "Headers & Footers";
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
376AD1801F4258C50083072A /* Support Files */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -167,6 +190,7 @@
|
||||
88916B231CF0DF2F00469F91 /* Products */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
usesTabs = 0;
|
||||
};
|
||||
88916B231CF0DF2F00469F91 /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
@@ -216,11 +240,12 @@
|
||||
B09643981F295D43004D0129 /* Extensions */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
38C867991F50EA1000811974 /* UIView+Extensions.swift */,
|
||||
B09643851F286C9E004D0129 /* String+Extensions.swift */,
|
||||
B096438F1F289142004D0129 /* UIColor+Extensions.swift */,
|
||||
B0AA1F521F44388900BAE583 /* NSAttributedString+Extensions.swift */,
|
||||
B0147C821F5BE9220035B36E /* Bundle+Extensions.swift */,
|
||||
B0AA1F521F44388900BAE583 /* NSAttributedString+Extensions.swift */,
|
||||
B09643851F286C9E004D0129 /* String+Extensions.swift */,
|
||||
2EB618EE1F8462CA007FBA0E /* UICollectionView+Extensions.swift */,
|
||||
B096438F1F289142004D0129 /* UIColor+Extensions.swift */,
|
||||
38C867991F50EA1000811974 /* UIView+Extensions.swift */,
|
||||
);
|
||||
name = Extensions;
|
||||
sourceTree = "<group>";
|
||||
@@ -246,21 +271,16 @@
|
||||
B096439A1F295D68004D0129 /* Views */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
B0655A2D1F23D8BC00542A83 /* MessagesCollectionView.swift */,
|
||||
B0655A4C1F244C0600542A83 /* MessageCollectionViewCell.swift */,
|
||||
2EB618F11F846899007FBA0E /* Headers & Footers */,
|
||||
2EB618F01F84676A007FBA0E /* Cells */,
|
||||
372F6AEA1F36C15600B57FBD /* AvatarView.swift */,
|
||||
B0655A371F23EE8B00542A83 /* MessageInputBar.swift */,
|
||||
38C8679D1F50EA4A00811974 /* InputBarItem.swift */,
|
||||
171D5AB81F36712B0053DF69 /* InputTextView.swift */,
|
||||
B074EE921F35587100ABB8C8 /* MessageHeaderView.swift */,
|
||||
B074EE941F35588A00ABB8C8 /* MessageFooterView.swift */,
|
||||
B074EEA71F3971A600ABB8C8 /* MessageLabel.swift */,
|
||||
E8586DB41F59A1C300C9BE9D /* MessageContainerView.swift */,
|
||||
B0147C8F1F5ED0810035B36E /* MessageDateHeaderView.swift */,
|
||||
B0291DA81F6DBB9F00BEDF03 /* TextMessageCell.swift */,
|
||||
B0D943BD1F6DC9AB008B7BFD /* MediaMessageCell.swift */,
|
||||
B0655A371F23EE8B00542A83 /* MessageInputBar.swift */,
|
||||
B074EEA71F3971A600ABB8C8 /* MessageLabel.swift */,
|
||||
B0655A2D1F23D8BC00542A83 /* MessagesCollectionView.swift */,
|
||||
B010490F1F6F8684008DBA58 /* PlayButtonView.swift */,
|
||||
B01049111F6F86E8008DBA58 /* LocationMessageCell.swift */,
|
||||
);
|
||||
name = Views;
|
||||
sourceTree = "<group>";
|
||||
@@ -456,6 +476,7 @@
|
||||
B09643861F286C9E004D0129 /* String+Extensions.swift in Sources */,
|
||||
B015E81F1F259D8E007EDFB6 /* MessageInputBarDelegate.swift in Sources */,
|
||||
B01280F31F4E8798004BCD3E /* MessageLabelDelegate.swift in Sources */,
|
||||
2EB618EF1F8462CA007FBA0E /* UICollectionView+Extensions.swift in Sources */,
|
||||
B0147C981F61AF930035B36E /* LabelAlignment.swift in Sources */,
|
||||
376AD1881F4259D20083072A /* TestMessagesViewControllerModel.swift in Sources */,
|
||||
B0655A2A1F23D77200542A83 /* Sender.swift in Sources */,
|
||||
|
||||
@@ -26,6 +26,7 @@ import UIKit
|
||||
import MapKit
|
||||
|
||||
open class LocationMessageCell: MessageCollectionViewCell<UIImageView> {
|
||||
open override class func reuseIdentifier() -> String { return "messagekit.cell.location" }
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
import Foundation
|
||||
import MapKit
|
||||
|
||||
|
||||
/// Conform to this protocol to customize location messages's style
|
||||
public protocol LocationMessageDisplayDelegate: MessagesDisplayDelegate {
|
||||
|
||||
@@ -50,7 +49,6 @@ public protocol LocationMessageDisplayDelegate: MessagesDisplayDelegate {
|
||||
/// - Returns: Your customized MKAnnotationView or nil to not show any.
|
||||
func annotationViewForLocation(message: MessageType, at indexPath: IndexPath, in messageCollectionView: MessagesCollectionView) -> MKAnnotationView?
|
||||
|
||||
|
||||
/// Ask the delegate for a custom animation block to run when whe map screenshot is ready to be displaied in the given location message
|
||||
/// The animation block is called with the image view to be animated. You can animate it with CoreAnimation, UIView.animate or any library you prefer.
|
||||
///
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
import UIKit
|
||||
|
||||
open class MediaMessageCell: MessageCollectionViewCell<UIImageView> {
|
||||
open override class func reuseIdentifier() -> String { return "messagekit.cell.mediamessage" }
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
open class MessageCollectionViewCell<ContentView: UIView>: UICollectionViewCell {
|
||||
open class MessageCollectionViewCell<ContentView: UIView>: UICollectionViewCell, CollectionViewReusable {
|
||||
open class func reuseIdentifier() -> String { return "messagekit.cell.base-cell" }
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
import UIKit
|
||||
|
||||
open class MessageDateHeaderView: MessageHeaderView {
|
||||
open override class func reuseIdentifier() -> String { return "messagekit.header.date" }
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -24,7 +24,8 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
open class MessageFooterView: UICollectionReusableView {
|
||||
open class MessageFooterView: UICollectionReusableView, CollectionViewReusable {
|
||||
open class func reuseIdentifier() -> String { return "messagekit.footer.base" }
|
||||
|
||||
// MARK: - Initializers
|
||||
|
||||
|
||||
@@ -24,12 +24,11 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
open class MessageHeaderView: UICollectionReusableView {
|
||||
open class MessageHeaderView: UICollectionReusableView, CollectionViewReusable {
|
||||
open class func reuseIdentifier() -> String { return "messagekit.header.base" }
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
static let identifier = "MessageHeaderView"
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
@@ -34,7 +34,6 @@ open class MessagesViewController: UIViewController {
|
||||
|
||||
open var scrollsToBottomOnFirstLayout: Bool = false
|
||||
|
||||
|
||||
open var scrollsToBottomOnKeybordBeginsEditing: Bool = false
|
||||
|
||||
open var additionalTopContentInset: CGFloat = 0 {
|
||||
@@ -107,26 +106,13 @@ open class MessagesViewController: UIViewController {
|
||||
|
||||
private func registerReusableViews() {
|
||||
|
||||
messagesCollectionView.register(TextMessageCell.self,
|
||||
forCellWithReuseIdentifier: "TextMessageCell")
|
||||
messagesCollectionView.register(TextMessageCell.self)
|
||||
messagesCollectionView.register(MediaMessageCell.self)
|
||||
messagesCollectionView.register(LocationMessageCell.self)
|
||||
|
||||
messagesCollectionView.register(MediaMessageCell.self,
|
||||
forCellWithReuseIdentifier: "MediaMessageCell")
|
||||
|
||||
messagesCollectionView.register(LocationMessageCell.self,
|
||||
forCellWithReuseIdentifier: "LocationMessageCell")
|
||||
|
||||
messagesCollectionView.register(MessageFooterView.self,
|
||||
forSupplementaryViewOfKind: UICollectionElementKindSectionFooter,
|
||||
withReuseIdentifier: "MessageFooterView")
|
||||
|
||||
messagesCollectionView.register(MessageHeaderView.self,
|
||||
forSupplementaryViewOfKind: UICollectionElementKindSectionHeader,
|
||||
withReuseIdentifier: "MessageHeaderView")
|
||||
|
||||
messagesCollectionView.register(MessageDateHeaderView.self,
|
||||
forSupplementaryViewOfKind: UICollectionElementKindSectionHeader,
|
||||
withReuseIdentifier: "MessageDateHeaderView")
|
||||
messagesCollectionView.register(MessageFooterView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionFooter)
|
||||
messagesCollectionView.register(MessageHeaderView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader)
|
||||
messagesCollectionView.register(MessageDateHeaderView.self, forSupplementaryViewOfKind: UICollectionElementKindSectionHeader)
|
||||
|
||||
}
|
||||
|
||||
@@ -186,21 +172,15 @@ extension MessagesViewController: UICollectionViewDataSource {
|
||||
|
||||
switch message.data {
|
||||
case .text, .attributedText, .emoji:
|
||||
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "TextMessageCell", for: indexPath) as? TextMessageCell else {
|
||||
fatalError("Unable to dequeue TextMessageCell")
|
||||
}
|
||||
let cell = collectionView.dequeueReusableCell(TextMessageCell.self, for: indexPath)
|
||||
cell.configure(with: message, at: indexPath, and: messagesCollectionView)
|
||||
return cell
|
||||
case .photo, .video:
|
||||
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "MediaMessageCell", for: indexPath) as? MediaMessageCell else {
|
||||
fatalError("Unable to dequeue MediaMessageCell")
|
||||
}
|
||||
let cell = collectionView.dequeueReusableCell(MediaMessageCell.self, for: indexPath)
|
||||
cell.configure(with: message, at: indexPath, and: messagesCollectionView)
|
||||
return cell
|
||||
case .location:
|
||||
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "LocationMessageCell", for: indexPath) as? LocationMessageCell else {
|
||||
fatalError("Unable to dequeue LocationMessageCell")
|
||||
}
|
||||
let cell = collectionView.dequeueReusableCell(LocationMessageCell.self, for: indexPath)
|
||||
cell.configure(with: message, at: indexPath, and: messagesCollectionView)
|
||||
return cell
|
||||
}
|
||||
@@ -252,7 +232,6 @@ extension MessagesViewController: UICollectionViewDataSource {
|
||||
|
||||
extension MessagesViewController {
|
||||
|
||||
|
||||
fileprivate func addKeyboardObservers() {
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleKeyboardDidChangeState), name: .UIKeyboardWillChangeFrame, object: nil)
|
||||
NotificationCenter.default.addObserver(self, selector: #selector(handleTextViewDidBeginEditing), name: .UITextViewTextDidBeginEditing, object: messageInputBar.inputTextView)
|
||||
|
||||
@@ -49,11 +49,11 @@ public class NSLayoutConstraintSet {
|
||||
self.height = height
|
||||
}
|
||||
|
||||
/// All of the currently configured constraints
|
||||
private var availableConstraints: [NSLayoutConstraint] {
|
||||
return [top, bottom, left, right, centerX, centerY, width, height]
|
||||
.flatMap {$0}
|
||||
}
|
||||
/// All of the currently configured constraints
|
||||
private var availableConstraints: [NSLayoutConstraint] {
|
||||
return [top, bottom, left, right, centerX, centerY, width, height]
|
||||
.flatMap {$0}
|
||||
}
|
||||
|
||||
/// Activates all of the non-nil constraints
|
||||
///
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
import UIKit
|
||||
|
||||
open class TextMessageCell: MessageCollectionViewCell<MessageLabel> {
|
||||
open override class func reuseIdentifier() -> String { return "messagekit.cell.text" }
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
//
|
||||
// UICollectionView+Extensions.swift
|
||||
// MessageKit
|
||||
//
|
||||
// Created by Frederic Barthelemy on 10/3/17.
|
||||
// Copyright © 2017 MessageKit. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
/// Optional Cell Protocol to Simplify registration/cell type loading in a generic way
|
||||
protocol CollectionViewReusable: class {
|
||||
static func reuseIdentifier() -> String
|
||||
}
|
||||
|
||||
extension UICollectionView {
|
||||
/// Registers a particular cell using its reuse-identifier
|
||||
func register<CellType: UICollectionViewCell & CollectionViewReusable>(_ cellClass: CellType.Type) {
|
||||
register(cellClass, forCellWithReuseIdentifier: CellType.reuseIdentifier())
|
||||
}
|
||||
|
||||
/// Registers a reusable view for a specific SectionKind
|
||||
func register<ViewType: UICollectionReusableView & CollectionViewReusable>(_ headerFooterClass: ViewType.Type, forSupplementaryViewOfKind kind: String) {
|
||||
register(headerFooterClass,
|
||||
forSupplementaryViewOfKind: kind,
|
||||
withReuseIdentifier: ViewType.reuseIdentifier())
|
||||
}
|
||||
|
||||
/// Generically dequeues a cell of the correct type allowing you to avoid scattering your code with guard-let-else-fatal
|
||||
func dequeueReusableCell<CellType: UICollectionViewCell & CollectionViewReusable>(_ cellClass: CellType.Type, for indexPath: IndexPath) -> CellType {
|
||||
guard let cell = dequeueReusableCell(withReuseIdentifier: cellClass.reuseIdentifier(), for: indexPath) as? CellType else {
|
||||
fatalError("Unable to dequeue \(String(describing: cellClass)) with reuseId of \(cellClass.reuseIdentifier())")
|
||||
}
|
||||
return cell
|
||||
}
|
||||
}
|
||||
@@ -32,13 +32,13 @@ extension UIView {
|
||||
}
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
let constraints: [NSLayoutConstraint] = [
|
||||
leftAnchor.constraint(equalTo: superview.leftAnchor),
|
||||
rightAnchor.constraint(equalTo: superview.rightAnchor),
|
||||
topAnchor.constraint(equalTo: superview.topAnchor),
|
||||
bottomAnchor.constraint(equalTo: superview.bottomAnchor)
|
||||
]
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
let constraints: [NSLayoutConstraint] = [
|
||||
leftAnchor.constraint(equalTo: superview.leftAnchor),
|
||||
rightAnchor.constraint(equalTo: superview.rightAnchor),
|
||||
topAnchor.constraint(equalTo: superview.topAnchor),
|
||||
bottomAnchor.constraint(equalTo: superview.bottomAnchor)
|
||||
]
|
||||
NSLayoutConstraint.activate(constraints)
|
||||
}
|
||||
|
||||
@discardableResult
|
||||
|
||||
Reference in New Issue
Block a user