Cache system message text.

pull/1/head
Matthew Chen 7 years ago
parent fe492b8a98
commit 0ac1cb1e72

@ -18,7 +18,6 @@ NS_ASSUME_NONNULL_BEGIN
@class TSMessage;
@class TSOutgoingMessage;
@class TSQuotedMessage;
@class YapDatabaseReadTransaction;
@protocol ConversationViewCellDelegate <NSObject>
@ -85,9 +84,9 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, nullable) ConversationStyle *conversationStyle;
- (void)loadForDisplayWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (void)loadForDisplay;
- (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (CGSize)cellSize;
@end

@ -19,12 +19,12 @@ NS_ASSUME_NONNULL_BEGIN
self.conversationStyle = nil;
}
- (void)loadForDisplayWithTransaction:(YapDatabaseReadTransaction *)transaction
- (void)loadForDisplay
{
OWS_ABSTRACT_METHOD();
}
- (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction
- (CGSize)cellSize
{
OWS_ABSTRACT_METHOD();

@ -108,7 +108,7 @@ NS_ASSUME_NONNULL_BEGIN
return NSStringFromClass([self class]);
}
- (void)loadForDisplayWithTransaction:(YapDatabaseReadTransaction *)transaction
- (void)loadForDisplay
{
OWSAssert(self.conversationStyle);
OWSAssert(self.conversationStyle.viewWidth > 0);
@ -173,7 +173,7 @@ NS_ASSUME_NONNULL_BEGIN
return (24.f + self.addToContactsButton.titleLabel.font.lineHeight);
}
- (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction
- (CGSize)cellSize
{
OWSAssert(self.conversationStyle);
OWSAssert(self.conversationStyle.viewWidth > 0);

@ -124,7 +124,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Load
- (void)loadForDisplayWithTransaction:(YapDatabaseReadTransaction *)transaction
- (void)loadForDisplay
{
OWSAssert(self.conversationStyle);
OWSAssert(self.viewItem);
@ -320,7 +320,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Measurement
- (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction
- (CGSize)cellSize
{
OWSAssert(self.conversationStyle);
OWSAssert(self.conversationStyle.viewWidth > 0);

@ -161,11 +161,10 @@ typedef void (^SystemMessageActionBlock)(void);
return NSStringFromClass([self class]);
}
- (void)loadForDisplayWithTransaction:(YapDatabaseReadTransaction *)transaction
- (void)loadForDisplay
{
OWSAssert(self.conversationStyle);
OWSAssert(self.viewItem);
OWSAssert(transaction);
self.cellBackgroundView.backgroundColor = [Theme backgroundColor];
@ -185,7 +184,7 @@ typedef void (^SystemMessageActionBlock)(void);
}
self.titleLabel.textColor = [self textColor];
[self applyTitleForInteraction:interaction label:self.titleLabel transaction:transaction];
[self applyTitleForInteraction:interaction label:self.titleLabel];
CGSize titleSize = [self titleSize];
if (self.action) {
@ -312,52 +311,14 @@ typedef void (^SystemMessageActionBlock)(void);
- (void)applyTitleForInteraction:(TSInteraction *)interaction
label:(UILabel *)label
transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(interaction);
OWSAssert(label);
OWSAssert(transaction);
OWSAssert(self.viewItem.systemMessageText.length > 0);
[self configureFonts];
// TODO: Should we move the copy generation into this view?
if ([interaction isKindOfClass:[TSErrorMessage class]]) {
TSErrorMessage *errorMessage = (TSErrorMessage *)interaction;
label.text = [errorMessage previewTextWithTransaction:transaction];
} else if ([interaction isKindOfClass:[TSInfoMessage class]]) {
TSInfoMessage *infoMessage = (TSInfoMessage *)interaction;
if ([infoMessage isKindOfClass:[OWSVerificationStateChangeMessage class]]) {
OWSVerificationStateChangeMessage *verificationMessage = (OWSVerificationStateChangeMessage *)infoMessage;
BOOL isVerified = verificationMessage.verificationState == OWSVerificationStateVerified;
NSString *displayName =
[[Environment current].contactsManager displayNameForPhoneIdentifier:verificationMessage.recipientId];
NSString *titleFormat = (isVerified
? (verificationMessage.isLocalChange
? NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_LOCAL",
@"Format for info message indicating that the verification state was verified on "
@"this device. Embeds {{user's name or phone number}}.")
: NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_OTHER_DEVICE",
@"Format for info message indicating that the verification state was verified on "
@"another device. Embeds {{user's name or phone number}}."))
: (verificationMessage.isLocalChange
? NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_LOCAL",
@"Format for info message indicating that the verification state was unverified on "
@"this device. Embeds {{user's name or phone number}}.")
: NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_OTHER_DEVICE",
@"Format for info message indicating that the verification state was unverified on "
@"another device. Embeds {{user's name or phone number}}.")));
label.text = [NSString stringWithFormat:titleFormat, displayName];
} else {
label.text = [infoMessage previewTextWithTransaction:transaction];
}
} else if ([interaction isKindOfClass:[TSCall class]]) {
TSCall *call = (TSCall *)interaction;
label.text = [call previewTextWithTransaction:transaction];
} else {
OWSFail(@"Unknown interaction type: %@", [interaction class]);
label.text = nil;
}
label.text = self.viewItem.systemMessageText;
}
- (CGFloat)topVMargin
@ -389,7 +350,7 @@ typedef void (^SystemMessageActionBlock)(void);
return [self.titleLabel sizeThatFits:CGSizeMake(maxTitleWidth, CGFLOAT_MAX)];
}
- (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction
- (CGSize)cellSize
{
OWSAssert(self.conversationStyle);
OWSAssert(self.viewItem);
@ -409,7 +370,7 @@ typedef void (^SystemMessageActionBlock)(void);
result.height += self.iconSize + self.iconVSpacing;
}
[self applyTitleForInteraction:interaction label:self.titleLabel transaction:transaction];
[self applyTitleForInteraction:interaction label:self.titleLabel];
CGSize titleSize = [self titleSize];
result.height += titleSize.height;

@ -569,8 +569,7 @@ typedef enum : NSUInteger {
{
OWSAssert(self.conversationStyle);
_layout = [[ConversationViewLayout alloc] initWithConversationStyle:self.conversationStyle
uiDatabaseConnection:self.uiDatabaseConnection];
_layout = [[ConversationViewLayout alloc] initWithConversationStyle:self.conversationStyle];
self.conversationStyle.viewWidth = self.view.width;
self.layout.delegate = self;
@ -5167,9 +5166,7 @@ typedef enum : NSUInteger {
}
cell.conversationStyle = self.conversationStyle;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[cell loadForDisplayWithTransaction:transaction];
}];
[cell loadForDisplay];
return cell;
}

@ -109,6 +109,8 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType);
@property (nonatomic, readonly, nullable) ContactShareViewModel *contactShare;
@property (nonatomic, nullable) NSString *systemMessageText;
#pragma mark - MessageActions
@property (nonatomic, readonly) BOOL hasBodyTextActionContent;

@ -113,6 +113,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
self.mediaSize = CGSizeZero;
self.displayableQuotedText = nil;
self.quotedReply = nil;
self.systemMessageText = nil;
[self clearCachedLayoutState];
@ -215,9 +216,8 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
self.cachedCellSize = nil;
}
- (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction
- (CGSize)cellSize
{
OWSAssert(transaction);
OWSAssertIsOnMainThread();
OWSAssert(self.conversationStyle);
@ -225,7 +225,7 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
ConversationViewCell *_Nullable measurementCell = [self measurementCell];
measurementCell.viewItem = self;
measurementCell.conversationStyle = self.conversationStyle;
CGSize cellSize = [measurementCell cellSizeWithTransaction:transaction];
CGSize cellSize = [measurementCell cellSize];
self.cachedCellSize = [NSValue valueWithCGSize:cellSize];
[measurementCell prepareForReuse];
}
@ -438,12 +438,27 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
OWSAssert(transaction);
OWSAssert(!self.hasViewState);
if (![self.interaction isKindOfClass:[TSOutgoingMessage class]]
&& ![self.interaction isKindOfClass:[TSIncomingMessage class]]) {
// Only text & attachment messages have "view state".
return;
switch (self.interaction.interactionType) {
case OWSInteractionType_Unknown:
case OWSInteractionType_Offer:
return;
case OWSInteractionType_Error:
case OWSInteractionType_Info:
case OWSInteractionType_Call:
self.systemMessageText = [self systemMessageTextWithTransaction:transaction];
OWSAssert(self.systemMessageText.length > 0);
return;
case OWSInteractionType_IncomingMessage:
case OWSInteractionType_OutgoingMessage:
break;
default:
OWSFail(@"%@ Unknown interaction type.", self.logTag);
return;
}
OWSAssert([self.interaction isKindOfClass:[TSOutgoingMessage class]] ||
[self.interaction isKindOfClass:[TSIncomingMessage class]]);
self.hasViewState = YES;
TSMessage *message = (TSMessage *)self.interaction;
@ -533,6 +548,57 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType)
}
}
- (NSString *)systemMessageTextWithTransaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(transaction);
switch (self.interaction.interactionType) {
case OWSInteractionType_Error: {
TSErrorMessage *errorMessage = (TSErrorMessage *)self.interaction;
return [errorMessage previewTextWithTransaction:transaction];
}
case OWSInteractionType_Info: {
TSInfoMessage *infoMessage = (TSInfoMessage *)self.interaction;
if ([infoMessage isKindOfClass:[OWSVerificationStateChangeMessage class]]) {
OWSVerificationStateChangeMessage *verificationMessage
= (OWSVerificationStateChangeMessage *)infoMessage;
BOOL isVerified = verificationMessage.verificationState == OWSVerificationStateVerified;
NSString *displayName = [[Environment current].contactsManager
displayNameForPhoneIdentifier:verificationMessage.recipientId];
NSString *titleFormat = (isVerified
? (verificationMessage.isLocalChange
? NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_LOCAL",
@"Format for info message indicating that the verification state was verified "
@"on "
@"this device. Embeds {{user's name or phone number}}.")
: NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_VERIFIED_OTHER_DEVICE",
@"Format for info message indicating that the verification state was verified "
@"on "
@"another device. Embeds {{user's name or phone number}}."))
: (verificationMessage.isLocalChange
? NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_LOCAL",
@"Format for info message indicating that the verification state was "
@"unverified on "
@"this device. Embeds {{user's name or phone number}}.")
: NSLocalizedString(@"VERIFICATION_STATE_CHANGE_FORMAT_NOT_VERIFIED_OTHER_DEVICE",
@"Format for info message indicating that the verification state was "
@"unverified on "
@"another device. Embeds {{user's name or phone number}}.")));
return [NSString stringWithFormat:titleFormat, displayName];
} else {
return [infoMessage previewTextWithTransaction:transaction];
}
}
case OWSInteractionType_Call: {
TSCall *call = (TSCall *)self.interaction;
return [call previewTextWithTransaction:transaction];
}
default:
OWSFail(@"%@ not a system message.", self.logTag);
return nil;
}
}
- (nullable NSString *)quotedAttachmentMimetype
{
return self.quotedReply.contentType;

@ -5,12 +5,10 @@
NS_ASSUME_NONNULL_BEGIN
@class ConversationStyle;
@class YapDatabaseConnection;
@class YapDatabaseReadTransaction;
@protocol ConversationViewLayoutItem <NSObject>
- (CGSize)cellSizeWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (CGSize)cellSize;
- (CGFloat)vSpacingWithPreviousLayoutItem:(id<ConversationViewLayoutItem>)previousLayoutItem;
@ -39,8 +37,7 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithConversationStyle:(ConversationStyle *)conversationStyle
uiDatabaseConnection:(YapDatabaseConnection *)uiDatabaseConnection;
- (instancetype)initWithConversationStyle:(ConversationStyle *)conversationStyle;
@end

@ -10,8 +10,6 @@ NS_ASSUME_NONNULL_BEGIN
@interface ConversationViewLayout ()
@property (nonatomic, readonly) YapDatabaseConnection *uiDatabaseConnection;
@property (nonatomic) CGSize contentSize;
@property (nonatomic, readonly) NSMutableDictionary<NSNumber *, UICollectionViewLayoutAttributes *> *itemAttributesMap;
@ -31,12 +29,10 @@ NS_ASSUME_NONNULL_BEGIN
@implementation ConversationViewLayout
- (instancetype)initWithConversationStyle:(ConversationStyle *)conversationStyle
uiDatabaseConnection:(YapDatabaseConnection *)uiDatabaseConnection
{
if (self = [super init]) {
_itemAttributesMap = [NSMutableDictionary new];
_conversationStyle = conversationStyle;
_uiDatabaseConnection = uiDatabaseConnection;
}
return self;
@ -98,15 +94,11 @@ NS_ASSUME_NONNULL_BEGIN
// TODO: Remove this log statement after we've reduced the invalidation churn.
DDLogVerbose(@"%@ prepareLayout", self.logTag);
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[self prepareLayoutWithTransaction:transaction];
}];
[self prepareLayoutOfItems];
}
- (void)prepareLayoutWithTransaction:(YapDatabaseReadTransaction *)transaction
- (void)prepareLayoutOfItems
{
OWSAssert(transaction);
const CGFloat viewWidth = self.conversationStyle.viewWidth;
NSArray<id<ConversationViewLayoutItem>> *layoutItems = self.delegate.layoutItems;
@ -121,7 +113,7 @@ NS_ASSUME_NONNULL_BEGIN
y += [layoutItem vSpacingWithPreviousLayoutItem:previousLayoutItem];
}
CGSize layoutSize = CGSizeCeil([layoutItem cellSizeWithTransaction:transaction]);
CGSize layoutSize = CGSizeCeil([layoutItem cellSize]);
// Ensure cell fits within view.
OWSAssert(layoutSize.width <= viewWidth);

Loading…
Cancel
Save