Merge branch 'v0.3.0' into input-text-view

This commit is contained in:
Steven Deutsch
2017-08-06 04:02:25 -05:00
committed by GitHub
11 changed files with 254 additions and 65 deletions
+3 -4
View File
@@ -1,6 +1,5 @@
line_length:
warning: 150
ignores_comments: true
disabled_rules:
identifier_name
- identifier_name
- trailing_whitespace
- line_length
@@ -111,9 +111,9 @@ extension ConversationViewController: MessagesDataSource {
extension ConversationViewController: MessagesDisplayDataSource {
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> Avatar {
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> AvatarView {
let image = isFromCurrentSender(message: message) ? #imageLiteral(resourceName: "Steve-Jobs") : #imageLiteral(resourceName: "Tim-Cook")
return Avatar(placeholderImage: image)
return AvatarView(image: image)
}
func headerForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageHeaderView? {
+10 -4
View File
@@ -8,6 +8,8 @@
/* Begin PBXBuildFile section */
171D5AB91F36712B0053DF69 /* InputTextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 171D5AB81F36712B0053DF69 /* InputTextView.swift */; };
372F6AEB1F36C15600B57FBD /* AvatarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372F6AEA1F36C15600B57FBD /* AvatarView.swift */; };
372F6AEF1F36C61000B57FBD /* AvatarViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 372F6AEE1F36C61000B57FBD /* AvatarViewTests.swift */; };
882D75841DE507320033F95F /* MessagesDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 882D75831DE507320033F95F /* MessagesDataSource.swift */; };
888CEBFC1D3FD525005178DE /* MessagesViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 888CEBFB1D3FD525005178DE /* MessagesViewController.swift */; };
88916B2D1CF0DF2F00469F91 /* MessageKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 88916B221CF0DF2F00469F91 /* MessageKit.framework */; };
@@ -17,7 +19,6 @@
B015E8191F24623D007EDFB6 /* MessagesCollectionViewLayoutAttributes.swift in Sources */ = {isa = PBXBuildFile; fileRef = B015E8181F24623D007EDFB6 /* MessagesCollectionViewLayoutAttributes.swift */; };
B015E81F1F259D8E007EDFB6 /* MessageInputBarDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B015E81E1F259D8E007EDFB6 /* MessageInputBarDelegate.swift */; };
B03FF9AF1F31BB1200754FE5 /* MessageCellDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B03FF9AE1F31BB1200754FE5 /* MessageCellDelegate.swift */; };
B0655A261F23D6C500542A83 /* Avatar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0655A251F23D6C500542A83 /* Avatar.swift */; };
B0655A281F23D71400542A83 /* MessageDirection.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0655A271F23D71400542A83 /* MessageDirection.swift */; };
B0655A2A1F23D77200542A83 /* Sender.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0655A291F23D77200542A83 /* Sender.swift */; };
B0655A2C1F23D81600542A83 /* MessageData.swift in Sources */ = {isa = PBXBuildFile; fileRef = B0655A2B1F23D81600542A83 /* MessageData.swift */; };
@@ -45,6 +46,9 @@
/* Begin PBXFileReference section */
171D5AB81F36712B0053DF69 /* InputTextView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTextView.swift; sourceTree = "<group>"; };
372F6AEA1F36C15600B57FBD /* AvatarView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarView.swift; sourceTree = "<group>"; };
372F6AED1F36C1C100B57FBD /* AvatarView.playground */ = {isa = PBXFileReference; lastKnownFileType = file.playground; path = AvatarView.playground; sourceTree = "<group>"; };
372F6AEE1F36C61000B57FBD /* AvatarViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AvatarViewTests.swift; sourceTree = "<group>"; };
882D75831DE507320033F95F /* MessagesDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesDataSource.swift; sourceTree = "<group>"; };
888CEBFB1D3FD525005178DE /* MessagesViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesViewController.swift; sourceTree = "<group>"; };
88916B221CF0DF2F00469F91 /* MessageKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MessageKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -57,7 +61,6 @@
B015E8181F24623D007EDFB6 /* MessagesCollectionViewLayoutAttributes.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessagesCollectionViewLayoutAttributes.swift; sourceTree = "<group>"; };
B015E81E1F259D8E007EDFB6 /* MessageInputBarDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageInputBarDelegate.swift; sourceTree = "<group>"; };
B03FF9AE1F31BB1200754FE5 /* MessageCellDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageCellDelegate.swift; sourceTree = "<group>"; };
B0655A251F23D6C500542A83 /* Avatar.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Avatar.swift; sourceTree = "<group>"; };
B0655A271F23D71400542A83 /* MessageDirection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageDirection.swift; sourceTree = "<group>"; };
B0655A291F23D77200542A83 /* Sender.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sender.swift; sourceTree = "<group>"; };
B0655A2B1F23D81600542A83 /* MessageData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageData.swift; sourceTree = "<group>"; };
@@ -129,6 +132,7 @@
children = (
88916B421CF0DF5900469F91 /* Info.plist */,
88916B431CF0DF5900469F91 /* MessageKitTests.swift */,
372F6AEE1F36C61000B57FBD /* AvatarViewTests.swift */,
);
path = Tests;
sourceTree = SOURCE_ROOT;
@@ -145,7 +149,6 @@
B09643991F295D58004D0129 /* Models */ = {
isa = PBXGroup;
children = (
B0655A251F23D6C500542A83 /* Avatar.swift */,
B0655A291F23D77200542A83 /* Sender.swift */,
B0655A2B1F23D81600542A83 /* MessageData.swift */,
B0655A271F23D71400542A83 /* MessageDirection.swift */,
@@ -158,6 +161,8 @@
children = (
B0655A2D1F23D8BC00542A83 /* MessagesCollectionView.swift */,
B0655A4C1F244C0600542A83 /* MessageCollectionViewCell.swift */,
372F6AEA1F36C15600B57FBD /* AvatarView.swift */,
372F6AED1F36C1C100B57FBD /* AvatarView.playground */,
B0655A371F23EE8B00542A83 /* MessageInputBar.swift */,
171D5AB81F36712B0053DF69 /* InputTextView.swift */,
B074EE921F35587100ABB8C8 /* MessageHeaderView.swift */,
@@ -339,7 +344,6 @@
B0655A2C1F23D81600542A83 /* MessageData.swift in Sources */,
B09643861F286C9E004D0129 /* String+Extensions.swift in Sources */,
B0655A281F23D71400542A83 /* MessageDirection.swift in Sources */,
B0655A261F23D6C500542A83 /* Avatar.swift in Sources */,
B015E81F1F259D8E007EDFB6 /* MessageInputBarDelegate.swift in Sources */,
B0655A2A1F23D77200542A83 /* Sender.swift in Sources */,
B074EE931F35587100ABB8C8 /* MessageHeaderView.swift in Sources */,
@@ -348,6 +352,7 @@
B074EE951F35588A00ABB8C8 /* MessageFooterView.swift in Sources */,
B09643901F289142004D0129 /* UIColor+Extensions.swift in Sources */,
B0655A381F23EE8B00542A83 /* MessageInputBar.swift in Sources */,
372F6AEB1F36C15600B57FBD /* AvatarView.swift in Sources */,
88916B471CF0DFE600469F91 /* MessageType.swift in Sources */,
B03FF9AF1F31BB1200754FE5 /* MessageCellDelegate.swift in Sources */,
B096438E1F2890FB004D0129 /* MessagesDisplayDataSource.swift in Sources */,
@@ -360,6 +365,7 @@
buildActionMask = 2147483647;
files = (
88916B451CF0DF5900469F91 /* MessageKitTests.swift in Sources */,
372F6AEF1F36C61000B57FBD /* AvatarViewTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
-51
View File
@@ -1,51 +0,0 @@
/*
MIT License
Copyright (c) 2017 MessageKit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import Foundation
public struct Avatar {
public let image: UIImage?
public let highlightedImage: UIImage?
public let placeholderImage: UIImage
public init(image: UIImage? = nil, highlightedImage: UIImage? = nil, placeholderImage: UIImage) {
self.image = image
self.highlightedImage = highlightedImage
self.placeholderImage = placeholderImage
}
public func image(highlighted: Bool) -> UIImage {
switch highlighted {
case true:
return highlightedImage ?? image ?? placeholderImage
case false:
return image ?? placeholderImage
}
}
}
@@ -0,0 +1,37 @@
import UIKit
import MessageKit
import PlaygroundSupport
//: Discover what is possible with the Avatar Class
//Get an image
let testImage = #imageLiteral(resourceName: "NiceSelfi.jpg")
let view = UIView(frame: CGRect(x: 0, y: 0, width: 50, height: 200))
view.backgroundColor = UIColor.white
//: Uncomment any line to see how it changes the `Avatar`.
//: By default its a circlular avatar with a gray background and initals of ?
let avatar = AvatarView()
//: Configure any one of the initilization parameters and delete the ones you dont want to set.
//let avatar = AvatarView(size: 50, image: testImage, highlightedImage: testImage, initals: "PL", cornerRounding: 9)
//: Throw in just an image.
//let avatar = AvatarView(image: testImage)
//: Dont have an image just add the users initals
//let avatar = AvatarView(initals: "PL")
//: Want rounded squares instead of circles just change the `cornderRounding`.
//let avatar = AvatarView(image: testImage, cornerRounding: 9)
//:Change its size
//let avatar = AvatarView(size: 5)
//let avatar = AvatarView(size: 100)
//: Everything has a default so if you dont want to set it then you dont have to.
//Helper method.
PlaygroundPage.current.liveView = avatar
Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<playground version='5.0' target-platform='ios'>
<timeline fileName='timeline.xctimeline'/>
</playground>
+115
View File
@@ -0,0 +1,115 @@
/*
MIT License
Copyright (c) 2017 MessageKit
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
import Foundation
open class AvatarView: UIView {
// MARK: - Properties
internal var initalsLabel = UILabel()
internal var imageView = UIImageView()
internal var initals: String = "?"
// MARK: - initializers
override init(frame: CGRect) {
super.init(frame: frame)
prepareView()
}
convenience public init(size: CGFloat = 30, image: UIImage? = nil, highlightedImage: UIImage? = nil, initals inInitals: String = "?", cornerRounding: CGFloat? = nil) {
let frame = CGRect(x: 0, y: 0, width: size, height: size)
self.init(frame: frame)
setCorner(radius: cornerRounding)
setBackground(color: UIColor.gray)
imageView.image = image
imageView.highlightedImage = highlightedImage
initals = inInitals
prepareView()
}
convenience public init() {
let frame = CGRect(x: 0, y: 0, width: 30, height: 30)
self.init(frame: frame)
setBackground(color: UIColor.gray)
setCorner(radius: nil)
prepareView()
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
// MARK: - internal methods
internal func prepareView() {
prepareInitalsLabel()
prepareImageView()
imageView.isHidden = imageView.image == nil
}
internal func prepareInitalsLabel() {
initalsLabel.text = initals
initalsLabel.textAlignment = .center
setInitalsFont()
addSubview(initalsLabel)
initalsLabel.center = center
initalsLabel.frame = frame
}
internal func prepareImageView() {
contentMode = .scaleAspectFill
layer.masksToBounds = true
clipsToBounds = true
addSubview(imageView)
imageView.contentMode = .scaleAspectFill
imageView.frame = frame
}
// MARK: - Open methods
open func set(image: UIImage) {
imageView.image = image
}
open func setInitalsFont(size: CGFloat = 16, color: UIColor = .white) {
initalsLabel.font = UIFont.systemFont(ofSize: size)
initalsLabel.textColor = color
}
open func setBackground(color: UIColor) {
backgroundColor = color
}
open func getImage() -> UIImage? {
return imageView.image
}
open func setCorner(radius: CGFloat?) {
guard let radius = radius else {
//if corner radius not set default to Circle
layer.cornerRadius = frame.height/2
return
}
layer.cornerRadius = radius
}
}
+1 -1
View File
@@ -28,7 +28,7 @@ public protocol MessagesDisplayDataSource: class, MessagesDataSource {
func messageColorFor(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> UIColor
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> Avatar
func avatarForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> AvatarView
func headerForMessage(_ message: MessageType, at indexPath: IndexPath, in messagesCollectionView: MessagesCollectionView) -> MessageHeaderView?
+2 -3
View File
@@ -172,9 +172,8 @@ extension MessagesViewController: UICollectionViewDataSource {
let message = displayDataSource.messageForItem(at: indexPath, in: messagesCollectionView)
let messageColor = displayDataSource.messageColorFor(message, at: indexPath, in: messagesCollectionView)
let avatar = displayDataSource.avatarForMessage(message, at: indexPath, in: messagesCollectionView)
cell.avatarImageView.image = avatar.image(highlighted: false)
cell.avatarImageView.highlightedImage = avatar.image(highlighted: true)
//TODO: replace this completely
cell.avatarImageView.image = avatar.getImage()
cell.messageContainerView.backgroundColor = messageColor
cell.configure(with: message)
+80
View File
@@ -0,0 +1,80 @@
//
// AvatarViewTests.swift
// MessageKit
//
// Created by Dan Leonard on 8/5/17.
// Copyright © 2017 Hexed Bits. All rights reserved.
//
import XCTest
@testable import MessageKit
class AvatarViewTests: XCTestCase {
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
}
func testNoParams() {
let avatar = AvatarView()
XCTAssertEqual(avatar.initals, "?")
XCTAssertEqual(avatar.initalsLabel.text, "?")
XCTAssertEqual(avatar.layer.cornerRadius, 15.0)
XCTAssertNil(avatar.imageView.image)
XCTAssertTrue(avatar.imageView.isHidden)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
}
func testWithImage() {
let avatar = AvatarView(image: UIImage())
XCTAssertEqual(avatar.initals, "?")
XCTAssertEqual(avatar.initalsLabel.text, "?")
XCTAssertEqual(avatar.layer.cornerRadius, 15.0)
XCTAssertFalse(avatar.imageView.isHidden)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
XCTAssertEqual(avatar.backgroundColor, UIColor.gray)
}
func testCustom() {
let avatar = AvatarView(size: 50, image: UIImage(), highlightedImage: nil, initals: "lol", cornerRounding: 6)
XCTAssertEqual(avatar.initals, "lol")
XCTAssertEqual(avatar.initalsLabel.text, "lol")
XCTAssertEqual(avatar.layer.cornerRadius, 6.0)
XCTAssertFalse(avatar.imageView.isHidden)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
XCTAssertEqual(avatar.backgroundColor, UIColor.gray)
}
func testSetBackground() {
let avatar = AvatarView(image: UIImage())
XCTAssertEqual(avatar.backgroundColor, UIColor.gray)
avatar.setBackground(color: UIColor.red)
XCTAssertEqual(avatar.backgroundColor, UIColor.red)
}
func testGetImage() {
let image = UIImage()
let avatar = AvatarView(image: image)
XCTAssertEqual(avatar.getImage(), image)
}
func testRoundedCorners() {
let avatar = AvatarView(image: UIImage())
XCTAssertEqual(avatar.layer.cornerRadius, 15.0)
avatar.setCorner(radius: 2)
XCTAssertEqual(avatar.layer.cornerRadius, 2.0)
}
func testInitalsFont() {
let avatar = AvatarView(image: UIImage())
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.white)
XCTAssertEqual(avatar.initalsLabel.font.pointSize, 16)
avatar.setInitalsFont(size: 20, color: UIColor.blue)
XCTAssertEqual(avatar.initalsLabel.textColor, UIColor.blue)
XCTAssertEqual(avatar.initalsLabel.font.pointSize, 20)
}
}