blob: 527d2686c198c31dee6f8bf12349276d34d7e5ab [file] [log] [blame]
//
// Created by Jesse Squires
// http://www.jessesquires.com
//
//
// Documentation
// http://cocoadocs.org/docsets/JSQMessagesViewController
//
//
// GitHub
// https://github.com/jessesquires/JSQMessagesViewController
//
//
// License
// Copyright (c) 2014 Jesse Squires
// Released under an MIT license: http://opensource.org/licenses/MIT
//
#import "JSQMessagesCollectionView.h"
#import "JSQMessagesCollectionViewFlowLayout.h"
#import "JSQMessagesCollectionViewCellIncoming.h"
#import "JSQMessagesCollectionViewCellOutgoing.h"
#import "JSQMessagesTypingIndicatorFooterView.h"
#import "JSQMessagesLoadEarlierHeaderView.h"
#import "UIColor+JSQMessages.h"
@interface JSQMessagesCollectionView () <JSQMessagesLoadEarlierHeaderViewDelegate>
- (void)jsq_configureCollectionView;
@end
@implementation JSQMessagesCollectionView
@dynamic dataSource;
@dynamic delegate;
@dynamic collectionViewLayout;
#pragma mark - Initialization
- (void)jsq_configureCollectionView
{
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
self.backgroundColor = [UIColor whiteColor];
self.keyboardDismissMode = UIScrollViewKeyboardDismissModeNone;
self.alwaysBounceVertical = YES;
self.bounces = YES;
[self registerNib:[JSQMessagesCollectionViewCellIncoming nib]
forCellWithReuseIdentifier:[JSQMessagesCollectionViewCellIncoming cellReuseIdentifier]];
[self registerNib:[JSQMessagesCollectionViewCellOutgoing nib]
forCellWithReuseIdentifier:[JSQMessagesCollectionViewCellOutgoing cellReuseIdentifier]];
[self registerNib:[JSQMessagesCollectionViewCellIncoming nib]
forCellWithReuseIdentifier:[JSQMessagesCollectionViewCellIncoming mediaCellReuseIdentifier]];
[self registerNib:[JSQMessagesCollectionViewCellOutgoing nib]
forCellWithReuseIdentifier:[JSQMessagesCollectionViewCellOutgoing mediaCellReuseIdentifier]];
[self registerNib:[JSQMessagesTypingIndicatorFooterView nib]
forSupplementaryViewOfKind:UICollectionElementKindSectionFooter
withReuseIdentifier:[JSQMessagesTypingIndicatorFooterView footerReuseIdentifier]];
[self registerNib:[JSQMessagesLoadEarlierHeaderView nib]
forSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:[JSQMessagesLoadEarlierHeaderView headerReuseIdentifier]];
_typingIndicatorDisplaysOnLeft = YES;
_typingIndicatorMessageBubbleColor = [UIColor jsq_messageBubbleLightGrayColor];
_typingIndicatorEllipsisColor = [_typingIndicatorMessageBubbleColor jsq_colorByDarkeningColorWithValue:0.3f];
_loadEarlierMessagesHeaderTextColor = [UIColor jsq_messageBubbleBlueColor];
}
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
{
self = [super initWithFrame:frame collectionViewLayout:layout];
if (self) {
[self jsq_configureCollectionView];
}
return self;
}
- (void)awakeFromNib
{
[super awakeFromNib];
[self jsq_configureCollectionView];
}
#pragma mark - Typing indicator
- (JSQMessagesTypingIndicatorFooterView *)dequeueTypingIndicatorFooterViewForIndexPath:(NSIndexPath *)indexPath
{
JSQMessagesTypingIndicatorFooterView *footerView = [super dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionFooter
withReuseIdentifier:[JSQMessagesTypingIndicatorFooterView footerReuseIdentifier]
forIndexPath:indexPath];
[footerView configureWithEllipsisColor:self.typingIndicatorEllipsisColor
messageBubbleColor:self.typingIndicatorMessageBubbleColor
shouldDisplayOnLeft:self.typingIndicatorDisplaysOnLeft
forCollectionView:self];
return footerView;
}
#pragma mark - Load earlier messages header
- (JSQMessagesLoadEarlierHeaderView *)dequeueLoadEarlierMessagesViewHeaderForIndexPath:(NSIndexPath *)indexPath
{
JSQMessagesLoadEarlierHeaderView *headerView = [super dequeueReusableSupplementaryViewOfKind:UICollectionElementKindSectionHeader
withReuseIdentifier:[JSQMessagesLoadEarlierHeaderView headerReuseIdentifier]
forIndexPath:indexPath];
headerView.loadButton.tintColor = self.loadEarlierMessagesHeaderTextColor;
headerView.delegate = self;
return headerView;
}
#pragma mark - Load earlier messages header delegate
- (void)headerView:(JSQMessagesLoadEarlierHeaderView *)headerView didPressLoadButton:(UIButton *)sender
{
if ([self.delegate respondsToSelector:@selector(collectionView:header:didTapLoadEarlierMessagesButton:)]) {
[self.delegate collectionView:self header:headerView didTapLoadEarlierMessagesButton:sender];
}
}
#pragma mark - Messages collection view cell delegate
- (void)messagesCollectionViewCellDidTapAvatar:(JSQMessagesCollectionViewCell *)cell
{
NSIndexPath *indexPath = [self indexPathForCell:cell];
if (indexPath == nil) {
return;
}
[self.delegate collectionView:self
didTapAvatarImageView:cell.avatarImageView
atIndexPath:indexPath];
}
- (void)messagesCollectionViewCellDidTapMessageBubble:(JSQMessagesCollectionViewCell *)cell
{
NSIndexPath *indexPath = [self indexPathForCell:cell];
if (indexPath == nil) {
return;
}
[self.delegate collectionView:self didTapMessageBubbleAtIndexPath:indexPath];
}
- (void)messagesCollectionViewCellDidTapCell:(JSQMessagesCollectionViewCell *)cell atPosition:(CGPoint)position
{
NSIndexPath *indexPath = [self indexPathForCell:cell];
if (indexPath == nil) {
return;
}
[self.delegate collectionView:self
didTapCellAtIndexPath:indexPath
touchLocation:position];
}
- (void)messagesCollectionViewCell:(JSQMessagesCollectionViewCell *)cell didPerformAction:(SEL)action withSender:(id)sender
{
NSIndexPath *indexPath = [self indexPathForCell:cell];
if (indexPath == nil) {
return;
}
[self.delegate collectionView:self
performAction:action
forItemAtIndexPath:indexPath
withSender:sender];
}
@end