mirror of https://github.com/oxen-io/session-ios
Merge pull request #1255 from WhisperSystems/update-jsqmvc
Unfork/Update JSQMessagesViewControllerpull/1/head
commit
cca4bc451c
@ -0,0 +1,60 @@
|
||||
// Created by Dylan Bourgeois on 20/11/14.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "TSMessageAdapter.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <JSQMessagesViewController/JSQMessageData.h>
|
||||
|
||||
typedef enum : NSUInteger {
|
||||
kCallOutgoing = 1,
|
||||
kCallIncoming = 2,
|
||||
kCallMissed = 3,
|
||||
kGroupUpdateJoin = 4,
|
||||
kGroupUpdateLeft = 5,
|
||||
kGroupUpdate = 6
|
||||
} CallStatus;
|
||||
|
||||
@interface OWSCall : NSObject <JSQMessageData, NSCoding, NSCopying>
|
||||
|
||||
/*
|
||||
* Returns the string Id of the user who initiated the call
|
||||
*/
|
||||
@property (copy, nonatomic, readonly) NSString *senderId;
|
||||
|
||||
/*
|
||||
* Returns the display name for user who initiated the call
|
||||
*/
|
||||
@property (copy, nonatomic, readonly) NSString *senderDisplayName;
|
||||
|
||||
/*
|
||||
* Returns date of the call
|
||||
*/
|
||||
@property (copy, nonatomic, readonly) NSDate *date;
|
||||
|
||||
/*
|
||||
* Returns the call status
|
||||
* @see CallStatus
|
||||
*/
|
||||
@property (nonatomic) CallStatus status;
|
||||
|
||||
/*
|
||||
* Returns message type for adapter
|
||||
*/
|
||||
@property (nonatomic) TSMessageAdapterType messageType;
|
||||
|
||||
/**
|
||||
* String to be displayed
|
||||
*/
|
||||
@property (nonatomic, copy) NSString *detailString;
|
||||
|
||||
#pragma mark - Initialization
|
||||
|
||||
- (instancetype)initWithCallerId:(NSString *)callerId
|
||||
callerDisplayName:(NSString *)callerDisplayName
|
||||
date:(NSDate *)date
|
||||
status:(CallStatus)status
|
||||
displayString:(NSString *)detailString NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (NSString *)dateText;
|
||||
|
||||
@end
|
@ -0,0 +1,144 @@
|
||||
// Created by Dylan Bourgeois on 20/11/14.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSCall.h"
|
||||
#import <JSQMessagesViewController/JSQMessagesTimestampFormatter.h>
|
||||
#import <JSQMessagesViewController/UIImage+JSQMessages.h>
|
||||
|
||||
@implementation OWSCall
|
||||
|
||||
#pragma mark - Initialzation
|
||||
|
||||
- (id)init
|
||||
{
|
||||
NSAssert(NO,
|
||||
@"%s is not a valid initializer for %@. Use %@ instead",
|
||||
__PRETTY_FUNCTION__,
|
||||
[self class],
|
||||
NSStringFromSelector(@selector(initWithCallerId:callerDisplayName:date:status:displayString:)));
|
||||
return [self initWithCallerId:nil callerDisplayName:nil date:nil status:0 displayString:nil];
|
||||
}
|
||||
|
||||
- (instancetype)initWithCallerId:(NSString *)senderId
|
||||
callerDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date
|
||||
status:(CallStatus)status
|
||||
displayString:(NSString *)detailString
|
||||
{
|
||||
NSParameterAssert(senderId != nil);
|
||||
NSParameterAssert(senderDisplayName != nil);
|
||||
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_senderId = [senderId copy];
|
||||
_senderDisplayName = [senderDisplayName copy];
|
||||
_date = [date copy];
|
||||
_status = status;
|
||||
_messageType = TSCallAdapter;
|
||||
|
||||
// TODO interpret detailString from status. make sure it works for calls and
|
||||
// our re-use of calls as group update display
|
||||
_detailString = [detailString stringByAppendingFormat:@" "];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)dateText
|
||||
{
|
||||
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
|
||||
dateFormatter.timeStyle = NSDateFormatterShortStyle;
|
||||
dateFormatter.dateStyle = NSDateFormatterMediumStyle;
|
||||
dateFormatter.doesRelativeDateFormatting = YES;
|
||||
return [dateFormatter stringFromDate:_date];
|
||||
}
|
||||
|
||||
#pragma mark - NSObject
|
||||
|
||||
- (BOOL)isEqual:(id)object
|
||||
{
|
||||
if (self == object) {
|
||||
return YES;
|
||||
}
|
||||
|
||||
if (![object isKindOfClass:[self class]]) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
OWSCall *aCall = (OWSCall *)object;
|
||||
|
||||
return [self.senderId isEqualToString:aCall.senderId] &&
|
||||
[self.senderDisplayName isEqualToString:aCall.senderDisplayName]
|
||||
&& ([self.date compare:aCall.date] == NSOrderedSame) && self.status == aCall.status;
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return self.senderId.hash ^ self.date.hash;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: senderId=%@, senderDisplayName=%@, date=%@>",
|
||||
[self class],
|
||||
self.senderId,
|
||||
self.senderDisplayName,
|
||||
self.date];
|
||||
}
|
||||
|
||||
#pragma mark - JSQMessageData
|
||||
|
||||
- (BOOL)isMediaMessage
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - NSCoding
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)aDecoder
|
||||
{
|
||||
NSString *senderId = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(senderId))];
|
||||
NSString *senderDisplayName = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(senderDisplayName))];
|
||||
NSDate *date = [aDecoder decodeObjectForKey:NSStringFromSelector(@selector(date))];
|
||||
CallStatus status = (CallStatus)[aDecoder decodeIntegerForKey:NSStringFromSelector(@selector(status))];
|
||||
NSString *displayString = @""; // FIXME what should this be?
|
||||
|
||||
return [self initWithCallerId:senderId
|
||||
callerDisplayName:senderDisplayName
|
||||
date:date
|
||||
status:status
|
||||
displayString:displayString];
|
||||
}
|
||||
|
||||
- (void)encodeWithCoder:(NSCoder *)aCoder
|
||||
{
|
||||
[aCoder encodeObject:self.senderId forKey:NSStringFromSelector(@selector(senderId))];
|
||||
[aCoder encodeObject:self.senderDisplayName forKey:NSStringFromSelector(@selector(senderDisplayName))];
|
||||
[aCoder encodeObject:self.date forKey:NSStringFromSelector(@selector(date))];
|
||||
[aCoder encodeDouble:self.status forKey:NSStringFromSelector(@selector(status))];
|
||||
}
|
||||
|
||||
#pragma mark - NSCopying
|
||||
|
||||
- (instancetype)copyWithZone:(NSZone *)zone
|
||||
{
|
||||
return [[[self class] allocWithZone:zone] initWithCallerId:self.senderId
|
||||
callerDisplayName:self.senderDisplayName
|
||||
date:self.date
|
||||
status:self.status
|
||||
displayString:self.detailString];
|
||||
}
|
||||
|
||||
- (NSUInteger)messageHash
|
||||
{
|
||||
return self.hash;
|
||||
}
|
||||
|
||||
- (NSString *)text
|
||||
{
|
||||
return _detailString;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,38 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "JSQMessageData.h"
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
/* OWSDisplayedMessage message is the parent class for displaying information to the user
|
||||
* from within the conversation view. Do not use directly :
|
||||
*
|
||||
* @see OWSInfoMessage
|
||||
* @see OWSErrorMessage
|
||||
*
|
||||
*/
|
||||
@interface OWSDisplayedMessage : NSObject <JSQMessageData>
|
||||
|
||||
/*
|
||||
* Returns the unique identifier of the person affected by the displayed message
|
||||
*/
|
||||
@property (copy, nonatomic, readonly) NSString *senderId;
|
||||
|
||||
/*
|
||||
* Returns the name of the person affected by the displayed message
|
||||
*/
|
||||
@property (copy, nonatomic, readonly) NSString *senderDisplayName;
|
||||
|
||||
/*
|
||||
* Returns date of the displayed message
|
||||
*/
|
||||
@property (copy, nonatomic, readonly) NSDate *date;
|
||||
|
||||
#pragma mark - Initializer
|
||||
|
||||
- (instancetype)initWithSenderId:(NSString *)senderId
|
||||
senderDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date;
|
||||
|
||||
@end
|
@ -0,0 +1,45 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSDisplayedMessage.h"
|
||||
|
||||
@implementation OWSDisplayedMessage
|
||||
|
||||
- (id)init
|
||||
{
|
||||
NSAssert(NO,
|
||||
@"%s is not a valid initializer for %@. Use %@ instead",
|
||||
__PRETTY_FUNCTION__,
|
||||
[self class],
|
||||
NSStringFromSelector(@selector(initWithSenderId:senderDisplayName:date:)));
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (instancetype)initWithSenderId:(NSString *)senderId
|
||||
senderDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_senderId = [senderId copy];
|
||||
_senderDisplayName = [senderDisplayName copy];
|
||||
_date = [date copy];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSUInteger)messageHash
|
||||
{
|
||||
return self.date.hash ^ self.senderId.hash;
|
||||
}
|
||||
|
||||
- (BOOL)isMediaMessage
|
||||
{
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,32 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSDisplayedMessage.h"
|
||||
#import "TSMessageAdapter.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, OWSErrorMessageType) {
|
||||
OWSErrorMessageNoSession,
|
||||
OWSErrorMessageWrongTrustedIdentityKey,
|
||||
OWSErrorMessageInvalidKeyException,
|
||||
OWSErrorMessageMissingKeyId,
|
||||
OWSErrorMessageInvalidMessage,
|
||||
OWSErrorMessageDuplicateMessage,
|
||||
OWSErrorMessageInvalidVersion
|
||||
};
|
||||
|
||||
@interface OWSErrorMessage : OWSDisplayedMessage
|
||||
|
||||
@property (nonatomic) OWSErrorMessageType errorMessageType;
|
||||
@property (nonatomic) TSMessageAdapterType messageType;
|
||||
|
||||
#pragma mark - Initialization
|
||||
|
||||
- (instancetype)initWithErrorType:(OWSErrorMessageType)messageType
|
||||
senderId:(NSString *)senderId
|
||||
senderDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date;
|
||||
|
||||
- (NSString *)text;
|
||||
|
||||
@end
|
@ -0,0 +1,75 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
|
||||
#import "OWSErrorMessage.h"
|
||||
|
||||
@implementation OWSErrorMessage
|
||||
|
||||
- (instancetype)initWithErrorType:(OWSErrorMessageType)messageType
|
||||
senderId:(NSString *)senderId
|
||||
senderDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date
|
||||
{
|
||||
self = [super initWithSenderId:senderId senderDisplayName:senderDisplayName date:date];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_errorMessageType = messageType;
|
||||
_messageType = TSErrorMessageAdapter;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)text
|
||||
{
|
||||
switch (self.errorMessageType) {
|
||||
case OWSErrorMessageNoSession:
|
||||
return [NSString stringWithFormat:@"No session error"];
|
||||
break;
|
||||
case OWSErrorMessageWrongTrustedIdentityKey:
|
||||
return [NSString stringWithFormat:@"Error : Wrong trusted identity key for %@.", self.senderDisplayName];
|
||||
break;
|
||||
case OWSErrorMessageInvalidKeyException:
|
||||
return [NSString stringWithFormat:@"Error : Invalid key exception for %@.", self.senderDisplayName];
|
||||
break;
|
||||
case OWSErrorMessageMissingKeyId:
|
||||
return [NSString stringWithFormat:@"Error: Missing key identifier for %@", self.senderDisplayName];
|
||||
break;
|
||||
case OWSErrorMessageInvalidMessage:
|
||||
return [NSString stringWithFormat:@"Error: Invalid message"];
|
||||
break;
|
||||
case OWSErrorMessageDuplicateMessage:
|
||||
return [NSString stringWithFormat:@"Error: Duplicate message"];
|
||||
break;
|
||||
case OWSErrorMessageInvalidVersion:
|
||||
return [NSString stringWithFormat:@"Error: Invalid version for contact %@.", self.senderDisplayName];
|
||||
break;
|
||||
|
||||
default:
|
||||
return nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return self.senderId.hash ^ self.date.hash;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: senderId=%@, senderDisplayName=%@, date=%@, type=%ld>",
|
||||
[self class],
|
||||
self.senderId,
|
||||
self.senderDisplayName,
|
||||
self.date,
|
||||
self.errorMessageType];
|
||||
}
|
||||
|
||||
- (TSMessageAdapterType)messageType
|
||||
{
|
||||
return TSErrorMessageAdapter;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,26 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSDisplayedMessage.h"
|
||||
#import "TSMessageAdapter.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, OWSInfoMessageType) {
|
||||
OWSInfoMessageTypeSessionDidEnd,
|
||||
};
|
||||
|
||||
@interface OWSInfoMessage : OWSDisplayedMessage
|
||||
|
||||
@property (nonatomic) OWSInfoMessageType infoMessageType;
|
||||
@property (nonatomic) TSMessageAdapterType messageType;
|
||||
|
||||
#pragma mark - Initialization
|
||||
|
||||
- (instancetype)initWithInfoType:(OWSInfoMessageType)messageType
|
||||
senderId:(NSString *)senderId
|
||||
senderDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date;
|
||||
|
||||
- (NSString *)text;
|
||||
|
||||
@end
|
@ -0,0 +1,55 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSInfoMessage.h"
|
||||
|
||||
@implementation OWSInfoMessage
|
||||
|
||||
- (instancetype)initWithInfoType:(OWSInfoMessageType)messageType
|
||||
senderId:(NSString *)senderId
|
||||
senderDisplayName:(NSString *)senderDisplayName
|
||||
date:(NSDate *)date
|
||||
{
|
||||
//@discussion: NSParameterAssert() ?
|
||||
|
||||
self = [super initWithSenderId:senderId senderDisplayName:senderDisplayName date:date];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_infoMessageType = messageType;
|
||||
_messageType = TSInfoMessageAdapter;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSString *)text
|
||||
{
|
||||
switch (self.infoMessageType) {
|
||||
case OWSInfoMessageTypeSessionDidEnd:
|
||||
return [NSString stringWithFormat:@"Session with %@ ended.", self.senderDisplayName];
|
||||
break;
|
||||
|
||||
default:
|
||||
return nil;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
- (NSUInteger)hash
|
||||
{
|
||||
return self.senderId.hash ^ self.date.hash;
|
||||
}
|
||||
|
||||
- (NSString *)description
|
||||
{
|
||||
return [NSString stringWithFormat:@"<%@: senderId=%@, senderDisplayName=%@, date=%@, type=%ld>",
|
||||
[self class],
|
||||
self.senderId,
|
||||
self.senderDisplayName,
|
||||
self.date,
|
||||
self.infoMessageType];
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,7 @@
|
||||
// Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import <JSQMessagesViewController/JSQMessagesBubblesSizeCalculator.h>
|
||||
|
||||
@interface OWSMessagesBubblesSizeCalculator : JSQMessagesBubblesSizeCalculator
|
||||
|
||||
@end
|
@ -0,0 +1,36 @@
|
||||
// Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSMessagesBubblesSizeCalculator.h"
|
||||
#import "OWSDisplayedMessageCollectionViewCell.h"
|
||||
#import "TSMessageAdapter.h"
|
||||
|
||||
@implementation OWSMessagesBubblesSizeCalculator
|
||||
|
||||
/**
|
||||
* Computes and returns the size of the `messageBubbleImageView` property
|
||||
* of a `JSQMessagesCollectionViewCell` for the specified messageData at indexPath.
|
||||
*
|
||||
* @param messageData A message data object.
|
||||
* @param indexPath The index path at which messageData is located.
|
||||
* @param layout The layout object asking for this information.
|
||||
*
|
||||
* @return A sizes that specifies the required dimensions to display the entire message contents.
|
||||
* Note, this is *not* the entire cell, but only its message bubble.
|
||||
*/
|
||||
- (CGSize)messageBubbleSizeForMessageData:(id<JSQMessageData>)messageData
|
||||
atIndexPath:(NSIndexPath *)indexPath
|
||||
withLayout:(JSQMessagesCollectionViewFlowLayout *)layout
|
||||
{
|
||||
CGSize superSize = [super messageBubbleSizeForMessageData:messageData atIndexPath:indexPath withLayout:layout];
|
||||
|
||||
TSMessageAdapter *message = (TSMessageAdapter *)messageData;
|
||||
if (message.messageType == TSInfoMessageAdapter || message.messageType == TSErrorMessageAdapter) {
|
||||
|
||||
// Prevent cropping message text by accounting for message container/icon
|
||||
superSize.height = OWSDisplayedMessageCellHeight;
|
||||
}
|
||||
|
||||
return superSize;
|
||||
}
|
||||
|
||||
@end
|
@ -1,15 +0,0 @@
|
||||
//
|
||||
// UIButton+OWS.h
|
||||
// Signal
|
||||
//
|
||||
// Created by Christine Corbett Moran on 2/10/15.
|
||||
// Copyright (c) 2013 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface UIButton (OWS)
|
||||
|
||||
+ (UIButton *)ows_blueButtonWithTitle:(NSString *)title;
|
||||
|
||||
@end
|
@ -1,37 +0,0 @@
|
||||
//
|
||||
// UIButton+OWS.m
|
||||
// Signal
|
||||
//
|
||||
// Created by Christine Corbett Moran on 2/10/15.
|
||||
// Copyright (c) 2013 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "UIButton+OWS.h"
|
||||
#import "UIColor+OWS.h"
|
||||
#import "UIFont+OWS.h"
|
||||
@implementation UIButton (OWS)
|
||||
|
||||
+ (UIButton *)ows_blueButtonWithTitle:(NSString *)title {
|
||||
NSDictionary *buttonTextAttributes = @{
|
||||
NSFontAttributeName : [UIFont ows_regularFontWithSize:15.0f],
|
||||
NSForegroundColorAttributeName : [UIColor ows_materialBlueColor]
|
||||
};
|
||||
UIButton *button = [[UIButton alloc] init];
|
||||
NSMutableAttributedString *attributedTitle = [[NSMutableAttributedString alloc] initWithString:title];
|
||||
[attributedTitle setAttributes:buttonTextAttributes range:NSMakeRange(0, [attributedTitle length])];
|
||||
[button setAttributedTitle:attributedTitle forState:UIControlStateNormal];
|
||||
|
||||
NSDictionary *disabledAttributes = @{
|
||||
NSFontAttributeName : [UIFont ows_regularFontWithSize:15.0f],
|
||||
NSForegroundColorAttributeName : [UIColor ows_darkGrayColor]
|
||||
};
|
||||
NSMutableAttributedString *attributedTitleDisabled = [[NSMutableAttributedString alloc] initWithString:title];
|
||||
[attributedTitleDisabled setAttributes:disabledAttributes range:NSMakeRange(0, [attributedTitle length])];
|
||||
[button setAttributedTitle:attributedTitleDisabled forState:UIControlStateDisabled];
|
||||
|
||||
[button.titleLabel setTextAlignment:NSTextAlignmentCenter];
|
||||
|
||||
return button;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,18 @@
|
||||
// Created by Dylan Bourgeois on 20/11/14.
|
||||
// Portions Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <JSQMessagesViewController/JSQMessagesCollectionViewCell.h>
|
||||
|
||||
@interface OWSCallCollectionViewCell : JSQMessagesCollectionViewCell
|
||||
|
||||
@property (weak, nonatomic, readonly) JSQMessagesLabel *cellLabel;
|
||||
@property (weak, nonatomic, readonly) UIImageView *outgoingCallImageView;
|
||||
@property (weak, nonatomic, readonly) UIImageView *incomingCallImageView;
|
||||
|
||||
#pragma mark - Class methods
|
||||
|
||||
+ (UINib *)nib;
|
||||
+ (NSString *)cellReuseIdentifier;
|
||||
|
||||
@end
|
@ -0,0 +1,53 @@
|
||||
// Created by Dylan Bourgeois on 20/11/14.
|
||||
// Portions Copyright (c) 2014 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSCallCollectionViewCell.h"
|
||||
#import <JSQMessagesViewController/UIView+JSQMessages.h>
|
||||
|
||||
@interface OWSCallCollectionViewCell ()
|
||||
|
||||
@property (weak, nonatomic) IBOutlet JSQMessagesLabel *cellLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *outgoingCallImageView;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *incomingCallImageView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSCallCollectionViewCell
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass([self class]) bundle:[NSBundle mainBundle]];
|
||||
}
|
||||
|
||||
+ (NSString *)cellReuseIdentifier
|
||||
{
|
||||
return NSStringFromClass([self class]);
|
||||
}
|
||||
|
||||
#pragma mark - Initializer
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
|
||||
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
self.cellLabel.textAlignment = NSTextAlignmentCenter;
|
||||
self.cellLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14.0f];
|
||||
self.cellLabel.textColor = [UIColor lightGrayColor];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - Collection view cell
|
||||
|
||||
- (void)prepareForReuse
|
||||
{
|
||||
[super prepareForReuse];
|
||||
self.cellLabel.text = nil;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,61 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="Efo-Hk-7Hw" customClass="OWSCallCollectionViewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="20"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YEr-eC-P6i" customClass="JSQMessagesLabel">
|
||||
<rect key="frame" x="39" y="0.0" width="242" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="7nw-w2-91p"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="o2l-Ms-1mk">
|
||||
<rect key="frame" x="281" y="0.0" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="78L-mQ-gEo"/>
|
||||
<constraint firstAttribute="width" constant="20" id="olH-5o-XyR"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="H8m-r4-eEC">
|
||||
<rect key="frame" x="19" y="0.0" width="20" height="20"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="20" id="Qay-jM-aBk"/>
|
||||
<constraint firstAttribute="width" constant="20" id="RpE-jJ-cYX"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstItem="YEr-eC-P6i" firstAttribute="centerY" secondItem="o2l-Ms-1mk" secondAttribute="centerY" id="8wg-Tg-9Nh"/>
|
||||
<constraint firstAttribute="trailing" secondItem="YEr-eC-P6i" secondAttribute="trailing" constant="39" id="Hj7-z5-WMM"/>
|
||||
<constraint firstItem="YEr-eC-P6i" firstAttribute="leading" secondItem="H8m-r4-eEC" secondAttribute="trailing" id="ZZJ-jL-10d"/>
|
||||
<constraint firstItem="YEr-eC-P6i" firstAttribute="top" secondItem="Efo-Hk-7Hw" secondAttribute="top" id="rEI-cY-6lx"/>
|
||||
<constraint firstItem="YEr-eC-P6i" firstAttribute="leading" secondItem="Efo-Hk-7Hw" secondAttribute="leading" constant="39" id="uNd-aK-1hE"/>
|
||||
<constraint firstItem="YEr-eC-P6i" firstAttribute="centerY" secondItem="H8m-r4-eEC" secondAttribute="centerY" id="wg8-V9-pBf"/>
|
||||
<constraint firstItem="o2l-Ms-1mk" firstAttribute="leading" secondItem="YEr-eC-P6i" secondAttribute="trailing" id="wmR-MD-QeR"/>
|
||||
</constraints>
|
||||
<size key="customSize" width="320" height="20"/>
|
||||
<connections>
|
||||
<outlet property="cellLabel" destination="YEr-eC-P6i" id="jii-8O-zLL"/>
|
||||
<outlet property="incomingCallImageView" destination="H8m-r4-eEC" id="hVW-Ng-BnU"/>
|
||||
<outlet property="outgoingCallImageView" destination="o2l-Ms-1mk" id="Q5m-uX-80H"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="219" y="435"/>
|
||||
</collectionViewCell>
|
||||
</objects>
|
||||
</document>
|
@ -0,0 +1,16 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import <JSQMessagesViewController/JSQMessagesCollectionViewCell.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
static const CGFloat OWSDisplayedMessageCellHeight = 70.0f;
|
||||
|
||||
@interface OWSDisplayedMessageCollectionViewCell : JSQMessagesCollectionViewCell
|
||||
|
||||
@property (weak, nonatomic, readonly) JSQMessagesLabel *cellLabel;
|
||||
@property (weak, nonatomic, readonly) UIImageView *headerImageView;
|
||||
@property (strong, nonatomic, readonly) UIView *textContainer;
|
||||
|
||||
@end
|
@ -0,0 +1,58 @@
|
||||
// Created by Dylan Bourgeois on 29/11/14.
|
||||
// Copyright (c) 2014 Hexed Bits. All rights reserved.
|
||||
// Portions Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSDisplayedMessageCollectionViewCell.h"
|
||||
|
||||
#import <JSQMessagesViewController/UIView+JSQMessages.h>
|
||||
|
||||
@interface OWSDisplayedMessageCollectionViewCell ()
|
||||
|
||||
@property (weak, nonatomic) IBOutlet JSQMessagesLabel *cellLabel;
|
||||
@property (weak, nonatomic) IBOutlet UIImageView *headerImageView;
|
||||
@property (strong, nonatomic) IBOutlet UIView *textContainer;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSDisplayedMessageCollectionViewCell
|
||||
|
||||
#pragma mark - Class Methods
|
||||
|
||||
+ (UINib *)nib
|
||||
{
|
||||
return [UINib nibWithNibName:NSStringFromClass([self class]) bundle:[NSBundle mainBundle]];
|
||||
}
|
||||
|
||||
+ (NSString *)cellReuseIdentifier
|
||||
{
|
||||
return NSStringFromClass([self class]);
|
||||
}
|
||||
|
||||
#pragma mark - Initializer
|
||||
|
||||
- (void)awakeFromNib
|
||||
{
|
||||
[super awakeFromNib];
|
||||
|
||||
[self setTranslatesAutoresizingMaskIntoConstraints:NO];
|
||||
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
self.textContainer.layer.borderColor = [[UIColor lightGrayColor] CGColor];
|
||||
self.textContainer.layer.borderWidth = 0.75f;
|
||||
self.textContainer.layer.cornerRadius = 5.0f;
|
||||
self.cellLabel.textAlignment = NSTextAlignmentCenter;
|
||||
self.cellLabel.font = [UIFont fontWithName:@"HelveticaNeue-Light" size:14.0f];
|
||||
self.cellLabel.textColor = [UIColor lightGrayColor];
|
||||
}
|
||||
|
||||
#pragma mark - Collection view cell
|
||||
|
||||
- (void)prepareForReuse
|
||||
{
|
||||
[super prepareForReuse];
|
||||
|
||||
self.cellLabel.text = nil;
|
||||
}
|
||||
|
||||
@end
|
@ -0,0 +1,69 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
<capability name="Alignment constraints with different attributes" minToolsVersion="5.1"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<collectionViewCell opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" id="eMU-z2-CzM" customClass="OWSDisplayedMessageCollectionViewCell">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="70"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="70"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="qCf-bs-dBd" userLabel="textContainer">
|
||||
<rect key="frame" x="0.0" y="22" width="320" height="48"/>
|
||||
<subviews>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Info Message" textAlignment="center" lineBreakMode="wordWrap" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="OVa-Xw-5vl" customClass="JSQMessagesLabel">
|
||||
<rect key="frame" x="8" y="12" width="304" height="28"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" relation="greaterThanOrEqual" constant="14" id="fed-2c-dqd"/>
|
||||
</constraints>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<color key="textColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<constraints>
|
||||
<constraint firstItem="OVa-Xw-5vl" firstAttribute="leading" secondItem="qCf-bs-dBd" secondAttribute="leading" constant="8" id="2IE-8k-czI"/>
|
||||
<constraint firstAttribute="bottom" secondItem="OVa-Xw-5vl" secondAttribute="bottom" constant="8" id="MtI-jW-t1x"/>
|
||||
<constraint firstAttribute="trailing" secondItem="OVa-Xw-5vl" secondAttribute="trailing" constant="8" id="Y8z-8G-PLt"/>
|
||||
<constraint firstItem="OVa-Xw-5vl" firstAttribute="top" secondItem="qCf-bs-dBd" secondAttribute="top" constant="12" id="v5B-tB-pOB"/>
|
||||
</constraints>
|
||||
</view>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="warning_white.png" translatesAutoresizingMaskIntoConstraints="NO" id="ePO-Cy-jUE">
|
||||
<rect key="frame" x="143" y="0.0" width="35" height="35"/>
|
||||
<constraints>
|
||||
<constraint firstAttribute="height" constant="35" id="Llx-81-oyV"/>
|
||||
<constraint firstAttribute="width" constant="35" id="Nth-3D-Wo9"/>
|
||||
</constraints>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<constraints>
|
||||
<constraint firstItem="ePO-Cy-jUE" firstAttribute="top" secondItem="eMU-z2-CzM" secondAttribute="top" id="D28-BQ-Qam"/>
|
||||
<constraint firstAttribute="trailing" secondItem="qCf-bs-dBd" secondAttribute="trailing" id="F3T-1l-nCg"/>
|
||||
<constraint firstItem="qCf-bs-dBd" firstAttribute="leading" secondItem="eMU-z2-CzM" secondAttribute="leading" id="OzF-VM-85V"/>
|
||||
<constraint firstAttribute="bottom" secondItem="qCf-bs-dBd" secondAttribute="bottom" id="PNq-zm-usq"/>
|
||||
<constraint firstItem="qCf-bs-dBd" firstAttribute="top" secondItem="ePO-Cy-jUE" secondAttribute="centerY" constant="4" id="UzU-DS-8WZ"/>
|
||||
<constraint firstItem="ePO-Cy-jUE" firstAttribute="centerX" secondItem="eMU-z2-CzM" secondAttribute="centerX" id="qtQ-mS-o6z"/>
|
||||
</constraints>
|
||||
<size key="customSize" width="320" height="55"/>
|
||||
<connections>
|
||||
<outlet property="cellLabel" destination="OVa-Xw-5vl" id="7PC-oj-dQZ"/>
|
||||
<outlet property="headerImageView" destination="ePO-Cy-jUE" id="4uq-2C-V7U"/>
|
||||
<outlet property="textContainer" destination="qCf-bs-dBd" id="fL7-LO-El1"/>
|
||||
</connections>
|
||||
<point key="canvasLocation" x="219" y="433"/>
|
||||
</collectionViewCell>
|
||||
</objects>
|
||||
<resources>
|
||||
<image name="warning_white.png" width="100" height="100"/>
|
||||
</resources>
|
||||
</document>
|
Loading…
Reference in New Issue