mirror of https://github.com/oxen-io/session-ios
parent
580781e3e4
commit
acb89f0b0f
@ -0,0 +1,14 @@
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class TSMessagesManager;
|
||||
|
||||
@interface OWSReadReceiptObserver : NSObject
|
||||
|
||||
- (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager;
|
||||
- (void)startObserving;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,110 @@
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSReadReceiptObserver.h"
|
||||
#import "OWSReadReceipt.h"
|
||||
#import "OWSReadReceiptsMessage.h"
|
||||
#import "TSContactThread.h"
|
||||
#import "TSIncomingMessage.h"
|
||||
#import "TSMessagesManager+sendMessages.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSReadReceiptObserver ()
|
||||
|
||||
@property (atomic) NSMutableArray<OWSReadReceipt *> *readReceiptsQueue;
|
||||
@property (nonatomic, readonly) TSMessagesManager *messagesManager;
|
||||
@property BOOL isObserving;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSReadReceiptObserver
|
||||
|
||||
- (instancetype)initWithMessagesManager:(TSMessagesManager *)messagesManager
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_readReceiptsQueue = [NSMutableArray new];
|
||||
_messagesManager = messagesManager;
|
||||
_isObserving = NO;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)startObserving
|
||||
{
|
||||
if (self.isObserving) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.isObserving = true;
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(handleReadNotification:)
|
||||
name:TSIncomingMessageWasReadOnThisDeviceNotification
|
||||
object:nil];
|
||||
}
|
||||
|
||||
- (void)handleReadNotification:(NSNotification *)notification
|
||||
{
|
||||
if (![notification.object isKindOfClass:[TSIncomingMessage class]]) {
|
||||
DDLogError(@"Read receipt notifier got unexpected object: %@", notification.object);
|
||||
return;
|
||||
}
|
||||
|
||||
TSIncomingMessage *message = (TSIncomingMessage *)notification.object;
|
||||
|
||||
// Only groupthread sets authorId, thus this crappy code.
|
||||
// TODO ALL incoming messages should have an authorId.
|
||||
NSString *messageAuthorId;
|
||||
if (message.authorId) { // Group Thread
|
||||
messageAuthorId = message.authorId;
|
||||
} else { // Contact Thread
|
||||
messageAuthorId = [TSContactThread contactIdFromThreadId:message.uniqueThreadId];
|
||||
}
|
||||
|
||||
OWSReadReceipt *readReceipt = [[OWSReadReceipt alloc] initWithSenderId:messageAuthorId timestamp:message.timestamp];
|
||||
[self.readReceiptsQueue addObject:readReceipt];
|
||||
|
||||
// Wait a bit to bundle up read receipts into one request.
|
||||
__weak typeof(self) weakSelf = self;
|
||||
[weakSelf performSelector:@selector(sendAllReadReceiptsInQueue) withObject:nil afterDelay:2.0];
|
||||
}
|
||||
|
||||
- (void)sendAllReadReceiptsInQueue
|
||||
{
|
||||
// Synchronized so we don't lose any read receipts while replacing the queue
|
||||
__block NSArray<OWSReadReceipt *> *receiptsToSend;
|
||||
@synchronized(self)
|
||||
{
|
||||
if (self.readReceiptsQueue.count > 0) {
|
||||
receiptsToSend = [self.readReceiptsQueue copy];
|
||||
self.readReceiptsQueue = [NSMutableArray new];
|
||||
}
|
||||
}
|
||||
|
||||
if (receiptsToSend) {
|
||||
[self sendReadReceipts:receiptsToSend];
|
||||
} else {
|
||||
DDLogVerbose(@"Read receipts queue already drained.");
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sendReadReceipts:(NSArray<OWSReadReceipt *> *)readReceipts
|
||||
{
|
||||
OWSReadReceiptsMessage *message = [[OWSReadReceiptsMessage alloc] initWithReadReceipts:readReceipts];
|
||||
|
||||
[self.messagesManager sendMessage:message
|
||||
inThread:nil
|
||||
success:^{
|
||||
DDLogInfo(@"Successfully sent %ld read receipt", (unsigned long)readReceipts.count);
|
||||
}
|
||||
failure:^{
|
||||
DDLogError(@"Failed to send read receipt");
|
||||
}];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,15 @@
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSOutgoingSyncMessage.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class OWSReadReceipt;
|
||||
|
||||
@interface OWSReadReceiptsMessage : OWSOutgoingSyncMessage
|
||||
|
||||
- (instancetype)initWithReadReceipts:(NSArray<OWSReadReceipt *> *)readReceipts;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
@ -0,0 +1,45 @@
|
||||
// Copyright © 2016 Open Whisper Systems. All rights reserved.
|
||||
|
||||
#import "OWSReadReceiptsMessage.h"
|
||||
#import "OWSReadReceipt.h"
|
||||
#import "OWSSignalServiceProtos.pb.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSReadReceiptsMessage ()
|
||||
|
||||
@property (nonatomic, readonly) NSArray<OWSReadReceipt *> *readReceipts;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSReadReceiptsMessage
|
||||
|
||||
- (instancetype)initWithReadReceipts:(NSArray<OWSReadReceipt *> *)readReceipts
|
||||
{
|
||||
self = [super init];
|
||||
if (!self) {
|
||||
return self;
|
||||
}
|
||||
|
||||
_readReceipts = [readReceipts copy];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (OWSSignalServiceProtosSyncMessage *)buildSyncMessage
|
||||
{
|
||||
OWSSignalServiceProtosSyncMessageBuilder *syncMessageBuilder = [OWSSignalServiceProtosSyncMessageBuilder new];
|
||||
for (OWSReadReceipt *readReceipt in self.readReceipts) {
|
||||
OWSSignalServiceProtosSyncMessageReadBuilder *readProtoBuilder =
|
||||
[OWSSignalServiceProtosSyncMessageReadBuilder new];
|
||||
[readProtoBuilder setSender:readReceipt.senderId];
|
||||
[readProtoBuilder setTimestamp:readReceipt.timestamp];
|
||||
[syncMessageBuilder addRead:[readProtoBuilder build]];
|
||||
}
|
||||
|
||||
return [syncMessageBuilder build];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
Loading…
Reference in New Issue