Minor tweaks to the message request banner on the HomeVC

Fixed the unread message counting for message requests
Updated the message request banner to indicate the number of message requests with an unread message
Updated the message request banner to automatically disappear if the user has no unread message requests
Renamed a variable for ReadReceipt management to make it a bit more self-documenting (it looked like it would trigger a read receipt to be sent regardless of the setting)
pull/568/head
Morgan Pretty 2 years ago
parent 9251d98bde
commit 1b3f6c0ca6

@ -229,7 +229,7 @@ public class ConversationMessageMapping: NSObject {
let indexPtr: UnsafeMutablePointer<UInt> = UnsafeMutablePointer<UInt>.allocate(capacity: 1) let indexPtr: UnsafeMutablePointer<UInt> = UnsafeMutablePointer<UInt>.allocate(capacity: 1)
let wasFound = view.getGroup(nil, index: indexPtr, forKey: uniqueId, inCollection: TSInteraction.collection()) let wasFound = view.getGroup(nil, index: indexPtr, forKey: uniqueId, inCollection: TSInteraction.collection())
guard wasFound else { guard wasFound else {
owsFailDebug("Could not find interaction.") SNLog("Could not find interaction.")
return nil return nil
} }
let index = indexPtr.pointee let index = indexPtr.pointee

@ -731,9 +731,12 @@ final class ConversationVC : BaseVC, ConversationViewModelDelegate, OWSConversat
} }
func markAllAsRead() { func markAllAsRead() {
guard !thread.isMessageRequest() else { return }
guard let lastSortID = viewItems.last?.interaction.sortId else { return } guard let lastSortID = viewItems.last?.interaction.sortId else { return }
OWSReadReceiptManager.shared().markAsReadLocally(beforeSortId: lastSortID, thread: thread) OWSReadReceiptManager.shared().markAsReadLocally(
beforeSortId: lastSortID,
thread: thread,
trySendReadReceipt: !thread.isMessageRequest()
)
SSKEnvironment.shared.disappearingMessagesJob.cleanupMessagesWhichFailedToStartExpiringFromNow() SSKEnvironment.shared.disappearingMessagesJob.cleanupMessagesWhichFailedToStartExpiringFromNow()
} }

@ -6,6 +6,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
private var threads: YapDatabaseViewMappings! private var threads: YapDatabaseViewMappings!
private var threadViewModelCache: [String:ThreadViewModel] = [:] // Thread ID to ThreadViewModel private var threadViewModelCache: [String:ThreadViewModel] = [:] // Thread ID to ThreadViewModel
private var tableViewTopConstraint: NSLayoutConstraint! private var tableViewTopConstraint: NSLayoutConstraint!
private var unreadMessageRequestCount: UInt = 0
private var messageRequestCount: UInt { private var messageRequestCount: UInt {
threads.numberOfItems(inGroup: TSMessageRequestGroup) threads.numberOfItems(inGroup: TSMessageRequestGroup)
@ -196,7 +197,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
switch indexPath.section { switch indexPath.section {
case 0: case 0:
let cell = tableView.dequeueReusableCell(withIdentifier: MessageRequestsCell.reuseIdentifier) as! MessageRequestsCell let cell = tableView.dequeueReusableCell(withIdentifier: MessageRequestsCell.reuseIdentifier) as! MessageRequestsCell
cell.update(with: Int(messageRequestCount)) cell.update(with: Int(unreadMessageRequestCount))
return cell return cell
default: default:
@ -263,6 +264,14 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
} }
} }
// Update the number of unread message requests
unreadMessageRequestCount = OWSMessageUtils.sharedManager().unreadMessageRequestCount()
// If there are no unread message requests then hide the message request banner
if unreadMessageRequestCount == 0 {
CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] = true
}
return reload() return reload()
} }
} }
@ -286,6 +295,15 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
// If we need to unhide the message request row and then re-insert it // If we need to unhide the message request row and then re-insert it
if !messageRequestChanges.isEmpty { if !messageRequestChanges.isEmpty {
// Update the number of unread message requests
unreadMessageRequestCount = OWSMessageUtils.sharedManager().unreadMessageRequestCount()
// If there are no unread message requests then hide the message request banner
if unreadMessageRequestCount == 0 && tableView.numberOfRows(inSection: 0) == 1 {
CurrentAppContext().appUserDefaults()[.hasHiddenMessageRequests] = true
tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
}
else {
if tableView.numberOfRows(inSection: 0) == 1 && Int(messageRequestCount) <= 0 { if tableView.numberOfRows(inSection: 0) == 1 && Int(messageRequestCount) <= 0 {
tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .automatic) tableView.deleteRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
} }
@ -293,6 +311,7 @@ final class HomeVC : BaseVC, UITableViewDataSource, UITableViewDelegate, NewConv
tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .automatic) tableView.insertRows(at: [IndexPath(row: 0, section: 0)], with: .automatic)
} }
} }
}
inboxRowChanges.forEach { rowChange in inboxRowChanges.forEach { rowChange in
let key = rowChange.collectionKey.key let key = rowChange.collectionKey.key

@ -140,16 +140,16 @@ NS_ASSUME_NONNULL_BEGIN
return YES; return YES;
} }
- (void)markAsReadNowWithSendReadReceipt:(BOOL)sendReadReceipt - (void)markAsReadNowWithTrySendReadReceipt:(BOOL)trySendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
{ {
[self markAsReadAtTimestamp:[NSDate millisecondTimestamp] [self markAsReadAtTimestamp:[NSDate millisecondTimestamp]
sendReadReceipt:sendReadReceipt trySendReadReceipt:trySendReadReceipt
transaction:transaction]; transaction:transaction];
} }
- (void)markAsReadAtTimestamp:(uint64_t)readTimestamp - (void)markAsReadAtTimestamp:(uint64_t)readTimestamp
sendReadReceipt:(BOOL)sendReadReceipt trySendReadReceipt:(BOOL)trySendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
{ {
if (_read && readTimestamp >= self.expireStartedAt) { if (_read && readTimestamp >= self.expireStartedAt) {
@ -174,7 +174,7 @@ NS_ASSUME_NONNULL_BEGIN
expirationStartedAt:readTimestamp expirationStartedAt:readTimestamp
transaction:transaction]; transaction:transaction];
if (sendReadReceipt) { if (trySendReadReceipt) {
[OWSReadReceiptManager.sharedManager messageWasReadLocally:self]; [OWSReadReceiptManager.sharedManager messageWasReadLocally:self];
} }
} }

@ -134,7 +134,7 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
} }
- (void)markAsReadAtTimestamp:(uint64_t)readTimestamp - (void)markAsReadAtTimestamp:(uint64_t)readTimestamp
sendReadReceipt:(BOOL)sendReadReceipt trySendReadReceipt:(BOOL)trySendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
if (_read) { if (_read) {
@ -144,7 +144,7 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
_read = YES; _read = YES;
[self saveWithTransaction:transaction]; [self saveWithTransaction:transaction];
// Ignore sendReadReceipt, it doesn't apply to info messages. // Ignore trySendReadReceipt, it doesn't apply to info messages.
} }
@end @end

@ -390,7 +390,7 @@ extension MessageReceiver {
if let tsOutgoingMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) as? TSOutgoingMessage, if let tsOutgoingMessage = TSMessage.fetch(uniqueId: tsMessageID, transaction: transaction) as? TSOutgoingMessage,
let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) { let thread = TSThread.fetch(uniqueId: threadID, transaction: transaction) {
// Mark previous messages as read if there is a sync message // Mark previous messages as read if there is a sync message
OWSReadReceiptManager.shared().markAsReadLocally(beforeSortId: tsOutgoingMessage.sortId, thread: thread) OWSReadReceiptManager.shared().markAsReadLocally(beforeSortId: tsOutgoingMessage.sortId, thread: thread, trySendReadReceipt: true)
} }
// Update the contact's approval status of the current user if needed (if we are getting messages from // Update the contact's approval status of the current user if needed (if we are getting messages from

@ -45,7 +45,7 @@ extern NSString *const kIncomingMessageMarkedAsReadNotification;
// This method can be called from any thread. // This method can be called from any thread.
- (void)messageWasReadLocally:(TSIncomingMessage *)message; - (void)messageWasReadLocally:(TSIncomingMessage *)message;
- (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread; - (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread trySendReadReceipt:(BOOL)trySendReadReceipt;
#pragma mark - Settings #pragma mark - Settings

@ -180,13 +180,13 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
#pragma mark - Mark as Read Locally #pragma mark - Mark as Read Locally
- (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread - (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread trySendReadReceipt:(BOOL)trySendReadReceipt
{ {
[LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self markAsReadBeforeSortId:sortId [self markAsReadBeforeSortId:sortId
thread:thread thread:thread
readTimestamp:[NSDate millisecondTimestamp] readTimestamp:[NSDate millisecondTimestamp]
wasLocal:YES trySendReadReceipt:trySendReadReceipt
transaction:transaction]; transaction:transaction];
}]; }];
} }
@ -254,7 +254,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
- (void)markAsReadBeforeSortId:(uint64_t)sortId - (void)markAsReadBeforeSortId:(uint64_t)sortId
thread:(TSThread *)thread thread:(TSThread *)thread
readTimestamp:(uint64_t)readTimestamp readTimestamp:(uint64_t)readTimestamp
wasLocal:(BOOL)wasLocal trySendReadReceipt:(BOOL)trySendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction transaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
NSMutableArray<id<OWSReadTracking>> *newlyReadList = [NSMutableArray new]; NSMutableArray<id<OWSReadTracking>> *newlyReadList = [NSMutableArray new];
@ -285,7 +285,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
} }
for (id<OWSReadTracking> readItem in newlyReadList) { for (id<OWSReadTracking> readItem in newlyReadList) {
[readItem markAsReadAtTimestamp:readTimestamp sendReadReceipt:wasLocal transaction:transaction]; [readItem markAsReadAtTimestamp:readTimestamp trySendReadReceipt:trySendReadReceipt transaction:transaction];
} }
} }

@ -29,7 +29,7 @@ NS_ASSUME_NONNULL_BEGIN
* Used both for *responding* to a remote read receipt and in response to the local user's activity. * Used both for *responding* to a remote read receipt and in response to the local user's activity.
*/ */
- (void)markAsReadAtTimestamp:(uint64_t)readTimestamp - (void)markAsReadAtTimestamp:(uint64_t)readTimestamp
sendReadReceipt:(BOOL)sendReadReceipt trySendReadReceipt:(BOOL)trySendReadReceipt
transaction:(YapDatabaseReadWriteTransaction *)transaction; transaction:(YapDatabaseReadWriteTransaction *)transaction;
@end @end

@ -309,7 +309,7 @@ BOOL IsNoteToSelfEnabled(void)
- (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction - (void)markAllAsReadWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{ {
for (id<OWSReadTracking> message in [self unseenMessagesWithTransaction:transaction]) { for (id<OWSReadTracking> message in [self unseenMessagesWithTransaction:transaction]) {
[message markAsReadAtTimestamp:[NSDate ows_millisecondTimeStamp] sendReadReceipt:YES transaction:transaction]; [message markAsReadAtTimestamp:[NSDate ows_millisecondTimeStamp] trySendReadReceipt:YES transaction:transaction];
} }
} }

@ -16,6 +16,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (instancetype)sharedManager; + (instancetype)sharedManager;
- (NSUInteger)unreadMessagesCount; - (NSUInteger)unreadMessagesCount;
- (NSUInteger)unreadMessageRequestCount;
- (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread; - (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread;
- (void)updateApplicationBadgeCount; - (void)updateApplicationBadgeCount;

@ -112,6 +112,38 @@ NS_ASSUME_NONNULL_BEGIN
return numberOfItems; return numberOfItems;
} }
- (NSUInteger)unreadMessageRequestCount {
__block NSUInteger count = 0;
[LKStorage readWithBlock:^(YapDatabaseReadTransaction *transaction) {
YapDatabaseViewTransaction *unreadMessages = [transaction ext:TSUnreadDatabaseViewExtensionName];
NSArray<NSString *> *allGroups = [unreadMessages allGroups];
// FIXME: Confusingly, `allGroups` includes contact threads as well
for (NSString *groupID in allGroups) {
TSThread *thread = [TSThread fetchObjectWithUniqueID:groupID transaction:transaction];
// Only increase the count for message requests
if (!thread.isMessageRequest) { continue; }
[unreadMessages enumerateKeysAndObjectsInGroup:groupID
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
if (![object conformsToProtocol:@protocol(OWSReadTracking)]) {
return;
}
id<OWSReadTracking> unread = (id<OWSReadTracking>)object;
if (unread.read) {
NSLog(@"Found an already read message in the * unread * messages list.");
return;
}
count += 1;
*stop = YES;
}];
}
}];
return count;
}
- (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread - (NSUInteger)unreadMessagesCountExcept:(TSThread *)thread
{ {
__block NSUInteger numberOfItems; __block NSUInteger numberOfItems;

Loading…
Cancel
Save