WIP unjank home screen

verify `description` isn't used elsewhere (notifications? conversation
view?)

Probably want to remove overzealous asserts for now, but would be good
to work towards leaving them enabled.

// FREEBIE
This commit is contained in:
Michael Kirk 2018-04-21 10:25:13 -04:00
parent 7912598ccb
commit 1fb1b5bbe2
14 changed files with 96 additions and 47 deletions

View File

@ -6,6 +6,7 @@ NS_ASSUME_NONNULL_BEGIN
@class OWSContactsManager;
@class TSThread;
@class YapDatabaseReadTransaction;
@interface HomeViewCell : UITableViewCell
@ -15,7 +16,8 @@ NS_ASSUME_NONNULL_BEGIN
- (void)configureWithThread:(TSThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
blockedPhoneNumberSet:(NSSet<NSString *> *)blockedPhoneNumberSet;
blockedPhoneNumberSet:(NSSet<NSString *> *)blockedPhoneNumberSet
transaction:(YapDatabaseReadTransaction *)transaction;
@end

View File

@ -146,11 +146,13 @@ NS_ASSUME_NONNULL_BEGIN
- (void)configureWithThread:(TSThread *)thread
contactsManager:(OWSContactsManager *)contactsManager
blockedPhoneNumberSet:(NSSet<NSString *> *)blockedPhoneNumberSet
transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssertIsOnMainThread();
OWSAssert(thread);
OWSAssert(contactsManager);
OWSAssert(blockedPhoneNumberSet);
OWSAssert(transaction);
self.thread = thread;
self.contactsManager = contactsManager;
@ -171,7 +173,9 @@ NS_ASSUME_NONNULL_BEGIN
// changes to the dynamic type settings are reflected.
self.snippetLabel.font = [self snippetFont];
self.snippetLabel.attributedText =
[self attributedSnippetForThread:thread blockedPhoneNumberSet:blockedPhoneNumberSet];
[self attributedSnippetForThread:thread
blockedPhoneNumberSet:blockedPhoneNumberSet
transaction:transaction];
self.dateTimeLabel.text = [self stringForDate:thread.lastMessageDate];
@ -253,6 +257,7 @@ NS_ASSUME_NONNULL_BEGIN
- (NSAttributedString *)attributedSnippetForThread:(TSThread *)thread
blockedPhoneNumberSet:(NSSet<NSString *> *)blockedPhoneNumberSet
transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(thread);
@ -285,7 +290,7 @@ NS_ASSUME_NONNULL_BEGIN
: [UIColor lightGrayColor]),
}]];
}
NSString *displayableText = thread.lastMessageLabel.filterStringForDisplay;
NSString *displayableText = [thread lastMessageLabelWithTransaction:transaction];
if (displayableText) {
[snippetText appendAttributedString:[[NSAttributedString alloc]
initWithString:displayableText

View File

@ -395,7 +395,11 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
if ([TSThread numberOfKeysInCollection] > 0) {
__block BOOL hasAnyMessages;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction * _Nonnull transaction) {
hasAnyMessages = [self hasAnyMessagesWithTransaction:transaction];
}];
if (hasAnyMessages) {
[self.contactsManager requestSystemContactsOnceWithCompletion:^(NSError *_Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateReminderViews];
@ -490,7 +494,11 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
// If the user hasn't already granted contact access
// we don't want to request until they receive a message.
if ([TSThread numberOfKeysInCollection] > 0) {
__block BOOL hasAnyMessages;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction * _Nonnull transaction) {
hasAnyMessages = [self hasAnyMessagesWithTransaction:transaction];
}];
if (hasAnyMessages) {
[self.contactsManager requestSystemContactsOnce];
}
}
@ -506,11 +514,21 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
self.isAppInBackground = YES;
}
- (BOOL)hasAnyMessagesWithTransaction:(YapDatabaseReadTransaction *)transaction
{
return [TSThread numberOfKeysInCollectionWithTransaction:transaction] > 0;
}
- (void)applicationDidBecomeActive:(NSNotification *)notification
{
// It's possible a thread was created while we where in the background. But since we don't honor contact
// requests unless the app is in the foregrond, we must check again here upon becoming active.
if ([TSThread numberOfKeysInCollection] > 0) {
__block BOOL hasAnyMessages;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction * _Nonnull transaction) {
hasAnyMessages = [self hasAnyMessagesWithTransaction:transaction];
}];
if (hasAnyMessages) {
[self.contactsManager requestSystemContactsOnceWithCompletion:^(NSError *_Nullable error) {
dispatch_async(dispatch_get_main_queue(), ^{
[self updateReminderViews];
@ -584,9 +602,12 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
TSThread *thread = [self threadForIndexPath:indexPath];
[cell configureWithThread:thread
contactsManager:self.contactsManager
blockedPhoneNumberSet:self.blockedPhoneNumberSet];
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction * _Nonnull transaction) {
[cell configureWithThread:thread
contactsManager:self.contactsManager
blockedPhoneNumberSet:self.blockedPhoneNumberSet
transaction:transaction];
}];
if ((unsigned long)indexPath.row == [self.threadMappings numberOfItemsInSection:0] - 1) {
cell.separatorInset = UIEdgeInsetsMake(0.f, cell.bounds.size.width, 0.f, 0.f);

View File

@ -90,7 +90,7 @@ NS_ASSUME_NONNULL_BEGIN
*
* @return Thread preview string.
*/
- (NSString *)lastMessageLabel;
- (NSString *)lastMessageLabelWithTransaction:(YapDatabaseReadTransaction *)transaction;
/**
* Updates the thread's caches of the latest interaction.

View File

@ -4,6 +4,7 @@
#import "TSThread.h"
#import "NSDate+OWS.h"
#import "NSString+SSK.h"
#import "OWSPrimaryStorage.h"
#import "OWSReadTracking.h"
#import "TSDatabaseView.h"
@ -246,26 +247,24 @@ NS_ASSUME_NONNULL_BEGIN
return last;
}
- (TSInteraction *)lastInteractionForInbox
- (TSInteraction *)lastInteractionForInboxWithTransaction:(YapDatabaseReadTransaction *)transaction
{
__block TSInteraction *last = nil;
[OWSPrimaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[[transaction ext:TSMessageDatabaseViewExtensionName]
enumerateRowsInGroup:self.uniqueId
withOptions:NSEnumerationReverse
usingBlock:^(
NSString *collection, NSString *key, id object, id metadata, NSUInteger index, BOOL *stop) {
OWSAssert([object isKindOfClass:[TSInteraction class]]);
TSInteraction *interaction = (TSInteraction *)object;
if ([TSThread shouldInteractionAppearInInbox:interaction]) {
last = interaction;
*stop = YES;
}
}];
}];
[[transaction ext:TSMessageDatabaseViewExtensionName]
enumerateRowsInGroup:self.uniqueId
withOptions:NSEnumerationReverse
usingBlock:^(
NSString *collection, NSString *key, id object, id metadata, NSUInteger index, BOOL *stop) {
OWSAssert([object isKindOfClass:[TSInteraction class]]);
TSInteraction *interaction = (TSInteraction *)object;
if ([TSThread shouldInteractionAppearInInbox:interaction]) {
last = interaction;
*stop = YES;
}
}];
return last;
}
@ -277,12 +276,14 @@ NS_ASSUME_NONNULL_BEGIN
}
}
- (NSString *)lastMessageLabel {
TSInteraction *interaction = self.lastInteractionForInbox;
if (interaction == nil) {
return @"";
- (NSString *)lastMessageLabelWithTransaction:(YapDatabaseReadTransaction *)transaction
{
TSInteraction *interaction = [self lastInteractionForInboxWithTransaction:transaction];
if ([interaction conformsToProtocol:@protocol(OWSPreviewText)]) {
id<OWSPreviewText> previewable = (id<OWSPreviewText>)interaction;
return [previewable previewTextWithTransaction:transaction].filterStringForDisplay;
} else {
return interaction.description;
return @"";
}
}

View File

@ -56,7 +56,7 @@ NS_ASSUME_NONNULL_BEGIN
return NO;
}
- (NSString *)description
-(NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
{
if (self.createdByRemoteName) {
if (self.configurationIsEnabled && self.configurationDurationSeconds > 0) {

View File

@ -97,7 +97,8 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
return OWSInteractionType_Error;
}
- (NSString *)description {
- (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
{
switch (_errorType) {
case TSErrorMessageNoSession:
return NSLocalizedString(@"ERROR_MESSAGE_NO_SESSION", @"");

View File

@ -91,7 +91,8 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
return OWSInteractionType_Info;
}
- (NSString *)description {
- (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
{
switch (_messageType) {
case TSInfoMessageTypeSessionDidEnd:
return NSLocalizedString(@"SECURE_SESSION_RESET", nil);

View File

@ -19,6 +19,12 @@ typedef NS_ENUM(NSInteger, OWSInteractionType) {
OWSInteractionType_Offer,
};
@protocol OWSPreviewText
- (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction;
@end
@interface TSInteraction : TSYapDatabaseObject
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread;

View File

@ -128,6 +128,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (NSString *)description {
OWSFail(@"Abstract Method");
return @"Interaction description";
}

View File

@ -15,7 +15,7 @@ NS_ASSUME_NONNULL_BEGIN
@class TSQuotedMessage;
@class YapDatabaseReadWriteTransaction;
@interface TSMessage : TSInteraction
@interface TSMessage : TSInteraction <OWSPreviewText>
@property (nonatomic, readonly) NSMutableArray<NSString *> *attachmentIds;
@property (nonatomic, readonly, nullable) NSString *body;
@ -39,7 +39,6 @@ NS_ASSUME_NONNULL_BEGIN
- (BOOL)hasAttachments;
- (nullable TSAttachment *)attachmentWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction;
- (void)setQuotedMessageThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream;
- (BOOL)shouldStartExpireTimer;

View File

@ -265,14 +265,11 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
}
}
// TODO deprecate this and implement something like previewTextWithTransaction: for all TSInteractions
- (NSString *)description
{
__block NSString *result;
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
result = [self previewTextWithTransaction:transaction];
}];
return result;
// TODO verify this isn't exposed in the UI
OWSFail(@"%@ in %s verify this isn't being used anywhere except logging.", self.logTag, __PRETTY_FUNCTION__);
return [super description];
}
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction

View File

@ -67,7 +67,13 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
return OWSInteractionType_Call;
}
- (NSString *)description {
- (NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
{
return [self previewText];
}
- (NSString *)previewText
{
switch (_callType) {
case RPRecentCallTypeIncoming:
return NSLocalizedString(@"INCOMING_CALL", @"");
@ -83,10 +89,16 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
return NSLocalizedString(@"INFO_MESSAGE_MISSED_CALL_DUE_TO_CHANGED_IDENITY", @"info message text shown in conversation view");
case RPRecentCallTypeIncomingDeclined:
return NSLocalizedString(@"INCOMING_DECLINED_CALL",
@"info message recorded in conversation history when local user declined a call");
@"info message recorded in conversation history when local user declined a call");
}
}
- (NSString *)description
{
OWSFail(@"%@ in %s verify this isnt exposed in the UI", self.logTag, __PRETTY_FUNCTION__);
return [self previewText];
}
#pragma mark - OWSReadTracking
- (uint64_t)expireStartedAt

View File

@ -109,17 +109,20 @@ NS_ASSUME_NONNULL_BEGIN
+ (YapDatabaseConnection *)dbReadConnection
{
OWSAssert(![NSThread isMainThread]);
// We use TSYapDatabaseObject's dbReadWriteConnection (not OWSPrimaryStorage's
// dbReadConnection) for consistency, since we tend to [TSYapDatabaseObject
// save] and want to write to the same connection we read from. To get true
// consistency, we'd want to update entities by reading & writing from within
// the same transaction, but that'll be a big refactor.
return self.dbReadWriteConnection;
}
+ (YapDatabaseConnection *)dbReadWriteConnection
{
OWSAssert(![NSThread isMainThread]);
// Use a dedicated connection for model reads & writes.
static YapDatabaseConnection *dbReadWriteConnection = nil;
static dispatch_once_t onceToken;