From fe0a000fc536ec46efe1a4e49af6ad39e27cfed3 Mon Sep 17 00:00:00 2001 From: Pavel Anokhov Date: Sat, 8 Sep 2018 11:16:42 +0300 Subject: [PATCH 1/8] MessagesDataSource & MessagesLayoutDelegate methods for MessageType.custom handling. --- Sources/Controllers/MessagesViewController.swift | 2 +- .../MessagesCollectionViewFlowLayout.swift | 2 +- Sources/Protocols/MessagesDataSource.swift | 16 ++++++++++++++++ Sources/Protocols/MessagesLayoutDelegate.swift | 16 ++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Sources/Controllers/MessagesViewController.swift b/Sources/Controllers/MessagesViewController.swift index 41ab6b10..c9bf68d3 100644 --- a/Sources/Controllers/MessagesViewController.swift +++ b/Sources/Controllers/MessagesViewController.swift @@ -206,7 +206,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) } } diff --git a/Sources/Layout/MessagesCollectionViewFlowLayout.swift b/Sources/Layout/MessagesCollectionViewFlowLayout.swift index ff123360..26fb385a 100644 --- a/Sources/Layout/MessagesCollectionViewFlowLayout.swift +++ b/Sources/Layout/MessagesCollectionViewFlowLayout.swift @@ -151,7 +151,7 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { case .location: return locationMessageSizeCalculator case .custom: - fatalError("Must return a CellSizeCalculator for MessageKind.custom(Any?)") + return messagesLayoutDelegate.cellSizeCalculator(for: message, at: indexPath, in: messagesCollectionView) } } diff --git a/Sources/Protocols/MessagesDataSource.swift b/Sources/Protocols/MessagesDataSource.swift index 1763a8c8..0d35e592 100644 --- a/Sources/Protocols/MessagesDataSource.swift +++ b/Sources/Protocols/MessagesDataSource.swift @@ -92,6 +92,18 @@ 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 +127,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) + } } diff --git a/Sources/Protocols/MessagesLayoutDelegate.swift b/Sources/Protocols/MessagesLayoutDelegate.swift index 24a13c7a..f00955a7 100644 --- a/Sources/Protocols/MessagesLayoutDelegate.swift +++ b/Sources/Protocols/MessagesLayoutDelegate.swift @@ -80,6 +80,18 @@ 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 + + + /// 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 cellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator } public extension MessagesLayoutDelegate { @@ -103,4 +115,8 @@ public extension MessagesLayoutDelegate { func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat { return 0 } + + func cellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator { + fatalError("Must return a CellSizeCalculator for MessageKind.custom(Any?)") + } } From 485b4602af6d6f90063c158a127908e61320c55a Mon Sep 17 00:00:00 2001 From: Pavel Anokhov Date: Thu, 27 Sep 2018 14:32:47 +0300 Subject: [PATCH 2/8] swiftlint --- Sources/Protocols/MessagesDataSource.swift | 1 - Sources/Protocols/MessagesLayoutDelegate.swift | 1 - 2 files changed, 2 deletions(-) diff --git a/Sources/Protocols/MessagesDataSource.swift b/Sources/Protocols/MessagesDataSource.swift index 0d35e592..3caba08b 100644 --- a/Sources/Protocols/MessagesDataSource.swift +++ b/Sources/Protocols/MessagesDataSource.swift @@ -93,7 +93,6 @@ 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: diff --git a/Sources/Protocols/MessagesLayoutDelegate.swift b/Sources/Protocols/MessagesLayoutDelegate.swift index f00955a7..cbda0fe7 100644 --- a/Sources/Protocols/MessagesLayoutDelegate.swift +++ b/Sources/Protocols/MessagesLayoutDelegate.swift @@ -81,7 +81,6 @@ public protocol MessagesLayoutDelegate: AnyObject { /// The default value returned by this method is zero. func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat - /// Cell size calculator for messages with MessageType.custom. /// /// - Parameters: From 2aa9573c58b5a4f96e3bb5a1776fa9ed335202c3 Mon Sep 17 00:00:00 2001 From: Pavel Anokhov Date: Tue, 2 Oct 2018 12:19:47 +0300 Subject: [PATCH 3/8] Better method names --- Sources/Layout/MessagesCollectionViewFlowLayout.swift | 2 +- Sources/Models/MessageKind.swift | 6 +++--- Sources/Protocols/MessagesLayoutDelegate.swift | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Sources/Layout/MessagesCollectionViewFlowLayout.swift b/Sources/Layout/MessagesCollectionViewFlowLayout.swift index 26fb385a..075758c7 100644 --- a/Sources/Layout/MessagesCollectionViewFlowLayout.swift +++ b/Sources/Layout/MessagesCollectionViewFlowLayout.swift @@ -151,7 +151,7 @@ open class MessagesCollectionViewFlowLayout: UICollectionViewFlowLayout { case .location: return locationMessageSizeCalculator case .custom: - return messagesLayoutDelegate.cellSizeCalculator(for: message, at: indexPath, in: messagesCollectionView) + return messagesLayoutDelegate.customCellSizeCalculator(for: message, at: indexPath, in: messagesCollectionView) } } diff --git a/Sources/Models/MessageKind.swift b/Sources/Models/MessageKind.swift index fc130f52..a29d76d5 100644 --- a/Sources/Models/MessageKind.swift +++ b/Sources/Models/MessageKind.swift @@ -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 diff --git a/Sources/Protocols/MessagesLayoutDelegate.swift b/Sources/Protocols/MessagesLayoutDelegate.swift index cbda0fe7..4dd75743 100644 --- a/Sources/Protocols/MessagesLayoutDelegate.swift +++ b/Sources/Protocols/MessagesLayoutDelegate.swift @@ -81,7 +81,7 @@ public protocol MessagesLayoutDelegate: AnyObject { /// The default value returned by this method is zero. func messageBottomLabelHeight(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CGFloat - /// Cell size calculator for messages with MessageType.custom. + /// Custom cell size calculator for messages with MessageType.custom. /// /// - Parameters: /// - message: The custom message @@ -90,7 +90,7 @@ public protocol MessagesLayoutDelegate: AnyObject { /// /// - Note: /// The default implementation will throw fatalError(). You must override this method if you are using messages with MessageType.custom. - func cellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator + func customCellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator } public extension MessagesLayoutDelegate { @@ -115,7 +115,7 @@ public extension MessagesLayoutDelegate { return 0 } - func cellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator { + func customCellSizeCalculator(for message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> CellSizeCalculator { fatalError("Must return a CellSizeCalculator for MessageKind.custom(Any?)") } } From 4156260d9350193278d335059d2702e4915eb654 Mon Sep 17 00:00:00 2001 From: Marius Serban Date: Tue, 16 Oct 2018 21:58:22 +0100 Subject: [PATCH 4/8] allow dynamic avatar size per message size calculator (#898) * allow dynamic calculation of avatar size instead of having the same avatar size per size calculator, allow a subclass to override it so it can provide multiple avatar sizes depending on the message * make sizing functions overridable by subclasses --- Sources/Layout/MessageSizeCalculator.swift | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Sources/Layout/MessageSizeCalculator.swift b/Sources/Layout/MessageSizeCalculator.swift index 02b12b75..f83f826e 100644 --- a/Sources/Layout/MessageSizeCalculator.swift +++ b/Sources/Layout/MessageSizeCalculator.swift @@ -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 From 5ce67b4a2dd6139a582f07e87c6148a00c094f46 Mon Sep 17 00:00:00 2001 From: Steven Deutsch Date: Tue, 16 Oct 2018 21:40:09 -0500 Subject: [PATCH 5/8] Fix CHANGELOG entry order (#914) --- CHANGELOG.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a404e4f7..0ca12065 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,15 +4,15 @@ 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) +## [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) -- **Breaking Change** Updated codebase to Swift 4.2 [#883](https://github.com/MessageKit/MessageKit/pull/883) by [@nathantannar4](https://github.com/nathantannar4) - ### Added - Added support for detection and handling of `NSLink`s inside of messages. @@ -29,13 +29,12 @@ The changelog for `MessageKit`. Also see the [releases](https://github.com/Messa ### 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) @@ -46,7 +45,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) From eb848be3f03f4ebeccff72dc5488a7a23de59b5a Mon Sep 17 00:00:00 2001 From: Pavel Anokhov Date: Fri, 19 Oct 2018 16:32:46 +0300 Subject: [PATCH 6/8] Changelog and some comments --- CHANGELOG.md | 3 +++ Sources/Controllers/MessagesViewController.swift | 2 ++ Sources/Layout/MessagesCollectionViewFlowLayout.swift | 2 ++ 3 files changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e63133c..1b257ebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,9 @@ 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 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. diff --git a/Sources/Controllers/MessagesViewController.swift b/Sources/Controllers/MessagesViewController.swift index c9bf68d3..454b8aff 100644 --- a/Sources/Controllers/MessagesViewController.swift +++ b/Sources/Controllers/MessagesViewController.swift @@ -180,6 +180,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 { diff --git a/Sources/Layout/MessagesCollectionViewFlowLayout.swift b/Sources/Layout/MessagesCollectionViewFlowLayout.swift index 075758c7..1061dc99 100644 --- a/Sources/Layout/MessagesCollectionViewFlowLayout.swift +++ b/Sources/Layout/MessagesCollectionViewFlowLayout.swift @@ -135,6 +135,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 { From 801b1e206e733d64c01d447da09cb8666a3005f6 Mon Sep 17 00:00:00 2001 From: Cruz Date: Sat, 20 Oct 2018 09:59:51 +0900 Subject: [PATCH 7/8] Fix Code of Conduct link broken (#918) --- CONTRIBUTING.md | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6b37d5ae..eb2c5b40 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 diff --git a/README.md b/README.md index da37ba31..55b22a7b 100644 --- a/README.md +++ b/README.md @@ -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. From e5bc7627bdbaff0d059a065bf40e50b1332611f3 Mon Sep 17 00:00:00 2001 From: hamzaozturk Date: Tue, 23 Oct 2018 11:04:00 +0300 Subject: [PATCH 8/8] Settings aded to enable/disable message types. --- Example/Sources/AppDelegate.swift | 5 ++ .../Sources/Data Generation/SampleData.swift | 83 +++++++++++++------ Example/Sources/Models/MockSocket.swift | 4 +- Example/Sources/Settings+UserDefaults.swift | 10 +++ .../SettingsViewController.swift | 33 ++++++-- 5 files changed, 101 insertions(+), 34 deletions(-) diff --git a/Example/Sources/AppDelegate.swift b/Example/Sources/AppDelegate.swift index 5f31cfe2..ea28caaa 100644 --- a/Example/Sources/AppDelegate.swift +++ b/Example/Sources/AppDelegate.swift @@ -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 } diff --git a/Example/Sources/Data Generation/SampleData.swift b/Example/Sources/Data Generation/SampleData.swift index 63614a73..07b47218 100644 --- a/Example/Sources/Data Generation/SampleData.swift +++ b/Example/Sources/Data Generation/SampleData.swift @@ -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.. Void) { var messages: [MockMessage] = [] + // Enable Custom Messages + UserDefaults.standard.set(true, forKey: "Custom Messages") for _ in 0.. Void) { var messages: [MockMessage] = [] + // Disable Custom Messages + UserDefaults.standard.set(false, forKey: "Custom Messages") for _ in 0.. Bool { + let hasBeenLaunchedBeforeFlag = "hasBeenLaunchedBeforeFlag" + let isFirstLaunch = !UserDefaults.standard.bool(forKey: hasBeenLaunchedBeforeFlag) + if isFirstLaunch { + UserDefaults.standard.set(true, forKey: hasBeenLaunchedBeforeFlag) + UserDefaults.standard.synchronize() + } + return isFirstLaunch + } } diff --git a/Example/Sources/View Controllers/SettingsViewController.swift b/Example/Sources/View Controllers/SettingsViewController.swift index f1c6a214..882e0f9e 100644 --- a/Example/Sources/View Controllers/SettingsViewController.swift +++ b/Example/Sources/View Controllers/SettingsViewController.swift @@ -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 - } }