Send read receipts again
This commit is contained in:
parent
c8e63019ab
commit
4942da1d23
|
@ -543,12 +543,7 @@ const CGFloat kRemotelySourcedContentRowSpacing = 4;
|
||||||
NSString *_Nullable localNumber = [TSAccountManager localNumber];
|
NSString *_Nullable localNumber = [TSAccountManager localNumber];
|
||||||
NSString *quotedAuthorText;
|
NSString *quotedAuthorText;
|
||||||
if ([localNumber isEqualToString:self.quotedMessage.authorId]) {
|
if ([localNumber isEqualToString:self.quotedMessage.authorId]) {
|
||||||
|
quotedAuthorText = NSLocalizedString(@"You", @"");
|
||||||
if (self.isOutgoing) {
|
|
||||||
quotedAuthorText = NSLocalizedString(@"You", @"");
|
|
||||||
} else {
|
|
||||||
quotedAuthorText = NSLocalizedString(@"You", @"");
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
__block NSString *quotedAuthor = [SSKEnvironment.shared.profileManager profileNameForRecipientWithID:self.quotedMessage.authorId] ?: self.quotedMessage.authorId;
|
__block NSString *quotedAuthor = [SSKEnvironment.shared.profileManager profileNameForRecipientWithID:self.quotedMessage.authorId] ?: self.quotedMessage.authorId;
|
||||||
|
|
||||||
|
|
|
@ -2,9 +2,11 @@ import SessionUtilitiesKit
|
||||||
|
|
||||||
@objc(SNReadReceipt)
|
@objc(SNReadReceipt)
|
||||||
public final class ReadReceipt : ControlMessage {
|
public final class ReadReceipt : ControlMessage {
|
||||||
public var timestamps: [UInt64]?
|
@objc public var timestamps: [UInt64]?
|
||||||
|
|
||||||
// MARK: Initialization
|
// MARK: Initialization
|
||||||
|
public override init() { super.init() }
|
||||||
|
|
||||||
internal init(timestamps: [UInt64]) {
|
internal init(timestamps: [UInt64]) {
|
||||||
super.init()
|
super.init()
|
||||||
self.timestamps = timestamps
|
self.timestamps = timestamps
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
@objc(SNMessage)
|
@objc(SNMessage)
|
||||||
public class Message : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
public class Message : NSObject, NSCoding { // NSObject/NSCoding conformance is needed for YapDatabase compatibility
|
||||||
public var id: String?
|
public var id: String?
|
||||||
public var threadID: String?
|
@objc public var threadID: String?
|
||||||
public var sentTimestamp: UInt64?
|
public var sentTimestamp: UInt64?
|
||||||
public var receivedTimestamp: UInt64?
|
public var receivedTimestamp: UInt64?
|
||||||
public var recipient: String?
|
public var recipient: String?
|
||||||
|
|
|
@ -141,7 +141,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSTimeInterval secondsAgoRead = ((NSTimeInterval)[NSDate millisecondTimestamp] - (NSTimeInterval)readTimestamp) / 1000;
|
|
||||||
_read = YES;
|
_read = YES;
|
||||||
[self saveWithTransaction:transaction];
|
[self saveWithTransaction:transaction];
|
||||||
|
|
||||||
|
|
|
@ -253,7 +253,7 @@ NSString *const kOWSBlockingManager_SyncedBlockedGroupIdsKey = @"kOWSBlockingMan
|
||||||
|
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
if (sendSyncMessage) {
|
if (sendSyncMessage) {
|
||||||
[self sendBlockListSyncMessageWithPhoneNumbers:blockedPhoneNumbers groupIds:blockedGroupIds];
|
|
||||||
} else {
|
} else {
|
||||||
// If this update came from an incoming block list sync message,
|
// If this update came from an incoming block list sync message,
|
||||||
// update the "synced blocked list" state immediately,
|
// update the "synced blocked list" state immediately,
|
||||||
|
@ -299,70 +299,9 @@ NSString *const kOWSBlockingManager_SyncedBlockedGroupIdsKey = @"kOWSBlockingMan
|
||||||
_blockedGroupMap = [NSMutableDictionary new];
|
_blockedGroupMap = [NSMutableDictionary new];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self syncBlockListIfNecessary];
|
|
||||||
[self observeNotifications];
|
[self observeNotifications];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)syncBlockList
|
|
||||||
{
|
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
|
||||||
[self sendBlockListSyncMessageWithPhoneNumbers:self.blockedPhoneNumbers groupIds:self.blockedGroupIds];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// This method should only be called from within a synchronized block.
|
|
||||||
- (void)syncBlockListIfNecessary
|
|
||||||
{
|
|
||||||
// If we haven't yet successfully synced the current "block list" changes,
|
|
||||||
// try again to sync now.
|
|
||||||
NSArray<NSString *> *syncedBlockedPhoneNumbers =
|
|
||||||
[self.dbConnection objectForKey:kOWSBlockingManager_SyncedBlockedPhoneNumbersKey
|
|
||||||
inCollection:kOWSBlockingManager_BlockListCollection];
|
|
||||||
NSSet<NSString *> *syncedBlockedPhoneNumberSet =
|
|
||||||
[[NSSet alloc] initWithArray:(syncedBlockedPhoneNumbers ?: [NSArray new])];
|
|
||||||
|
|
||||||
NSArray<NSData *> *syncedBlockedGroupIds =
|
|
||||||
[self.dbConnection objectForKey:kOWSBlockingManager_SyncedBlockedGroupIdsKey
|
|
||||||
inCollection:kOWSBlockingManager_BlockListCollection];
|
|
||||||
NSSet<NSData *> *syncedBlockedGroupIdSet = [[NSSet alloc] initWithArray:(syncedBlockedGroupIds ?: [NSArray new])];
|
|
||||||
|
|
||||||
NSArray<NSData *> *localBlockedGroupIds = self.blockedGroupIds;
|
|
||||||
NSSet<NSData *> *localBlockedGroupIdSet = [[NSSet alloc] initWithArray:localBlockedGroupIds];
|
|
||||||
|
|
||||||
if ([self.blockedPhoneNumberSet isEqualToSet:syncedBlockedPhoneNumberSet] &&
|
|
||||||
[localBlockedGroupIdSet isEqualToSet:syncedBlockedGroupIdSet]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[self sendBlockListSyncMessageWithPhoneNumbers:self.blockedPhoneNumbers groupIds:localBlockedGroupIds];
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)sendBlockListSyncMessageWithPhoneNumbers:(NSArray<NSString *> *)blockedPhoneNumbers
|
|
||||||
groupIds:(NSArray<NSData *> *)blockedGroupIds
|
|
||||||
{
|
|
||||||
// TODO TODO TODO
|
|
||||||
|
|
||||||
/*
|
|
||||||
OWSAssertDebug(blockedPhoneNumbers);
|
|
||||||
OWSAssertDebug(blockedGroupIds);
|
|
||||||
|
|
||||||
OWSBlockedPhoneNumbersMessage *message =
|
|
||||||
[[OWSBlockedPhoneNumbersMessage alloc] initWithPhoneNumbers:blockedPhoneNumbers groupIds:blockedGroupIds];
|
|
||||||
|
|
||||||
[self.messageSender sendMessage:message
|
|
||||||
success:^{
|
|
||||||
OWSLogInfo(@"Successfully sent blocked phone numbers sync message");
|
|
||||||
|
|
||||||
// DURABLE CLEANUP - we could replace the custom durability logic in this class
|
|
||||||
// with a durable JobQueue.
|
|
||||||
[self saveSyncedBlockListWithPhoneNumbers:blockedPhoneNumbers groupIds:blockedGroupIds];
|
|
||||||
}
|
|
||||||
failure:^(NSError *error) {
|
|
||||||
OWSLogError(@"Failed to send blocked phone numbers sync message with error: %@", error);
|
|
||||||
}];
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Records the last block list which we successfully synced.
|
/// Records the last block list which we successfully synced.
|
||||||
- (void)saveSyncedBlockListWithPhoneNumbers:(NSArray<NSString *> *)blockedPhoneNumbers
|
- (void)saveSyncedBlockListWithPhoneNumbers:(NSArray<NSString *> *)blockedPhoneNumbers
|
||||||
groupIds:(NSArray<NSData *> *)blockedGroupIds
|
groupIds:(NSArray<NSData *> *)blockedGroupIds
|
||||||
|
@ -380,12 +319,7 @@ NSString *const kOWSBlockingManager_SyncedBlockedGroupIdsKey = @"kOWSBlockingMan
|
||||||
|
|
||||||
- (void)applicationDidBecomeActive:(NSNotification *)notification
|
- (void)applicationDidBecomeActive:(NSNotification *)notification
|
||||||
{
|
{
|
||||||
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
|
||||||
@synchronized(self)
|
|
||||||
{
|
|
||||||
[self syncBlockListIfNecessary];
|
|
||||||
}
|
|
||||||
}];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -224,7 +224,7 @@ public class OWSLinkPreview: MTLModel {
|
||||||
let filePath = OWSFileSystem.temporaryFilePath(withFileExtension: fileExtension)
|
let filePath = OWSFileSystem.temporaryFilePath(withFileExtension: fileExtension)
|
||||||
do {
|
do {
|
||||||
try imageData.write(to: NSURL.fileURL(withPath: filePath), options: .atomicWrite)
|
try imageData.write(to: NSURL.fileURL(withPath: filePath), options: .atomicWrite)
|
||||||
} catch let error as NSError {
|
} catch {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -126,8 +126,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSThread *thread = [message threadWithTransaction:transaction];
|
|
||||||
|
|
||||||
uint64_t timestamp = message.timestamp;
|
uint64_t timestamp = message.timestamp;
|
||||||
|
|
||||||
NSString *_Nullable authorId = ^{
|
NSString *_Nullable authorId = ^{
|
||||||
|
|
|
@ -103,7 +103,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
}
|
}
|
||||||
|
|
||||||
NSMutableArray<AnyPromise *> *sendPromises = [NSMutableArray array];
|
NSMutableArray<AnyPromise *> *sendPromises = [NSMutableArray array];
|
||||||
[sendPromises addObjectsFromArray:[self sendReceiptsForReceiptType:OWSReceiptType_Delivery]];
|
|
||||||
[sendPromises addObjectsFromArray:[self sendReceiptsForReceiptType:OWSReceiptType_Read]];
|
[sendPromises addObjectsFromArray:[self sendReceiptsForReceiptType:OWSReceiptType_Read]];
|
||||||
|
|
||||||
if (sendPromises.count < 1) {
|
if (sendPromises.count < 1) {
|
||||||
|
@ -149,8 +148,8 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
NSMutableArray<AnyPromise *> *sendPromises = [NSMutableArray array];
|
NSMutableArray<AnyPromise *> *sendPromises = [NSMutableArray array];
|
||||||
|
|
||||||
for (NSString *recipientId in queuedReceiptMap) {
|
for (NSString *recipientId in queuedReceiptMap) {
|
||||||
NSSet<NSNumber *> *timestamps = queuedReceiptMap[recipientId];
|
NSSet<NSNumber *> *timestampsAsSet = queuedReceiptMap[recipientId];
|
||||||
if (timestamps.count < 1) {
|
if (timestampsAsSet.count < 1) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,51 +159,19 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO TODO TODO
|
SNReadReceipt *readReceipt = [SNReadReceipt new];
|
||||||
|
NSMutableArray<NSNumber *> *timestamps = [NSMutableArray new];
|
||||||
/*
|
for (NSNumber *timestamp in timestampsAsSet) {
|
||||||
OWSReceiptsForSenderMessage *message;
|
[timestamps addObject:timestamp];
|
||||||
NSString *receiptName;
|
|
||||||
switch (receiptType) {
|
|
||||||
case OWSReceiptType_Delivery:
|
|
||||||
message =
|
|
||||||
[OWSReceiptsForSenderMessage deliveryReceiptsForSenderMessageWithThread:thread
|
|
||||||
messageTimestamps:timestamps.allObjects];
|
|
||||||
receiptName = @"Delivery";
|
|
||||||
break;
|
|
||||||
case OWSReceiptType_Read:
|
|
||||||
message = [OWSReceiptsForSenderMessage readReceiptsForSenderMessageWithThread:thread
|
|
||||||
messageTimestamps:timestamps.allObjects];
|
|
||||||
receiptName = @"Read";
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
readReceipt.timestamps = timestamps;
|
||||||
AnyPromise *sendPromise = [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
|
[LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||||
[self.messageSender sendMessage:message
|
AnyPromise *promise = [SNMessageSender sendNonDurably:readReceipt inThread:thread usingTransaction:transaction]
|
||||||
success:^{
|
.thenOn(self.serialQueue, ^(id object) {
|
||||||
OWSLogInfo(
|
[self dequeueReceiptsWithRecipientId:recipientId timestamps:timestampsAsSet receiptType:@"Read"];
|
||||||
@"Successfully sent %lu %@ receipts to sender.", (unsigned long)timestamps.count, receiptName);
|
});
|
||||||
|
[sendPromises addObject:promise];
|
||||||
// DURABLE CLEANUP - we could replace the custom durability logic in this class
|
|
||||||
// with a durable JobQueue.
|
|
||||||
[self dequeueReceiptsWithRecipientId:recipientId timestamps:timestamps receiptType:receiptType];
|
|
||||||
|
|
||||||
// The value doesn't matter, we just need any non-NSError value.
|
|
||||||
resolve(@(1));
|
|
||||||
}
|
|
||||||
failure:^(NSError *error) {
|
|
||||||
OWSLogError(@"Failed to send %@ receipts to sender with error: %@", receiptName, error);
|
|
||||||
|
|
||||||
if (error.domain == OWSSignalServiceKitErrorDomain
|
|
||||||
&& error.code == OWSErrorCodeNoSuchSignalRecipient) {
|
|
||||||
[self dequeueReceiptsWithRecipientId:recipientId timestamps:timestamps receiptType:receiptType];
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve(error);
|
|
||||||
}];
|
|
||||||
}];
|
}];
|
||||||
[sendPromises addObject:sendPromise];
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return [sendPromises copy];
|
return [sendPromises copy];
|
||||||
|
|
|
@ -234,46 +234,20 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
|
|
||||||
- (void)messageWasReadLocally:(TSIncomingMessage *)message
|
- (void)messageWasReadLocally:(TSIncomingMessage *)message
|
||||||
{
|
{
|
||||||
// TODO TODO TODO
|
|
||||||
|
|
||||||
/*
|
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
@synchronized(self)
|
@synchronized(self)
|
||||||
{
|
{
|
||||||
NSString *threadUniqueId = message.uniqueThreadId;
|
|
||||||
OWSAssertDebug(threadUniqueId.length > 0);
|
|
||||||
|
|
||||||
NSString *messageAuthorId = message.authorId;
|
NSString *messageAuthorId = message.authorId;
|
||||||
OWSAssertDebug(messageAuthorId.length > 0);
|
|
||||||
|
|
||||||
OWSLinkedDeviceReadReceipt *newReadReceipt =
|
if (!message.thread.isGroupThread) { return; } // Don't send read receipts in group threads
|
||||||
[[OWSLinkedDeviceReadReceipt alloc] initWithSenderId:messageAuthorId
|
|
||||||
messageIdTimestamp:message.timestamp
|
|
||||||
readTimestamp:[NSDate ows_millisecondTimeStamp]];
|
|
||||||
|
|
||||||
OWSLinkedDeviceReadReceipt *_Nullable oldReadReceipt = self.toLinkedDevicesReadReceiptMap[threadUniqueId];
|
|
||||||
if (oldReadReceipt && oldReadReceipt.messageIdTimestamp > newReadReceipt.messageIdTimestamp) {
|
|
||||||
// If there's an existing "linked device" read receipt for the same thread with
|
|
||||||
// a newer timestamp, discard this "linked device" read receipt.
|
|
||||||
OWSLogVerbose(@"Ignoring redundant read receipt for linked devices.");
|
|
||||||
} else {
|
|
||||||
OWSLogVerbose(@"Enqueuing read receipt for linked devices.");
|
|
||||||
self.toLinkedDevicesReadReceiptMap[threadUniqueId] = newReadReceipt;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (![LKSessionMetaProtocol shouldSendReceiptInThread:message.thread]) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ([self areReadReceiptsEnabled]) {
|
if ([self areReadReceiptsEnabled]) {
|
||||||
OWSLogVerbose(@"Enqueuing read receipt for sender.");
|
|
||||||
[self.outgoingReceiptManager enqueueReadReceiptForEnvelope:messageAuthorId timestamp:message.timestamp];
|
[self.outgoingReceiptManager enqueueReadReceiptForEnvelope:messageAuthorId timestamp:message.timestamp];
|
||||||
}
|
}
|
||||||
|
|
||||||
[self scheduleProcessing];
|
[self scheduleProcessing];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Read Receipts From Recipient
|
#pragma mark - Read Receipts From Recipient
|
||||||
|
|
|
@ -272,11 +272,8 @@ public class TypingIndicatorsImpl: NSObject, TypingIndicators {
|
||||||
|
|
||||||
let typingIndicator = TypingIndicator()
|
let typingIndicator = TypingIndicator()
|
||||||
typingIndicator.kind = action
|
typingIndicator.kind = action
|
||||||
typingIndicator.threadID = thread.uniqueId!
|
|
||||||
let destination = Message.Destination.from(thread)
|
|
||||||
let job = MessageSendJob(message: typingIndicator, destination: destination)
|
|
||||||
Storage.write { transaction in
|
Storage.write { transaction in
|
||||||
SessionMessagingKit.JobQueue.shared.add(job, using: transaction)
|
MessageSender.send(typingIndicator, in: thread, using: transaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -111,8 +111,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (void)playWithAudioActivity:(OWSAudioActivity *)audioActivity
|
- (void)playWithAudioActivity:(OWSAudioActivity *)audioActivity
|
||||||
{
|
{
|
||||||
BOOL success = [self.audioSession startAudioActivity:audioActivity];
|
|
||||||
|
|
||||||
[self.audioPlayerPoller invalidate];
|
[self.audioPlayerPoller invalidate];
|
||||||
|
|
||||||
self.delegate.audioPlaybackState = AudioPlaybackState_Playing;
|
self.delegate.audioPlaybackState = AudioPlaybackState_Playing;
|
||||||
|
|
|
@ -37,7 +37,6 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
|
||||||
_soundURL = url;
|
_soundURL = url;
|
||||||
|
|
||||||
SystemSoundID newSoundID;
|
SystemSoundID newSoundID;
|
||||||
OSStatus status = AudioServicesCreateSystemSoundID((__bridge CFURLRef _Nonnull)(url), &newSoundID);
|
|
||||||
_soundID = newSoundID;
|
_soundID = newSoundID;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -45,7 +44,7 @@ NSString *const kOWSSoundsStorageGlobalNotificationKey = @"kOWSSoundsStorageGlob
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
OSStatus status = AudioServicesDisposeSystemSoundID(_soundID);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -2822,6 +2822,8 @@
|
||||||
C33FDBEC255A581B00E217F9 /* OWSRecipientIdentity.m */,
|
C33FDBEC255A581B00E217F9 /* OWSRecipientIdentity.m */,
|
||||||
C32C5C92256DD12D003C73A2 /* OWSUDManager.swift */,
|
C32C5C92256DD12D003C73A2 /* OWSUDManager.swift */,
|
||||||
C33FDBB9255A581600E217F9 /* ProfileManagerProtocol.h */,
|
C33FDBB9255A581600E217F9 /* ProfileManagerProtocol.h */,
|
||||||
|
C33FDAEC255A580500E217F9 /* SignalRecipient.h */,
|
||||||
|
C33FDBB7255A581600E217F9 /* SignalRecipient.m */,
|
||||||
C33FDB94255A581300E217F9 /* TSAccountManager.h */,
|
C33FDB94255A581300E217F9 /* TSAccountManager.h */,
|
||||||
C33FDB88255A581200E217F9 /* TSAccountManager.m */,
|
C33FDB88255A581200E217F9 /* TSAccountManager.m */,
|
||||||
);
|
);
|
||||||
|
@ -3338,8 +3340,6 @@
|
||||||
C3BBE0B42554F0E10050F1E3 /* ProofOfWork.swift */,
|
C3BBE0B42554F0E10050F1E3 /* ProofOfWork.swift */,
|
||||||
C33FDB91255A581200E217F9 /* ProtoUtils.h */,
|
C33FDB91255A581200E217F9 /* ProtoUtils.h */,
|
||||||
C33FDA6C255A57FA00E217F9 /* ProtoUtils.m */,
|
C33FDA6C255A57FA00E217F9 /* ProtoUtils.m */,
|
||||||
C33FDAEC255A580500E217F9 /* SignalRecipient.h */,
|
|
||||||
C33FDBB7255A581600E217F9 /* SignalRecipient.m */,
|
|
||||||
C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */,
|
C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */,
|
||||||
C33FDB31255A580A00E217F9 /* SSKEnvironment.h */,
|
C33FDB31255A580A00E217F9 /* SSKEnvironment.h */,
|
||||||
C33FDAF4255A580600E217F9 /* SSKEnvironment.m */,
|
C33FDAF4255A580600E217F9 /* SSKEnvironment.m */,
|
||||||
|
|
Loading…
Reference in New Issue