Rework and unify the system messages.

// FREEBIE
pull/1/head
Matthew Chen 7 years ago
parent f5caf37042
commit 2cbf1e1d05

@ -12,6 +12,7 @@
3400C7991EAFB772008A8584 /* ThreadViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 3400C7981EAFB772008A8584 /* ThreadViewHelper.m */; };
340CB2241EAC155C0001CAA1 /* ContactsViewHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 340CB2231EAC155C0001CAA1 /* ContactsViewHelper.m */; };
340CB2271EAC25820001CAA1 /* UpdateGroupViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */; };
341207271EE19F6A00463194 /* OWSSystemMessageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 341207261EE19F6A00463194 /* OWSSystemMessageCell.m */; };
341BB7491DB727EE001E2975 /* JSQMediaItem+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 341BB7481DB727EE001E2975 /* JSQMediaItem+OWS.m */; };
34330A5A1E7875FB00DF2FB9 /* fontawesome-webfont.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */; };
34330A5C1E787A9800DF2FB9 /* dripicons-v2.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 34330A5B1E787A9800DF2FB9 /* dripicons-v2.ttf */; };
@ -377,6 +378,8 @@
340CB2231EAC155C0001CAA1 /* ContactsViewHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ContactsViewHelper.m; sourceTree = "<group>"; };
340CB2251EAC25820001CAA1 /* UpdateGroupViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UpdateGroupViewController.h; sourceTree = "<group>"; };
340CB2261EAC25820001CAA1 /* UpdateGroupViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UpdateGroupViewController.m; sourceTree = "<group>"; };
341207251EE19F6A00463194 /* OWSSystemMessageCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSSystemMessageCell.h; sourceTree = "<group>"; };
341207261EE19F6A00463194 /* OWSSystemMessageCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSSystemMessageCell.m; sourceTree = "<group>"; };
341BB7471DB727EE001E2975 /* JSQMediaItem+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JSQMediaItem+OWS.h"; sourceTree = "<group>"; };
341BB7481DB727EE001E2975 /* JSQMediaItem+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "JSQMediaItem+OWS.m"; sourceTree = "<group>"; };
34330A591E7875FB00DF2FB9 /* fontawesome-webfont.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = "fontawesome-webfont.ttf"; sourceTree = "<group>"; };
@ -1390,6 +1393,8 @@
45F2B1961D9CA207000D2C69 /* OWSOutgoingMessageCollectionViewCell.xib */,
34330AA11E79686200DF2FB9 /* OWSProgressView.h */,
34330AA21E79686200DF2FB9 /* OWSProgressView.m */,
341207251EE19F6A00463194 /* OWSSystemMessageCell.h */,
341207261EE19F6A00463194 /* OWSSystemMessageCell.m */,
34F3089D1ECA580B00BB7697 /* OWSUnreadIndicatorCell.h */,
34F3089E1ECA580B00BB7697 /* OWSUnreadIndicatorCell.m */,
45A6DAD51EBBF85500893231 /* ReminderView.swift */,
@ -2208,6 +2213,7 @@
FCC81A981A44558300DFEC7D /* UIDevice+TSHardwareVersion.m in Sources */,
3400C7991EAFB772008A8584 /* ThreadViewHelper.m in Sources */,
76EB054018170B33006006FC /* AppDelegate.m in Sources */,
341207271EE19F6A00463194 /* OWSSystemMessageCell.m in Sources */,
341BB7491DB727EE001E2975 /* JSQMediaItem+OWS.m in Sources */,
34B3F89C1E8DF3270035BE1A /* BlockListViewController.m in Sources */,
45F2B1941D9C9F48000D2C69 /* OWSOutgoingMessageCollectionViewCell.m in Sources */,

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "system_message_security@1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "system_message_security@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "system_message_security@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

@ -5,6 +5,7 @@
#import "OWSMessagesBubblesSizeCalculator.h"
#import "OWSCall.h"
#import "OWSDisplayedMessageCollectionViewCell.h"
#import "OWSSystemMessageCell.h"
#import "OWSUnreadIndicatorCell.h"
#import "TSGenericAttachmentAdapter.h"
#import "TSMessageAdapter.h"
@ -50,13 +51,15 @@ NS_ASSUME_NONNULL_BEGIN
{
if ([messageData isKindOfClass:[TSMessageAdapter class]]) {
TSMessageAdapter *message = (TSMessageAdapter *)messageData;
if (message.messageType == TSInfoMessageAdapter || message.messageType == TSErrorMessageAdapter) {
if (message.messageType == TSErrorMessageAdapter) {
return [OWSSystemMessageCell cellSizeForInteraction:((TSMessageAdapter *)messageData).interaction
collectionViewWidth:layout.collectionView.bounds.size.width];
} else if (message.messageType == TSInfoMessageAdapter || message.messageType == TSErrorMessageAdapter) {
return [self messageBubbleSizeForInfoMessageData:messageData atIndexPath:indexPath withLayout:layout];
} else if (message.messageType == TSUnreadIndicatorAdapter) {
return [OWSUnreadIndicatorCell
cellSizeForInteraction:(TSUnreadIndicatorInteraction *)((TSMessageAdapter *)messageData).interaction
collectionViewWidth:layout.collectionView.bounds.size.width];
return [self messageBubbleSizeForInfoMessageData:messageData atIndexPath:indexPath withLayout:layout];
}
}

@ -30,6 +30,7 @@
#import "OWSMessagesInputToolbar.h"
#import "OWSMessagesToolbarContentView.h"
#import "OWSOutgoingMessageCollectionViewCell.h"
#import "OWSSystemMessageCell.h"
#import "OWSUnreadIndicatorCell.h"
#import "PropertyListPreferences.h"
#import "Signal-Swift.h"
@ -423,6 +424,9 @@ typedef enum : NSUInteger {
[self.collectionView registerNib:[OWSCallCollectionViewCell nib]
forCellWithReuseIdentifier:[OWSCallCollectionViewCell cellReuseIdentifier]];
[self.collectionView registerClass:[OWSSystemMessageCell class]
forCellWithReuseIdentifier:[OWSSystemMessageCell cellReuseIdentifier]];
[self.collectionView registerClass:[OWSUnreadIndicatorCell class]
forCellWithReuseIdentifier:[OWSUnreadIndicatorCell cellReuseIdentifier]];
@ -1465,7 +1469,7 @@ typedef enum : NSUInteger {
break;
}
case TSErrorMessageAdapter: {
cell = [self loadErrorMessageCellForMessage:(TSMessageAdapter *)message atIndexPath:indexPath];
cell = [self loadErrorMessageCell:indexPath interaction:message.interaction];
break;
}
case TSIncomingMessageAdapter: {
@ -1647,21 +1651,36 @@ typedef enum : NSUInteger {
return infoCell;
}
- (OWSDisplayedMessageCollectionViewCell *)loadErrorMessageCellForMessage:(TSMessageAdapter *)errorMessage
atIndexPath:(NSIndexPath *)indexPath
- (OWSSystemMessageCell *)loadErrorMessageCell:(NSIndexPath *)indexPath interaction:(TSInteraction *)interaction
// ForMessage:(TSMessageAdapter *)errorMessage
// atIndexPath:(NSIndexPath *)indexPath
{
OWSDisplayedMessageCollectionViewCell *errorCell =
[self loadDisplayedMessageCollectionViewCellForIndexPath:indexPath];
errorCell.textView.text = [errorMessage text];
OWSAssert(indexPath);
OWSAssert(interaction);
// OWSAssert([interaction isKindOfClass:[TSUnreadIndicatorInteraction class]]);
// Disable text selectability. Specifying this in prepareForReuse/awakeFromNib was not sufficient.
errorCell.textView.userInteractionEnabled = NO;
errorCell.textView.selectable = NO;
// TSUnreadIndicatorInteraction *unreadIndicator = (TSUnreadIndicatorInteraction *)interaction;
OWSSystemMessageCell *cell =
[self.collectionView dequeueReusableCellWithReuseIdentifier:[OWSSystemMessageCell cellReuseIdentifier]
forIndexPath:indexPath];
cell.interaction = interaction;
[cell configure];
errorCell.messageBubbleContainerView.layer.borderColor = [[UIColor ows_errorMessageBorderColor] CGColor];
errorCell.headerImageView.image = [UIImage imageNamed:@"error_white"];
return cell;
return errorCell;
// OWSDisplayedMessageCollectionViewCell *errorCell =
// [self loadDisplayedMessageCollectionViewCellForIndexPath:indexPath];
// errorCell.textView.text = [errorMessage text];
//
// // Disable text selectability. Specifying this in prepareForReuse/awakeFromNib was not sufficient.
// errorCell.textView.userInteractionEnabled = NO;
// errorCell.textView.selectable = NO;
//
// errorCell.messageBubbleContainerView.layer.borderColor = [[UIColor ows_errorMessageBorderColor] CGColor];
// errorCell.headerImageView.image = [UIImage imageNamed:@"error_white"];
//
// return errorCell;
}
#pragma mark - Adjusting cell label heights
@ -3908,8 +3927,10 @@ typedef enum : NSUInteger {
- (BOOL)isSpecialItemAtIndexPath:(NSIndexPath *)indexPath
{
// TODO:
TSInteraction *interaction = [self interactionAtIndexPath:indexPath];
return [interaction isKindOfClass:[TSUnreadIndicatorInteraction class]];
return ([interaction isKindOfClass:[TSUnreadIndicatorInteraction class]] ||
[interaction isKindOfClass:[TSErrorMessage class]]);
}
#pragma mark - Class methods

@ -7,6 +7,11 @@
#import "Signal-Swift.h"
#import "ThreadUtil.h"
#import <AFNetworking/AFNetworking.h>
#import <AxolotlKit/PreKeyBundle.h>
#import <SignalServiceKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalServiceKit/TSCall.h>
#import <SignalServiceKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
#import <SignalServiceKit/TSStorageManager+SessionStore.h>
#import <SignalServiceKit/TSThread.h>
@ -35,6 +40,10 @@ NS_ASSUME_NONNULL_BEGIN
return [OWSTableSection
sectionWithTitle:@"Messages"
items:@[
[OWSTableItem itemWithTitle:@"Create all system messages"
actionBlock:^{
[DebugUIMessages createSystemMessagesInThread:thread];
}],
[OWSTableItem itemWithTitle:@"Send 10 messages (1/sec.)"
actionBlock:^{
[DebugUIMessages sendTextMessage:10 thread:thread];
@ -492,6 +501,147 @@ NS_ASSUME_NONNULL_BEGIN
[ThreadUtil sendMessageWithAttachment:attachment inThread:thread messageSender:messageSender];
}
+ (OWSSignalServiceProtosEnvelope *)createEnvelopeForThread:(TSThread *)thread
{
OWSAssert(thread);
OWSSignalServiceProtosEnvelopeBuilder *builder = [OWSSignalServiceProtosEnvelopeBuilder new];
if ([thread isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *gThread = (TSGroupThread *)thread;
[builder setSource:gThread.groupModel.groupMemberIds[0]];
} else if ([thread isKindOfClass:[TSContactThread class]]) {
TSContactThread *contactThread = (TSContactThread *)thread;
[builder setSource:contactThread.contactIdentifier];
}
return [builder build];
}
+ (void)createSystemMessagesInThread:(TSThread *)thread
{
OWSAssert(thread);
[[TSStorageManager sharedManager].dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
if ([thread isKindOfClass:[TSContactThread class]]) {
TSContactThread *contactThread = (TSContactThread *)thread;
[[[TSCall alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
withCallNumber:@"+19174054215"
callType:RPRecentCallTypeIncoming
inThread:contactThread] saveWithTransaction:transaction];
[[[TSCall alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
withCallNumber:@"+19174054215"
callType:RPRecentCallTypeOutgoing
inThread:contactThread] saveWithTransaction:transaction];
[[[TSCall alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
withCallNumber:@"+19174054215"
callType:RPRecentCallTypeMissed
inThread:contactThread] saveWithTransaction:transaction];
[[[TSCall alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
withCallNumber:@"+19174054215"
callType:RPRecentCallTypeOutgoingIncomplete
inThread:contactThread] saveWithTransaction:transaction];
[[[TSCall alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
withCallNumber:@"+19174054215"
callType:RPRecentCallTypeIncomingIncomplete
inThread:contactThread] saveWithTransaction:transaction];
}
{
NSNumber *durationSeconds = [OWSDisappearingMessagesConfiguration validDurationsSeconds][0];
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
[[OWSDisappearingMessagesConfiguration alloc] initWithThreadId:thread.uniqueId
enabled:YES
durationSeconds:(uint32_t)[durationSeconds intValue]];
[[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"]
saveWithTransaction:transaction];
}
{
NSNumber *durationSeconds = [[OWSDisappearingMessagesConfiguration validDurationsSeconds] lastObject];
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
[[OWSDisappearingMessagesConfiguration alloc] initWithThreadId:thread.uniqueId
enabled:YES
durationSeconds:(uint32_t)[durationSeconds intValue]];
[[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"]
saveWithTransaction:transaction];
}
{
OWSDisappearingMessagesConfiguration *disappearingMessagesConfiguration =
[[OWSDisappearingMessagesConfiguration alloc] initWithThreadId:thread.uniqueId
enabled:NO
durationSeconds:0];
[[[OWSDisappearingConfigurationUpdateInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
thread:thread
configuration:disappearingMessagesConfiguration
createdByRemoteName:@"Alice"]
saveWithTransaction:transaction];
}
[[TSInfoMessage userNotRegisteredMessageInThread:thread] saveWithTransaction:transaction];
[[[TSInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageType:TSInfoMessageTypeSessionDidEnd] saveWithTransaction:transaction];
// TODO: customMessage?
[[[TSInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageType:TSInfoMessageTypeGroupUpdate] saveWithTransaction:transaction];
// TODO: customMessage?
[[[TSInfoMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageType:TSInfoMessageTypeGroupQuit] saveWithTransaction:transaction];
[[TSErrorMessage missingSessionWithEnvelope:[self createEnvelopeForThread:thread] withTransaction:transaction]
saveWithTransaction:transaction];
[[TSErrorMessage invalidKeyExceptionWithEnvelope:[self createEnvelopeForThread:thread]
withTransaction:transaction] saveWithTransaction:transaction];
[[TSErrorMessage invalidVersionWithEnvelope:[self createEnvelopeForThread:thread] withTransaction:transaction]
saveWithTransaction:transaction];
[[TSInvalidIdentityKeyReceivingErrorMessage untrustedKeyWithEnvelope:[self createEnvelopeForThread:thread]
withTransaction:transaction]
saveWithTransaction:transaction];
[[TSErrorMessage corruptedMessageWithEnvelope:[self createEnvelopeForThread:thread] withTransaction:transaction]
saveWithTransaction:transaction];
[[[TSErrorMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
failedMessageType:TSErrorMessageNonBlockingIdentityChange
recipientId:@"+19174054215"] saveWithTransaction:transaction];
}];
{
OWSDisappearingMessagesConfiguration *configuration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
TSOutgoingMessage *outgoingMessage =
[[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageBody:@"hi"
attachmentIds:[NSMutableArray new]
expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)];
PreKeyBundle *preKeyBundle = [[PreKeyBundle alloc] initWithRegistrationId:0
deviceId:0
preKeyId:0
preKeyPublic:[self createRandomNSDataOfSize:16]
signedPreKeyPublic:[self createRandomNSDataOfSize:16]
signedPreKeyId:0
signedPreKeySignature:[self createRandomNSDataOfSize:16]
identityKey:[self createRandomNSDataOfSize:16]];
[[TSInvalidIdentityKeySendingErrorMessage untrustedKeyWithOutgoingMessage:outgoingMessage
inThread:thread
forRecipient:@"+19174054215"
preKeyBundle:preKeyBundle] save];
}
}
@end
NS_ASSUME_NONNULL_END

@ -28,15 +28,38 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Factory Methods
- (void)pushPageWithSection:(OWSTableSection *)section
{
DebugUITableViewController *viewController = [DebugUITableViewController new];
OWSTableContents *contents = [OWSTableContents new];
contents.title = section.headerTitle;
[contents addSection:section];
viewController.contents = contents;
[self.navigationController pushViewController:viewController animated:YES];
}
+ (void)presentDebugUIForThread:(TSThread *)thread fromViewController:(UIViewController *)fromViewController
{
OWSAssert(thread);
OWSAssert(fromViewController);
DebugUITableViewController *viewController = [DebugUITableViewController new];
__weak DebugUITableViewController *weakSelf = viewController;
OWSTableContents *contents = [OWSTableContents new];
contents.title = @"Debug: Conversation";
[contents addSection:[DebugUIMessages sectionForThread:thread]];
[contents
addSection:[OWSTableSection
sectionWithTitle:[DebugUIMessages sectionForThread:thread].headerTitle
items:@[
[OWSTableItem
disclosureItemWithText:[DebugUIMessages sectionForThread:thread].headerTitle
actionBlock:^{
[weakSelf pushPageWithSection:[DebugUIMessages
sectionForThread:thread]];
}],
]]];
[contents
addSection:[OWSTableSection
@ -129,7 +152,6 @@ NS_ASSUME_NONNULL_BEGIN
}],
]]];
DebugUITableViewController *viewController = [DebugUITableViewController new];
viewController.contents = contents;
[viewController presentFromViewController:fromViewController];
}

@ -153,6 +153,13 @@
#pragma mark - Signal Messages
- (void)notifyUserForErrorMessage:(TSErrorMessage *)message inThread:(TSThread *)thread {
OWSAssert(message);
OWSAssert(thread);
if (thread.isMuted) {
return;
}
NSString *messageDescription = message.description;
if (([UIApplication sharedApplication].applicationState != UIApplicationStateActive) && messageDescription) {
@ -186,6 +193,10 @@
inThread:(TSThread *)thread
contactsManager:(id<ContactsManagerProtocol>)contactsManager
{
OWSAssert(message);
OWSAssert(thread);
OWSAssert(contactsManager);
if (thread.isMuted) {
return;
}

@ -0,0 +1,18 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import <JSQMessagesViewController/JSQMessagesCollectionViewCell.h>
#import <UIKit/UIKit.h>
@class TSInteraction;
@interface OWSSystemMessageCell : JSQMessagesCollectionViewCell
@property (nonatomic) TSInteraction *interaction;
- (void)configure;
+ (CGSize)cellSizeForInteraction:(TSInteraction *)interaction collectionViewWidth:(CGFloat)collectionViewWidth;
@end

@ -0,0 +1,292 @@
//
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "OWSSystemMessageCell.h"
#import "NSBundle+JSQMessages.h"
#import "TSUnreadIndicatorInteraction.h"
#import "UIColor+OWS.h"
#import "UIFont+OWS.h"
#import "UIView+OWS.h"
#import <JSQMessagesViewController/UIView+JSQMessages.h>
#import <SignalServiceKit/TSErrorMessage.h>
@interface OWSSystemMessageCell ()
//@property (nonatomic) UIView *bannerView;
//@property (nonatomic) UIView *bannerTopHighlightView;
//@property (nonatomic) UIView *bannerBottomHighlightView1;
//@property (nonatomic) UIView *bannerBottomHighlightView2;
@property (nonatomic) UIImageView *imageView;
@property (nonatomic) UILabel *titleLabel;
//@property (nonatomic) UILabel *subtitleLabel;
@end
#pragma mark -
@implementation OWSSystemMessageCell
+ (NSString *)cellReuseIdentifier
{
return NSStringFromClass([self class]);
}
- (void)configure
{
self.backgroundColor = [UIColor whiteColor];
if (!self.titleLabel) {
// self.bannerView = [UIView new];
// self.bannerView.backgroundColor = [UIColor colorWithRGBHex:0xf6eee3];
// [self.contentView addSubview:self.bannerView];
//
// self.bannerTopHighlightView = [UIView new];
// self.bannerTopHighlightView.backgroundColor = [UIColor colorWithRGBHex:0xf9f3eb];
// [self.bannerView addSubview:self.bannerTopHighlightView];
//
// self.bannerBottomHighlightView1 = [UIView new];
// self.bannerBottomHighlightView1.backgroundColor = [UIColor colorWithRGBHex:0xd1c6b8];
// [self.bannerView addSubview:self.bannerBottomHighlightView1];
//
// self.bannerBottomHighlightView2 = [UIView new];
// self.bannerBottomHighlightView2.backgroundColor = [UIColor colorWithRGBHex:0xdbcfc0];
// [self.bannerView addSubview:self.bannerBottomHighlightView2];
self.imageView = [UIImageView new];
[self.contentView addSubview:self.imageView];
self.titleLabel = [UILabel new];
self.titleLabel.textColor = [UIColor colorWithRGBHex:0x403e3b];
self.titleLabel.font = [OWSSystemMessageCell titleFont];
self.titleLabel.numberOfLines = 0;
self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
[self.contentView addSubview:self.titleLabel];
// self.subtitleLabel = [UILabel new];
// self.subtitleLabel.text = [OWSSystemMessageCell subtitleForInteraction:self.interaction];
// self.subtitleLabel.textColor = [UIColor ows_infoMessageBorderColor];
// self.subtitleLabel.font = [OWSSystemMessageCell subtitleFont];
// self.subtitleLabel.numberOfLines = 0;
// self.subtitleLabel.lineBreakMode = NSLineBreakByWordWrapping;
// self.subtitleLabel.textAlignment = NSTextAlignmentCenter;
// [self.contentView addSubview:self.subtitleLabel];
}
// [self.imageView addRedBorder];
// [self addRedBorder];
UIColor *contentColor = [UIColor ows_darkGrayColor];
UIImage *icon = [self iconForInteraction:self.interaction];
self.imageView.image = [icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
// self.imageView.tintColor = [UIColor colorWithRGBHex:0x505050];
self.imageView.tintColor = contentColor;
// self.imageView.image = [OWSSystemMessageCell iconForInteraction:self.interaction];
self.titleLabel.text = [OWSSystemMessageCell titleForInteraction:self.interaction];
self.titleLabel.textColor = contentColor;
[self setNeedsLayout];
}
- (UIImage *)iconForInteraction:(TSInteraction *)interaction
{
UIImage *result = nil;
if ([interaction isKindOfClass:[TSErrorMessage class]]) {
// TODO:
result = [UIImage imageNamed:@"system_message_security"];
} else {
OWSFail(@"Unknown interaction type");
return nil;
}
OWSAssert(result);
return result;
// return NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR", @"Indicator that separates read from unread
// messages.")
// .uppercaseString;
}
+ (NSString *)titleForInteraction:(TSInteraction *)interaction
{
if ([interaction isKindOfClass:[TSErrorMessage class]]) {
// TODO: Should we move the copy generation into this view?
return interaction.description;
} else {
OWSFail(@"Unknown interaction type");
return nil;
}
// return NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR", @"Indicator that separates read from unread
// messages.")
// .uppercaseString;
}
+ (UIFont *)titleFont
{
return [UIFont ows_regularFontWithSize:13.f];
}
//+ (UIFont *)subtitleFont
//{
// return [UIFont ows_regularFontWithSize:12.f];
//}
//+ (NSString *)subtitleForInteraction:(TSUnreadIndicatorInteraction *)interaction
//{
// if (!interaction.hasMoreUnseenMessages) {
// return nil;
// }
// NSString *subtitleFormat = (interaction.missingUnseenSafetyNumberChangeCount > 0
// ? NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_FORMAT",
// @"Messages that indicates that there are more unseen messages that be revealed by tapping the 'load
// "
// @"earlier messages' button. Embeds {{the name of the 'load earlier messages' button}}")
// : NSLocalizedString(
// @"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES_FORMAT",
// @"Messages that indicates that there are more unseen messages including safety number changes that "
// @"be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier
// "
// @"messages' button}}."));
// NSString *loadMoreButtonName = [NSBundle jsq_localizedStringForKey:@"load_earlier_messages"];
// return [NSString stringWithFormat:subtitleFormat, loadMoreButtonName];
//}
//+ (CGFloat)subtitleHMargin
//{
// return 20.f;
//}
//
//+ (CGFloat)subtitleVSpacing
//{
// return 3.f;
//}
//
//+ (CGFloat)titleInnerHMargin
//{
// return 10.f;
//}
//
//+ (CGFloat)titleVMargin
//{
// return 5.5f;
//}
+ (CGFloat)hMargin
{
return 30.f;
}
+ (CGFloat)topVMargin
{
return 5.f;
}
+ (CGFloat)bottomVMargin
{
return 5.f;
}
+ (CGFloat)hSpacing
{
return 10.f;
}
+ (CGFloat)iconSize
{
return 30.f;
}
- (void)layoutSubviews
{
[super layoutSubviews];
// [self.titleLabel sizeToFit];
//
// // It's a bit of a hack, but we use a view that extends _outside_ the cell's bounds
// // to draw its background, since we want the background to extend to the edges of the
// // collection view.
// //
// // This layout logic assumes that the cell insets are symmetrical and can be deduced
// // from the cell frame.
// CGRect bannerViewFrame = CGRectMake(-self.left,
// round(OWSSystemMessageCell.topVMargin),
// round(self.width + self.left * 2.f),
// round(self.titleLabel.height + OWSSystemMessageCell.titleVMargin * 2.f));
// self.bannerView.frame = [self convertRect:bannerViewFrame toView:self.contentView];
//
// // The highlights should be 1px (not 1pt), so adapt their thickness to
// // the device resolution.
// CGFloat kHighlightThickness = 1.f / [UIScreen mainScreen].scale;
// self.bannerTopHighlightView.frame = CGRectMake(0, 0, self.bannerView.width, kHighlightThickness);
// self.bannerBottomHighlightView1.frame
// = CGRectMake(0, self.bannerView.height - kHighlightThickness * 2.f, self.bannerView.width,
// kHighlightThickness);
// self.bannerBottomHighlightView2.frame
// = CGRectMake(0, self.bannerView.height - kHighlightThickness * 1.f, self.bannerView.width,
// kHighlightThickness);
//
// [self.titleLabel centerOnSuperview];
CGFloat maxTitleWidth = (self.contentView.width
- ([OWSSystemMessageCell hMargin] * 2.f + [OWSSystemMessageCell hSpacing] + [OWSSystemMessageCell iconSize]));
CGSize titleSize = [self.titleLabel sizeThatFits:CGSizeMake(maxTitleWidth, CGFLOAT_MAX)];
// CGFloat contentWidth = ceil([OWSSystemMessageCell iconSize] +
// [OWSSystemMessageCell hSpacing] +
// titleSize.width);
// self.imageView.frame = CGRectMake(round((self.contentView.width - contentWidth) * 0.5f),
self.imageView.frame = CGRectMake(round([OWSSystemMessageCell hMargin]),
round((self.contentView.height - [OWSSystemMessageCell iconSize]) * 0.5f),
[OWSSystemMessageCell iconSize],
[OWSSystemMessageCell iconSize]);
self.titleLabel.frame = CGRectMake(round(self.imageView.right + [OWSSystemMessageCell hSpacing]),
round((self.contentView.height - titleSize.height) * 0.5f),
ceil(titleSize.width + 1.f),
ceil(titleSize.height + 1.f));
// [self.titleLabel addRedBorder];
// if (self.subtitleLabel.text.length > 0) {
// CGSize subtitleSize = [self.subtitleLabel
// sizeThatFits:CGSizeMake(
// self.contentView.width - [OWSSystemMessageCell subtitleHMargin] * 2.f, CGFLOAT_MAX)];
// self.subtitleLabel.frame = CGRectMake(round((self.contentView.width - subtitleSize.width) * 0.5f),
// round(self.bannerView.bottom + OWSSystemMessageCell.subtitleVSpacing),
// ceil(subtitleSize.width),
// ceil(subtitleSize.height));
// }
}
+ (CGSize)cellSizeForInteraction:(TSInteraction *)interaction collectionViewWidth:(CGFloat)collectionViewWidth
{
CGSize result = CGSizeMake(collectionViewWidth, 0);
// result.height += self.titleVMargin * 2.f;
result.height += self.topVMargin;
result.height += self.bottomVMargin;
NSString *title = [self titleForInteraction:interaction];
// NSString *subtitle = [self subtitleForInteraction:interaction];
// Creating a UILabel to measure the layout is expensive, but it's the only
// reliable way to do it. Unread indicators should be rare, so this is acceptable.
UILabel *label = [UILabel new];
label.font = [self titleFont];
label.text = title;
label.numberOfLines = 0;
label.lineBreakMode = NSLineBreakByWordWrapping;
CGFloat maxTitleWidth = (collectionViewWidth - ([self hMargin] * 2.f + [self hSpacing] + [self iconSize]));
CGSize titleSize = [label sizeThatFits:CGSizeMake(maxTitleWidth, CGFLOAT_MAX)];
CGFloat contentHeight = ceil(MAX([self iconSize], titleSize.height));
result.height += contentHeight;
// if (subtitle.length > 0) {
// result.height += self.subtitleVSpacing;
//
// label.font = [self subtitleFont];
// label.text = subtitle;
// // The subtitle may wrap to a second line.
// label.lineBreakMode = NSLineBreakByWordWrapping;
// label.numberOfLines = 0;
// result.height += ceil(
// [label sizeThatFits:CGSizeMake(collectionViewWidth - self.subtitleHMargin * 2.f,
// CGFLOAT_MAX)].height);
// }
return result;
}
@end

@ -2,11 +2,11 @@
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
//
#import "TSMessage.h"
#import <SignalServiceKit/TSInteraction.h>
NS_ASSUME_NONNULL_BEGIN
@interface TSUnreadIndicatorInteraction : TSMessage
@interface TSUnreadIndicatorInteraction : TSInteraction
@property (atomic, readonly) BOOL hasMoreUnseenMessages;

@ -14,6 +14,7 @@ NS_ASSUME_NONNULL_BEGIN
@end
#pragma mark -
@implementation TSUnreadIndicatorInteraction
@ -27,12 +28,7 @@ NS_ASSUME_NONNULL_BEGIN
hasMoreUnseenMessages:(BOOL)hasMoreUnseenMessages
missingUnseenSafetyNumberChangeCount:(NSUInteger)missingUnseenSafetyNumberChangeCount
{
self = [super initWithTimestamp:timestamp
inThread:thread
messageBody:nil
attachmentIds:@[]
expiresInSeconds:0
expireStartedAt:0];
self = [super initWithTimestamp:timestamp inThread:thread];
if (!self) {
return self;

Loading…
Cancel
Save