mirror of
https://github.com/MessageKit/MessageKit.git
synced 2026-02-06 19:03:19 +00:00
Merge branch 'development' into patch-1
This commit is contained in:
+16
-8
@@ -4,18 +4,22 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa
|
||||
|
||||
--------------------------------------
|
||||
|
||||
## [2.0.0](https://github.com/MessageKit/MessageKit/releases/tag/2.0.0-beta.1)
|
||||
## Upcoming Release
|
||||
|
||||
### Changed
|
||||
|
||||
- Change acl of `handleGesture(touchLocation:)` in `MessageLabel` from internal to open.
|
||||
[#912](https://github.com/MessageKit/MessageKit/pull/912) by [@julienkode](https://github.com/JulienKode)
|
||||
|
||||
- Fixed the way that the Strings and UIImages are parsed in the `InputTextView` to prevent crashes in `parseForComponents()`.
|
||||
[#791](https://github.com/MessageKit/MessageKit/pull/791) by [@nathantannar4](https://github.com/nathantannar4)
|
||||
## [2.0.0-beta.1](https://github.com/MessageKit/MessageKit/releases/tag/2.0.0-beta.1)
|
||||
|
||||
### Changed
|
||||
|
||||
- **Breaking Change** Updated codebase to Swift 4.2 [#883](https://github.com/MessageKit/MessageKit/pull/883) by [@nathantannar4](https://github.com/nathantannar4)
|
||||
|
||||
- Fixed the way that the Strings and UIImages are parsed in the `InputTextView` to prevent crashes in `parseForComponents()`.
|
||||
[#791](https://github.com/MessageKit/MessageKit/pull/791) by [@nathantannar4](https://github.com/nathantannar4)
|
||||
|
||||
### Added
|
||||
|
||||
- Added support for detection and handling of `NSLink`s inside of messages.
|
||||
@@ -30,15 +34,17 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa
|
||||
- Added `additionalBottomInset` property that allows to adjust the bottom content inset automatically set on the messages collection view by the view controller.
|
||||
[#787](https://github.com/MessageKit/MessageKit/pull/787) by [@andreyvit](https://github.com/andreyvit)
|
||||
|
||||
- Added new methods to simplify using of custom messages: `customCellSizeCalculator(for:at:in:)` for `MessagesLayoutDelegate` and `customCell(for:at:in:)` for `MessagesDataSource`.
|
||||
[#879](https://github.com/MessageKit/MessageKit/pull/879) by [@realbonus](https://github.com/RealBonus)
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed a bug that prevented `MessageLabel` from laying out properly when contained by superviews using autolayout.
|
||||
[#889](https://github.com/MessageKit/MessageKit/pull/889) by [@marius-serban](https://github.com/marius-serban).
|
||||
|
||||
|
||||
- **Breaking Change** Fixed typo of `scrollsToBottomOnKeybordBeginsEditing` to `scrollsToBottomOnKeyboardBeginsEditing`.
|
||||
[#856](https://github.com/MessageKit/MessageKit/pull/856) by [@p-petrenko](https://github.com/p-petrenko)
|
||||
|
||||
- Fixed a bug that prevented `MessageLabel` from laying out properly when contained by superviews using autolayout.
|
||||
[#889](https://github.com/MessageKit/MessageKit/pull/889) by [@marius-serban](https://github.com/marius-serban).
|
||||
|
||||
- Fixed bottom content inset adjustment when using an undocked keyboard on iPad, or when `edgesForExtendedLayout` does not include `.top`, or when a parent container view controller adds extra views at the top of the screen.
|
||||
[#787](https://github.com/MessageKit/MessageKit/pull/787) by [@andreyvit](https://github.com/andreyvit)
|
||||
|
||||
@@ -49,7 +55,9 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa
|
||||
|
||||
- Fixed `MessagesCollectionView` to allow to use nibs with `MessageReusableView`.
|
||||
[#832](https://github.com/MessageKit/MessageKit/pull/832) by [@maxxx777](https://github.com/maxxx777).
|
||||
- Fixed multiple crashes at views, when views are being called from another XIB. [#905](https://github.com/MessageKit/MessageKit/pull/905) by [@talanov](https://github.com/talanov).
|
||||
|
||||
- Fixed multiple crashes at views, when views are being called from another XIB.
|
||||
[#905](https://github.com/MessageKit/MessageKit/pull/905) by [@talanov](https://github.com/talanov).
|
||||
|
||||
## [1.0.0](https://github.com/MessageKit/MessageKit/releases/tag/1.0.0)
|
||||
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
|
||||
### Code of Conduct
|
||||
|
||||
Please read our [Code of Conduct](https://github.com/MessageKit/MessageKit/blob/master/Code_of_Conduct.md).
|
||||
Please read our [Code of Conduct](https://github.com/MessageKit/MessageKit/blob/master/CODE_OF_CONDUCT.md).
|
||||
The MessageKit maintainers take this Code of Conduct very seriously. Intolerance, disrespect, harassment, and any form of negativity will not be tolerated.
|
||||
|
||||
### Ways to Contribute
|
||||
|
||||
@@ -35,6 +35,11 @@ final internal class AppDelegate: UIResponder, UIApplicationDelegate {
|
||||
window?.rootViewController = NavigationController(rootViewController: LaunchViewController())
|
||||
window?.makeKeyAndVisible()
|
||||
|
||||
if UserDefaults.isFirstLaunch() {
|
||||
// Enable Text Messages
|
||||
UserDefaults.standard.set(true, forKey: "Text Messages")
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,26 @@ final internal class SampleData {
|
||||
static let shared = SampleData()
|
||||
|
||||
private init() {}
|
||||
|
||||
enum MessageTypes: UInt32, CaseIterable {
|
||||
case Text = 0
|
||||
case AttributedText = 1
|
||||
case Photo = 2
|
||||
case Video = 3
|
||||
case Emoji = 4
|
||||
case Location = 5
|
||||
case Url = 6
|
||||
case Phone = 7
|
||||
case Custom = 8
|
||||
|
||||
static func random() -> MessageTypes {
|
||||
// Update as new enumerations are added
|
||||
let maxValue = Custom.rawValue
|
||||
|
||||
let rand = arc4random_uniform(maxValue+1)
|
||||
return MessageTypes(rawValue: rand)!
|
||||
}
|
||||
}
|
||||
|
||||
let system = Sender(id: "000000", displayName: "System")
|
||||
let nathan = Sender(id: "000001", displayName: "Nathan Tannar")
|
||||
@@ -46,8 +66,6 @@ final internal class SampleData {
|
||||
|
||||
let messageImages: [UIImage] = [#imageLiteral(resourceName: "img1"), #imageLiteral(resourceName: "img2")]
|
||||
|
||||
let messageTypes = ["Text", "Text", "Text", "AttributedText", "Location", "Photo", "Emoji", "Video", "URL", "Phone", "Custom"]
|
||||
|
||||
let emojis = [
|
||||
"👍",
|
||||
"😂😂😂",
|
||||
@@ -116,51 +134,62 @@ final internal class SampleData {
|
||||
return date
|
||||
}
|
||||
}
|
||||
|
||||
func randomMessageType() -> MessageTypes {
|
||||
let messageType = MessageTypes.random()
|
||||
|
||||
func randomMessage(isCustomEnabled: Bool, allowedSenders: [Sender]) -> MockMessage {
|
||||
if !UserDefaults.standard.bool(forKey: "\(messageType)" + " Messages") {
|
||||
return randomMessageType()
|
||||
}
|
||||
|
||||
return messageType
|
||||
}
|
||||
|
||||
func randomMessage(allowedSenders: [Sender]) -> MockMessage {
|
||||
|
||||
let randomNumberSender = Int(arc4random_uniform(UInt32(allowedSenders.count)))
|
||||
let randomNumberImage = Int(arc4random_uniform(UInt32(messageImages.count)))
|
||||
let randomMessageType = Int(arc4random_uniform(UInt32(messageTypes.count - (isCustomEnabled ? 0 : 1))))
|
||||
let randomNumberLocation = Int(arc4random_uniform(UInt32(locations.count)))
|
||||
let randomNumberEmoji = Int(arc4random_uniform(UInt32(emojis.count)))
|
||||
|
||||
let randomSentance = Lorem.sentence()
|
||||
let uniqueID = NSUUID().uuidString
|
||||
let sender = allowedSenders[randomNumberSender]
|
||||
let date = dateAddingRandomTime()
|
||||
|
||||
switch messageTypes[randomMessageType] {
|
||||
case "Text":
|
||||
return MockMessage(text: randomSentance, sender: sender, messageId: uniqueID, date: date)
|
||||
case "AttributedText":
|
||||
let attributedText = attributedString(with: randomSentance)
|
||||
switch randomMessageType() {
|
||||
case .Text:
|
||||
let randomSentence = Lorem.sentence()
|
||||
return MockMessage(text: randomSentence, sender: sender, messageId: uniqueID, date: date)
|
||||
case .AttributedText:
|
||||
let randomSentence = Lorem.sentence()
|
||||
let attributedText = attributedString(with: randomSentence)
|
||||
return MockMessage(attributedText: attributedText, sender: senders[randomNumberSender], messageId: uniqueID, date: date)
|
||||
case "Photo":
|
||||
case .Photo:
|
||||
let randomNumberImage = Int(arc4random_uniform(UInt32(messageImages.count)))
|
||||
let image = messageImages[randomNumberImage]
|
||||
return MockMessage(image: image, sender: sender, messageId: uniqueID, date: date)
|
||||
case "Video":
|
||||
case .Video:
|
||||
let randomNumberImage = Int(arc4random_uniform(UInt32(messageImages.count)))
|
||||
let image = messageImages[randomNumberImage]
|
||||
return MockMessage(thumbnail: image, sender: sender, messageId: uniqueID, date: date)
|
||||
case "Emoji":
|
||||
case .Emoji:
|
||||
let randomNumberEmoji = Int(arc4random_uniform(UInt32(emojis.count)))
|
||||
return MockMessage(emoji: emojis[randomNumberEmoji], sender: sender, messageId: uniqueID, date: date)
|
||||
case "Location":
|
||||
case .Location:
|
||||
let randomNumberLocation = Int(arc4random_uniform(UInt32(locations.count)))
|
||||
return MockMessage(location: locations[randomNumberLocation], sender: sender, messageId: uniqueID, date: date)
|
||||
case "URL":
|
||||
case .Url:
|
||||
return MockMessage(text: "https://github.com/MessageKit", sender: sender, messageId: uniqueID, date: date)
|
||||
case "Phone":
|
||||
case .Phone:
|
||||
return MockMessage(text: "123-456-7890", sender: sender, messageId: uniqueID, date: date)
|
||||
case "Custom":
|
||||
case .Custom:
|
||||
return MockMessage(custom: "Someone left the conversation", sender: system, messageId: uniqueID, date: date)
|
||||
default:
|
||||
fatalError("Unrecognized mock message type")
|
||||
}
|
||||
}
|
||||
|
||||
func getMessages(count: Int, completion: ([MockMessage]) -> Void) {
|
||||
var messages: [MockMessage] = []
|
||||
// Disable Custom Messages
|
||||
UserDefaults.standard.set(false, forKey: "Custom Messages")
|
||||
for _ in 0..<count {
|
||||
let message = randomMessage(isCustomEnabled: false, allowedSenders: senders)
|
||||
let message = randomMessage(allowedSenders: senders)
|
||||
messages.append(message)
|
||||
}
|
||||
completion(messages)
|
||||
@@ -168,8 +197,10 @@ final internal class SampleData {
|
||||
|
||||
func getAdvancedMessages(count: Int, completion: ([MockMessage]) -> Void) {
|
||||
var messages: [MockMessage] = []
|
||||
// Enable Custom Messages
|
||||
UserDefaults.standard.set(true, forKey: "Custom Messages")
|
||||
for _ in 0..<count {
|
||||
let message = randomMessage(isCustomEnabled: true, allowedSenders: senders)
|
||||
let message = randomMessage(allowedSenders: senders)
|
||||
messages.append(message)
|
||||
}
|
||||
completion(messages)
|
||||
@@ -177,8 +208,10 @@ final internal class SampleData {
|
||||
|
||||
func getMessages(count: Int, allowedSenders: [Sender], completion: ([MockMessage]) -> Void) {
|
||||
var messages: [MockMessage] = []
|
||||
// Disable Custom Messages
|
||||
UserDefaults.standard.set(false, forKey: "Custom Messages")
|
||||
for _ in 0..<count {
|
||||
let message = randomMessage(isCustomEnabled: false, allowedSenders: allowedSenders)
|
||||
let message = randomMessage(allowedSenders: allowedSenders)
|
||||
messages.append(message)
|
||||
}
|
||||
completion(messages)
|
||||
|
||||
@@ -77,7 +77,9 @@ final class MockSocket {
|
||||
queuedMessage = nil
|
||||
} else {
|
||||
let sender = arc4random_uniform(1) % 2 == 0 ? connectedUsers.first! : connectedUsers.last!
|
||||
queuedMessage = MockMessage(text: Lorem.sentence(), sender: sender, messageId: UUID().uuidString, date: Date())
|
||||
SampleData.shared.getMessages(count: 1, allowedSenders: [sender]) { (message) in
|
||||
queuedMessage = message.first
|
||||
}
|
||||
onTypingStatusCode?()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,4 +41,14 @@ extension UserDefaults {
|
||||
}
|
||||
return 20
|
||||
}
|
||||
|
||||
static func isFirstLaunch() -> Bool {
|
||||
let hasBeenLaunchedBeforeFlag = "hasBeenLaunchedBeforeFlag"
|
||||
let isFirstLaunch = !UserDefaults.standard.bool(forKey: hasBeenLaunchedBeforeFlag)
|
||||
if isFirstLaunch {
|
||||
UserDefaults.standard.set(true, forKey: hasBeenLaunchedBeforeFlag)
|
||||
UserDefaults.standard.synchronize()
|
||||
}
|
||||
return isFirstLaunch
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,12 +30,12 @@ final internal class SettingsViewController: UITableViewController {
|
||||
|
||||
// MARK: - Properties
|
||||
|
||||
var selectedMockMessagesCount: Int = 20
|
||||
|
||||
override var preferredStatusBarStyle: UIStatusBarStyle {
|
||||
return .lightContent
|
||||
}
|
||||
|
||||
let cells = ["Mock messages count", "Text Messages", "AttributedText Messages", "Photo Messages", "Video Messages", "Emoji Messages", "Location Messages", "Url Messages", "Phone Messages"]
|
||||
|
||||
// MARK: - Picker
|
||||
|
||||
var messagesPicker = UIPickerView()
|
||||
@@ -55,6 +55,8 @@ final internal class SettingsViewController: UITableViewController {
|
||||
messagesPicker.dataSource = self
|
||||
messagesPicker.delegate = self
|
||||
messagesPicker.backgroundColor = .white
|
||||
|
||||
messagesPicker.selectRow(UserDefaults.standard.mockMessagesCount(), inComponent: 0, animated: false)
|
||||
}
|
||||
|
||||
// MARK: - Toolbar
|
||||
@@ -82,12 +84,25 @@ final internal class SettingsViewController: UITableViewController {
|
||||
// MARK: - TableViewDelegate & TableViewDataSource
|
||||
|
||||
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return 1
|
||||
return cells.count
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
let cellValue = cells[indexPath.row]
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") ?? UITableViewCell()
|
||||
cell.textLabel?.text = cells[indexPath.row]
|
||||
|
||||
return indexPath.row == 0 ? configureTextFieldTableViewCell(at: indexPath) : UITableViewCell()
|
||||
switch cellValue {
|
||||
case "Mock messages count":
|
||||
return configureTextFieldTableViewCell(at: indexPath)
|
||||
default:
|
||||
let switchView = UISwitch(frame: .zero)
|
||||
switchView.isOn = UserDefaults.standard.bool(forKey: cellValue)
|
||||
switchView.tag = indexPath.row
|
||||
switchView.addTarget(self, action: #selector(self.switchChanged(_:)), for: .valueChanged)
|
||||
cell.accessoryView = switchView
|
||||
}
|
||||
return cell
|
||||
}
|
||||
|
||||
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
|
||||
@@ -118,6 +133,12 @@ final internal class SettingsViewController: UITableViewController {
|
||||
}
|
||||
return TextFieldTableViewCell()
|
||||
}
|
||||
|
||||
@objc func switchChanged(_ sender: UISwitch!) {
|
||||
let cell = cells[sender.tag]
|
||||
|
||||
UserDefaults.standard.set(sender.isOn, forKey: cell)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - UIPickerViewDelegate, UIPickerViewDataSource
|
||||
@@ -134,8 +155,4 @@ extension SettingsViewController: UIPickerViewDelegate, UIPickerViewDataSource {
|
||||
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
|
||||
return "\(row)"
|
||||
}
|
||||
|
||||
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
|
||||
selectedMockMessagesCount = row
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ github "MessageKit/MessageKit"
|
||||
## Contributing
|
||||
|
||||
Great! Look over these things first.
|
||||
- Please read our [Code of Conduct](https://github.com/MessageKit/MessageKit/blob/master/Code_of_Conduct.md)
|
||||
- Please read our [Code of Conduct](https://github.com/MessageKit/MessageKit/blob/master/CODE_OF_CONDUCT.md)
|
||||
- Check the [Contributing Guide Lines](https://github.com/MessageKit/MessageKit/blob/master/CONTRIBUTING.md).
|
||||
- Come join us on [Slack](https://join.slack.com/t/messagekit/shared_invite/MjI4NzIzNzMyMzU0LTE1MDMwODIzMDUtYzllYzIyNTU4MA) and 🗣 don't be a stranger.
|
||||
- Check out the [current issues](https://github.com/MessageKit/MessageKit/issues) and see if you can tackle any of those.
|
||||
|
||||
@@ -181,6 +181,8 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
|
||||
return collectionView.messagesDataSource?.numberOfItems(inSection: section, in: collectionView) ?? 0
|
||||
}
|
||||
|
||||
/// Note:
|
||||
/// If you override this method, remember to call MessagesDataSource's customCell(for:at:in:) for MessageKind.custom messages, if necessary
|
||||
open func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
|
||||
|
||||
guard let messagesCollectionView = collectionView as? MessagesCollectionView else {
|
||||
@@ -207,7 +209,7 @@ UICollectionViewDelegateFlowLayout, UICollectionViewDataSource {
|
||||
cell.configure(with: message, at: indexPath, and: messagesCollectionView)
|
||||
return cell
|
||||
case .custom:
|
||||
fatalError(MessageKitError.customDataUnresolvedCell)
|
||||
return messagesDataSource.customCell(for: message, at: indexPath, in: messagesCollectionView)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -132,7 +132,7 @@ open class MessageSizeCalculator: CellSizeCalculator {
|
||||
|
||||
// MARK: - Avatar
|
||||
|
||||
public func avatarPosition(for message: MessageType) -> AvatarPosition {
|
||||
open func avatarPosition(for message: MessageType) -> AvatarPosition {
|
||||
let dataSource = messagesLayout.messagesDataSource
|
||||
let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
|
||||
var position = isFromCurrentSender ? outgoingAvatarPosition : incomingAvatarPosition
|
||||
@@ -146,7 +146,7 @@ open class MessageSizeCalculator: CellSizeCalculator {
|
||||
return position
|
||||
}
|
||||
|
||||
public func avatarSize(for message: MessageType) -> CGSize {
|
||||
open func avatarSize(for message: MessageType) -> CGSize {
|
||||
let dataSource = messagesLayout.messagesDataSource
|
||||
let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
|
||||
return isFromCurrentSender ? outgoingAvatarSize : incomingAvatarSize
|
||||
@@ -154,14 +154,14 @@ open class MessageSizeCalculator: CellSizeCalculator {
|
||||
|
||||
// MARK: - Top cell Label
|
||||
|
||||
public func cellTopLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
|
||||
open func cellTopLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
|
||||
let layoutDelegate = messagesLayout.messagesLayoutDelegate
|
||||
let collectionView = messagesLayout.messagesCollectionView
|
||||
let height = layoutDelegate.cellTopLabelHeight(for: message, at: indexPath, in: collectionView)
|
||||
return CGSize(width: messagesLayout.itemWidth, height: height)
|
||||
}
|
||||
|
||||
public func cellTopLabelAlignment(for message: MessageType) -> LabelAlignment {
|
||||
open func cellTopLabelAlignment(for message: MessageType) -> LabelAlignment {
|
||||
let dataSource = messagesLayout.messagesDataSource
|
||||
let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
|
||||
return isFromCurrentSender ? outgoingCellTopLabelAlignment : incomingCellTopLabelAlignment
|
||||
@@ -169,14 +169,14 @@ open class MessageSizeCalculator: CellSizeCalculator {
|
||||
|
||||
// MARK: - Top message Label
|
||||
|
||||
public func messageTopLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
|
||||
open func messageTopLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
|
||||
let layoutDelegate = messagesLayout.messagesLayoutDelegate
|
||||
let collectionView = messagesLayout.messagesCollectionView
|
||||
let height = layoutDelegate.messageTopLabelHeight(for: message, at: indexPath, in: collectionView)
|
||||
return CGSize(width: messagesLayout.itemWidth, height: height)
|
||||
}
|
||||
|
||||
public func messageTopLabelAlignment(for message: MessageType) -> LabelAlignment {
|
||||
open func messageTopLabelAlignment(for message: MessageType) -> LabelAlignment {
|
||||
let dataSource = messagesLayout.messagesDataSource
|
||||
let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
|
||||
return isFromCurrentSender ? outgoingMessageTopLabelAlignment : incomingMessageTopLabelAlignment
|
||||
@@ -184,14 +184,14 @@ open class MessageSizeCalculator: CellSizeCalculator {
|
||||
|
||||
// MARK: - Bottom Label
|
||||
|
||||
public func messageBottomLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
|
||||
open func messageBottomLabelSize(for message: MessageType, at indexPath: IndexPath) -> CGSize {
|
||||
let layoutDelegate = messagesLayout.messagesLayoutDelegate
|
||||
let collectionView = messagesLayout.messagesCollectionView
|
||||
let height = layoutDelegate.messageBottomLabelHeight(for: message, at: indexPath, in: collectionView)
|
||||
return CGSize(width: messagesLayout.itemWidth, height: height)
|
||||
}
|
||||
|
||||
public func messageBottomLabelAlignment(for message: MessageType) -> LabelAlignment {
|
||||
open func messageBottomLabelAlignment(for message: MessageType) -> LabelAlignment {
|
||||
let dataSource = messagesLayout.messagesDataSource
|
||||
let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
|
||||
return isFromCurrentSender ? outgoingMessageBottomLabelAlignment : incomingMessageBottomLabelAlignment
|
||||
@@ -213,7 +213,7 @@ open class MessageSizeCalculator: CellSizeCalculator {
|
||||
|
||||
// MARK: - MessageContainer
|
||||
|
||||
public func messageContainerPadding(for message: MessageType) -> UIEdgeInsets {
|
||||
open func messageContainerPadding(for message: MessageType) -> UIEdgeInsets {
|
||||
let dataSource = messagesLayout.messagesDataSource
|
||||
let isFromCurrentSender = dataSource.isFromCurrentSender(message: message)
|
||||
return isFromCurrentSender ? outgoingMessagePadding : incomingMessagePadding
|
||||
|
||||
@@ -147,6 +147,8 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout {
|
||||
lazy open var videoMessageSizeCalculator = MediaMessageSizeCalculator(layout: self)
|
||||
lazy open var locationMessageSizeCalculator = LocationMessageSizeCalculator(layout: self)
|
||||
|
||||
/// - Note:
|
||||
/// If you override this method, remember to call MessageLayoutDelegate's customCellSizeCalculator(for:at:in:) method for MessageKind.custom messages, if necessary
|
||||
open func cellSizeCalculatorForItem(at indexPath: IndexPath) -> CellSizeCalculator {
|
||||
let message = messagesDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
|
||||
switch message.kind {
|
||||
@@ -163,7 +165,7 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout {
|
||||
case .location:
|
||||
return locationMessageSizeCalculator
|
||||
case .custom:
|
||||
fatalError("Must return a CellSizeCalculator for MessageKind.custom(Any?)")
|
||||
return messagesLayoutDelegate.customCellSizeCalculator(for: message, at: indexPath, in: messagesCollectionView)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,9 +52,9 @@ public enum MessageKind {
|
||||
case emoji(String)
|
||||
|
||||
/// A custom message.
|
||||
/// - Note: Using this case requires that you override the following methods and handle this case:
|
||||
/// - `collectionView(_:cellForItemAt indexPath: IndexPath) -> UICollectionViewCell`
|
||||
/// - `cellSizeCalculatorForItem(at indexPath: IndexPath) -> CellSizeCalculator`
|
||||
/// - Note: Using this case requires that you implement the following methods and handle this case:
|
||||
/// - MessagesDataSource: customCell(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UICollectionViewCell
|
||||
/// - MessagesLayoutDelegate: customCellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator
|
||||
case custom(Any?)
|
||||
|
||||
// MARK: - Not supported yet
|
||||
|
||||
@@ -92,6 +92,17 @@ public protocol MessagesDataSource: AnyObject {
|
||||
///
|
||||
/// The default value returned by this method is `nil`.
|
||||
func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString?
|
||||
|
||||
/// Custom collectionView cell for message with `custom` message type.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - message: The `custom` message type
|
||||
/// - indexPath: The `IndexPath` of the cell.
|
||||
/// - messagesCollectionView: The `MessagesCollectionView` in which this cell will be displayed.
|
||||
///
|
||||
/// - Note:
|
||||
/// This method will call fatalError() on default. You must override this method if you are using MessageType.custom messages.
|
||||
func customCell(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UICollectionViewCell
|
||||
}
|
||||
|
||||
public extension MessagesDataSource {
|
||||
@@ -115,4 +126,8 @@ public extension MessagesDataSource {
|
||||
func messageBottomLabelAttributedText(for message: MessageType, at indexPath: IndexPath) -> NSAttributedString? {
|
||||
return nil
|
||||
}
|
||||
|
||||
func customCell(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UICollectionViewCell {
|
||||
fatalError(MessageKitError.customDataUnresolvedCell)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,6 +80,17 @@ public protocol MessagesLayoutDelegate: AnyObject {
|
||||
/// - Note:
|
||||
/// The default value returned by this method is zero.
|
||||
func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat
|
||||
|
||||
/// Custom cell size calculator for messages with MessageType.custom.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - message: The custom message
|
||||
/// - indexPath: The `IndexPath` of the cell.
|
||||
/// - messagesCollectionView: The `MessagesCollectionView` in which this cell will be displayed.
|
||||
///
|
||||
/// - Note:
|
||||
/// The default implementation will throw fatalError(). You must override this method if you are using messages with MessageType.custom.
|
||||
func customCellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator
|
||||
}
|
||||
|
||||
public extension MessagesLayoutDelegate {
|
||||
@@ -103,4 +114,8 @@ public extension MessagesLayoutDelegate {
|
||||
func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat {
|
||||
return 0
|
||||
}
|
||||
|
||||
func customCellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator {
|
||||
fatalError("Must return a CellSizeCalculator for MessageKind.custom(Any?)")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user