Restructure
This commit is contained in:
parent
178ab7e3e2
commit
5dfd4b1965
6
Podfile
6
Podfile
|
@ -69,8 +69,11 @@ target 'SessionMessagingKit' do
|
||||||
pod 'AFNetworking', inhibit_warnings: true
|
pod 'AFNetworking', inhibit_warnings: true
|
||||||
pod 'CryptoSwift', :inhibit_warnings => true
|
pod 'CryptoSwift', :inhibit_warnings => true
|
||||||
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
|
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
|
||||||
|
pod 'HKDFKit', :inhibit_warnings => true
|
||||||
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
|
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
|
||||||
pod 'PromiseKit', :inhibit_warnings => true
|
pod 'PromiseKit', :inhibit_warnings => true
|
||||||
|
pod 'Reachability', :inhibit_warnings => true
|
||||||
|
pod 'SAMKeychain', :inhibit_warnings => true
|
||||||
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
|
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
|
||||||
pod 'SwiftProtobuf', '~> 1.5.0', :inhibit_warnings => true
|
pod 'SwiftProtobuf', '~> 1.5.0', :inhibit_warnings => true
|
||||||
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
|
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
|
||||||
|
@ -92,13 +95,16 @@ target 'SessionSnodeKit' do
|
||||||
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
|
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
|
||||||
pod 'PromiseKit', :inhibit_warnings => true
|
pod 'PromiseKit', :inhibit_warnings => true
|
||||||
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
|
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
|
||||||
|
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
|
||||||
end
|
end
|
||||||
|
|
||||||
target 'SessionUtilitiesKit' do
|
target 'SessionUtilitiesKit' do
|
||||||
|
pod 'AFNetworking', inhibit_warnings: true
|
||||||
pod 'CryptoSwift', :inhibit_warnings => true
|
pod 'CryptoSwift', :inhibit_warnings => true
|
||||||
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
|
pod 'Curve25519Kit', git: 'https://github.com/signalapp/Curve25519Kit.git', :inhibit_warnings => true
|
||||||
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
|
pod 'Mantle', git: 'https://github.com/signalapp/Mantle', branch: 'signal-master', :inhibit_warnings => true
|
||||||
pod 'PromiseKit', :inhibit_warnings => true
|
pod 'PromiseKit', :inhibit_warnings => true
|
||||||
|
pod 'SAMKeychain', :inhibit_warnings => true
|
||||||
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
|
pod 'SignalCoreKit', git: 'https://github.com/signalapp/SignalCoreKit.git', :inhibit_warnings => true
|
||||||
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
|
pod 'YapDatabase/SQLCipher', :git => 'https://github.com/signalapp/YapDatabase.git', branch: 'signal-release', :inhibit_warnings => true
|
||||||
end
|
end
|
||||||
|
|
|
@ -230,6 +230,6 @@ SPEC CHECKSUMS:
|
||||||
YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665
|
YYImage: 6db68da66f20d9f169ceb94dfb9947c3867b9665
|
||||||
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
ZXingObjC: fdbb269f25dd2032da343e06f10224d62f537bdb
|
||||||
|
|
||||||
PODFILE CHECKSUM: 62df79698293257648cb6e60724f720f8477bd0f
|
PODFILE CHECKSUM: b12682bc3bf974c758ec8e4b9838639f7ec51d5e
|
||||||
|
|
||||||
COCOAPODS: 1.10.0.rc.1
|
COCOAPODS: 1.10.0.rc.1
|
||||||
|
|
|
@ -66,31 +66,31 @@
|
||||||
#import <SessionUtilitiesKit/DataSource.h>
|
#import <SessionUtilitiesKit/DataSource.h>
|
||||||
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
||||||
#import <SessionUtilitiesKit/NSData+Image.h>
|
#import <SessionUtilitiesKit/NSData+Image.h>
|
||||||
#import <SignalUtilitiesKit/NSNotificationCenter+OWS.h>
|
#import <SessionUtilitiesKit/NSNotificationCenter+OWS.h>
|
||||||
#import <SignalUtilitiesKit/NSString+SSK.h>
|
#import <SignalUtilitiesKit/NSString+SSK.h>
|
||||||
#import <SignalUtilitiesKit/OWSBackgroundTask.h>
|
#import <SessionMessagingKit/OWSBackgroundTask.h>
|
||||||
#import <SignalUtilitiesKit/OWSContactsOutputStream.h>
|
#import <SignalUtilitiesKit/OWSContactsOutputStream.h>
|
||||||
#import <SignalUtilitiesKit/OWSDispatch.h>
|
#import <SignalUtilitiesKit/OWSDispatch.h>
|
||||||
#import <SignalUtilitiesKit/OWSError.h>
|
#import <SignalUtilitiesKit/OWSError.h>
|
||||||
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
||||||
#import <SignalUtilitiesKit/OWSIdentityManager.h>
|
#import <SessionMessagingKit/OWSIdentityManager.h>
|
||||||
#import <SignalUtilitiesKit/OWSMediaGalleryFinder.h>
|
#import <SignalUtilitiesKit/OWSMediaGalleryFinder.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage+SessionStore.h>
|
#import <SignalUtilitiesKit/OWSPrimaryStorage+SessionStore.h>
|
||||||
#import <SignalUtilitiesKit/OWSRecipientIdentity.h>
|
#import <SignalUtilitiesKit/OWSRecipientIdentity.h>
|
||||||
#import <SignalUtilitiesKit/SignalAccount.h>
|
#import <SignalUtilitiesKit/SignalAccount.h>
|
||||||
#import <SignalUtilitiesKit/SignalRecipient.h>
|
#import <SignalUtilitiesKit/SignalRecipient.h>
|
||||||
#import <SignalUtilitiesKit/TSAccountManager.h>
|
#import <SessionMessagingKit/TSAccountManager.h>
|
||||||
#import <SessionMessagingKit/TSAttachment.h>
|
#import <SessionMessagingKit/TSAttachment.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentPointer.h>
|
#import <SessionMessagingKit/TSAttachmentPointer.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentStream.h>
|
#import <SessionMessagingKit/TSAttachmentStream.h>
|
||||||
#import <SignalUtilitiesKit/TSContactThread.h>
|
#import <SessionMessagingKit/TSContactThread.h>
|
||||||
#import <SignalUtilitiesKit/TSErrorMessage.h>
|
#import <SignalUtilitiesKit/TSErrorMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSGroupThread.h>
|
#import <SessionMessagingKit/TSGroupThread.h>
|
||||||
#import <SignalUtilitiesKit/TSIncomingMessage.h>
|
#import <SessionMessagingKit/TSIncomingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSInfoMessage.h>
|
#import <SignalUtilitiesKit/TSInfoMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSOutgoingMessage.h>
|
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSPreKeyManager.h>
|
#import <SignalUtilitiesKit/TSPreKeyManager.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
#import <SignalUtilitiesKit/LKGroupUtilities.h>
|
#import <SignalUtilitiesKit/LKGroupUtilities.h>
|
||||||
#import <SessionUtilitiesKit/UIImage+OWS.h>
|
#import <SessionUtilitiesKit/UIImage+OWS.h>
|
||||||
#import <WebRTC/RTCAudioSession.h>
|
#import <WebRTC/RTCAudioSession.h>
|
||||||
|
|
|
@ -8,8 +8,8 @@
|
||||||
#import <SignalUtilitiesKit/Environment.h>
|
#import <SignalUtilitiesKit/Environment.h>
|
||||||
#import <SignalUtilitiesKit/OWSPreferences.h>
|
#import <SignalUtilitiesKit/OWSPreferences.h>
|
||||||
#import <SignalUtilitiesKit/UIUtil.h>
|
#import <SignalUtilitiesKit/UIUtil.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage.h>
|
#import <SessionMessagingKit/OWSPrimaryStorage.h>
|
||||||
#import <SignalUtilitiesKit/TSDatabaseView.h>
|
#import <SessionMessagingKit/TSDatabaseView.h>
|
||||||
|
|
||||||
@implementation AboutTableViewController
|
@implementation AboutTableViewController
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
|
|
||||||
#import "AddToBlockListViewController.h"
|
#import "AddToBlockListViewController.h"
|
||||||
#import "BlockListUIUtils.h"
|
#import "BlockListUIUtils.h"
|
||||||
#import <SignalUtilitiesKit/SSKEnvironment.h>
|
#import <SessionMessagingKit/SSKEnvironment.h>
|
||||||
#import <SignalUtilitiesKit/OWSBlockingManager.h>
|
#import <SessionMessagingKit/OWSBlockingManager.h>
|
||||||
#import <SignalUtilitiesKit/SignalAccount.h>
|
#import <SignalUtilitiesKit/SignalAccount.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -18,17 +18,17 @@
|
||||||
#import <SignalUtilitiesKit/OWSPreferences.h>
|
#import <SignalUtilitiesKit/OWSPreferences.h>
|
||||||
#import <SignalUtilitiesKit/OWSProfileManager.h>
|
#import <SignalUtilitiesKit/OWSProfileManager.h>
|
||||||
#import <SignalUtilitiesKit/VersionMigrations.h>
|
#import <SignalUtilitiesKit/VersionMigrations.h>
|
||||||
#import <SignalUtilitiesKit/AppReadiness.h>
|
#import <SessionMessagingKit/AppReadiness.h>
|
||||||
#import <SignalUtilitiesKit/NSUserDefaults+OWS.h>
|
#import <SessionUtilitiesKit/NSUserDefaults+OWS.h>
|
||||||
#import <SignalUtilitiesKit/OWSDisappearingMessagesJob.h>
|
#import <SessionMessagingKit/OWSDisappearingMessagesJob.h>
|
||||||
#import <SignalUtilitiesKit/OWSFailedAttachmentDownloadsJob.h>
|
#import <SignalUtilitiesKit/OWSFailedAttachmentDownloadsJob.h>
|
||||||
#import <SignalUtilitiesKit/OWSFailedMessagesJob.h>
|
#import <SignalUtilitiesKit/OWSFailedMessagesJob.h>
|
||||||
#import <SignalUtilitiesKit/OWSMath.h>
|
#import <SignalUtilitiesKit/OWSMath.h>
|
||||||
#import <SignalUtilitiesKit/OWSReadReceiptManager.h>
|
#import <SessionMessagingKit/OWSReadReceiptManager.h>
|
||||||
#import <SignalUtilitiesKit/SSKEnvironment.h>
|
#import <SessionMessagingKit/SSKEnvironment.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SignalUtilitiesKit/TSAccountManager.h>
|
#import <SessionMessagingKit/TSAccountManager.h>
|
||||||
#import <SignalUtilitiesKit/TSDatabaseView.h>
|
#import <SessionMessagingKit/TSDatabaseView.h>
|
||||||
#import <SignalUtilitiesKit/TSPreKeyManager.h>
|
#import <SignalUtilitiesKit/TSPreKeyManager.h>
|
||||||
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
||||||
#import <sys/utsname.h>
|
#import <sys/utsname.h>
|
||||||
|
|
|
@ -10,8 +10,8 @@
|
||||||
#import <SignalUtilitiesKit/UIUtil.h>
|
#import <SignalUtilitiesKit/UIUtil.h>
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSGroupModel.h>
|
#import <SignalUtilitiesKit/TSGroupModel.h>
|
||||||
#import <SignalUtilitiesKit/TSGroupThread.h>
|
#import <SessionMessagingKit/TSGroupThread.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#import "TSGroupThread.h"
|
#import "TSGroupThread.h"
|
||||||
#import "TSIncomingMessage.h"
|
#import "TSIncomingMessage.h"
|
||||||
#import "TSInfoMessage.h"
|
#import "TSInfoMessage.h"
|
||||||
#import <SignalUtilitiesKit/TSInvalidIdentityKeyErrorMessage.h>
|
#import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
|
||||||
#import "UIFont+OWS.h"
|
#import "UIFont+OWS.h"
|
||||||
#import "UIViewController+Permissions.h"
|
#import "UIViewController+Permissions.h"
|
||||||
#import <AVFoundation/AVFoundation.h>
|
#import <AVFoundation/AVFoundation.h>
|
||||||
|
@ -53,15 +53,15 @@
|
||||||
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
||||||
#import <SignalUtilitiesKit/NSString+SSK.h>
|
#import <SignalUtilitiesKit/NSString+SSK.h>
|
||||||
#import <SignalUtilitiesKit/OWSAttachmentDownloads.h>
|
#import <SignalUtilitiesKit/OWSAttachmentDownloads.h>
|
||||||
#import <SignalUtilitiesKit/OWSBlockingManager.h>
|
#import <SessionMessagingKit/OWSBlockingManager.h>
|
||||||
#import <SignalUtilitiesKit/OWSDisappearingMessagesConfiguration.h>
|
#import <SessionMessagingKit/OWSDisappearingMessagesConfiguration.h>
|
||||||
#import <SignalUtilitiesKit/OWSIdentityManager.h>
|
#import <SessionMessagingKit/OWSIdentityManager.h>
|
||||||
#import <SignalUtilitiesKit/OWSMessageUtils.h>
|
#import <SignalUtilitiesKit/OWSMessageUtils.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage.h>
|
#import <SessionMessagingKit/OWSPrimaryStorage.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage+Loki.h>
|
#import <SignalUtilitiesKit/OWSPrimaryStorage+Loki.h>
|
||||||
#import <SignalUtilitiesKit/OWSReadReceiptManager.h>
|
#import <SessionMessagingKit/OWSReadReceiptManager.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SignalUtilitiesKit/TSAccountManager.h>
|
#import <SessionMessagingKit/TSAccountManager.h>
|
||||||
#import <SignalUtilitiesKit/TSGroupModel.h>
|
#import <SignalUtilitiesKit/TSGroupModel.h>
|
||||||
#import <SignalUtilitiesKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
|
#import <SignalUtilitiesKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSQuotedMessage.h>
|
#import <SignalUtilitiesKit/TSQuotedMessage.h>
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#import <SignalUtilitiesKit/NSString+SSK.h>
|
#import <SignalUtilitiesKit/NSString+SSK.h>
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSInteraction.h>
|
#import <SignalUtilitiesKit/TSInteraction.h>
|
||||||
#import <SignalUtilitiesKit/SSKEnvironment.h>
|
#import <SessionMessagingKit/SSKEnvironment.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -11,14 +11,14 @@
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SignalUtilitiesKit/OWSUnreadIndicator.h>
|
#import <SignalUtilitiesKit/OWSUnreadIndicator.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SignalUtilitiesKit/OWSBlockingManager.h>
|
#import <SessionMessagingKit/OWSBlockingManager.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage.h>
|
#import <SessionMessagingKit/OWSPrimaryStorage.h>
|
||||||
#import <SignalUtilitiesKit/SSKEnvironment.h>
|
#import <SessionMessagingKit/SSKEnvironment.h>
|
||||||
#import <SignalUtilitiesKit/TSDatabaseView.h>
|
#import <SessionMessagingKit/TSDatabaseView.h>
|
||||||
#import <SignalUtilitiesKit/TSIncomingMessage.h>
|
#import <SessionMessagingKit/TSIncomingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSOutgoingMessage.h>
|
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
#import <SignalUtilitiesKit/TSGroupThread.h>
|
#import <SessionMessagingKit/TSGroupThread.h>
|
||||||
#import <SignalUtilitiesKit/TSGroupModel.h>
|
#import <SignalUtilitiesKit/TSGroupModel.h>
|
||||||
#import <YapDatabase/YapDatabase.h>
|
#import <YapDatabase/YapDatabase.h>
|
||||||
#import <YapDatabase/YapDatabaseAutoView.h>
|
#import <YapDatabase/YapDatabaseAutoView.h>
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
#import <SignalUtilitiesKit/Environment.h>
|
#import <SignalUtilitiesKit/Environment.h>
|
||||||
#import <SignalUtilitiesKit/OWSProfileManager.h>
|
#import <SignalUtilitiesKit/OWSProfileManager.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SignalUtilitiesKit/OWSIdentityManager.h>
|
#import <SessionMessagingKit/OWSIdentityManager.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
#import "Session-Swift.h"
|
#import "Session-Swift.h"
|
||||||
#import <PromiseKit/AnyPromise.h>
|
#import <PromiseKit/AnyPromise.h>
|
||||||
#import <SignalCoreKit/Randomness.h>
|
#import <SignalCoreKit/Randomness.h>
|
||||||
#import <SignalUtilitiesKit/OWSIdentityManager.h>
|
#import <SessionMessagingKit/OWSIdentityManager.h>
|
||||||
#import <SignalUtilitiesKit/YapDatabaseConnection+OWS.h>
|
#import <SessionMessagingKit/YapDatabaseConnection+OWS.h>
|
||||||
|
|
||||||
@import CloudKit;
|
@import CloudKit;
|
||||||
|
|
||||||
|
|
|
@ -10,13 +10,13 @@
|
||||||
#import <SignalCoreKit/NSData+OWS.h>
|
#import <SignalCoreKit/NSData+OWS.h>
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SignalCoreKit/Threading.h>
|
#import <SignalCoreKit/Threading.h>
|
||||||
#import <SignalUtilitiesKit/OWSBackgroundTask.h>
|
#import <SessionMessagingKit/OWSBackgroundTask.h>
|
||||||
#import <SignalUtilitiesKit/OWSError.h>
|
#import <SignalUtilitiesKit/OWSError.h>
|
||||||
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
||||||
#import <SessionMessagingKit/TSAttachment.h>
|
#import <SessionMessagingKit/TSAttachment.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentStream.h>
|
#import <SessionMessagingKit/TSAttachmentStream.h>
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SignalUtilitiesKit/TSMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
|
|
||||||
@import CloudKit;
|
@import CloudKit;
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,11 @@
|
||||||
#import "Session-Swift.h"
|
#import "Session-Swift.h"
|
||||||
#import <PromiseKit/AnyPromise.h>
|
#import <PromiseKit/AnyPromise.h>
|
||||||
#import <SignalCoreKit/NSData+OWS.h>
|
#import <SignalCoreKit/NSData+OWS.h>
|
||||||
#import <SignalUtilitiesKit/OWSBackgroundTask.h>
|
#import <SessionMessagingKit/OWSBackgroundTask.h>
|
||||||
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
||||||
#import <SessionMessagingKit/TSAttachment.h>
|
#import <SessionMessagingKit/TSAttachment.h>
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SignalUtilitiesKit/TSMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
|
|
@ -23,12 +23,12 @@
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SignalUtilitiesKit/UIUtil.h>
|
#import <SignalUtilitiesKit/UIUtil.h>
|
||||||
#import <SignalUtilitiesKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
|
#import <SignalUtilitiesKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
|
||||||
#import <SignalUtilitiesKit/OWSDisappearingMessagesConfiguration.h>
|
#import <SessionMessagingKit/OWSDisappearingMessagesConfiguration.h>
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage.h>
|
#import <SessionMessagingKit/OWSPrimaryStorage.h>
|
||||||
#import <SignalUtilitiesKit/TSGroupThread.h>
|
#import <SessionMessagingKit/TSGroupThread.h>
|
||||||
#import <SignalUtilitiesKit/TSOutgoingMessage.h>
|
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
|
|
||||||
@import ContactsUI;
|
@import ContactsUI;
|
||||||
@import PromiseKit;
|
@import PromiseKit;
|
||||||
|
|
|
@ -7,17 +7,17 @@
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SignalUtilitiesKit/OWSProfileManager.h>
|
#import <SignalUtilitiesKit/OWSProfileManager.h>
|
||||||
#import <SignalUtilitiesKit/OWSUserProfile.h>
|
#import <SignalUtilitiesKit/OWSUserProfile.h>
|
||||||
#import <SignalUtilitiesKit/AppReadiness.h>
|
#import <SessionMessagingKit/AppReadiness.h>
|
||||||
#import <SignalUtilitiesKit/AppVersion.h>
|
#import <SignalUtilitiesKit/AppVersion.h>
|
||||||
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
||||||
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
#import <SessionUtilitiesKit/OWSFileSystem.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage.h>
|
#import <SessionMessagingKit/OWSPrimaryStorage.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentStream.h>
|
#import <SessionMessagingKit/TSAttachmentStream.h>
|
||||||
#import <SignalUtilitiesKit/TSInteraction.h>
|
#import <SignalUtilitiesKit/TSInteraction.h>
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SignalUtilitiesKit/TSMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSQuotedMessage.h>
|
#import <SignalUtilitiesKit/TSQuotedMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
#import <SignalUtilitiesKit/YapDatabaseTransaction+OWS.h>
|
#import <SessionMessagingKit/YapDatabaseTransaction+OWS.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <YapDatabase/YapDatabase.h>
|
#import <YapDatabase/YapDatabase.h>
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/SSKJobRecord.h>
|
#import <SessionMessagingKit/SSKJobRecord.h>
|
||||||
|
|
||||||
@class TSContactThread;
|
@class TSContactThread;
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "OWSSessionResetJobRecord.h"
|
#import "OWSSessionResetJobRecord.h"
|
||||||
#import <SignalUtilitiesKit/TSContactThread.h>
|
#import <SessionMessagingKit/TSContactThread.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
#import <SignalUtilitiesKit/NSString+SSK.h>
|
#import <SignalUtilitiesKit/NSString+SSK.h>
|
||||||
#import <SignalUtilitiesKit/ThreadUtil.h>
|
#import <SignalUtilitiesKit/ThreadUtil.h>
|
||||||
#import <SignalUtilitiesKit/OWSReadReceiptManager.h>
|
#import <SessionMessagingKit/OWSReadReceiptManager.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -9,9 +9,9 @@
|
||||||
#import <SignalCoreKit/Threading.h>
|
#import <SignalCoreKit/Threading.h>
|
||||||
#import <SignalUtilitiesKit/DebugLogger.h>
|
#import <SignalUtilitiesKit/DebugLogger.h>
|
||||||
#import <SignalUtilitiesKit/Environment.h>
|
#import <SignalUtilitiesKit/Environment.h>
|
||||||
#import <SignalUtilitiesKit/OWSPrimaryStorage.h>
|
#import <SessionMessagingKit/OWSPrimaryStorage.h>
|
||||||
#import <SignalUtilitiesKit/TSContactThread.h>
|
#import <SessionMessagingKit/TSContactThread.h>
|
||||||
#import <SignalUtilitiesKit/TSGroupThread.h>
|
#import <SessionMessagingKit/TSGroupThread.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
|
|
@ -2,15 +2,10 @@ import SessionProtocolKit
|
||||||
|
|
||||||
public struct Configuration {
|
public struct Configuration {
|
||||||
public let storage: SessionMessagingKitStorageProtocol
|
public let storage: SessionMessagingKitStorageProtocol
|
||||||
public let messageSenderDelegate: MessageSenderDelegate
|
|
||||||
public let messageReceiverDelegate: MessageReceiverDelegate
|
|
||||||
public let signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore
|
public let signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore
|
||||||
public let identityKeyStore: IdentityKeyStore
|
public let identityKeyStore: IdentityKeyStore
|
||||||
public let sessionRestorationImplementation: SessionRestorationProtocol
|
public let sessionRestorationImplementation: SessionRestorationProtocol
|
||||||
public let certificateValidator: SMKCertificateValidator
|
public let certificateValidator: SMKCertificateValidator
|
||||||
public let openGroupAPIDelegate: OpenGroupAPIDelegate
|
|
||||||
public let pnServerURL: String
|
|
||||||
public let pnServerPublicKey: String
|
|
||||||
|
|
||||||
internal static var shared: Configuration!
|
internal static var shared: Configuration!
|
||||||
}
|
}
|
||||||
|
@ -19,27 +14,17 @@ public enum SNMessagingKit { // Just to make the external API nice
|
||||||
|
|
||||||
public static func configure(
|
public static func configure(
|
||||||
storage: SessionMessagingKitStorageProtocol,
|
storage: SessionMessagingKitStorageProtocol,
|
||||||
messageSenderDelegate: MessageSenderDelegate,
|
|
||||||
messageReceiverDelegate: MessageReceiverDelegate,
|
|
||||||
signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore,
|
signalStorage: SessionStore & PreKeyStore & SignedPreKeyStore,
|
||||||
identityKeyStore: IdentityKeyStore,
|
identityKeyStore: IdentityKeyStore,
|
||||||
sessionRestorationImplementation: SessionRestorationProtocol,
|
sessionRestorationImplementation: SessionRestorationProtocol,
|
||||||
certificateValidator: SMKCertificateValidator,
|
certificateValidator: SMKCertificateValidator
|
||||||
openGroupAPIDelegate: OpenGroupAPIDelegate,
|
|
||||||
pnServerURL: String,
|
|
||||||
pnServerPublicKey: String
|
|
||||||
) {
|
) {
|
||||||
Configuration.shared = Configuration(
|
Configuration.shared = Configuration(
|
||||||
storage: storage,
|
storage: storage,
|
||||||
messageSenderDelegate: messageSenderDelegate,
|
|
||||||
messageReceiverDelegate: messageReceiverDelegate,
|
|
||||||
signalStorage: signalStorage,
|
signalStorage: signalStorage,
|
||||||
identityKeyStore: identityKeyStore,
|
identityKeyStore: identityKeyStore,
|
||||||
sessionRestorationImplementation: sessionRestorationImplementation,
|
sessionRestorationImplementation: sessionRestorationImplementation,
|
||||||
certificateValidator: certificateValidator,
|
certificateValidator: certificateValidator
|
||||||
openGroupAPIDelegate: openGroupAPIDelegate,
|
|
||||||
pnServerURL: pnServerURL,
|
|
||||||
pnServerPublicKey: pnServerPublicKey
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/OWSStorage.h>
|
#import <SessionMessagingKit/OWSStorage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
#import "OWSPrimaryStorage.h"
|
#import "OWSPrimaryStorage.h"
|
||||||
#import "AppContext.h"
|
#import "AppContext.h"
|
||||||
#import "OWSDisappearingMessagesFinder.h"
|
#import "OWSDisappearingMessagesFinder.h"
|
||||||
#import "OWSFailedAttachmentDownloadsJob.h"
|
|
||||||
#import "OWSFailedMessagesJob.h"
|
|
||||||
#import "OWSFileSystem.h"
|
#import "OWSFileSystem.h"
|
||||||
#import "OWSIncomingMessageFinder.h"
|
#import "OWSIncomingMessageFinder.h"
|
||||||
#import "OWSMediaGalleryFinder.h"
|
#import "OWSMediaGalleryFinder.h"
|
||||||
|
@ -14,7 +12,8 @@
|
||||||
#import "SSKEnvironment.h"
|
#import "SSKEnvironment.h"
|
||||||
#import "TSDatabaseSecondaryIndexes.h"
|
#import "TSDatabaseSecondaryIndexes.h"
|
||||||
#import "TSDatabaseView.h"
|
#import "TSDatabaseView.h"
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
|
#import <YapDatabase/YapDatabaseConnectionPool.h>
|
||||||
#import "SSKAsserts.h"
|
#import "SSKAsserts.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
@ -201,8 +200,6 @@ void VerifyRegistrationsForPrimaryStorage(OWSStorage *storage)
|
||||||
[FullTextSearchFinder asyncRegisterDatabaseExtensionWithStorage:self];
|
[FullTextSearchFinder asyncRegisterDatabaseExtensionWithStorage:self];
|
||||||
[OWSIncomingMessageFinder asyncRegisterExtensionWithPrimaryStorage:self];
|
[OWSIncomingMessageFinder asyncRegisterExtensionWithPrimaryStorage:self];
|
||||||
[OWSDisappearingMessagesFinder asyncRegisterDatabaseExtensions:self];
|
[OWSDisappearingMessagesFinder asyncRegisterDatabaseExtensions:self];
|
||||||
[OWSFailedMessagesJob asyncRegisterDatabaseExtensionsWithPrimaryStorage:self];
|
|
||||||
[OWSFailedAttachmentDownloadsJob asyncRegisterDatabaseExtensionsWithPrimaryStorage:self];
|
|
||||||
[OWSMediaGalleryFinder asyncRegisterDatabaseExtensionsWithPrimaryStorage:self];
|
[OWSMediaGalleryFinder asyncRegisterDatabaseExtensionsWithPrimaryStorage:self];
|
||||||
[TSDatabaseView asyncRegisterLazyRestoreAttachmentsDatabaseView:self];
|
[TSDatabaseView asyncRegisterLazyRestoreAttachmentsDatabaseView:self];
|
||||||
[SSKJobRecordFinder asyncRegisterDatabaseExtensionObjCWithStorage:self];
|
[SSKJobRecordFinder asyncRegisterDatabaseExtensionObjCWithStorage:self];
|
|
@ -4,24 +4,24 @@
|
||||||
|
|
||||||
#import "OWSStorage.h"
|
#import "OWSStorage.h"
|
||||||
#import "AppContext.h"
|
#import "AppContext.h"
|
||||||
#import "NSNotificationCenter+OWS.h"
|
|
||||||
#import "NSUserDefaults+OWS.h"
|
|
||||||
#import "OWSBackgroundTask.h"
|
#import "OWSBackgroundTask.h"
|
||||||
#import "OWSFileSystem.h"
|
#import "OWSFileSystem.h"
|
||||||
#import "OWSPrimaryStorage.h"
|
#import "OWSPrimaryStorage.h"
|
||||||
#import "OWSStorage+Subclass.h"
|
#import "TSYapDatabaseObject.h"
|
||||||
#import "TSAttachmentStream.h"
|
#import "TSAttachmentStream.h"
|
||||||
#import <SignalCoreKit/NSData+OWS.h>
|
#import <SignalCoreKit/SignalCoreKit.h>
|
||||||
#import <SignalCoreKit/Randomness.h>
|
#import <SignalCoreKit/Randomness.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
|
||||||
#import <YapDatabase/YapDatabase.h>
|
#import <YapDatabase/YapDatabase.h>
|
||||||
#import <YapDatabase/YapDatabaseAutoView.h>
|
#import <YapDatabase/YapDatabaseAutoView.h>
|
||||||
#import <YapDatabase/YapDatabaseCrossProcessNotification.h>
|
|
||||||
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
#import <YapDatabase/YapDatabaseCryptoUtils.h>
|
||||||
|
#import <YapDatabase/YapDatabaseCrossProcessNotification.h>
|
||||||
#import <YapDatabase/YapDatabaseFullTextSearch.h>
|
#import <YapDatabase/YapDatabaseFullTextSearch.h>
|
||||||
#import <YapDatabase/YapDatabaseFullTextSearchPrivate.h>
|
#import <YapDatabase/YapDatabaseFullTextSearchPrivate.h>
|
||||||
#import <YapDatabase/YapDatabaseSecondaryIndex.h>
|
#import <YapDatabase/YapDatabaseSecondaryIndex.h>
|
||||||
#import <YapDatabase/YapDatabaseSecondaryIndexPrivate.h>
|
#import <YapDatabase/YapDatabaseSecondaryIndexPrivate.h>
|
||||||
|
#import <YapDatabase/YapDatabaseSecondaryIndexSetup.h>
|
||||||
|
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
||||||
|
#import <SessionUtilitiesKit/AppContext.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -59,8 +59,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
OWSAssertDebug(delegate);
|
|
||||||
|
|
||||||
self.delegate = delegate;
|
self.delegate = delegate;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -76,8 +74,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
- (void)readWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block
|
- (void)readWriteWithBlock:(void (^)(YapDatabaseReadWriteTransaction *transaction))block
|
||||||
{
|
{
|
||||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||||
OWSAssertDebug(delegate);
|
|
||||||
OWSAssertDebug(delegate.areAllRegistrationsComplete);
|
|
||||||
|
|
||||||
OWSBackgroundTask *_Nullable backgroundTask = nil;
|
OWSBackgroundTask *_Nullable backgroundTask = nil;
|
||||||
if (CurrentAppContext().isMainApp && !CurrentAppContext().isRunningTests) {
|
if (CurrentAppContext().isMainApp && !CurrentAppContext().isRunningTests) {
|
||||||
|
@ -103,8 +99,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
completionBlock:(nullable dispatch_block_t)completionBlock
|
completionBlock:(nullable dispatch_block_t)completionBlock
|
||||||
{
|
{
|
||||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||||
OWSAssertDebug(delegate);
|
|
||||||
OWSAssertDebug(delegate.areAllRegistrationsComplete);
|
|
||||||
|
|
||||||
__block OWSBackgroundTask *_Nullable backgroundTask = nil;
|
__block OWSBackgroundTask *_Nullable backgroundTask = nil;
|
||||||
if (CurrentAppContext().isMainApp) {
|
if (CurrentAppContext().isMainApp) {
|
||||||
|
@ -155,8 +149,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
OWSAssertDebug(delegate);
|
|
||||||
|
|
||||||
self.delegate = delegate;
|
self.delegate = delegate;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
|
@ -169,7 +161,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
- (YapDatabaseConnection *)newConnection
|
- (YapDatabaseConnection *)newConnection
|
||||||
{
|
{
|
||||||
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
id<OWSDatabaseConnectionDelegate> delegate = self.delegate;
|
||||||
OWSAssertDebug(delegate);
|
|
||||||
|
|
||||||
OWSDatabaseConnection *connection = [[OWSDatabaseConnection alloc] initWithDatabase:self delegate:delegate];
|
OWSDatabaseConnection *connection = [[OWSDatabaseConnection alloc] initWithDatabase:self delegate:delegate];
|
||||||
[self addConnection:connection];
|
[self addConnection:connection];
|
||||||
|
@ -201,8 +192,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
- (void)encodeWithCoder:(NSCoder *)aCoder
|
- (void)encodeWithCoder:(NSCoder *)aCoder
|
||||||
{
|
{
|
||||||
OWSFailDebug(@"Tried to save object from unknown collection");
|
|
||||||
|
|
||||||
return [super encodeWithCoder:aCoder];
|
return [super encodeWithCoder:aCoder];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,22 +207,16 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSFailDebug(@"Tried to save unknown object");
|
|
||||||
|
|
||||||
// No-op.
|
// No-op.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)touchWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSFailDebug(@"Tried to touch unknown object");
|
|
||||||
|
|
||||||
// No-op.
|
// No-op.
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSFailDebug(@"Tried to remove unknown object");
|
|
||||||
|
|
||||||
// No-op.
|
// No-op.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,11 +236,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
cannotDecodeObjectOfClassName:(NSString *)name
|
cannotDecodeObjectOfClassName:(NSString *)name
|
||||||
originalClasses:(NSArray<NSString *> *)classNames
|
originalClasses:(NSArray<NSString *> *)classNames
|
||||||
{
|
{
|
||||||
if ([name isEqualToString:@"TSRecipient"]) {
|
|
||||||
OWSLogError(@"Could not decode object: %@", name);
|
|
||||||
} else {
|
|
||||||
NSLog(@"Could not decode object: %@", name);
|
|
||||||
}
|
|
||||||
return [OWSUnknownDBObject class];
|
return [OWSUnknownDBObject class];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -295,9 +273,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
- (void)dealloc
|
- (void)dealloc
|
||||||
{
|
{
|
||||||
// Surface memory leaks by logging the deallocation of this class.
|
|
||||||
OWSLogVerbose(@"Dealloc: %@", self.class);
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -308,7 +283,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
//
|
//
|
||||||
// The best we can try to do is to discard the current database
|
// The best we can try to do is to discard the current database
|
||||||
// and behave like a clean install.
|
// and behave like a clean install.
|
||||||
OWSFailDebug(@"Could not load database");
|
|
||||||
|
|
||||||
// Try to reset app by deleting all databases.
|
// Try to reset app by deleting all databases.
|
||||||
//
|
//
|
||||||
|
@ -316,34 +290,27 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
// [OWSStorage deleteDatabaseFiles];
|
// [OWSStorage deleteDatabaseFiles];
|
||||||
|
|
||||||
if (![self tryToLoadDatabase]) {
|
if (![self tryToLoadDatabase]) {
|
||||||
OWSFailDebug(@"Could not load database (second try)");
|
|
||||||
|
|
||||||
// Sleep to give analytics events time to be delivered.
|
// Sleep to give analytics events time to be delivered.
|
||||||
[NSThread sleepForTimeInterval:15.0f];
|
[NSThread sleepForTimeInterval:15.0f];
|
||||||
|
|
||||||
OWSFail(@"Failed to initialize database.");
|
NSAssert(NO, @"Couldn't load database");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable id)dbNotificationObject
|
- (nullable id)dbNotificationObject
|
||||||
{
|
{
|
||||||
OWSAssertDebug(self.database);
|
|
||||||
|
|
||||||
return self.database;
|
return self.database;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)areAsyncRegistrationsComplete
|
- (BOOL)areAsyncRegistrationsComplete
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (BOOL)areSyncRegistrationsComplete
|
- (BOOL)areSyncRegistrationsComplete
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,26 +321,22 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
- (void)runSyncRegistrations
|
- (void)runSyncRegistrations
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion
|
- (void)runAsyncRegistrationsWithCompletion:(void (^_Nonnull)(void))completion
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)registerExtensionsWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock
|
+ (void)registerExtensionsWithMigrationBlock:(OWSStorageMigrationBlock)migrationBlock
|
||||||
{
|
{
|
||||||
OWSAssertDebug(migrationBlock);
|
|
||||||
|
|
||||||
__block OWSBackgroundTask *_Nullable backgroundTask =
|
__block OWSBackgroundTask *_Nullable backgroundTask =
|
||||||
[OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
|
[OWSBackgroundTask backgroundTaskWithLabelStr:__PRETTY_FUNCTION__];
|
||||||
|
|
||||||
[OWSPrimaryStorage.sharedManager runSyncRegistrations];
|
[OWSPrimaryStorage.sharedManager runSyncRegistrations];
|
||||||
|
|
||||||
[OWSPrimaryStorage.sharedManager runAsyncRegistrationsWithCompletion:^{
|
[OWSPrimaryStorage.sharedManager runAsyncRegistrationsWithCompletion:^{
|
||||||
OWSAssertDebug(self.isStorageReady);
|
|
||||||
|
|
||||||
[self postRegistrationCompleteNotification];
|
[self postRegistrationCompleteNotification];
|
||||||
|
|
||||||
migrationBlock();
|
migrationBlock();
|
||||||
|
@ -390,10 +353,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
// Returns YES IFF all registrations are complete.
|
// Returns YES IFF all registrations are complete.
|
||||||
+ (void)postRegistrationCompleteNotification
|
+ (void)postRegistrationCompleteNotification
|
||||||
{
|
{
|
||||||
OWSAssertDebug(self.isStorageReady);
|
|
||||||
|
|
||||||
OWSLogInfo(@"");
|
|
||||||
|
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:StorageIsReadyNotification
|
[[NSNotificationCenter defaultCenter] postNotificationNameAsync:StorageIsReadyNotification
|
||||||
|
@ -424,15 +383,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
// https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate
|
// https://www.zetetic.net/sqlcipher/sqlcipher-api/#cipher_migrate
|
||||||
options.legacyCipherCompatibilityVersion = 3;
|
options.legacyCipherCompatibilityVersion = 3;
|
||||||
|
|
||||||
// If any of these asserts fails, we need to verify and update
|
|
||||||
// OWSDatabaseConverter which assumes the values of these options.
|
|
||||||
OWSAssertDebug(options.cipherDefaultkdfIterNumber == 0);
|
|
||||||
OWSAssertDebug(options.kdfIterNumber == 0);
|
|
||||||
OWSAssertDebug(options.cipherPageSize == 0);
|
|
||||||
OWSAssertDebug(options.pragmaPageSize == 0);
|
|
||||||
OWSAssertDebug(options.pragmaJournalSizeLimit == 0);
|
|
||||||
OWSAssertDebug(options.pragmaMMapSize == 0);
|
|
||||||
|
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -445,13 +395,11 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
// (e.g. by using OWSAssertDebug()) or this database will contain a
|
// (e.g. by using OWSAssertDebug()) or this database will contain a
|
||||||
// circular reference and will leak.
|
// circular reference and will leak.
|
||||||
OWSStorage *strongSelf = weakSelf;
|
OWSStorage *strongSelf = weakSelf;
|
||||||
OWSCAssertDebug(strongSelf);
|
|
||||||
|
|
||||||
// Rather than compute this once and capture the value of the key
|
// Rather than compute this once and capture the value of the key
|
||||||
// in the closure, we prefer to fetch the key from the keychain multiple times
|
// in the closure, we prefer to fetch the key from the keychain multiple times
|
||||||
// in order to keep the key out of application memory.
|
// in order to keep the key out of application memory.
|
||||||
NSData *databaseKeySpec = [strongSelf databaseKeySpec];
|
NSData *databaseKeySpec = [strongSelf databaseKeySpec];
|
||||||
OWSCAssertDebug(databaseKeySpec.length == kSQLCipherKeySpecLength);
|
|
||||||
return databaseKeySpec;
|
return databaseKeySpec;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -484,7 +432,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
return ^id(NSString __unused *collection, NSString __unused *key, NSData *data) {
|
return ^id(NSString __unused *collection, NSString __unused *key, NSData *data) {
|
||||||
if (!data || data.length <= 0) {
|
if (!data || data.length <= 0) {
|
||||||
OWSFailDebug(@"can't deserialize null object: %@", collection);
|
|
||||||
return [OWSUnknownDBObject new];
|
return [OWSUnknownDBObject new];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -502,9 +449,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
- (YapDatabaseConnection *)newDatabaseConnection
|
- (YapDatabaseConnection *)newDatabaseConnection
|
||||||
{
|
{
|
||||||
YapDatabaseConnection *dbConnection = self.database.newConnection;
|
YapDatabaseConnection *dbConnection = self.database.newConnection;
|
||||||
if (!dbConnection) {
|
|
||||||
OWSFail(@"Storage could not open new database connection.");
|
|
||||||
}
|
|
||||||
return dbConnection;
|
return dbConnection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -512,8 +456,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
+ (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName
|
+ (void)incrementVersionOfDatabaseExtension:(NSString *)extensionName
|
||||||
{
|
{
|
||||||
OWSLogError(@"%@", extensionName);
|
|
||||||
|
|
||||||
// Don't increment version of a given extension more than once
|
// Don't increment version of a given extension more than once
|
||||||
// per launch.
|
// per launch.
|
||||||
static NSMutableSet<NSString *> *incrementedViewSet = nil;
|
static NSMutableSet<NSString *> *incrementedViewSet = nil;
|
||||||
|
@ -523,14 +465,12 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
});
|
});
|
||||||
@synchronized(incrementedViewSet) {
|
@synchronized(incrementedViewSet) {
|
||||||
if ([incrementedViewSet containsObject:extensionName]) {
|
if ([incrementedViewSet containsObject:extensionName]) {
|
||||||
OWSLogInfo(@"Ignoring redundant increment: %@", extensionName);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
[incrementedViewSet addObject:extensionName];
|
[incrementedViewSet addObject:extensionName];
|
||||||
}
|
}
|
||||||
|
|
||||||
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
|
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
|
||||||
OWSAssertDebug(appUserDefaults);
|
|
||||||
NSMutableDictionary<NSString *, NSNumber *> *_Nullable versionMap =
|
NSMutableDictionary<NSString *, NSNumber *> *_Nullable versionMap =
|
||||||
[[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap] mutableCopy];
|
[[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap] mutableCopy];
|
||||||
if (!versionMap) {
|
if (!versionMap) {
|
||||||
|
@ -545,10 +485,7 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
- (nullable NSString *)appendSuffixToDatabaseExtensionVersionIfNecessary:(nullable NSString *)versionTag
|
- (nullable NSString *)appendSuffixToDatabaseExtensionVersionIfNecessary:(nullable NSString *)versionTag
|
||||||
extensionName:(NSString *)extensionName
|
extensionName:(NSString *)extensionName
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
|
||||||
|
|
||||||
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
|
NSUserDefaults *appUserDefaults = [NSUserDefaults appUserDefaults];
|
||||||
OWSAssertDebug(appUserDefaults);
|
|
||||||
NSDictionary<NSString *, NSNumber *> *_Nullable versionMap =
|
NSDictionary<NSString *, NSNumber *> *_Nullable versionMap =
|
||||||
[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap];
|
[appUserDefaults valueForKey:kNSUserDefaults_DatabaseExtensionVersionMap];
|
||||||
NSNumber *_Nullable versionSuffix = versionMap[extensionName];
|
NSNumber *_Nullable versionSuffix = versionMap[extensionName];
|
||||||
|
@ -556,7 +493,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
if (versionSuffix) {
|
if (versionSuffix) {
|
||||||
NSString *result =
|
NSString *result =
|
||||||
[NSString stringWithFormat:@"%@.%@", (versionTag.length < 1 ? @"0" : versionTag), versionSuffix];
|
[NSString stringWithFormat:@"%@.%@", (versionTag.length < 1 ? @"0" : versionTag), versionSuffix];
|
||||||
OWSLogWarn(@"database extension version: %@ + %@ -> %@", versionTag, versionSuffix, result);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return versionTag;
|
return versionTag;
|
||||||
|
@ -564,9 +500,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
- (YapDatabaseExtension *)updateExtensionVersion:(YapDatabaseExtension *)extension withName:(NSString *)extensionName
|
- (YapDatabaseExtension *)updateExtensionVersion:(YapDatabaseExtension *)extension withName:(NSString *)extensionName
|
||||||
{
|
{
|
||||||
OWSAssertDebug(extension);
|
|
||||||
OWSAssertDebug(extensionName.length > 0);
|
|
||||||
|
|
||||||
if ([extension isKindOfClass:[YapDatabaseAutoView class]]) {
|
if ([extension isKindOfClass:[YapDatabaseAutoView class]]) {
|
||||||
YapDatabaseAutoView *databaseView = (YapDatabaseAutoView *)extension;
|
YapDatabaseAutoView *databaseView = (YapDatabaseAutoView *)extension;
|
||||||
YapDatabaseAutoView *databaseViewCopy = [[YapDatabaseAutoView alloc]
|
YapDatabaseAutoView *databaseViewCopy = [[YapDatabaseAutoView alloc]
|
||||||
|
@ -578,8 +511,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
return databaseViewCopy;
|
return databaseViewCopy;
|
||||||
} else if ([extension isKindOfClass:[YapDatabaseSecondaryIndex class]]) {
|
} else if ([extension isKindOfClass:[YapDatabaseSecondaryIndex class]]) {
|
||||||
YapDatabaseSecondaryIndex *secondaryIndex = (YapDatabaseSecondaryIndex *)extension;
|
YapDatabaseSecondaryIndex *secondaryIndex = (YapDatabaseSecondaryIndex *)extension;
|
||||||
OWSAssertDebug(secondaryIndex->setup);
|
|
||||||
OWSAssertDebug(secondaryIndex->handler);
|
|
||||||
YapDatabaseSecondaryIndex *secondaryIndexCopy = [[YapDatabaseSecondaryIndex alloc]
|
YapDatabaseSecondaryIndex *secondaryIndexCopy = [[YapDatabaseSecondaryIndex alloc]
|
||||||
initWithSetup:secondaryIndex->setup
|
initWithSetup:secondaryIndex->setup
|
||||||
handler:secondaryIndex->handler
|
handler:secondaryIndex->handler
|
||||||
|
@ -606,7 +537,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
// This method needs to be able to update the versionTag of all extensions.
|
// This method needs to be able to update the versionTag of all extensions.
|
||||||
// If we start using other extension types, we need to modify this method to
|
// If we start using other extension types, we need to modify this method to
|
||||||
// handle them as well.
|
// handle them as well.
|
||||||
OWSFailDebug(@"Unknown extension type: %@", [extension class]);
|
|
||||||
|
|
||||||
return extension;
|
return extension;
|
||||||
}
|
}
|
||||||
|
@ -616,7 +546,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
{
|
{
|
||||||
extension = [self updateExtensionVersion:extension withName:extensionName];
|
extension = [self updateExtensionVersion:extension withName:extensionName];
|
||||||
|
|
||||||
OWSAssertDebug(![self.extensionNames containsObject:extensionName]);
|
|
||||||
[self.extensionNames addObject:extensionName];
|
[self.extensionNames addObject:extensionName];
|
||||||
|
|
||||||
return [self.database registerExtension:extension withName:extensionName];
|
return [self.database registerExtension:extension withName:extensionName];
|
||||||
|
@ -634,18 +563,11 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
{
|
{
|
||||||
extension = [self updateExtensionVersion:extension withName:extensionName];
|
extension = [self updateExtensionVersion:extension withName:extensionName];
|
||||||
|
|
||||||
OWSAssertDebug(![self.extensionNames containsObject:extensionName]);
|
|
||||||
[self.extensionNames addObject:extensionName];
|
[self.extensionNames addObject:extensionName];
|
||||||
|
|
||||||
[self.database asyncRegisterExtension:extension
|
[self.database asyncRegisterExtension:extension
|
||||||
withName:extensionName
|
withName:extensionName
|
||||||
completionBlock:^(BOOL ready) {
|
completionBlock:^(BOOL ready) {
|
||||||
if (!ready) {
|
|
||||||
OWSFailDebug(@"asyncRegisterExtension failed: %@", extensionName);
|
|
||||||
} else {
|
|
||||||
OWSLogVerbose(@"asyncRegisterExtension succeeded: %@", extensionName);
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_main_queue(), ^{
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
if (completion) {
|
if (completion) {
|
||||||
completion();
|
completion();
|
||||||
|
@ -710,22 +632,16 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
- (NSString *)databaseFilePath
|
- (NSString *)databaseFilePath
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
|
|
||||||
return @"";
|
return @"";
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)databaseFilePath_SHM
|
- (NSString *)databaseFilePath_SHM
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
|
|
||||||
return @"";
|
return @"";
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)databaseFilePath_WAL
|
- (NSString *)databaseFilePath_WAL
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
|
|
||||||
return @"";
|
return @"";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -740,10 +656,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error) {
|
|
||||||
OWSLogWarn(@"Database key couldn't be accessed: %@", error.localizedDescription);
|
|
||||||
}
|
|
||||||
|
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,29 +667,21 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
+ (nullable NSData *)tryToLoadDatabaseCipherKeySpec:(NSError **)errorHandle
|
+ (nullable NSData *)tryToLoadDatabaseCipherKeySpec:(NSError **)errorHandle
|
||||||
{
|
{
|
||||||
NSData *_Nullable data = [self tryToLoadKeyChainValue:keychainDBCipherKeySpec errorHandle:errorHandle];
|
NSData *_Nullable data = [self tryToLoadKeyChainValue:keychainDBCipherKeySpec errorHandle:errorHandle];
|
||||||
OWSAssertDebug(!data || data.length == kSQLCipherKeySpecLength);
|
|
||||||
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)storeDatabaseCipherKeySpec:(NSData *)cipherKeySpecData
|
+ (void)storeDatabaseCipherKeySpec:(NSData *)cipherKeySpecData
|
||||||
{
|
{
|
||||||
OWSAssertDebug(cipherKeySpecData.length == kSQLCipherKeySpecLength);
|
|
||||||
|
|
||||||
[self storeKeyChainValue:cipherKeySpecData keychainKey:keychainDBCipherKeySpec];
|
[self storeKeyChainValue:cipherKeySpecData keychainKey:keychainDBCipherKeySpec];
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)removeLegacyPassphrase
|
+ (void)removeLegacyPassphrase
|
||||||
{
|
{
|
||||||
OWSLogInfo(@"removing legacy passphrase");
|
|
||||||
|
|
||||||
NSError *_Nullable error;
|
NSError *_Nullable error;
|
||||||
BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService
|
BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService
|
||||||
key:keychainDBLegacyPassphrase
|
key:keychainDBLegacyPassphrase
|
||||||
error:&error];
|
error:&error];
|
||||||
if (error || !result) {
|
|
||||||
OWSFailDebug(@"could not remove legacy passphrase.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)ensureDatabaseKeySpecExists
|
- (void)ensureDatabaseKeySpecExists
|
||||||
|
@ -800,8 +704,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
errorDescription = [errorDescription
|
errorDescription = [errorDescription
|
||||||
stringByAppendingFormat:@", ApplicationState: %@", NSStringForUIApplicationState(applicationState)];
|
stringByAppendingFormat:@", ApplicationState: %@", NSStringForUIApplicationState(applicationState)];
|
||||||
}
|
}
|
||||||
OWSLogError(@"%@", errorDescription);
|
|
||||||
[DDLog flushLog];
|
|
||||||
|
|
||||||
if (CurrentAppContext().isMainApp) {
|
if (CurrentAppContext().isMainApp) {
|
||||||
if (CurrentAppContext().isInBackground) {
|
if (CurrentAppContext().isInBackground) {
|
||||||
|
@ -818,9 +720,6 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
// or the keychain has become corrupt. Either way, we want to get back to a
|
// or the keychain has become corrupt. Either way, we want to get back to a
|
||||||
// "known good state" and behave like a new install.
|
// "known good state" and behave like a new install.
|
||||||
BOOL doesDBExist = [NSFileManager.defaultManager fileExistsAtPath:[self databaseFilePath]];
|
BOOL doesDBExist = [NSFileManager.defaultManager fileExistsAtPath:[self databaseFilePath]];
|
||||||
if (doesDBExist) {
|
|
||||||
OWSFailDebug(@"Could not load database metadata");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CurrentAppContext().isRunningTests) {
|
if (!CurrentAppContext().isRunningTests) {
|
||||||
// Try to reset app by deleting database.
|
// Try to reset app by deleting database.
|
||||||
|
@ -838,12 +737,10 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
NSData *_Nullable keySpec = [[self class] tryToLoadDatabaseCipherKeySpec:&error];
|
NSData *_Nullable keySpec = [[self class] tryToLoadDatabaseCipherKeySpec:&error];
|
||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
OWSLogError(@"failed to fetch databaseKeySpec with error: %@", error);
|
|
||||||
[self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec inaccessible"];
|
[self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec inaccessible"];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (keySpec.length != kSQLCipherKeySpecLength) {
|
if (keySpec.length != kSQLCipherKeySpecLength) {
|
||||||
OWSLogError(@"keyspec had length: %lu", (unsigned long)keySpec.length);
|
|
||||||
[self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec invalid"];
|
[self raiseKeySpecInaccessibleExceptionWithErrorDescription:@"CipherKeySpec invalid"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -852,15 +749,12 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
- (void)raiseKeySpecInaccessibleExceptionWithErrorDescription:(NSString *)errorDescription
|
- (void)raiseKeySpecInaccessibleExceptionWithErrorDescription:(NSString *)errorDescription
|
||||||
{
|
{
|
||||||
OWSAssertDebug(CurrentAppContext().isMainApp && CurrentAppContext().isInBackground);
|
|
||||||
|
|
||||||
// Sleep to give analytics events time to be delivered.
|
// Sleep to give analytics events time to be delivered.
|
||||||
[NSThread sleepForTimeInterval:5.0f];
|
[NSThread sleepForTimeInterval:5.0f];
|
||||||
|
|
||||||
// Presumably this happened in response to a push notification. It's possible that the keychain is corrupted
|
// Presumably this happened in response to a push notification. It's possible that the keychain is corrupted
|
||||||
// but it could also just be that the user hasn't yet unlocked their device since our password is
|
// but it could also just be that the user hasn't yet unlocked their device since our password is
|
||||||
// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
|
// kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
|
||||||
OWSFail(@"%@", errorDescription);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)deleteDBKeys
|
+ (void)deleteDBKeys
|
||||||
|
@ -869,15 +763,9 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService
|
BOOL result = [CurrentAppContext().keychainStorage removeWithService:keychainService
|
||||||
key:keychainDBLegacyPassphrase
|
key:keychainDBLegacyPassphrase
|
||||||
error:&error];
|
error:&error];
|
||||||
if (error || !result) {
|
|
||||||
OWSFailDebug(@"could not remove legacy passphrase.");
|
|
||||||
}
|
|
||||||
result = [CurrentAppContext().keychainStorage removeWithService:keychainService
|
result = [CurrentAppContext().keychainStorage removeWithService:keychainService
|
||||||
key:keychainDBCipherKeySpec
|
key:keychainDBCipherKeySpec
|
||||||
error:&error];
|
error:&error];
|
||||||
if (error || !result) {
|
|
||||||
OWSFailDebug(@"could not remove cipher key spec.");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (unsigned long long)databaseFileSize
|
- (unsigned long long)databaseFileSize
|
||||||
|
@ -897,42 +785,27 @@ NSString *const kNSUserDefaults_DatabaseExtensionVersionMap = @"kNSUserDefaults_
|
||||||
|
|
||||||
+ (nullable NSData *)tryToLoadKeyChainValue:(NSString *)keychainKey errorHandle:(NSError **)errorHandle
|
+ (nullable NSData *)tryToLoadKeyChainValue:(NSString *)keychainKey errorHandle:(NSError **)errorHandle
|
||||||
{
|
{
|
||||||
OWSAssertDebug(keychainKey.length > 0);
|
|
||||||
OWSAssertDebug(errorHandle);
|
|
||||||
|
|
||||||
NSData *_Nullable data =
|
NSData *_Nullable data =
|
||||||
[CurrentAppContext().keychainStorage dataForService:keychainService key:keychainKey error:errorHandle];
|
[CurrentAppContext().keychainStorage dataForService:keychainService key:keychainKey error:errorHandle];
|
||||||
if (*errorHandle || !data) {
|
|
||||||
OWSLogWarn(@"could not load keychain value.");
|
|
||||||
}
|
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (void)storeKeyChainValue:(NSData *)data keychainKey:(NSString *)keychainKey
|
+ (void)storeKeyChainValue:(NSData *)data keychainKey:(NSString *)keychainKey
|
||||||
{
|
{
|
||||||
OWSAssertDebug(keychainKey.length > 0);
|
|
||||||
OWSAssertDebug(data.length > 0);
|
|
||||||
|
|
||||||
NSError *error;
|
NSError *error;
|
||||||
BOOL success =
|
BOOL success =
|
||||||
[CurrentAppContext().keychainStorage setWithData:data service:keychainService key:keychainKey error:&error];
|
[CurrentAppContext().keychainStorage setWithData:data service:keychainService key:keychainKey error:&error];
|
||||||
if (!success || error) {
|
if (!success || error) {
|
||||||
OWSFailDebug(@"Could not store database metadata");
|
|
||||||
|
|
||||||
// Sleep to give analytics events time to be delivered.
|
// Sleep to give analytics events time to be delivered.
|
||||||
[NSThread sleepForTimeInterval:15.0f];
|
[NSThread sleepForTimeInterval:15.0f];
|
||||||
|
|
||||||
OWSFail(@"Setting keychain value failed with error: %@", error);
|
|
||||||
} else {
|
|
||||||
OWSLogWarn(@"Successfully set new keychain value.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)logFileSizes
|
- (void)logFileSizes
|
||||||
{
|
{
|
||||||
OWSLogInfo(@"Database file size: %@", [OWSFileSystem fileSizeOfPath:self.databaseFilePath]);
|
|
||||||
OWSLogInfo(@"\t SHM file size: %@", [OWSFileSystem fileSizeOfPath:self.databaseFilePath_SHM]);
|
|
||||||
OWSLogInfo(@"\t WAL file size: %@", [OWSFileSystem fileSizeOfPath:self.databaseFilePath_WAL]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
|
@ -1,3 +1,4 @@
|
||||||
|
import SessionProtocolKit
|
||||||
|
|
||||||
extension Storage {
|
extension Storage {
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/OWSStorage.h>
|
#import <SessionMessagingKit/OWSStorage.h>
|
||||||
#import <YapDatabase/YapDatabaseViewTransaction.h>
|
#import <YapDatabase/YapDatabaseViewTransaction.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
|
@ -60,8 +60,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
|
|
||||||
+ (void)registerCrossProcessNotifier:(OWSStorage *)storage
|
+ (void)registerCrossProcessNotifier:(OWSStorage *)storage
|
||||||
{
|
{
|
||||||
OWSAssertDebug(storage);
|
|
||||||
|
|
||||||
// I don't think the identifier and name of this extension matter for our purposes,
|
// I don't think the identifier and name of this extension matter for our purposes,
|
||||||
// so long as they don't conflict with any other extension names.
|
// so long as they don't conflict with any other extension names.
|
||||||
YapDatabaseExtension *extension =
|
YapDatabaseExtension *extension =
|
||||||
|
@ -74,14 +72,8 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
version:(NSString *)version
|
version:(NSString *)version
|
||||||
storage:(OWSStorage *)storage
|
storage:(OWSStorage *)storage
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
|
||||||
OWSAssertDebug(viewName.length > 0);
|
|
||||||
OWSAssertDebug((viewGrouping));
|
|
||||||
OWSAssertDebug(storage);
|
|
||||||
|
|
||||||
YapDatabaseView *existingView = [storage registeredExtension:viewName];
|
YapDatabaseView *existingView = [storage registeredExtension:viewName];
|
||||||
if (existingView) {
|
if (existingView) {
|
||||||
OWSFailDebug(@"Registered database view twice: %@", viewName);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -142,7 +134,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
||||||
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
||||||
if (![object isKindOfClass:[TSInteraction class]]) {
|
if (![object isKindOfClass:[TSInteraction class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
TSInteraction *interaction = (TSInteraction *)object;
|
TSInteraction *interaction = (TSInteraction *)object;
|
||||||
|
@ -167,19 +158,14 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
|
|
||||||
+ (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage
|
+ (void)asyncRegisterLegacyThreadInteractionsDatabaseView:(OWSStorage *)storage
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
|
||||||
OWSAssert(storage);
|
|
||||||
|
|
||||||
YapDatabaseView *existingView = [storage registeredExtension:TSMessageDatabaseViewExtensionName_Legacy];
|
YapDatabaseView *existingView = [storage registeredExtension:TSMessageDatabaseViewExtensionName_Legacy];
|
||||||
if (existingView) {
|
if (existingView) {
|
||||||
OWSFailDebug(@"Registered database view twice: %@", TSMessageDatabaseViewExtensionName_Legacy);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
||||||
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
||||||
if (![object isKindOfClass:[TSInteraction class]]) {
|
if (![object isKindOfClass:[TSInteraction class]]) {
|
||||||
OWSFailDebug(@"%@ Unexpected entity %@ in collection: %@", self.logTag, [object class], collection);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
TSInteraction *interaction = (TSInteraction *)object;
|
TSInteraction *interaction = (TSInteraction *)object;
|
||||||
|
@ -197,11 +183,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
NSString *key2,
|
NSString *key2,
|
||||||
id object2) {
|
id object2) {
|
||||||
if (![object1 isKindOfClass:[TSInteraction class]]) {
|
if (![object1 isKindOfClass:[TSInteraction class]]) {
|
||||||
OWSFailDebug(@"%@ Unexpected entity %@ in collection: %@", self.logTag, [object1 class], collection1);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
if (![object2 isKindOfClass:[TSInteraction class]]) {
|
if (![object2 isKindOfClass:[TSInteraction class]]) {
|
||||||
OWSFailDebug(@"%@ Unexpected entity %@ in collection: %@", self.logTag, [object2 class], collection2);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
TSInteraction *interaction1 = (TSInteraction *)object1;
|
TSInteraction *interaction1 = (TSInteraction *)object1;
|
||||||
|
@ -237,7 +221,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
||||||
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
||||||
if (![object isKindOfClass:[TSInteraction class]]) {
|
if (![object isKindOfClass:[TSInteraction class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
TSInteraction *interaction = (TSInteraction *)object;
|
TSInteraction *interaction = (TSInteraction *)object;
|
||||||
|
@ -271,14 +254,12 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
{
|
{
|
||||||
YapDatabaseView *threadView = [storage registeredExtension:TSThreadDatabaseViewExtensionName];
|
YapDatabaseView *threadView = [storage registeredExtension:TSThreadDatabaseViewExtensionName];
|
||||||
if (threadView) {
|
if (threadView) {
|
||||||
OWSFailDebug(@"Registered database view twice: %@", TSThreadDatabaseViewExtensionName);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *(
|
||||||
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
||||||
if (![object isKindOfClass:[TSThread class]]) {
|
if (![object isKindOfClass:[TSThread class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
TSThread *thread = (TSThread *)object;
|
TSThread *thread = (TSThread *)object;
|
||||||
|
@ -287,7 +268,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
// Do nothing; we never hide threads that have ever had a message.
|
// Do nothing; we never hide threads that have ever had a message.
|
||||||
} else {
|
} else {
|
||||||
YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName];
|
YapDatabaseViewTransaction *viewTransaction = [transaction ext:TSMessageDatabaseViewExtensionName];
|
||||||
OWSAssertDebug(viewTransaction);
|
|
||||||
NSUInteger threadMessageCount = [viewTransaction numberOfItemsInGroup:thread.uniqueId];
|
NSUInteger threadMessageCount = [viewTransaction numberOfItemsInGroup:thread.uniqueId];
|
||||||
if (threadMessageCount < 1) {
|
if (threadMessageCount < 1) {
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -320,11 +300,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
NSString *key2,
|
NSString *key2,
|
||||||
id object2) {
|
id object2) {
|
||||||
if (![object1 isKindOfClass:[TSThread class]]) {
|
if (![object1 isKindOfClass:[TSThread class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object1 class], collection1);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
if (![object2 isKindOfClass:[TSThread class]]) {
|
if (![object2 isKindOfClass:[TSThread class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object2 class], collection2);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
TSThread *thread1 = (TSThread *)object1;
|
TSThread *thread1 = (TSThread *)object1;
|
||||||
|
@ -356,11 +334,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
NSString *key2,
|
NSString *key2,
|
||||||
id object2) {
|
id object2) {
|
||||||
if (![object1 isKindOfClass:[TSInteraction class]]) {
|
if (![object1 isKindOfClass:[TSInteraction class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object1 class], collection1);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
if (![object2 isKindOfClass:[TSInteraction class]]) {
|
if (![object2 isKindOfClass:[TSInteraction class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object2 class], collection2);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
TSInteraction *message1 = (TSInteraction *)object1;
|
TSInteraction *message1 = (TSInteraction *)object1;
|
||||||
|
@ -375,7 +351,6 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(
|
YapDatabaseViewGrouping *viewGrouping = [YapDatabaseViewGrouping withObjectBlock:^NSString *_Nullable(
|
||||||
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
YapDatabaseReadTransaction *transaction, NSString *collection, NSString *key, id object) {
|
||||||
if (![object isKindOfClass:[TSAttachment class]]) {
|
if (![object isKindOfClass:[TSAttachment class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object class], collection);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if (![object isKindOfClass:[TSAttachmentPointer class]]) {
|
if (![object isKindOfClass:[TSAttachmentPointer class]]) {
|
||||||
|
@ -399,11 +374,9 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
NSString *key2,
|
NSString *key2,
|
||||||
id object2) {
|
id object2) {
|
||||||
if (![object1 isKindOfClass:[TSAttachmentPointer class]]) {
|
if (![object1 isKindOfClass:[TSAttachmentPointer class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object1 class], collection1);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
if (![object2 isKindOfClass:[TSAttachmentPointer class]]) {
|
if (![object2 isKindOfClass:[TSAttachmentPointer class]]) {
|
||||||
OWSFailDebug(@"Unexpected entity %@ in collection: %@", [object2 class], collection2);
|
|
||||||
return NSOrderedSame;
|
return NSOrderedSame;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,15 +397,11 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
|
|
||||||
+ (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction
|
+ (id)unseenDatabaseViewExtension:(YapDatabaseReadTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
id _Nullable result = [transaction ext:TSUnseenDatabaseViewExtensionName];
|
id _Nullable result = [transaction ext:TSUnseenDatabaseViewExtensionName];
|
||||||
OWSAssertDebug(result);
|
|
||||||
|
|
||||||
// TODO: I believe we can now safely remove this?
|
// TODO: I believe we can now safely remove this?
|
||||||
if (!result) {
|
if (!result) {
|
||||||
result = [transaction ext:TSUnreadDatabaseViewExtensionName];
|
result = [transaction ext:TSUnreadDatabaseViewExtensionName];
|
||||||
OWSAssertDebug(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -441,20 +410,14 @@ NSString *const TSLazyRestoreAttachmentsGroup = @"TSLazyRestoreAttachmentsGroup"
|
||||||
// MJK TODO - dynamic interactions
|
// MJK TODO - dynamic interactions
|
||||||
+ (id)threadOutgoingMessageDatabaseView:(YapDatabaseReadTransaction *)transaction
|
+ (id)threadOutgoingMessageDatabaseView:(YapDatabaseReadTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
id result = [transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName];
|
id result = [transaction ext:TSThreadOutgoingMessageDatabaseViewExtensionName];
|
||||||
OWSAssertDebug(result);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
+ (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction
|
+ (id)threadSpecialMessagesDatabaseView:(YapDatabaseReadTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
id result = [transaction ext:TSThreadSpecialMessagesDatabaseViewExtensionName];
|
id result = [transaction ext:TSThreadSpecialMessagesDatabaseViewExtensionName];
|
||||||
OWSAssertDebug(result);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
|
@ -34,13 +34,13 @@ public final class NotifyPNServerJob : NSObject, Job, NSCoding { // NSObject/NSC
|
||||||
|
|
||||||
// MARK: Running
|
// MARK: Running
|
||||||
public func execute() {
|
public func execute() {
|
||||||
let server = Configuration.shared.pnServerURL
|
let server = PushNotificationAPI.server
|
||||||
let parameters = [ "data" : message.data.description, "send_to" : message.recipient ]
|
let parameters = [ "data" : message.data.description, "send_to" : message.recipient ]
|
||||||
let url = URL(string: "\(server)/notify")!
|
let url = URL(string: "\(server)/notify")!
|
||||||
let request = TSRequest(url: url, method: "POST", parameters: parameters)
|
let request = TSRequest(url: url, method: "POST", parameters: parameters)
|
||||||
request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ]
|
request.allHTTPHeaderFields = [ "Content-Type" : "application/json" ]
|
||||||
attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.global()) {
|
attempt(maxRetryCount: 4, recoveringOn: DispatchQueue.global()) {
|
||||||
OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: Configuration.shared.pnServerPublicKey).map { _ in }
|
OnionRequestAPI.sendOnionRequest(request, to: server, target: "/loki/v2/lsrpc", using: PushNotificationAPI.serverPublicKey).map { _ in }
|
||||||
}.done(on: DispatchQueue.global()) { // Intentionally capture self
|
}.done(on: DispatchQueue.global()) { // Intentionally capture self
|
||||||
self.handleSuccess()
|
self.handleSuccess()
|
||||||
}.catch(on: DispatchQueue.global()) { error in
|
}.catch(on: DispatchQueue.global()) { error in
|
||||||
|
|
|
@ -5,5 +5,20 @@ public extension Message {
|
||||||
case contact(publicKey: String)
|
case contact(publicKey: String)
|
||||||
case closedGroup(groupPublicKey: String)
|
case closedGroup(groupPublicKey: String)
|
||||||
case openGroup(channel: UInt64, server: String)
|
case openGroup(channel: UInt64, server: String)
|
||||||
|
|
||||||
|
static func from(_ thread: TSThread) -> Message.Destination {
|
||||||
|
if let thread = thread as? TSContactThread {
|
||||||
|
return .contact(publicKey: thread.contactIdentifier())
|
||||||
|
} else if let thread = thread as? TSGroupThread, thread.usesSharedSenderKeys {
|
||||||
|
let groupID = thread.groupModel.groupId
|
||||||
|
let groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
|
||||||
|
return .closedGroup(groupPublicKey: groupPublicKey)
|
||||||
|
} else if let thread = thread as? TSGroupThread, thread.isOpenGroup {
|
||||||
|
let openGroup = Storage.shared.getOpenGroup(for: thread.uniqueId!)!
|
||||||
|
return .openGroup(channel: openGroup.channel, server: openGroup.server)
|
||||||
|
} else {
|
||||||
|
preconditionFailure("TODO: Handle legacy closed groups.")
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/OWSReadTracking.h>
|
#import <SessionMessagingKit/OWSReadTracking.h>
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SessionMessagingKit/TSMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -7,8 +7,8 @@
|
||||||
#import "TSContactThread.h"
|
#import "TSContactThread.h"
|
||||||
#import "TSErrorMessage_privateConstructor.h"
|
#import "TSErrorMessage_privateConstructor.h"
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
|
||||||
#import <YapDatabase/YapDatabaseConnection.h>
|
#import <YapDatabase/YapDatabaseConnection.h>
|
||||||
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -205,13 +205,10 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
|
||||||
sendReadReceipt:(BOOL)sendReadReceipt
|
sendReadReceipt:(BOOL)sendReadReceipt
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
if (_read) {
|
if (_read) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OWSLogDebug(@"marking as read uniqueId: %@ which has timestamp: %llu", self.uniqueId, self.timestamp);
|
|
||||||
_read = YES;
|
_read = YES;
|
||||||
[self saveWithTransaction:transaction];
|
[self saveWithTransaction:transaction];
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSErrorMessage.h>
|
#import <SessionMessagingKit/TSErrorMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/OWSReadTracking.h>
|
#import <SessionMessagingKit/OWSReadTracking.h>
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SessionMessagingKit/TSMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#import "TSGroupThread.h"
|
#import "TSGroupThread.h"
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
#import <SessionProtocolKit/SessionProtocolKit.h>
|
||||||
#import <YapDatabase/YapDatabaseConnection.h>
|
#import <YapDatabase/YapDatabaseConnection.h>
|
||||||
|
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -36,7 +37,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_authorId == nil) {
|
if (_authorId == nil) {
|
||||||
OWSAssertDebug([self.uniqueThreadId hasPrefix:TSContactThreadPrefix]);
|
|
||||||
_authorId = [TSContactThread contactIdFromThreadId:self.uniqueThreadId];
|
_authorId = [TSContactThread contactIdFromThreadId:self.uniqueThreadId];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,8 +81,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
timestamp:(uint64_t)timestamp
|
timestamp:(uint64_t)timestamp
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
__block TSIncomingMessage *foundMessage;
|
__block TSIncomingMessage *foundMessage;
|
||||||
// In theory we could build a new secondaryIndex for (authorId,timestamp), but in practice there should
|
// In theory we could build a new secondaryIndex for (authorId,timestamp), but in practice there should
|
||||||
// be *very* few (millisecond) timestamps with multiple authors.
|
// be *very* few (millisecond) timestamps with multiple authors.
|
||||||
|
@ -93,9 +91,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[TSInteraction fetchObjectWithUniqueID:key transaction:transaction];
|
[TSInteraction fetchObjectWithUniqueID:key transaction:transaction];
|
||||||
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
|
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
|
||||||
TSIncomingMessage *message = (TSIncomingMessage *)interaction;
|
TSIncomingMessage *message = (TSIncomingMessage *)interaction;
|
||||||
|
|
||||||
OWSAssertDebug(message.authorId > 0);
|
|
||||||
|
|
||||||
if ([message.authorId isEqualToString:authorId]) {
|
if ([message.authorId isEqualToString:authorId]) {
|
||||||
foundMessage = message;
|
foundMessage = message;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +128,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
- (void)markAsReadNowWithSendReadReceipt:(BOOL)sendReadReceipt
|
- (void)markAsReadNowWithSendReadReceipt:(BOOL)sendReadReceipt
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||||
{
|
{
|
||||||
[self markAsReadAtTimestamp:[NSDate ows_millisecondTimeStamp]
|
[self markAsReadAtTimestamp:[NSDate millisecondTimestamp]
|
||||||
sendReadReceipt:sendReadReceipt
|
sendReadReceipt:sendReadReceipt
|
||||||
transaction:transaction];
|
transaction:transaction];
|
||||||
}
|
}
|
||||||
|
@ -142,17 +137,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
sendReadReceipt:(BOOL)sendReadReceipt
|
sendReadReceipt:(BOOL)sendReadReceipt
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
if (_read && readTimestamp >= self.expireStartedAt) {
|
if (_read && readTimestamp >= self.expireStartedAt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSTimeInterval secondsAgoRead = ((NSTimeInterval)[NSDate ows_millisecondTimeStamp] - (NSTimeInterval)readTimestamp) / 1000;
|
NSTimeInterval secondsAgoRead = ((NSTimeInterval)[NSDate millisecondTimestamp] - (NSTimeInterval)readTimestamp) / 1000;
|
||||||
OWSLogDebug(@"marking uniqueId: %@ which has timestamp: %llu as read: %f seconds ago",
|
|
||||||
self.uniqueId,
|
|
||||||
self.timestamp,
|
|
||||||
secondsAgoRead);
|
|
||||||
_read = YES;
|
_read = YES;
|
||||||
[self saveWithTransaction:transaction];
|
[self saveWithTransaction:transaction];
|
||||||
|
|
|
@ -2,8 +2,8 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/OWSReadTracking.h>
|
#import <SessionMessagingKit/OWSReadTracking.h>
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SessionMessagingKit/TSMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#import "SSKEnvironment.h"
|
#import "SSKEnvironment.h"
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
#import <SessionProtocolKit/SessionProtocolKit.h>
|
||||||
#import <YapDatabase/YapDatabaseConnection.h>
|
#import <YapDatabase/YapDatabaseConnection.h>
|
||||||
|
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -97,11 +98,8 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
|
||||||
|
|
||||||
+ (instancetype)userNotRegisteredMessageInThread:(TSThread *)thread recipientId:(NSString *)recipientId
|
+ (instancetype)userNotRegisteredMessageInThread:(TSThread *)thread recipientId:(NSString *)recipientId
|
||||||
{
|
{
|
||||||
OWSAssertDebug(thread);
|
|
||||||
OWSAssertDebug(recipientId);
|
|
||||||
|
|
||||||
// MJK TODO - remove senderTimestamp
|
// MJK TODO - remove senderTimestamp
|
||||||
return [[self alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp]
|
return [[self alloc] initWithTimestamp:[NSDate millisecondTimestamp]
|
||||||
inThread:thread
|
inThread:thread
|
||||||
messageType:TSInfoMessageUserNotRegistered
|
messageType:TSInfoMessageUserNotRegistered
|
||||||
unregisteredRecipientId:recipientId];
|
unregisteredRecipientId:recipientId];
|
||||||
|
@ -169,13 +167,10 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
|
||||||
sendReadReceipt:(BOOL)sendReadReceipt
|
sendReadReceipt:(BOOL)sendReadReceipt
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
if (_read) {
|
if (_read) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OWSLogDebug(@"marking as read uniqueId: %@ which has timestamp: %llu", self.uniqueId, self.timestamp);
|
|
||||||
_read = YES;
|
_read = YES;
|
||||||
[self saveWithTransaction:transaction];
|
[self saveWithTransaction:transaction];
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
#import "TSThread.h"
|
#import "TSThread.h"
|
||||||
#import "TSGroupThread.h"
|
#import "TSGroupThread.h"
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -47,8 +47,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
ofClass:(Class)clazz
|
ofClass:(Class)clazz
|
||||||
withTransaction:(YapDatabaseReadTransaction *)transaction
|
withTransaction:(YapDatabaseReadTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(timestamp > 0);
|
|
||||||
|
|
||||||
// Accept any interaction.
|
// Accept any interaction.
|
||||||
return [self interactionsWithTimestamp:timestamp
|
return [self interactionsWithTimestamp:timestamp
|
||||||
filter:^(TSInteraction *interaction) {
|
filter:^(TSInteraction *interaction) {
|
||||||
|
@ -61,8 +59,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
filter:(BOOL (^_Nonnull)(TSInteraction *))filter
|
filter:(BOOL (^_Nonnull)(TSInteraction *))filter
|
||||||
withTransaction:(YapDatabaseReadTransaction *)transaction
|
withTransaction:(YapDatabaseReadTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(timestamp > 0);
|
|
||||||
|
|
||||||
NSMutableArray<TSInteraction *> *interactions = [NSMutableArray new];
|
NSMutableArray<TSInteraction *> *interactions = [NSMutableArray new];
|
||||||
|
|
||||||
[TSDatabaseSecondaryIndexes
|
[TSDatabaseSecondaryIndexes
|
||||||
|
@ -88,8 +84,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
timestamp:(uint64_t)timestamp
|
timestamp:(uint64_t)timestamp
|
||||||
inThread:(TSThread *)thread
|
inThread:(TSThread *)thread
|
||||||
{
|
{
|
||||||
OWSAssertDebug(timestamp > 0);
|
|
||||||
|
|
||||||
self = [super initWithUniqueId:uniqueId];
|
self = [super initWithUniqueId:uniqueId];
|
||||||
|
|
||||||
if (!self) {
|
if (!self) {
|
||||||
|
@ -104,8 +98,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
|
|
||||||
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread
|
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread
|
||||||
{
|
{
|
||||||
OWSAssertDebug(timestamp > 0);
|
|
||||||
|
|
||||||
self = [super initWithUniqueId:[[NSUUID UUID] UUIDString]];
|
self = [super initWithUniqueId:[[NSUUID UUID] UUIDString]];
|
||||||
|
|
||||||
if (!self) {
|
if (!self) {
|
||||||
|
@ -169,8 +161,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)applyChangeToSelfAndLatestCopy:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
changeBlock:(void (^)(id))changeBlock
|
changeBlock:(void (^)(id))changeBlock
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[super applyChangeToSelfAndLatestCopy:transaction changeBlock:changeBlock];
|
[super applyChangeToSelfAndLatestCopy:transaction changeBlock:changeBlock];
|
||||||
[self touchThreadWithTransaction:transaction];
|
[self touchThreadWithTransaction:transaction];
|
||||||
}
|
}
|
||||||
|
@ -203,8 +193,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
|
|
||||||
- (NSComparisonResult)compareForSorting:(TSInteraction *)other
|
- (NSComparisonResult)compareForSorting:(TSInteraction *)other
|
||||||
{
|
{
|
||||||
OWSAssertDebug(other);
|
|
||||||
|
|
||||||
uint64_t sortId1;
|
uint64_t sortId1;
|
||||||
uint64_t sortId2;
|
uint64_t sortId2;
|
||||||
|
|
||||||
|
@ -230,8 +218,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
|
|
||||||
- (OWSInteractionType)interactionType
|
- (OWSInteractionType)interactionType
|
||||||
{
|
{
|
||||||
OWSFailDebug(@"unknown interaction type.");
|
|
||||||
|
|
||||||
return OWSInteractionType_Unknown;
|
return OWSInteractionType_Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +232,6 @@ NSString *NSStringFromOWSInteractionType(OWSInteractionType value)
|
||||||
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
if (!self.uniqueId) {
|
if (!self.uniqueId) {
|
||||||
OWSFailDebug(@"Missing uniqueId.");
|
|
||||||
self.uniqueId = [NSUUID new].UUIDString;
|
self.uniqueId = [NSUUID new].UUIDString;
|
||||||
}
|
}
|
||||||
if (self.sortId == 0) {
|
if (self.sortId == 0) {
|
|
@ -2,12 +2,10 @@
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSErrorMessage.h>
|
#import <SessionMessagingKit/TSErrorMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
@class OWSFingerprint;
|
|
||||||
|
|
||||||
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
|
@interface TSInvalidIdentityKeyErrorMessage : TSErrorMessage
|
||||||
|
|
||||||
- (void)throws_acceptNewIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
- (void)throws_acceptNewIdentityKey NS_SWIFT_UNAVAILABLE("throws objc exceptions");
|
|
@ -11,18 +11,16 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (void)throws_acceptNewIdentityKey
|
- (void)throws_acceptNewIdentityKey
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
- (nullable NSData *)throws_newIdentityKey
|
- (nullable NSData *)throws_newIdentityKey
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSString *)theirSignalId
|
- (NSString *)theirSignalId
|
||||||
{
|
{
|
||||||
OWSAbstractMethod();
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSInvalidIdentityKeyErrorMessage.h>
|
#import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
#import "TSErrorMessage_privateConstructor.h"
|
#import "TSErrorMessage_privateConstructor.h"
|
||||||
#import <SessionProtocolKit/NSData+keyVersionByte.h>
|
#import <SessionProtocolKit/NSData+keyVersionByte.h>
|
||||||
#import <SessionProtocolKit/PreKeyWhisperMessage.h>
|
#import <SessionProtocolKit/PreKeyWhisperMessage.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
|
||||||
#import <YapDatabase/YapDatabaseTransaction.h>
|
#import <YapDatabase/YapDatabaseTransaction.h>
|
||||||
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -59,7 +59,6 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
|
||||||
NSError *error;
|
NSError *error;
|
||||||
_envelopeData = [envelope serializedDataAndReturnError:&error];
|
_envelopeData = [envelope serializedDataAndReturnError:&error];
|
||||||
if (!_envelopeData || error != nil) {
|
if (!_envelopeData || error != nil) {
|
||||||
OWSFailDebug(@"failure: envelope data failed with error: %@", error);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +74,7 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
|
||||||
NSError *error;
|
NSError *error;
|
||||||
SNProtoEnvelope *_Nullable envelope = [SNProtoEnvelope parseData:self.envelopeData error:&error];
|
SNProtoEnvelope *_Nullable envelope = [SNProtoEnvelope parseData:self.envelopeData error:&error];
|
||||||
if (error || envelope == nil) {
|
if (error || envelope == nil) {
|
||||||
OWSFailDebug(@"Could not parse proto: %@", error);
|
|
||||||
} else {
|
} else {
|
||||||
_envelope = envelope;
|
_envelope = envelope;
|
||||||
}
|
}
|
||||||
|
@ -85,16 +84,12 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
|
||||||
|
|
||||||
- (void)throws_acceptNewIdentityKey
|
- (void)throws_acceptNewIdentityKey
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
|
||||||
|
|
||||||
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey) {
|
if (self.errorType != TSErrorMessageWrongTrustedIdentityKey) {
|
||||||
OWSLogError(@"Refusing to accept identity key for anything but a Key error.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSData *_Nullable newKey = [self throws_newIdentityKey];
|
NSData *_Nullable newKey = [self throws_newIdentityKey];
|
||||||
if (!newKey) {
|
if (!newKey) {
|
||||||
OWSFailDebug(@"Couldn't extract identity key to accept");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,18 +111,15 @@ __attribute__((deprecated)) @interface TSInvalidIdentityKeyReceivingErrorMessage
|
||||||
- (nullable NSData *)throws_newIdentityKey
|
- (nullable NSData *)throws_newIdentityKey
|
||||||
{
|
{
|
||||||
if (!self.envelope) {
|
if (!self.envelope) {
|
||||||
OWSLogError(@"Error message had no envelope data to extract key from");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self.envelope.type != SNProtoEnvelopeTypePrekeyBundle) {
|
if (self.envelope.type != SNProtoEnvelopeTypePrekeyBundle) {
|
||||||
OWSLogError(@"Refusing to attempt key extraction from an envelope which isn't a prekey bundle");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
NSData *pkwmData = self.envelope.content;
|
NSData *pkwmData = self.envelope.content;
|
||||||
if (!pkwmData) {
|
if (!pkwmData) {
|
||||||
OWSLogError(@"Ignoring acceptNewIdentityKey for empty message");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSInteraction.h>
|
#import <SessionMessagingKit/TSInteraction.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -17,6 +17,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
@class TSQuotedMessage;
|
@class TSQuotedMessage;
|
||||||
@class YapDatabaseReadWriteTransaction;
|
@class YapDatabaseReadWriteTransaction;
|
||||||
|
|
||||||
|
extern const NSUInteger kOversizeTextMessageSizeThreshold;
|
||||||
|
|
||||||
@interface TSMessage : TSInteraction <OWSPreviewText>
|
@interface TSMessage : TSInteraction <OWSPreviewText>
|
||||||
|
|
||||||
@property (nonatomic, readonly) NSMutableArray<NSString *> *attachmentIds;
|
@property (nonatomic, readonly) NSMutableArray<NSString *> *attachmentIds;
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SessionMessagingKit/TSMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
@import Foundation;
|
@import Foundation;
|
||||||
|
|
||||||
#import "TSOutgoingMessage.h"
|
#import "TSOutgoingMessage.h"
|
||||||
#import "NSString+SSK.h"
|
|
||||||
#import "TSDatabaseSecondaryIndexes.h"
|
#import "TSDatabaseSecondaryIndexes.h"
|
||||||
#import "OWSPrimaryStorage.h"
|
#import "OWSPrimaryStorage.h"
|
||||||
#import "ProfileManagerProtocol.h"
|
#import "ProfileManagerProtocol.h"
|
||||||
|
@ -18,9 +17,9 @@
|
||||||
#import "TSGroupThread.h"
|
#import "TSGroupThread.h"
|
||||||
#import "TSQuotedMessage.h"
|
#import "TSQuotedMessage.h"
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
|
||||||
#import <YapDatabase/YapDatabase.h>
|
#import <YapDatabase/YapDatabase.h>
|
||||||
#import <YapDatabase/YapDatabaseTransaction.h>
|
#import <YapDatabase/YapDatabaseTransaction.h>
|
||||||
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -109,7 +108,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
if (!self.recipientStateMap) {
|
if (!self.recipientStateMap) {
|
||||||
[self migrateRecipientStateMapWithCoder:coder];
|
[self migrateRecipientStateMapWithCoder:coder];
|
||||||
OWSAssertDebug(self.recipientStateMap);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -118,9 +116,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
- (void)migrateRecipientStateMapWithCoder:(NSCoder *)coder
|
- (void)migrateRecipientStateMapWithCoder:(NSCoder *)coder
|
||||||
{
|
{
|
||||||
OWSAssertDebug(!self.recipientStateMap);
|
|
||||||
OWSAssertDebug(coder);
|
|
||||||
|
|
||||||
// Determine the "overall message state."
|
// Determine the "overall message state."
|
||||||
TSOutgoingMessageState oldMessageState = TSOutgoingMessageStateFailed;
|
TSOutgoingMessageState oldMessageState = TSOutgoingMessageStateFailed;
|
||||||
NSNumber *_Nullable messageStateValue = [coder decodeObjectForKey:@"messageState"];
|
NSNumber *_Nullable messageStateValue = [coder decodeObjectForKey:@"messageState"];
|
||||||
|
@ -184,7 +179,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
NSString *_Nullable singleGroupRecipient = [coder decodeObjectForKey:@"singleGroupRecipient"];
|
NSString *_Nullable singleGroupRecipient = [coder decodeObjectForKey:@"singleGroupRecipient"];
|
||||||
if (singleGroupRecipient) {
|
if (singleGroupRecipient) {
|
||||||
OWSFailDebug(@"unexpected single group recipient message.");
|
|
||||||
// If this is a "single group recipient message", treat it as such.
|
// If this is a "single group recipient message", treat it as such.
|
||||||
recipientIds = @[
|
recipientIds = @[
|
||||||
singleGroupRecipient,
|
singleGroupRecipient,
|
||||||
|
@ -207,7 +201,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
||||||
recipientState.deliveryTimestamp = deliveryTimestamp;
|
recipientState.deliveryTimestamp = deliveryTimestamp;
|
||||||
} else if (wasDeliveredToContact) {
|
} else if (wasDeliveredToContact) {
|
||||||
OWSAssertDebug(!isGroupThread);
|
|
||||||
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
||||||
// Use message time as an estimate of delivery time.
|
// Use message time as an estimate of delivery time.
|
||||||
recipientState.deliveryTimestamp = @(self.timestamp);
|
recipientState.deliveryTimestamp = @(self.timestamp);
|
||||||
|
@ -329,7 +322,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
_groupMetaMessage = groupMetaMessage;
|
_groupMetaMessage = groupMetaMessage;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
OWSAssertDebug(groupMetaMessage == TSGroupMetaMessageUnspecified);
|
|
||||||
// Specifying a group meta message only makes sense for Group threads
|
// Specifying a group meta message only makes sense for Group threads
|
||||||
_groupMetaMessage = TSGroupMetaMessageUnspecified;
|
_groupMetaMessage = TSGroupMetaMessageUnspecified;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +369,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
TSAttachment *_Nullable attachment =
|
TSAttachment *_Nullable attachment =
|
||||||
[TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction];
|
[TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction];
|
||||||
if (!attachment) {
|
if (!attachment) {
|
||||||
OWSLogError(@"Couldn't load interaction's attachment for deletion.");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
[attachment removeWithTransaction:transaction];
|
[attachment removeWithTransaction:transaction];
|
||||||
|
@ -417,8 +408,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
+ (TSOutgoingMessageState)messageStateForRecipientStates:(NSArray<TSOutgoingMessageRecipientState *> *)recipientStates
|
+ (TSOutgoingMessageState)messageStateForRecipientStates:(NSArray<TSOutgoingMessageRecipientState *> *)recipientStates
|
||||||
{
|
{
|
||||||
OWSAssertDebug(recipientStates);
|
|
||||||
|
|
||||||
// If there are any "sending" recipients, consider this message "sending".
|
// If there are any "sending" recipients, consider this message "sending".
|
||||||
BOOL hasFailed = NO;
|
BOOL hasFailed = NO;
|
||||||
for (TSOutgoingMessageRecipientState *recipientState in recipientStates) {
|
for (TSOutgoingMessageRecipientState *recipientState in recipientStates) {
|
||||||
|
@ -455,8 +444,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
// There's no need to save this message, since it's not displayed to the user.
|
// There's no need to save this message, since it's not displayed to the user.
|
||||||
//
|
//
|
||||||
// Should we find a need to save this in the future, we need to exclude any non-serializable properties.
|
// Should we find a need to save this in the future, we need to exclude any non-serializable properties.
|
||||||
OWSLogDebug(@"Skipping save for transient outgoing message.");
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -483,8 +470,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
// no longer be considered sent.
|
// no longer be considered sent.
|
||||||
// So here we take extra care not to stop any expiration that had previously started.
|
// So here we take extra care not to stop any expiration that had previously started.
|
||||||
// This can also happen under normal cirumstances with an outgoing group message.
|
// This can also happen under normal cirumstances with an outgoing group message.
|
||||||
OWSLogWarn(@"expiration previously started");
|
|
||||||
|
|
||||||
return YES;
|
return YES;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,10 +572,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
- (nullable TSOutgoingMessageRecipientState *)recipientStateForRecipientId:(NSString *)recipientId
|
- (nullable TSOutgoingMessageRecipientState *)recipientStateForRecipientId:(NSString *)recipientId
|
||||||
{
|
{
|
||||||
OWSAssertDebug(recipientId.length > 0);
|
|
||||||
|
|
||||||
TSOutgoingMessageRecipientState *_Nullable result = self.recipientStateMap[recipientId];
|
TSOutgoingMessageRecipientState *_Nullable result = self.recipientStateMap[recipientId];
|
||||||
OWSAssertDebug(result);
|
|
||||||
return [result copy];
|
return [result copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,7 +580,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
- (void)updateWithSendingError:(NSError *)error transaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)updateWithSendingError:(NSError *)error transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(error);
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
// Mark any "sending" recipients as "failed."
|
// Mark any "sending" recipients as "failed."
|
||||||
|
@ -613,8 +594,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
- (void)updateWithAllSendingRecipientsMarkedAsFailedWithTansaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)updateWithAllSendingRecipientsMarkedAsFailedWithTansaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
// Mark any "sending" recipients as "failed."
|
// Mark any "sending" recipients as "failed."
|
||||||
|
@ -629,8 +608,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
- (void)updateWithMarkingAllUnsentRecipientsAsSendingWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)updateWithMarkingAllUnsentRecipientsAsSendingWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
// Mark any "sending" recipients as "failed."
|
// Mark any "sending" recipients as "failed."
|
||||||
|
@ -654,9 +631,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
- (void)updateWithCustomMessage:(NSString *)customMessage transaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)updateWithCustomMessage:(NSString *)customMessage transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(customMessage);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
[message setCustomMessage:customMessage];
|
[message setCustomMessage:customMessage];
|
||||||
|
@ -673,9 +647,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
- (void)updateWithSentRecipient:(NSString *)recipientId
|
- (void)updateWithSentRecipient:(NSString *)recipientId
|
||||||
wasSentByUD:(BOOL)wasSentByUD
|
wasSentByUD:(BOOL)wasSentByUD
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction {
|
transaction:(YapDatabaseReadWriteTransaction *)transaction {
|
||||||
OWSAssertDebug(recipientId.length > 0);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
TSOutgoingMessageRecipientState *_Nullable recipientState
|
TSOutgoingMessageRecipientState *_Nullable recipientState
|
||||||
|
@ -688,9 +659,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
|
|
||||||
- (void)updateWithSkippedRecipient:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction
|
- (void)updateWithSkippedRecipient:(NSString *)recipientId transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(recipientId.length > 0);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
TSOutgoingMessageRecipientState *_Nullable recipientState
|
TSOutgoingMessageRecipientState *_Nullable recipientState
|
||||||
|
@ -704,9 +672,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
deliveryTimestamp:(NSNumber *_Nullable)deliveryTimestamp
|
deliveryTimestamp:(NSNumber *_Nullable)deliveryTimestamp
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(recipientId.length > 0);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
// If delivery notification doesn't include timestamp, use "now" as an estimate.
|
// If delivery notification doesn't include timestamp, use "now" as an estimate.
|
||||||
if (!deliveryTimestamp) {
|
if (!deliveryTimestamp) {
|
||||||
deliveryTimestamp = @([NSDate ows_millisecondTimeStamp]);
|
deliveryTimestamp = @([NSDate ows_millisecondTimeStamp]);
|
||||||
|
@ -716,13 +681,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
TSOutgoingMessageRecipientState *_Nullable recipientState
|
TSOutgoingMessageRecipientState *_Nullable recipientState
|
||||||
= message.recipientStateMap[recipientId];
|
= message.recipientStateMap[recipientId];
|
||||||
if (!recipientState) {
|
if (!recipientState) { return; }
|
||||||
// OWSFailDebug(@"Missing recipient state for delivered recipient: %@", recipientId);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (recipientState.state != OWSOutgoingMessageRecipientStateSent) {
|
|
||||||
OWSLogWarn(@"marking unsent message as delivered.");
|
|
||||||
}
|
|
||||||
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
||||||
recipientState.deliveryTimestamp = deliveryTimestamp;
|
recipientState.deliveryTimestamp = deliveryTimestamp;
|
||||||
}];
|
}];
|
||||||
|
@ -732,16 +691,10 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
readTimestamp:(uint64_t)readTimestamp
|
readTimestamp:(uint64_t)readTimestamp
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(recipientId.length > 0);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
TSOutgoingMessageRecipientState *_Nullable recipientState = message.recipientStateMap[recipientId];
|
TSOutgoingMessageRecipientState *_Nullable recipientState = message.recipientStateMap[recipientId];
|
||||||
if (!recipientState) { return; }
|
if (!recipientState) { return; }
|
||||||
if (recipientState.state != OWSOutgoingMessageRecipientStateSent) {
|
|
||||||
OWSLogWarn(@"Marking unsent message as delivered.");
|
|
||||||
}
|
|
||||||
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
||||||
recipientState.readTimestamp = @(readTimestamp);
|
recipientState.readTimestamp = @(readTimestamp);
|
||||||
}];
|
}];
|
||||||
|
@ -752,8 +705,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
isSentUpdate:(BOOL)isSentUpdate
|
isSentUpdate:(BOOL)isSentUpdate
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self
|
[self
|
||||||
applyChangeToSelfAndLatestCopy:transaction
|
applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
|
@ -764,8 +715,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
= [NSMutableDictionary new];
|
= [NSMutableDictionary new];
|
||||||
for (NSString *recipientId in udRecipientIds) {
|
for (NSString *recipientId in udRecipientIds) {
|
||||||
if (recipientStateMap[recipientId]) {
|
if (recipientStateMap[recipientId]) {
|
||||||
OWSFailDebug(
|
|
||||||
@"recipient appears more than once in recipient lists: %@", recipientId);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TSOutgoingMessageRecipientState *recipientState =
|
TSOutgoingMessageRecipientState *recipientState =
|
||||||
|
@ -776,8 +725,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
}
|
}
|
||||||
for (NSString *recipientId in nonUdRecipientIds) {
|
for (NSString *recipientId in nonUdRecipientIds) {
|
||||||
if (recipientStateMap[recipientId]) {
|
if (recipientStateMap[recipientId]) {
|
||||||
OWSFailDebug(
|
|
||||||
@"recipient appears more than once in recipient lists: %@", recipientId);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
TSOutgoingMessageRecipientState *recipientState =
|
TSOutgoingMessageRecipientState *recipientState =
|
||||||
|
@ -822,9 +769,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
- (void)updateWithSendingToSingleGroupRecipient:(NSString *)singleGroupRecipient
|
- (void)updateWithSendingToSingleGroupRecipient:(NSString *)singleGroupRecipient
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
OWSAssertDebug(singleGroupRecipient.length > 0);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
TSOutgoingMessageRecipientState *recipientState =
|
TSOutgoingMessageRecipientState *recipientState =
|
||||||
|
@ -853,8 +797,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
- (void)updateWithFakeMessageState:(TSOutgoingMessageState)messageState
|
- (void)updateWithFakeMessageState:(TSOutgoingMessageState)messageState
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[self applyChangeToSelfAndLatestCopy:transaction
|
[self applyChangeToSelfAndLatestCopy:transaction
|
||||||
changeBlock:^(TSOutgoingMessage *message) {
|
changeBlock:^(TSOutgoingMessage *message) {
|
||||||
for (TSOutgoingMessageRecipientState *recipientState in message.recipientStateMap
|
for (TSOutgoingMessageRecipientState *recipientState in message.recipientStateMap
|
||||||
|
@ -870,7 +812,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
recipientState.state = OWSOutgoingMessageRecipientStateSent;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
OWSFailDebug(@"unexpected message state.");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -882,7 +823,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
- (nullable id)dataMessageBuilder
|
- (nullable id)dataMessageBuilder
|
||||||
{
|
{
|
||||||
TSThread *thread = self.thread;
|
TSThread *thread = self.thread;
|
||||||
OWSAssertDebug(thread);
|
|
||||||
|
|
||||||
SNProtoDataMessageBuilder *builder = [SNProtoDataMessage builder];
|
SNProtoDataMessageBuilder *builder = [SNProtoDataMessage builder];
|
||||||
[builder setTimestamp:self.timestamp];
|
[builder setTimestamp:self.timestamp];
|
||||||
|
@ -890,11 +830,8 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
if ([self.body lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) {
|
if ([self.body lengthOfBytesUsingEncoding:NSUTF8StringEncoding] <= kOversizeTextMessageSizeThreshold) {
|
||||||
[builder setBody:self.body];
|
[builder setBody:self.body];
|
||||||
} else {
|
} else {
|
||||||
OWSFailDebug(@"message body length too long.");
|
|
||||||
NSString *truncatedBody = [self.body copy];
|
NSString *truncatedBody = [self.body copy];
|
||||||
while ([truncatedBody lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > kOversizeTextMessageSizeThreshold) {
|
while ([truncatedBody lengthOfBytesUsingEncoding:NSUTF8StringEncoding] > kOversizeTextMessageSizeThreshold) {
|
||||||
OWSLogError(@"truncating body which is too long: %lu",
|
|
||||||
(unsigned long)[truncatedBody lengthOfBytesUsingEncoding:NSUTF8StringEncoding]);
|
|
||||||
truncatedBody = [truncatedBody substringToIndex:truncatedBody.length / 2];
|
truncatedBody = [truncatedBody substringToIndex:truncatedBody.length / 2];
|
||||||
}
|
}
|
||||||
[builder setBody:truncatedBody];
|
[builder setBody:truncatedBody];
|
||||||
|
@ -926,7 +863,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
SNProtoAttachmentPointer *_Nullable attachmentProto =
|
SNProtoAttachmentPointer *_Nullable attachmentProto =
|
||||||
[TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject];
|
[TSAttachmentStream buildProtoForAttachmentId:self.attachmentIds.firstObject];
|
||||||
if (!attachmentProto) {
|
if (!attachmentProto) {
|
||||||
OWSFailDebug(@"could not build protobuf.");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[groupBuilder setAvatar:attachmentProto];
|
[groupBuilder setAvatar:attachmentProto];
|
||||||
|
@ -939,7 +875,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
NSError *error;
|
NSError *error;
|
||||||
SNProtoGroupContext *_Nullable groupContextProto = [groupBuilder buildAndReturnError:&error];
|
SNProtoGroupContext *_Nullable groupContextProto = [groupBuilder buildAndReturnError:&error];
|
||||||
if (error || !groupContextProto) {
|
if (error || !groupContextProto) {
|
||||||
OWSFailDebug(@"could not build protobuf: %@.", error);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[builder setGroup:groupContextProto];
|
[builder setGroup:groupContextProto];
|
||||||
|
@ -952,7 +887,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
SNProtoAttachmentPointer *_Nullable attachmentProto =
|
SNProtoAttachmentPointer *_Nullable attachmentProto =
|
||||||
[TSAttachmentStream buildProtoForAttachmentId:attachmentId];
|
[TSAttachmentStream buildProtoForAttachmentId:attachmentId];
|
||||||
if (!attachmentProto) {
|
if (!attachmentProto) {
|
||||||
OWSFailDebug(@"could not build protobuf.");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[attachments addObject:attachmentProto];
|
[attachments addObject:attachmentProto];
|
||||||
|
@ -966,7 +900,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
NSError *error;
|
NSError *error;
|
||||||
SNProtoDataMessageQuote *_Nullable quoteProto = [quotedMessageBuilder buildAndReturnError:&error];
|
SNProtoDataMessageQuote *_Nullable quoteProto = [quotedMessageBuilder buildAndReturnError:&error];
|
||||||
if (error || !quoteProto) {
|
if (error || !quoteProto) {
|
||||||
OWSFailDebug(@"could not build protobuf: %@.", error);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
[builder setQuote:quoteProto];
|
[builder setQuote:quoteProto];
|
||||||
|
@ -983,7 +916,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
SNProtoAttachmentPointer *_Nullable attachmentProto =
|
SNProtoAttachmentPointer *_Nullable attachmentProto =
|
||||||
[TSAttachmentStream buildProtoForAttachmentId:self.linkPreview.imageAttachmentId];
|
[TSAttachmentStream buildProtoForAttachmentId:self.linkPreview.imageAttachmentId];
|
||||||
if (!attachmentProto) {
|
if (!attachmentProto) {
|
||||||
OWSFailDebug(@"Could not build link preview image protobuf.");
|
|
||||||
} else {
|
} else {
|
||||||
[previewBuilder setImage:attachmentProto];
|
[previewBuilder setImage:attachmentProto];
|
||||||
}
|
}
|
||||||
|
@ -992,7 +925,7 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
NSError *error;
|
NSError *error;
|
||||||
SNProtoDataMessagePreview *_Nullable previewProto = [previewBuilder buildAndReturnError:&error];
|
SNProtoDataMessagePreview *_Nullable previewProto = [previewBuilder buildAndReturnError:&error];
|
||||||
if (error || !previewProto) {
|
if (error || !previewProto) {
|
||||||
OWSFailDebug(@"Could not build link preview protobuf: %@.", error);
|
|
||||||
} else {
|
} else {
|
||||||
[builder addPreview:previewProto];
|
[builder addPreview:previewProto];
|
||||||
}
|
}
|
||||||
|
@ -1036,7 +969,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
SNProtoDataMessageQuoteQuotedAttachment *_Nullable quotedAttachmentMessage =
|
SNProtoDataMessageQuoteQuotedAttachment *_Nullable quotedAttachmentMessage =
|
||||||
[quotedAttachmentBuilder buildAndReturnError:&error];
|
[quotedAttachmentBuilder buildAndReturnError:&error];
|
||||||
if (error || !quotedAttachmentMessage) {
|
if (error || !quotedAttachmentMessage) {
|
||||||
OWSFailDebug(@"could not build protobuf: %@", error);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1047,7 +979,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
if (hasQuotedText || hasQuotedAttachment) {
|
if (hasQuotedText || hasQuotedAttachment) {
|
||||||
return quoteBuilder;
|
return quoteBuilder;
|
||||||
} else {
|
} else {
|
||||||
OWSFailDebug(@"Invalid quoted message data.");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1055,10 +986,8 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
// recipientId is nil when building "sent" sync messages for messages sent to groups.
|
// recipientId is nil when building "sent" sync messages for messages sent to groups.
|
||||||
- (nullable SNProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
|
- (nullable SNProtoDataMessage *)buildDataMessage:(NSString *_Nullable)recipientId
|
||||||
{
|
{
|
||||||
OWSAssertDebug(self.thread);
|
|
||||||
SNProtoDataMessageBuilder *_Nullable builder = [self dataMessageBuilder];
|
SNProtoDataMessageBuilder *_Nullable builder = [self dataMessageBuilder];
|
||||||
if (builder == nil) {
|
if (builder == nil) {
|
||||||
OWSFailDebug(@"Couldn't build protobuf.");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1082,7 +1011,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
NSError *error;
|
NSError *error;
|
||||||
SNProtoDataMessage *_Nullable dataProto = [builder buildAndReturnError:&error];
|
SNProtoDataMessage *_Nullable dataProto = [builder buildAndReturnError:&error];
|
||||||
if (error != nil || dataProto == nil) {
|
if (error != nil || dataProto == nil) {
|
||||||
OWSFailDebug(@"Couldn't build protobuf due to error: %@.", error);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
return dataProto;
|
return dataProto;
|
||||||
|
@ -1092,7 +1020,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
SNProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:recipient.recipientId];
|
SNProtoDataMessage *_Nullable dataMessage = [self buildDataMessage:recipient.recipientId];
|
||||||
|
|
||||||
if (dataMessage == nil) {
|
if (dataMessage == nil) {
|
||||||
OWSFailDebug(@"Couldn't build protobuf.");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1109,7 +1036,6 @@ NSString *NSStringForOutgoingMessageRecipientState(OWSOutgoingMessageRecipientSt
|
||||||
NSError *error;
|
NSError *error;
|
||||||
NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error];
|
NSData *_Nullable contentData = [contentBuilder buildSerializedDataAndReturnError:&error];
|
||||||
if (error != nil || contentData == nil) {
|
if (error != nil || contentData == nil) {
|
||||||
OWSFailDebug(@"Couldn't serialize protobuf due to error: %@.", error);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,47 @@
|
||||||
FOUNDATION_EXPORT double SessionMessagingKitVersionNumber;
|
FOUNDATION_EXPORT double SessionMessagingKitVersionNumber;
|
||||||
FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[];
|
FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[];
|
||||||
|
|
||||||
|
#import <SessionMessagingKit/AppReadiness.h>
|
||||||
|
#import <SessionMessagingKit/NotificationsProtocol.h>
|
||||||
|
#import <SessionMessagingKit/OWSBackgroundTask.h>
|
||||||
|
#import <SessionMessagingKit/OWSBlockingManager.h>
|
||||||
|
#import <SessionMessagingKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
|
||||||
|
#import <SessionMessagingKit/OWSDisappearingMessagesConfiguration.h>
|
||||||
|
#import <SessionMessagingKit/OWSDisappearingMessagesFinder.h>
|
||||||
|
#import <SessionMessagingKit/OWSDisappearingMessagesJob.h>
|
||||||
|
#import <SessionMessagingKit/OWSIdentityManager.h>
|
||||||
|
#import <SessionMessagingKit/OWSIncomingMessageFinder.h>
|
||||||
|
#import <SessionMessagingKit/OWSMediaGalleryFinder.h>
|
||||||
|
#import <SessionMessagingKit/OWSOutgoingReceiptManager.h>
|
||||||
|
#import <SessionMessagingKit/OWSPrimaryStorage.h>
|
||||||
|
#import <SessionMessagingKit/OWSQuotedReplyModel.h>
|
||||||
|
#import <SessionMessagingKit/OWSReadReceiptManager.h>
|
||||||
|
#import <SessionMessagingKit/OWSReadTracking.h>
|
||||||
|
#import <SessionMessagingKit/OWSRecipientIdentity.h>
|
||||||
|
#import <SessionMessagingKit/OWSStorage.h>
|
||||||
|
#import <SessionMessagingKit/ProfileManagerProtocol.h>
|
||||||
|
#import <SessionMessagingKit/ProtoUtils.h>
|
||||||
|
#import <SessionMessagingKit/SSKEnvironment.h>
|
||||||
|
#import <SessionMessagingKit/SSKJobRecord.h>
|
||||||
|
#import <SessionMessagingKit/TSAccountManager.h>
|
||||||
#import <SessionMessagingKit/TSAttachment.h>
|
#import <SessionMessagingKit/TSAttachment.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentPointer.h>
|
#import <SessionMessagingKit/TSAttachmentPointer.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentStream.h>
|
#import <SessionMessagingKit/TSAttachmentStream.h>
|
||||||
|
#import <SessionMessagingKit/TSContactThread.h>
|
||||||
|
#import <SessionMessagingKit/TSDatabaseSecondaryIndexes.h>
|
||||||
|
#import <SessionMessagingKit/TSDatabaseView.h>
|
||||||
|
#import <SessionMessagingKit/TSErrorMessage.h>
|
||||||
|
#import <SessionMessagingKit/TSErrorMessage_privateConstructor.h>
|
||||||
|
#import <SessionMessagingKit/TSGroupModel.h>
|
||||||
|
#import <SessionMessagingKit/TSGroupThread.h>
|
||||||
|
#import <SessionMessagingKit/TSIncomingMessage.h>
|
||||||
|
#import <SessionMessagingKit/TSInfoMessage.h>
|
||||||
|
#import <SessionMessagingKit/TSInteraction.h>
|
||||||
|
#import <SessionMessagingKit/TSInvalidIdentityKeyErrorMessage.h>
|
||||||
|
#import <SessionMessagingKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
|
||||||
|
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
||||||
|
#import <SessionMessagingKit/TSQuotedMessage.h>
|
||||||
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
|
#import <SessionMessagingKit/TSUnreadIndicatorInteraction.h>
|
||||||
|
#import <SessionMessagingKit/YapDatabaseConnection+OWS.h>
|
||||||
|
#import <SessionMessagingKit/YapDatabaseTransaction+OWS.h>
|
||||||
|
|
|
@ -350,7 +350,7 @@ public final class OpenGroupAPI : DotNetAPI {
|
||||||
storage.setUserCount(to: memberCount, forOpenGroupWithID: "\(server).\(channel)", using: transaction)
|
storage.setUserCount(to: memberCount, forOpenGroupWithID: "\(server).\(channel)", using: transaction)
|
||||||
}
|
}
|
||||||
let openGroupInfo = OpenGroupInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount)
|
let openGroupInfo = OpenGroupInfo(displayName: displayName, profilePictureURL: profilePictureURL, memberCount: memberCount)
|
||||||
Configuration.shared.openGroupAPIDelegate.updateProfileIfNeeded(for: channel, on: server, from: openGroupInfo)
|
OpenGroupAPI.updateProfileIfNeeded(for: channel, on: server, from: openGroupInfo)
|
||||||
return openGroupInfo
|
return openGroupInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,6 +358,39 @@ public final class OpenGroupAPI : DotNetAPI {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: OpenGroupInfo) {
|
||||||
|
let openGroupID = "\(server).\(channel)"
|
||||||
|
Storage.write { transaction in
|
||||||
|
// Update user count
|
||||||
|
Storage.shared.setUserCount(to: info.memberCount, forOpenGroupWithID: openGroupID, using: transaction)
|
||||||
|
let thread = TSGroupThread.getOrCreateThread(withGroupId: openGroupID.data(using: .utf8)!, groupType: .openGroup, transaction: transaction)
|
||||||
|
// Update display name if needed
|
||||||
|
let model = thread.groupModel
|
||||||
|
if model.groupName != info.displayName {
|
||||||
|
let newGroupModel = TSGroupModel(title: info.displayName, memberIds: model.groupMemberIds, image: model.groupImage, groupId: model.groupId, groupType: model.groupType, adminIds: model.groupAdminIds)
|
||||||
|
thread.groupModel = newGroupModel
|
||||||
|
thread.save(with: transaction)
|
||||||
|
}
|
||||||
|
// Download and update profile picture if needed
|
||||||
|
let oldProfilePictureURL = Storage.shared.getProfilePictureURL(forOpenGroupWithID: openGroupID)
|
||||||
|
if oldProfilePictureURL != info.profilePictureURL || model.groupImage == nil {
|
||||||
|
Storage.shared.setProfilePictureURL(to: info.profilePictureURL, forOpenGroupWithID: openGroupID, using: transaction)
|
||||||
|
if let profilePictureURL = info.profilePictureURL {
|
||||||
|
var sanitizedServerURL = server
|
||||||
|
while sanitizedServerURL.hasSuffix("/") { sanitizedServerURL.removeLast() }
|
||||||
|
var sanitizedProfilePictureURL = profilePictureURL
|
||||||
|
while sanitizedProfilePictureURL.hasPrefix("/") { sanitizedProfilePictureURL.removeFirst() }
|
||||||
|
let url = "\(sanitizedServerURL)/\(sanitizedProfilePictureURL)"
|
||||||
|
FileServerAPI.downloadAttachment(from: url).map2 { data in
|
||||||
|
let attachmentStream = TSAttachmentStream(contentType: OWSMimeTypeImageJpeg, byteCount: UInt32(data.count), sourceFilename: nil, caption: nil, albumMessageId: nil)
|
||||||
|
try attachmentStream.write(data)
|
||||||
|
thread.updateAvatar(with: attachmentStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static func join(_ channel: UInt64, on server: String) -> Promise<Void> {
|
public static func join(_ channel: UInt64, on server: String) -> Promise<Void> {
|
||||||
return attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global(qos: .default)) {
|
return attempt(maxRetryCount: maxRetryCount, recoveringOn: DispatchQueue.global(qos: .default)) {
|
||||||
getOpenGroupServerPublicKey(for: server).then(on: DispatchQueue.global(qos: .default)) { serverPublicKey in
|
getOpenGroupServerPublicKey(for: server).then(on: DispatchQueue.global(qos: .default)) { serverPublicKey in
|
||||||
|
|
|
@ -1,5 +0,0 @@
|
||||||
|
|
||||||
public protocol OpenGroupAPIDelegate {
|
|
||||||
|
|
||||||
func updateProfileIfNeeded(for channel: UInt64, on server: String, from info: OpenGroupInfo)
|
|
||||||
}
|
|
|
@ -8,7 +8,7 @@ import MobileCoreServices
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
import AVFoundation
|
import AVFoundation
|
||||||
|
|
||||||
enum SignalAttachmentError: Error {
|
public enum SignalAttachmentError: Error {
|
||||||
case missingData
|
case missingData
|
||||||
case fileSizeTooLarge
|
case fileSizeTooLarge
|
||||||
case invalidData
|
case invalidData
|
||||||
|
@ -21,17 +21,16 @@ enum SignalAttachmentError: Error {
|
||||||
}
|
}
|
||||||
|
|
||||||
extension String {
|
extension String {
|
||||||
var filenameWithoutExtension: String {
|
public var filenameWithoutExtension: String {
|
||||||
return (self as NSString).deletingPathExtension
|
return (self as NSString).deletingPathExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
var fileExtension: String? {
|
public var fileExtension: String? {
|
||||||
return (self as NSString).pathExtension
|
return (self as NSString).pathExtension
|
||||||
}
|
}
|
||||||
|
|
||||||
func appendingFileExtension(_ fileExtension: String) -> String {
|
public func appendingFileExtension(_ fileExtension: String) -> String {
|
||||||
guard let result = (self as NSString).appendingPathExtension(fileExtension) else {
|
guard let result = (self as NSString).appendingPathExtension(fileExtension) else {
|
||||||
owsFailDebug("Failed to append file extension: \(fileExtension) to string: \(self)")
|
|
||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
|
@ -160,12 +159,9 @@ public class SignalAttachment: NSObject {
|
||||||
@objc
|
@objc
|
||||||
public let dataUTI: String
|
public let dataUTI: String
|
||||||
|
|
||||||
var error: SignalAttachmentError? {
|
public var error: SignalAttachmentError? {
|
||||||
didSet {
|
didSet {
|
||||||
AssertIsOnMainThread()
|
|
||||||
|
|
||||||
assert(oldValue == nil)
|
assert(oldValue == nil)
|
||||||
Logger.verbose("Attachment has error: \(String(describing: error))")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -213,7 +209,6 @@ public class SignalAttachment: NSObject {
|
||||||
public var errorName: String? {
|
public var errorName: String? {
|
||||||
guard let error = error else {
|
guard let error = error else {
|
||||||
// This method should only be called if there is an error.
|
// This method should only be called if there is an error.
|
||||||
owsFailDebug("Missing error")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,11 +219,9 @@ public class SignalAttachment: NSObject {
|
||||||
public var localizedErrorDescription: String? {
|
public var localizedErrorDescription: String? {
|
||||||
guard let error = self.error else {
|
guard let error = self.error else {
|
||||||
// This method should only be called if there is an error.
|
// This method should only be called if there is an error.
|
||||||
owsFailDebug("Missing error")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
guard let errorDescription = error.errorDescription else {
|
guard let errorDescription = error.errorDescription else {
|
||||||
owsFailDebug("Missing error description")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -238,7 +231,6 @@ public class SignalAttachment: NSObject {
|
||||||
@objc
|
@objc
|
||||||
public class var missingDataErrorMessage: String {
|
public class var missingDataErrorMessage: String {
|
||||||
guard let errorDescription = SignalAttachmentError.missingData.errorDescription else {
|
guard let errorDescription = SignalAttachmentError.missingData.errorDescription else {
|
||||||
owsFailDebug("Missing error description")
|
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
return errorDescription
|
return errorDescription
|
||||||
|
@ -284,7 +276,6 @@ public class SignalAttachment: NSObject {
|
||||||
do {
|
do {
|
||||||
let filePath = mediaUrl.path
|
let filePath = mediaUrl.path
|
||||||
guard FileManager.default.fileExists(atPath: filePath) else {
|
guard FileManager.default.fileExists(atPath: filePath) else {
|
||||||
owsFailDebug("asset at \(filePath) doesn't exist")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +289,6 @@ public class SignalAttachment: NSObject {
|
||||||
return image
|
return image
|
||||||
|
|
||||||
} catch let error {
|
} catch let error {
|
||||||
Logger.verbose("Could not generate video thumbnail: \(error.localizedDescription)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,7 +526,6 @@ public class SignalAttachment: NSObject {
|
||||||
for dataUTI in inputImageUTISet {
|
for dataUTI in inputImageUTISet {
|
||||||
if pasteboardUTISet.contains(dataUTI) {
|
if pasteboardUTISet.contains(dataUTI) {
|
||||||
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
||||||
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
||||||
|
@ -547,7 +536,6 @@ public class SignalAttachment: NSObject {
|
||||||
for dataUTI in videoUTISet {
|
for dataUTI in videoUTISet {
|
||||||
if pasteboardUTISet.contains(dataUTI) {
|
if pasteboardUTISet.contains(dataUTI) {
|
||||||
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
||||||
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
||||||
|
@ -557,7 +545,6 @@ public class SignalAttachment: NSObject {
|
||||||
for dataUTI in audioUTISet {
|
for dataUTI in audioUTISet {
|
||||||
if pasteboardUTISet.contains(dataUTI) {
|
if pasteboardUTISet.contains(dataUTI) {
|
||||||
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
||||||
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
||||||
|
@ -567,7 +554,6 @@ public class SignalAttachment: NSObject {
|
||||||
|
|
||||||
let dataUTI = pasteboardUTISet[pasteboardUTISet.startIndex]
|
let dataUTI = pasteboardUTISet[pasteboardUTISet.startIndex]
|
||||||
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
guard let data = dataForFirstPasteboardItem(dataUTI: dataUTI) else {
|
||||||
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
let dataSource = DataSourceValue.dataSource(with: data, utiType: dataUTI)
|
||||||
|
@ -579,11 +565,9 @@ public class SignalAttachment: NSObject {
|
||||||
private class func dataForFirstPasteboardItem(dataUTI: String) -> Data? {
|
private class func dataForFirstPasteboardItem(dataUTI: String) -> Data? {
|
||||||
let itemSet = IndexSet(integer: 0)
|
let itemSet = IndexSet(integer: 0)
|
||||||
guard let datas = UIPasteboard.general.data(forPasteboardType: dataUTI, inItemSet: itemSet) else {
|
guard let datas = UIPasteboard.general.data(forPasteboardType: dataUTI, inItemSet: itemSet) else {
|
||||||
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
guard datas.count > 0 else {
|
guard datas.count > 0 else {
|
||||||
owsFailDebug("Missing expected pasteboard data for UTI: \(dataUTI)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return datas[0]
|
return datas[0]
|
||||||
|
@ -613,7 +597,6 @@ public class SignalAttachment: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
guard dataSource.dataLength() > 0 else {
|
guard dataSource.dataLength() > 0 else {
|
||||||
owsFailDebug("imageData was empty")
|
|
||||||
attachment.error = .invalidData
|
attachment.error = .invalidData
|
||||||
return attachment
|
return attachment
|
||||||
}
|
}
|
||||||
|
@ -625,7 +608,6 @@ public class SignalAttachment: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Never re-encode animated images (i.e. GIFs) as JPEGs.
|
// Never re-encode animated images (i.e. GIFs) as JPEGs.
|
||||||
Logger.verbose("Sending raw \(attachment.mimeType) to retain any animation")
|
|
||||||
return attachment
|
return attachment
|
||||||
} else {
|
} else {
|
||||||
guard let image = UIImage(data: dataSource.data()) else {
|
guard let image = UIImage(data: dataSource.data()) else {
|
||||||
|
@ -649,17 +631,14 @@ public class SignalAttachment: NSObject {
|
||||||
// However the problem comes in when you edit an HEIC image in Photos.app - the image is saved
|
// However the problem comes in when you edit an HEIC image in Photos.app - the image is saved
|
||||||
// in the Photos.app as a JPEG, but retains the (now incongruous) HEIC extension in the filename.
|
// in the Photos.app as a JPEG, but retains the (now incongruous) HEIC extension in the filename.
|
||||||
assert(dataUTI == kUTTypeJPEG as String || !isValidOutput)
|
assert(dataUTI == kUTTypeJPEG as String || !isValidOutput)
|
||||||
Logger.verbose("changing extension: \(sourceFileExtension) to match jpg uti type")
|
|
||||||
|
|
||||||
let baseFilename = sourceFilename.filenameWithoutExtension
|
let baseFilename = sourceFilename.filenameWithoutExtension
|
||||||
dataSource.sourceFilename = baseFilename.appendingFileExtension("jpg")
|
dataSource.sourceFilename = baseFilename.appendingFileExtension("jpg")
|
||||||
}
|
}
|
||||||
|
|
||||||
if isValidOutput {
|
if isValidOutput {
|
||||||
Logger.verbose("Rewriting attachment with metadata removed \(attachment.mimeType)")
|
|
||||||
return removeImageMetadata(attachment: attachment)
|
return removeImageMetadata(attachment: attachment)
|
||||||
} else {
|
} else {
|
||||||
Logger.verbose("Compressing attachment as image/jpeg, \(dataSource.dataLength()) bytes")
|
|
||||||
return compressImageAsJPEG(image: image, attachment: attachment, filename: dataSource.sourceFilename, imageQuality: imageQuality)
|
return compressImageAsJPEG(image: image, attachment: attachment, filename: dataSource.sourceFilename, imageQuality: imageQuality)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -706,7 +685,6 @@ public class SignalAttachment: NSObject {
|
||||||
let attachment = SignalAttachment(dataSource: dataSource, dataUTI: dataUTI)
|
let attachment = SignalAttachment(dataSource: dataSource, dataUTI: dataUTI)
|
||||||
attachment.cachedImage = image
|
attachment.cachedImage = image
|
||||||
|
|
||||||
Logger.verbose("Writing \(attachment.mimeType) as image/jpeg")
|
|
||||||
return compressImageAsJPEG(image: image, attachment: attachment, filename: filename, imageQuality: imageQuality)
|
return compressImageAsJPEG(image: image, attachment: attachment, filename: filename, imageQuality: imageQuality)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -751,7 +729,6 @@ public class SignalAttachment: NSObject {
|
||||||
dataSource.dataLength() <= kMaxFileSizeImage {
|
dataSource.dataLength() <= kMaxFileSizeImage {
|
||||||
let recompressedAttachment = SignalAttachment(dataSource: dataSource, dataUTI: kUTTypeJPEG as String)
|
let recompressedAttachment = SignalAttachment(dataSource: dataSource, dataUTI: kUTTypeJPEG as String)
|
||||||
recompressedAttachment.cachedImage = dstImage
|
recompressedAttachment.cachedImage = dstImage
|
||||||
Logger.verbose("Converted \(attachment.mimeType) to image/jpeg, \(jpgImageData.count) bytes")
|
|
||||||
return recompressedAttachment
|
return recompressedAttachment
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -781,7 +758,6 @@ public class SignalAttachment: NSObject {
|
||||||
// Resizing using a CGContext seems to work fine.
|
// Resizing using a CGContext seems to work fine.
|
||||||
private class func imageScaled(_ uiImage: UIImage, toMaxSize maxSize: CGFloat) -> UIImage? {
|
private class func imageScaled(_ uiImage: UIImage, toMaxSize maxSize: CGFloat) -> UIImage? {
|
||||||
guard let cgImage = uiImage.cgImage else {
|
guard let cgImage = uiImage.cgImage else {
|
||||||
owsFailDebug("UIImage missing cgImage.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -804,7 +780,6 @@ public class SignalAttachment: NSObject {
|
||||||
bytesPerRow: 0,
|
bytesPerRow: 0,
|
||||||
space: colorSpace,
|
space: colorSpace,
|
||||||
bitmapInfo: bitmapInfo.rawValue) else {
|
bitmapInfo: bitmapInfo.rawValue) else {
|
||||||
owsFailDebug("could not create CGContext.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
context.interpolationQuality = .high
|
context.interpolationQuality = .high
|
||||||
|
@ -814,7 +789,6 @@ public class SignalAttachment: NSObject {
|
||||||
context.draw(cgImage, in: drawRect)
|
context.draw(cgImage, in: drawRect)
|
||||||
|
|
||||||
guard let newCGImage = context.makeImage() else {
|
guard let newCGImage = context.makeImage() else {
|
||||||
owsFailDebug("could not create new CGImage.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return UIImage(cgImage: newCGImage,
|
return UIImage(cgImage: newCGImage,
|
||||||
|
@ -914,7 +888,6 @@ public class SignalAttachment: NSObject {
|
||||||
return strippedAttachment
|
return strippedAttachment
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
Logger.verbose("CGImageDestinationFinalize failed")
|
|
||||||
attachment.error = .couldNotRemoveMetadata
|
attachment.error = .couldNotRemoveMetadata
|
||||||
return attachment
|
return attachment
|
||||||
}
|
}
|
||||||
|
@ -934,10 +907,6 @@ public class SignalAttachment: NSObject {
|
||||||
return attachment
|
return attachment
|
||||||
}
|
}
|
||||||
|
|
||||||
if !isValidOutputVideo(dataSource: dataSource, dataUTI: dataUTI) {
|
|
||||||
owsFailDebug("building video with invalid output, migrate to async API using compressVideoAsMp4")
|
|
||||||
}
|
|
||||||
|
|
||||||
return newAttachment(dataSource: dataSource,
|
return newAttachment(dataSource: dataSource,
|
||||||
dataUTI: dataUTI,
|
dataUTI: dataUTI,
|
||||||
validUTISet: videoUTISet,
|
validUTISet: videoUTISet,
|
||||||
|
@ -949,7 +918,6 @@ public class SignalAttachment: NSObject {
|
||||||
OWSFileSystem.ensureDirectoryExists(baseDir.path)
|
OWSFileSystem.ensureDirectoryExists(baseDir.path)
|
||||||
let toUrl = baseDir.appendingPathComponent(fromUrl.lastPathComponent)
|
let toUrl = baseDir.appendingPathComponent(fromUrl.lastPathComponent)
|
||||||
|
|
||||||
Logger.debug("moving \(fromUrl) -> \(toUrl)")
|
|
||||||
try FileManager.default.copyItem(at: fromUrl, to: toUrl)
|
try FileManager.default.copyItem(at: fromUrl, to: toUrl)
|
||||||
|
|
||||||
return toUrl
|
return toUrl
|
||||||
|
@ -962,8 +930,6 @@ public class SignalAttachment: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func compressVideoAsMp4(dataSource: DataSource, dataUTI: String) -> (Promise<SignalAttachment>, AVAssetExportSession?) {
|
public class func compressVideoAsMp4(dataSource: DataSource, dataUTI: String) -> (Promise<SignalAttachment>, AVAssetExportSession?) {
|
||||||
Logger.debug("")
|
|
||||||
|
|
||||||
guard let url = dataSource.dataUrl() else {
|
guard let url = dataSource.dataUrl() else {
|
||||||
let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI)
|
let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI)
|
||||||
attachment.error = .missingData
|
attachment.error = .missingData
|
||||||
|
@ -987,15 +953,12 @@ public class SignalAttachment: NSObject {
|
||||||
|
|
||||||
let (promise, resolver) = Promise<SignalAttachment>.pending()
|
let (promise, resolver) = Promise<SignalAttachment>.pending()
|
||||||
|
|
||||||
Logger.debug("starting video export")
|
|
||||||
exportSession.exportAsynchronously {
|
exportSession.exportAsynchronously {
|
||||||
Logger.debug("Completed video export")
|
|
||||||
let baseFilename = dataSource.sourceFilename
|
let baseFilename = dataSource.sourceFilename
|
||||||
let mp4Filename = baseFilename?.filenameWithoutExtension.appendingFileExtension("mp4")
|
let mp4Filename = baseFilename?.filenameWithoutExtension.appendingFileExtension("mp4")
|
||||||
|
|
||||||
guard let dataSource = DataSourcePath.dataSource(with: exportURL,
|
guard let dataSource = DataSourcePath.dataSource(with: exportURL,
|
||||||
shouldDeleteOnDeallocation: true) else {
|
shouldDeleteOnDeallocation: true) else {
|
||||||
owsFailDebug("Failed to build data source for exported video URL")
|
|
||||||
let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI)
|
let attachment = SignalAttachment(dataSource: DataSourceValue.emptyDataSource(), dataUTI: dataUTI)
|
||||||
attachment.error = .couldNotConvertToMpeg4
|
attachment.error = .couldNotConvertToMpeg4
|
||||||
resolver.fulfill(attachment)
|
resolver.fulfill(attachment)
|
||||||
|
@ -1120,9 +1083,6 @@ public class SignalAttachment: NSObject {
|
||||||
// Check the attachment's error property.
|
// Check the attachment's error property.
|
||||||
@objc
|
@objc
|
||||||
public class func attachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment {
|
public class func attachment(dataSource: DataSource?, dataUTI: String) -> SignalAttachment {
|
||||||
if inputImageUTISet.contains(dataUTI) {
|
|
||||||
owsFailDebug("must specify image quality type")
|
|
||||||
}
|
|
||||||
return attachment(dataSource: dataSource, dataUTI: dataUTI, imageQuality: .original)
|
return attachment(dataSource: dataSource, dataUTI: dataUTI, imageQuality: .original)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1175,7 +1135,6 @@ public class SignalAttachment: NSObject {
|
||||||
}
|
}
|
||||||
|
|
||||||
guard dataSource.dataLength() > 0 else {
|
guard dataSource.dataLength() > 0 else {
|
||||||
owsFailDebug("Empty attachment")
|
|
||||||
assert(dataSource.dataLength() > 0)
|
assert(dataSource.dataLength() > 0)
|
||||||
attachment.error = .invalidData
|
attachment.error = .invalidData
|
||||||
return attachment
|
return attachment
|
|
@ -1,4 +1,5 @@
|
||||||
#import <SessionUtilitiesKit/TSYapDatabaseObject.h>
|
#import <SessionUtilitiesKit/TSYapDatabaseObject.h>
|
||||||
|
#import <SessionMessagingKit/TSMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -87,6 +88,16 @@ typedef NS_ENUM(NSUInteger, TSAttachmentType) {
|
||||||
|
|
||||||
+ (NSString *)emojiForMimeType:(NSString *)contentType;
|
+ (NSString *)emojiForMimeType:(NSString *)contentType;
|
||||||
|
|
||||||
|
#pragma mark - Media Album
|
||||||
|
|
||||||
|
- (nullable TSMessage *)fetchAlbumMessageWithTransaction:(YapDatabaseReadTransaction *)transaction;
|
||||||
|
|
||||||
|
// `migrateAlbumMessageId` is only used in the migration to the new multi-attachment message scheme,
|
||||||
|
// and shouldn't be used as a general purpose setter. Instead, `albumMessageId` should be passed as
|
||||||
|
// an initializer param.
|
||||||
|
- (void)migrateAlbumMessageId:(NSString *)albumMesssageId;
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
|
@ -244,6 +244,21 @@ NSUInteger const TSAttachmentSchemaVersion = 4;
|
||||||
return _contentType.filterFilename;
|
return _contentType.filterFilename;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Media Album
|
||||||
|
|
||||||
|
- (nullable TSMessage *)fetchAlbumMessageWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||||
|
{
|
||||||
|
if (self.albumMessageId == nil) {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
return [TSMessage fetchObjectWithUniqueID:self.albumMessageId transaction:transaction];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)migrateAlbumMessageId:(NSString *)albumMesssageId
|
||||||
|
{
|
||||||
|
self.albumMessageId = albumMesssageId;
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
|
@ -11,7 +11,7 @@
|
||||||
#import "TSContactThread.h"
|
#import "TSContactThread.h"
|
||||||
#import "TSGroupThread.h"
|
#import "TSGroupThread.h"
|
||||||
#import "YapDatabaseConnection+OWS.h"
|
#import "YapDatabaseConnection+OWS.h"
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
#import "SSKAsserts.h"
|
#import "SSKAsserts.h"
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
|
@ -2,7 +2,7 @@
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSInfoMessage.h>
|
#import <SessionMessagingKit/TSInfoMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#import "OWSDisappearingConfigurationUpdateInfoMessage.h"
|
#import "OWSDisappearingConfigurationUpdateInfoMessage.h"
|
||||||
#import "NSString+SSK.h"
|
#import "NSString+SSK.h"
|
||||||
#import "OWSDisappearingMessagesConfiguration.h"
|
#import "OWSDisappearingMessagesConfiguration.h"
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
#import <SignalCoreKit/NSString+OWS.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -34,8 +34,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
_configurationDurationSeconds = configuration.durationSeconds;
|
_configurationDurationSeconds = configuration.durationSeconds;
|
||||||
|
|
||||||
// At most one should be set
|
// At most one should be set
|
||||||
OWSAssertDebug(!remoteName || !createdInExistingGroup);
|
|
||||||
|
|
||||||
_createdByRemoteName = remoteName;
|
_createdByRemoteName = remoteName;
|
||||||
_createdInExistingGroup = createdInExistingGroup;
|
_createdInExistingGroup = createdInExistingGroup;
|
||||||
|
|
||||||
|
@ -52,7 +50,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
-(NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
|
-(NSString *)previewTextWithTransaction:(YapDatabaseReadTransaction *)transaction
|
||||||
{
|
{
|
||||||
if (self.createdInExistingGroup) {
|
if (self.createdInExistingGroup) {
|
||||||
OWSAssertDebug(self.configurationIsEnabled && self.configurationDurationSeconds > 0);
|
|
||||||
NSString *infoFormat = NSLocalizedString(@"DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT",
|
NSString *infoFormat = NSLocalizedString(@"DISAPPEARING_MESSAGES_CONFIGURATION_GROUP_EXISTING_FORMAT",
|
||||||
@"Info Message when added to a group which has enabled disappearing messages. Embeds {{time amount}} "
|
@"Info Message when added to a group which has enabled disappearing messages. Embeds {{time amount}} "
|
||||||
@"before messages disappear, see the *_TIME_AMOUNT strings for context.");
|
@"before messages disappear, see the *_TIME_AMOUNT strings for context.");
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SessionUtilitiesKit/TSYapDatabaseObject.h>
|
#import <SessionUtilitiesKit/TSYapDatabaseObject.h>
|
||||||
|
#import <SignalCoreKit/SignalCoreKit.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -4,7 +4,8 @@
|
||||||
|
|
||||||
#import "OWSDisappearingMessagesConfiguration.h"
|
#import "OWSDisappearingMessagesConfiguration.h"
|
||||||
#import "NSString+SSK.h"
|
#import "NSString+SSK.h"
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
|
#import <SignalCoreKit/NSString+OWS.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -85,9 +86,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
static dispatch_once_t onceToken;
|
static dispatch_once_t onceToken;
|
||||||
dispatch_once(&onceToken, ^{
|
dispatch_once(&onceToken, ^{
|
||||||
max = [[self.validDurationsSeconds valueForKeyPath:@"@max.intValue"] unsignedIntValue];
|
max = [[self.validDurationsSeconds valueForKeyPath:@"@max.intValue"] unsignedIntValue];
|
||||||
|
|
||||||
// It's safe to update this assert if we add a larger duration
|
|
||||||
OWSAssertDebug(max == 1 * kWeekInterval);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return max;
|
return max;
|
|
@ -15,7 +15,7 @@
|
||||||
#import "TSMessage.h"
|
#import "TSMessage.h"
|
||||||
#import "TSThread.h"
|
#import "TSThread.h"
|
||||||
#import <SignalCoreKit/NSDate+OWS.h>
|
#import <SignalCoreKit/NSDate+OWS.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
#import <SessionProtocolKit/SessionProtocolKit.h>
|
||||||
#import "SSKAsserts.h"
|
#import "SSKAsserts.h"
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import AFNetworking
|
||||||
import Foundation
|
import Foundation
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
|
||||||
|
@ -138,29 +139,23 @@ public class OWSLinkPreview: MTLModel {
|
||||||
throw LinkPreviewError.noPreview
|
throw LinkPreviewError.noPreview
|
||||||
}
|
}
|
||||||
guard dataMessage.attachments.count < 1 else {
|
guard dataMessage.attachments.count < 1 else {
|
||||||
Logger.error("Discarding link preview; message has attachments.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
let urlString = previewProto.url
|
let urlString = previewProto.url
|
||||||
|
|
||||||
guard URL(string: urlString) != nil else {
|
guard URL(string: urlString) != nil else {
|
||||||
Logger.error("Could not parse preview URL.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let body = body else {
|
guard let body = body else {
|
||||||
Logger.error("Preview for message without body.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
let previewUrls = allPreviewUrls(forMessageBodyText: body)
|
let previewUrls = allPreviewUrls(forMessageBodyText: body)
|
||||||
guard previewUrls.contains(urlString) else {
|
guard previewUrls.contains(urlString) else {
|
||||||
Logger.error("URL not present in body.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
|
|
||||||
guard isValidLinkUrl(urlString) else {
|
guard isValidLinkUrl(urlString) else {
|
||||||
Logger.verbose("Invalid link URL \(urlString).")
|
|
||||||
Logger.error("Invalid link URL.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -178,7 +173,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
imageAttachmentPointer.save(with: transaction)
|
imageAttachmentPointer.save(with: transaction)
|
||||||
imageAttachmentId = imageAttachmentPointer.uniqueId
|
imageAttachmentId = imageAttachmentPointer.uniqueId
|
||||||
} else {
|
} else {
|
||||||
Logger.error("Could not parse image proto.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -186,7 +180,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
let linkPreview = OWSLinkPreview(urlString: urlString, title: title, imageAttachmentId: imageAttachmentId)
|
let linkPreview = OWSLinkPreview(urlString: urlString, title: title, imageAttachmentId: imageAttachmentId)
|
||||||
|
|
||||||
guard linkPreview.isValid() else {
|
guard linkPreview.isValid() else {
|
||||||
Logger.error("Preview has neither title nor image.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -208,7 +201,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
let linkPreview = OWSLinkPreview(urlString: info.urlString, title: info.title, imageAttachmentId: imageAttachmentId)
|
let linkPreview = OWSLinkPreview(urlString: info.urlString, title: info.title, imageAttachmentId: imageAttachmentId)
|
||||||
|
|
||||||
guard linkPreview.isValid() else {
|
guard linkPreview.isValid() else {
|
||||||
owsFailDebug("Preview has neither title nor image.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,7 +217,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
|
|
||||||
let fileSize = imageData.count
|
let fileSize = imageData.count
|
||||||
guard fileSize > 0 else {
|
guard fileSize > 0 else {
|
||||||
owsFailDebug("Invalid file size for image data.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,17 +225,14 @@ public class OWSLinkPreview: MTLModel {
|
||||||
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 let error as NSError {
|
||||||
owsFailDebug("file write failed: \(filePath), \(error)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let dataSource = DataSourcePath.dataSource(withFilePath: filePath, shouldDeleteOnDeallocation: true) else {
|
guard let dataSource = DataSourcePath.dataSource(withFilePath: filePath, shouldDeleteOnDeallocation: true) else {
|
||||||
owsFailDebug("Could not create data source for path: \(filePath)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let attachment = TSAttachmentStream(contentType: mimeType, byteCount: UInt32(fileSize), sourceFilename: nil, caption: nil, albumMessageId: nil)
|
let attachment = TSAttachmentStream(contentType: mimeType, byteCount: UInt32(fileSize), sourceFilename: nil, caption: nil, albumMessageId: nil)
|
||||||
guard attachment.write(dataSource) else {
|
guard attachment.write(dataSource) else {
|
||||||
owsFailDebug("Could not write data source for path: \(filePath)")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
attachment.save(with: transaction)
|
attachment.save(with: transaction)
|
||||||
|
@ -264,11 +252,9 @@ public class OWSLinkPreview: MTLModel {
|
||||||
@objc
|
@objc
|
||||||
public func removeAttachment(transaction: YapDatabaseReadWriteTransaction) {
|
public func removeAttachment(transaction: YapDatabaseReadWriteTransaction) {
|
||||||
guard let imageAttachmentId = imageAttachmentId else {
|
guard let imageAttachmentId = imageAttachmentId else {
|
||||||
owsFailDebug("No attachment id.")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard let attachment = TSAttachment.fetch(uniqueId: imageAttachmentId, transaction: transaction) else {
|
guard let attachment = TSAttachment.fetch(uniqueId: imageAttachmentId, transaction: transaction) else {
|
||||||
owsFailDebug("Could not load attachment.")
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
attachment.remove(with: transaction)
|
attachment.remove(with: transaction)
|
||||||
|
@ -376,18 +362,15 @@ public class OWSLinkPreview: MTLModel {
|
||||||
@objc
|
@objc
|
||||||
public class func displayDomain(forUrl urlString: String?) -> String? {
|
public class func displayDomain(forUrl urlString: String?) -> String? {
|
||||||
guard let urlString = urlString else {
|
guard let urlString = urlString else {
|
||||||
owsFailDebug("Missing url.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
guard let url = URL(string: urlString) else {
|
guard let url = URL(string: urlString) else {
|
||||||
owsFailDebug("Invalid url.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
guard let result = whitelistedDomain(forUrl: url,
|
guard let result = whitelistedDomain(forUrl: url,
|
||||||
domainWhitelist: OWSLinkPreview.linkDomainWhitelist,
|
domainWhitelist: OWSLinkPreview.linkDomainWhitelist,
|
||||||
allowSubdomains: false) else {
|
allowSubdomains: false) else {
|
||||||
Logger.error("Missing domain.")
|
return nil
|
||||||
return nil
|
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -443,12 +426,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
|
|
||||||
private static let serialQueue = DispatchQueue(label: "org.signal.linkPreview")
|
private static let serialQueue = DispatchQueue(label: "org.signal.linkPreview")
|
||||||
|
|
||||||
private class func assertIsOnSerialQueue() {
|
|
||||||
if _isDebugAssertConfiguration(), #available(iOS 10.0, *) {
|
|
||||||
assertOnQueue(serialQueue)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Text Parsing
|
// MARK: - Text Parsing
|
||||||
|
|
||||||
// This cache should only be accessed on main thread.
|
// This cache should only be accessed on main thread.
|
||||||
|
@ -465,7 +442,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class func previewUrl(forMessageBodyText body: String?, selectedRange: NSRange?) -> String? {
|
public class func previewUrl(forMessageBodyText body: String?, selectedRange: NSRange?) -> String? {
|
||||||
AssertIsOnMainThread()
|
|
||||||
|
|
||||||
// Exit early if link previews are not enabled in order to avoid
|
// Exit early if link previews are not enabled in order to avoid
|
||||||
// tainting the cache.
|
// tainting the cache.
|
||||||
|
@ -482,7 +458,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let cachedUrl = previewUrlCache.object(forKey: body as NSString) as String? {
|
if let cachedUrl = previewUrlCache.object(forKey: body as NSString) as String? {
|
||||||
Logger.verbose("URL parsing cache hit.")
|
|
||||||
guard cachedUrl.count > 0 else {
|
guard cachedUrl.count > 0 else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -496,16 +471,13 @@ public class OWSLinkPreview: MTLModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let selectedRange = selectedRange {
|
if let selectedRange = selectedRange {
|
||||||
Logger.verbose("match: urlString: \(urlMatch.urlString) range: \(urlMatch.matchRange) selectedRange: \(selectedRange)")
|
|
||||||
let cursorAtEndOfMatch = urlMatch.matchRange.location + urlMatch.matchRange.length == selectedRange.location
|
let cursorAtEndOfMatch = urlMatch.matchRange.location + urlMatch.matchRange.length == selectedRange.location
|
||||||
if selectedRange.location != body.count,
|
if selectedRange.location != body.count,
|
||||||
(urlMatch.matchRange.intersection(selectedRange) != nil || cursorAtEndOfMatch) {
|
(urlMatch.matchRange.intersection(selectedRange) != nil || cursorAtEndOfMatch) {
|
||||||
Logger.debug("ignoring URL, since the user is currently editing it.")
|
|
||||||
// we don't want to cache the result here, as we want to fetch the link preview
|
// we don't want to cache the result here, as we want to fetch the link preview
|
||||||
// if the user moves the cursor.
|
// if the user moves the cursor.
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
Logger.debug("considering URL, since the user is not currently editing it.")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
previewUrlCache.setObject(urlMatch.urlString as NSString, forKey: body as NSString)
|
previewUrlCache.setObject(urlMatch.urlString as NSString, forKey: body as NSString)
|
||||||
|
@ -533,7 +505,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
do {
|
do {
|
||||||
detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
|
detector = try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
|
||||||
} catch {
|
} catch {
|
||||||
owsFailDebug("Could not create NSDataDetector: \(error).")
|
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -541,7 +512,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
let matches = detector.matches(in: body, options: [], range: NSRange(location: 0, length: body.count))
|
let matches = detector.matches(in: body, options: [], range: NSRange(location: 0, length: body.count))
|
||||||
for match in matches {
|
for match in matches {
|
||||||
guard let matchURL = match.url else {
|
guard let matchURL = match.url else {
|
||||||
owsFailDebug("Match missing url")
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
let urlString = matchURL.absoluteString
|
let urlString = matchURL.absoluteString
|
||||||
|
@ -564,10 +534,8 @@ public class OWSLinkPreview: MTLModel {
|
||||||
return serialQueue.sync {
|
return serialQueue.sync {
|
||||||
guard let linkPreviewDraft = linkPreviewDraftCache,
|
guard let linkPreviewDraft = linkPreviewDraftCache,
|
||||||
linkPreviewDraft.urlString == previewUrl else {
|
linkPreviewDraft.urlString == previewUrl else {
|
||||||
Logger.verbose("----- Cache miss.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
Logger.verbose("----- Cache hit.")
|
|
||||||
return linkPreviewDraft
|
return linkPreviewDraft
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -606,7 +574,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
return Promise(error: LinkPreviewError.invalidInput)
|
return Promise(error: LinkPreviewError.invalidInput)
|
||||||
}
|
}
|
||||||
if let cachedInfo = cachedLinkPreview(forPreviewUrl: previewUrl) {
|
if let cachedInfo = cachedLinkPreview(forPreviewUrl: previewUrl) {
|
||||||
Logger.verbose("Link preview info cache hit.")
|
|
||||||
return Promise.value(cachedInfo)
|
return Promise.value(cachedInfo)
|
||||||
}
|
}
|
||||||
return downloadLink(url: previewUrl)
|
return downloadLink(url: previewUrl)
|
||||||
|
@ -624,9 +591,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
|
|
||||||
class func downloadLink(url urlString: String,
|
class func downloadLink(url urlString: String,
|
||||||
remainingRetries: UInt = 3) -> Promise<Data> {
|
remainingRetries: UInt = 3) -> Promise<Data> {
|
||||||
|
|
||||||
Logger.verbose("url: \(urlString)")
|
|
||||||
|
|
||||||
// let sessionConfiguration = ContentProxy.sessionConfiguration() // Loki: Signal's proxy appears to have been banned by YouTube
|
// let sessionConfiguration = ContentProxy.sessionConfiguration() // Loki: Signal's proxy appears to have been banned by YouTube
|
||||||
let sessionConfiguration = URLSessionConfiguration.ephemeral
|
let sessionConfiguration = URLSessionConfiguration.ephemeral
|
||||||
|
|
||||||
|
@ -640,7 +604,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
sessionManager.responseSerializer = AFHTTPResponseSerializer()
|
sessionManager.responseSerializer = AFHTTPResponseSerializer()
|
||||||
|
|
||||||
guard ContentProxy.configureSessionManager(sessionManager: sessionManager, forUrl: urlString) else {
|
guard ContentProxy.configureSessionManager(sessionManager: sessionManager, forUrl: urlString) else {
|
||||||
owsFailDebug("Could not configure url: \(urlString).")
|
|
||||||
return Promise(error: LinkPreviewError.assertionFailure)
|
return Promise(error: LinkPreviewError.assertionFailure)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -652,40 +615,32 @@ public class OWSLinkPreview: MTLModel {
|
||||||
success: { task, value in
|
success: { task, value in
|
||||||
|
|
||||||
guard let response = task.response as? HTTPURLResponse else {
|
guard let response = task.response as? HTTPURLResponse else {
|
||||||
Logger.warn("Invalid response: \(type(of: task.response)).")
|
|
||||||
resolver.reject(LinkPreviewError.assertionFailure)
|
resolver.reject(LinkPreviewError.assertionFailure)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if let contentType = response.allHeaderFields["Content-Type"] as? String {
|
if let contentType = response.allHeaderFields["Content-Type"] as? String {
|
||||||
guard contentType.lowercased().hasPrefix("text/") else {
|
guard contentType.lowercased().hasPrefix("text/") else {
|
||||||
Logger.warn("Invalid content type: \(contentType).")
|
|
||||||
resolver.reject(LinkPreviewError.invalidContent)
|
resolver.reject(LinkPreviewError.invalidContent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
guard let data = value as? Data else {
|
guard let data = value as? Data else {
|
||||||
Logger.warn("Result is not data: \(type(of: value)).")
|
|
||||||
resolver.reject(LinkPreviewError.assertionFailure)
|
resolver.reject(LinkPreviewError.assertionFailure)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
guard data.count > 0 else {
|
guard data.count > 0 else {
|
||||||
Logger.warn("Empty data: \(type(of: value)).")
|
|
||||||
resolver.reject(LinkPreviewError.invalidContent)
|
resolver.reject(LinkPreviewError.invalidContent)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
resolver.fulfill(data)
|
resolver.fulfill(data)
|
||||||
},
|
},
|
||||||
failure: { _, error in
|
failure: { _, error in
|
||||||
Logger.verbose("Error: \(error)")
|
|
||||||
|
|
||||||
guard isRetryable(error: error) else {
|
guard isRetryable(error: error) else {
|
||||||
Logger.warn("Error is not retryable.")
|
|
||||||
resolver.reject(LinkPreviewError.couldNotDownload)
|
resolver.reject(LinkPreviewError.couldNotDownload)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
guard remainingRetries > 0 else {
|
guard remainingRetries > 0 else {
|
||||||
Logger.warn("No more retries.")
|
|
||||||
resolver.reject(LinkPreviewError.couldNotDownload)
|
resolver.reject(LinkPreviewError.couldNotDownload)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -700,16 +655,11 @@ public class OWSLinkPreview: MTLModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
private class func downloadImage(url urlString: String, imageMimeType: String) -> Promise<Data> {
|
private class func downloadImage(url urlString: String, imageMimeType: String) -> Promise<Data> {
|
||||||
|
|
||||||
Logger.verbose("url: \(urlString)")
|
|
||||||
|
|
||||||
guard let url = URL(string: urlString) else {
|
guard let url = URL(string: urlString) else {
|
||||||
Logger.error("Could not parse URL.")
|
|
||||||
return Promise(error: LinkPreviewError.invalidInput)
|
return Promise(error: LinkPreviewError.invalidInput)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let assetDescription = ProxiedContentAssetDescription(url: url as NSURL) else {
|
guard let assetDescription = ProxiedContentAssetDescription(url: url as NSURL) else {
|
||||||
Logger.error("Could not create asset description.")
|
|
||||||
return Promise(error: LinkPreviewError.invalidInput)
|
return Promise(error: LinkPreviewError.invalidInput)
|
||||||
}
|
}
|
||||||
let (promise, resolver) = Promise<ProxiedContentAsset>.pending()
|
let (promise, resolver) = Promise<ProxiedContentAsset>.pending()
|
||||||
|
@ -719,7 +669,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
success: { (_, asset) in
|
success: { (_, asset) in
|
||||||
resolver.fulfill(asset)
|
resolver.fulfill(asset)
|
||||||
}, failure: { (_) in
|
}, failure: { (_) in
|
||||||
Logger.warn("Error downloading asset")
|
|
||||||
resolver.reject(LinkPreviewError.couldNotDownload)
|
resolver.reject(LinkPreviewError.couldNotDownload)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -727,13 +676,11 @@ public class OWSLinkPreview: MTLModel {
|
||||||
do {
|
do {
|
||||||
let imageSize = NSData.imageSize(forFilePath: asset.filePath, mimeType: imageMimeType)
|
let imageSize = NSData.imageSize(forFilePath: asset.filePath, mimeType: imageMimeType)
|
||||||
guard imageSize.width > 0, imageSize.height > 0 else {
|
guard imageSize.width > 0, imageSize.height > 0 else {
|
||||||
Logger.error("Link preview is invalid or has invalid size.")
|
|
||||||
return Promise(error: LinkPreviewError.invalidContent)
|
return Promise(error: LinkPreviewError.invalidContent)
|
||||||
}
|
}
|
||||||
let data = try Data(contentsOf: URL(fileURLWithPath: asset.filePath))
|
let data = try Data(contentsOf: URL(fileURLWithPath: asset.filePath))
|
||||||
|
|
||||||
guard let srcImage = UIImage(data: data) else {
|
guard let srcImage = UIImage(data: data) else {
|
||||||
Logger.error("Could not parse image.")
|
|
||||||
return Promise(error: LinkPreviewError.invalidContent)
|
return Promise(error: LinkPreviewError.invalidContent)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -744,23 +691,19 @@ public class OWSLinkPreview: MTLModel {
|
||||||
let shouldResize = imageSize.width > maxImageSize || imageSize.height > maxImageSize
|
let shouldResize = imageSize.width > maxImageSize || imageSize.height > maxImageSize
|
||||||
guard shouldResize else {
|
guard shouldResize else {
|
||||||
guard let dstData = srcImage.jpegData(compressionQuality: 0.8) else {
|
guard let dstData = srcImage.jpegData(compressionQuality: 0.8) else {
|
||||||
Logger.error("Could not write resized image.")
|
|
||||||
return Promise(error: LinkPreviewError.invalidContent)
|
return Promise(error: LinkPreviewError.invalidContent)
|
||||||
}
|
}
|
||||||
return Promise.value(dstData)
|
return Promise.value(dstData)
|
||||||
}
|
}
|
||||||
|
|
||||||
guard let dstImage = srcImage.resized(withMaxDimensionPoints: maxImageSize) else {
|
guard let dstImage = srcImage.resized(withMaxDimensionPoints: maxImageSize) else {
|
||||||
Logger.error("Could not resize image.")
|
|
||||||
return Promise(error: LinkPreviewError.invalidContent)
|
return Promise(error: LinkPreviewError.invalidContent)
|
||||||
}
|
}
|
||||||
guard let dstData = dstImage.jpegData(compressionQuality: 0.8) else {
|
guard let dstData = dstImage.jpegData(compressionQuality: 0.8) else {
|
||||||
Logger.error("Could not write resized image.")
|
|
||||||
return Promise(error: LinkPreviewError.invalidContent)
|
return Promise(error: LinkPreviewError.invalidContent)
|
||||||
}
|
}
|
||||||
return Promise.value(dstData)
|
return Promise.value(dstData)
|
||||||
} catch {
|
} catch {
|
||||||
owsFailDebug("Could not load asset data: \(type(of: asset.filePath)).")
|
|
||||||
return Promise(error: LinkPreviewError.assertionFailure)
|
return Promise(error: LinkPreviewError.assertionFailure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -786,15 +729,12 @@ public class OWSLinkPreview: MTLModel {
|
||||||
}
|
}
|
||||||
|
|
||||||
guard isValidMediaUrl(imageUrl) else {
|
guard isValidMediaUrl(imageUrl) else {
|
||||||
Logger.error("Invalid image URL.")
|
|
||||||
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
||||||
}
|
}
|
||||||
guard let imageFileExtension = fileExtension(forImageUrl: imageUrl) else {
|
guard let imageFileExtension = fileExtension(forImageUrl: imageUrl) else {
|
||||||
Logger.error("Image URL has unknown or invalid file extension: \(imageUrl).")
|
|
||||||
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
||||||
}
|
}
|
||||||
guard let imageMimeType = mimetype(forImageFileExtension: imageFileExtension) else {
|
guard let imageMimeType = mimetype(forImageFileExtension: imageFileExtension) else {
|
||||||
Logger.error("Image URL has unknown or invalid content type: \(imageUrl).")
|
|
||||||
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -808,7 +748,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
return Promise.value(OWSLinkPreviewDraft(urlString: linkUrlString, title: title))
|
||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
owsFailDebug("Could not parse link data: \(error).")
|
|
||||||
return Promise(error: error)
|
return Promise(error: error)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -819,7 +758,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
// <meta property="og:image" content="https://i.ytimg.com/vi/tP-Ipsat90c/maxresdefault.jpg">
|
// <meta property="og:image" content="https://i.ytimg.com/vi/tP-Ipsat90c/maxresdefault.jpg">
|
||||||
class func parse(linkData: Data) throws -> OWSLinkPreviewContents {
|
class func parse(linkData: Data) throws -> OWSLinkPreviewContents {
|
||||||
guard let linkText = String(bytes: linkData, encoding: .utf8) else {
|
guard let linkText = String(bytes: linkData, encoding: .utf8) else {
|
||||||
owsFailDebug("Could not parse link text.")
|
|
||||||
throw LinkPreviewError.invalidInput
|
throw LinkPreviewError.invalidInput
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -835,8 +773,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.verbose("title: \(String(describing: title))")
|
|
||||||
|
|
||||||
guard let rawImageUrlString = NSRegularExpression.parseFirstMatch(pattern: "<meta\\s+property\\s*=\\s*\"og:image\"\\s+[^>]*content\\s*=\\s*\"(.*?)\"[^>]*/?>", text: linkText) else {
|
guard let rawImageUrlString = NSRegularExpression.parseFirstMatch(pattern: "<meta\\s+property\\s*=\\s*\"og:image\"\\s+[^>]*content\\s*=\\s*\"(.*?)\"[^>]*/?>", text: linkText) else {
|
||||||
return OWSLinkPreviewContents(title: title)
|
return OWSLinkPreviewContents(title: title)
|
||||||
}
|
}
|
||||||
|
@ -849,7 +785,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
|
|
||||||
class func fileExtension(forImageUrl urlString: String) -> String? {
|
class func fileExtension(forImageUrl urlString: String) -> String? {
|
||||||
guard let imageUrl = URL(string: urlString) else {
|
guard let imageUrl = URL(string: urlString) else {
|
||||||
Logger.error("Could not parse image URL.")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let imageFilename = imageUrl.lastPathComponent
|
let imageFilename = imageUrl.lastPathComponent
|
||||||
|
@ -874,7 +809,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
guard let imageMimeType = MIMETypeUtil.mimeType(forFileExtension: imageFileExtension) else {
|
guard let imageMimeType = MIMETypeUtil.mimeType(forFileExtension: imageFileExtension) else {
|
||||||
Logger.error("Image URL has unknown content type: \(imageFileExtension).")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
let kValidMimeTypes = [
|
let kValidMimeTypes = [
|
||||||
|
@ -883,7 +817,6 @@ public class OWSLinkPreview: MTLModel {
|
||||||
OWSMimeTypeImageGif,
|
OWSMimeTypeImageGif,
|
||||||
]
|
]
|
||||||
guard kValidMimeTypes.contains(imageMimeType) else {
|
guard kValidMimeTypes.contains(imageMimeType) else {
|
||||||
Logger.error("Image URL has invalid content type: \(imageMimeType).")
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return imageMimeType
|
return imageMimeType
|
|
@ -1,37 +1,35 @@
|
||||||
import SessionMessagingKit
|
import SessionProtocolKit
|
||||||
|
import SignalCoreKit
|
||||||
|
|
||||||
public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiverDelegate {
|
extension MessageReceiver {
|
||||||
|
|
||||||
public static let shared = MessageReceiverDelegate()
|
internal static func isBlocked(_ publicKey: String) -> Bool {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Blocking
|
|
||||||
|
|
||||||
public func isBlocked(_ publicKey: String) -> Bool {
|
|
||||||
return SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(publicKey)
|
return SSKEnvironment.shared.blockingManager.isRecipientIdBlocked(publicKey)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal static func handle(_ message: Message, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
|
||||||
|
switch message {
|
||||||
// MARK: - Profiles
|
case let message as ReadReceipt: handleReadReceipt(message, using: transaction)
|
||||||
|
case let message as TypingIndicator: handleTypingIndicator(message, using: transaction)
|
||||||
public func updateProfile(for publicKey: String, from profile: VisibleMessage.Profile, using transaction: Any) {
|
case let message as ClosedGroupUpdate: handleClosedGroupUpdate(message, using: transaction)
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction)
|
||||||
let profileManager = SSKEnvironment.shared.profileManager
|
case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, using: transaction)
|
||||||
if let displayName = profile.displayName {
|
default: fatalError()
|
||||||
profileManager.updateProfileForContact(withID: publicKey, displayName: displayName, with: transaction)
|
|
||||||
}
|
|
||||||
if let profileKey = profile.profileKey, let profilePictureURL = profile.profilePictureURL, profileKey.count == kAES256_KeyByteLength {
|
|
||||||
profileManager.setProfileKeyData(profileKey, forRecipientId: publicKey, avatarURL: profilePictureURL)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func handleReadReceipt(_ message: ReadReceipt, using transaction: Any) {
|
||||||
|
SSKEnvironment.shared.readReceiptManager.processReadReceipts(fromRecipientId: message.sender!, sentTimestamps: message.timestamps!.map { NSNumber(value: $0) }, readTimestamp: message.receivedTimestamp!)
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func handleTypingIndicator(_ message: TypingIndicator, using transaction: Any) {
|
||||||
|
switch message.kind! {
|
||||||
|
case .started: showTypingIndicatorIfNeeded(for: message.sender!)
|
||||||
|
case .stopped: hideTypingIndicatorIfNeeded(for: message.sender!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Typing Indicators
|
public static func showTypingIndicatorIfNeeded(for senderPublicKey: String) {
|
||||||
|
|
||||||
public func showTypingIndicatorIfNeeded(for senderPublicKey: String) {
|
|
||||||
var threadOrNil: TSContactThread?
|
var threadOrNil: TSContactThread?
|
||||||
Storage.read { transaction in
|
Storage.read { transaction in
|
||||||
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
|
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
|
||||||
|
@ -49,7 +47,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func hideTypingIndicatorIfNeeded(for senderPublicKey: String) {
|
public static func hideTypingIndicatorIfNeeded(for senderPublicKey: String) {
|
||||||
var threadOrNil: TSContactThread?
|
var threadOrNil: TSContactThread?
|
||||||
Storage.read { transaction in
|
Storage.read { transaction in
|
||||||
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
|
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
|
||||||
|
@ -67,7 +65,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func cancelTypingIndicatorsIfNeeded(for senderPublicKey: String) {
|
public static func cancelTypingIndicatorsIfNeeded(for senderPublicKey: String) {
|
||||||
var threadOrNil: TSContactThread?
|
var threadOrNil: TSContactThread?
|
||||||
Storage.read { transaction in
|
Storage.read { transaction in
|
||||||
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
|
threadOrNil = TSContactThread.getWithContactId(senderPublicKey, transaction: transaction)
|
||||||
|
@ -85,30 +83,15 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func handleExpirationTimerUpdate(_ message: ExpirationTimerUpdate, using transaction: Any) {
|
||||||
|
if message.duration! > 0 {
|
||||||
// MARK: - Notifications
|
setExpirationTimer(to: message.duration!, for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
|
||||||
|
} else {
|
||||||
public func notifyUserIfNeeded(forMessageWithID messageID: String, threadID: String) {
|
disableExpirationTimer(for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
|
||||||
guard let message = TSIncomingMessage.fetch(uniqueId: messageID), let thread = TSThread.fetch(uniqueId: threadID) else { return }
|
|
||||||
Storage.read { transaction in
|
|
||||||
SSKEnvironment.shared.notificationsManager!.notifyUser(for: message, in: thread, transaction: transaction)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static func setExpirationTimer(to duration: UInt32, for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
|
||||||
|
|
||||||
// MARK: - Read Receipts
|
|
||||||
|
|
||||||
public func markMessagesAsRead(_ timestamps: [UInt64], from senderPublicKey: String, at timestamp: UInt64) {
|
|
||||||
SSKEnvironment.shared.readReceiptManager.processReadReceipts(fromRecipientId: senderPublicKey, sentTimestamps: timestamps.map { NSNumber(value: $0) }, readTimestamp: timestamp)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// MARK: - Expiration
|
|
||||||
|
|
||||||
public func setExpirationTimer(to duration: UInt32, for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
|
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
var threadOrNil: TSThread?
|
var threadOrNil: TSThread?
|
||||||
Storage.read { transaction in
|
Storage.read { transaction in
|
||||||
|
@ -130,7 +113,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary()
|
SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary()
|
||||||
}
|
}
|
||||||
|
|
||||||
public func disableExpirationTimer(for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
|
public static func disableExpirationTimer(for senderPublicKey: String, groupPublicKey: String?, using transaction: Any) {
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
var threadOrNil: TSThread?
|
var threadOrNil: TSThread?
|
||||||
Storage.read { transaction in
|
Storage.read { transaction in
|
||||||
|
@ -152,11 +135,59 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary()
|
SSKEnvironment.shared.disappearingMessagesJob.startIfNecessary()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static func handleVisibleMessage(_ message: VisibleMessage, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
|
||||||
|
let storage = Configuration.shared.storage
|
||||||
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
|
// Parse & persist attachments
|
||||||
|
let attachments: [VisibleMessage.Attachment] = proto.dataMessage!.attachments.compactMap { proto in
|
||||||
|
guard let attachment = VisibleMessage.Attachment.fromProto(proto) else { return nil }
|
||||||
|
return attachment.isValid ? attachment : nil
|
||||||
|
}
|
||||||
|
let attachmentIDs = storage.persist(attachments, using: transaction)
|
||||||
|
message.attachmentIDs = attachmentIDs
|
||||||
|
// Update profile if needed
|
||||||
|
if let profile = message.profile {
|
||||||
|
let profileManager = SSKEnvironment.shared.profileManager
|
||||||
|
if let displayName = profile.displayName {
|
||||||
|
profileManager.updateProfileForContact(withID: message.sender!, displayName: displayName, with: transaction)
|
||||||
|
}
|
||||||
|
if let profileKey = profile.profileKey, let profilePictureURL = profile.profilePictureURL, profileKey.count == kAES256_KeyByteLength {
|
||||||
|
profileManager.setProfileKeyData(profileKey, forRecipientId: message.sender!, avatarURL: profilePictureURL)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Persist the message
|
||||||
|
guard let (threadID, tsIncomingMessageID) = storage.persist(message, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread }
|
||||||
|
message.threadID = threadID
|
||||||
|
// Start attachment downloads if needed
|
||||||
|
storage.withAsync({ transaction in
|
||||||
|
attachmentIDs.forEach { attachmentID in
|
||||||
|
let downloadJob = AttachmentDownloadJob(attachmentID: attachmentID, tsIncomingMessageID: tsIncomingMessageID)
|
||||||
|
if CurrentAppContext().isMainAppAndActive {
|
||||||
|
JobQueue.shared.add(downloadJob, using: transaction)
|
||||||
|
} else {
|
||||||
|
JobQueue.shared.addWithoutExecuting(downloadJob, using: transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, completion: { })
|
||||||
|
// Cancel any typing indicators
|
||||||
|
cancelTypingIndicatorsIfNeeded(for: message.sender!)
|
||||||
|
// Notify the user if needed
|
||||||
|
guard let tsIncomingMessage = TSIncomingMessage.fetch(uniqueId: tsIncomingMessageID), let thread = TSThread.fetch(uniqueId: threadID) else { return }
|
||||||
|
Storage.read { transaction in
|
||||||
|
SSKEnvironment.shared.notificationsManager!.notifyUser(for: tsIncomingMessage, in: thread, transaction: transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static func handleClosedGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) {
|
||||||
|
switch message.kind! {
|
||||||
|
case .new: handleNewGroup(message, using: transaction)
|
||||||
|
case .info: handleGroupUpdate(message, using: transaction)
|
||||||
|
case .senderKeyRequest: handleSenderKeyRequest(message, using: transaction)
|
||||||
|
case .senderKey: handleSenderKey(message, using: transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Closed Groups
|
private static func handleNewGroup(_ message: ClosedGroupUpdate, using transaction: Any) {
|
||||||
|
|
||||||
public func handleNewGroup(_ message: ClosedGroupUpdate, using transaction: Any) {
|
|
||||||
guard case let .new(groupPublicKeyAsData, name, groupPrivateKey, senderKeys, membersAsData, adminsAsData) = message.kind else { return }
|
guard case let .new(groupPublicKeyAsData, name, groupPrivateKey, senderKeys, membersAsData, adminsAsData) = message.kind else { return }
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
let groupPublicKey = groupPublicKeyAsData.toHexString()
|
let groupPublicKey = groupPublicKeyAsData.toHexString()
|
||||||
|
@ -185,7 +216,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
missingSenderKeys.subtracting([ userPublicKey ]).forEach { publicKey in
|
missingSenderKeys.subtracting([ userPublicKey ]).forEach { publicKey in
|
||||||
MessageSenderDelegate.shared.requestSenderKey(for: groupPublicKey, senderPublicKey: publicKey, using: transaction)
|
MessageSender.shared.requestSenderKey(for: groupPublicKey, senderPublicKey: publicKey, using: transaction)
|
||||||
}
|
}
|
||||||
// Create the group
|
// Create the group
|
||||||
let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey)
|
let groupID = LKGroupUtilities.getEncodedClosedGroupIDAsData(groupPublicKey)
|
||||||
|
@ -208,7 +239,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
infoMessage.save(with: transaction)
|
infoMessage.save(with: transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) {
|
private static func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) {
|
||||||
guard case let .info(groupPublicKeyAsData, name, senderKeys, membersAsData, adminsAsData) = message.kind else { return }
|
guard case let .info(groupPublicKeyAsData, name, senderKeys, membersAsData, adminsAsData) = message.kind else { return }
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
let groupPublicKey = groupPublicKeyAsData.toHexString()
|
let groupPublicKey = groupPublicKeyAsData.toHexString()
|
||||||
|
@ -272,7 +303,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any) {
|
private static func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any) {
|
||||||
guard case let .senderKeyRequest(groupPublicKeyAsData) = message.kind else { return }
|
guard case let .senderKeyRequest(groupPublicKeyAsData) = message.kind else { return }
|
||||||
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
let transaction = transaction as! YapDatabaseReadWriteTransaction
|
||||||
let userPublicKey = getUserHexEncodedPublicKey()
|
let userPublicKey = getUserHexEncodedPublicKey()
|
||||||
|
@ -300,7 +331,7 @@ public final class MessageReceiverDelegate : SessionMessagingKit.MessageReceiver
|
||||||
MessageSender.send(closedGroupUpdate, in: thread, using: transaction)
|
MessageSender.send(closedGroupUpdate, in: thread, using: transaction)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any) {
|
private static func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any) {
|
||||||
guard case let .senderKey(groupPublicKeyAsData, senderKey) = message.kind else { return }
|
guard case let .senderKey(groupPublicKeyAsData, senderKey) = message.kind else { return }
|
||||||
let groupPublicKey = groupPublicKeyAsData.toHexString()
|
let groupPublicKey = groupPublicKeyAsData.toHexString()
|
||||||
guard senderKey.publicKey.toHexString() == message.sender! else {
|
guard senderKey.publicKey.toHexString() == message.sender! else {
|
|
@ -2,7 +2,6 @@ import SessionUtilitiesKit
|
||||||
|
|
||||||
internal enum MessageReceiver {
|
internal enum MessageReceiver {
|
||||||
|
|
||||||
// MARK: Error
|
|
||||||
internal enum Error : LocalizedError {
|
internal enum Error : LocalizedError {
|
||||||
case invalidMessage
|
case invalidMessage
|
||||||
case unknownMessage
|
case unknownMessage
|
||||||
|
@ -42,7 +41,6 @@ internal enum MessageReceiver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Parsing
|
|
||||||
internal static func parse(_ data: Data, messageServerID: UInt64?, using transaction: Any) throws -> (Message, SNProtoContent) {
|
internal static func parse(_ data: Data, messageServerID: UInt64?, using transaction: Any) throws -> (Message, SNProtoContent) {
|
||||||
let userPublicKey = Configuration.shared.storage.getUserPublicKey()
|
let userPublicKey = Configuration.shared.storage.getUserPublicKey()
|
||||||
// Parse the envelope
|
// Parse the envelope
|
||||||
|
@ -59,7 +57,7 @@ internal enum MessageReceiver {
|
||||||
default: throw Error.unknownEnvelopeType
|
default: throw Error.unknownEnvelopeType
|
||||||
}
|
}
|
||||||
// Don't process the envelope any further if the sender is blocked
|
// Don't process the envelope any further if the sender is blocked
|
||||||
guard !Configuration.shared.messageReceiverDelegate.isBlocked(sender) else { throw Error.senderBlocked }
|
guard !isBlocked(sender) else { throw Error.senderBlocked }
|
||||||
// Ignore self sends
|
// Ignore self sends
|
||||||
guard sender != userPublicKey else { throw Error.selfSend }
|
guard sender != userPublicKey else { throw Error.selfSend }
|
||||||
// Parse the proto
|
// Parse the proto
|
||||||
|
@ -92,81 +90,4 @@ internal enum MessageReceiver {
|
||||||
throw Error.unknownMessage
|
throw Error.unknownMessage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: Handling
|
|
||||||
internal static func handle(_ message: Message, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
|
|
||||||
switch message {
|
|
||||||
case let message as ReadReceipt: handleReadReceipt(message, using: transaction)
|
|
||||||
case let message as TypingIndicator: handleTypingIndicator(message, using: transaction)
|
|
||||||
case let message as ClosedGroupUpdate: handleClosedGroupUpdate(message, using: transaction)
|
|
||||||
case let message as ExpirationTimerUpdate: handleExpirationTimerUpdate(message, using: transaction)
|
|
||||||
case let message as VisibleMessage: try handleVisibleMessage(message, associatedWithProto: proto, using: transaction)
|
|
||||||
default: fatalError()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func handleReadReceipt(_ message: ReadReceipt, using transaction: Any) {
|
|
||||||
Configuration.shared.messageReceiverDelegate.markMessagesAsRead(message.timestamps!, from: message.sender!, at: message.receivedTimestamp!)
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func handleTypingIndicator(_ message: TypingIndicator, using transaction: Any) {
|
|
||||||
let delegate = Configuration.shared.messageReceiverDelegate
|
|
||||||
switch message.kind! {
|
|
||||||
case .started: delegate.showTypingIndicatorIfNeeded(for: message.sender!)
|
|
||||||
case .stopped: delegate.hideTypingIndicatorIfNeeded(for: message.sender!)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func handleClosedGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any) {
|
|
||||||
let delegate = Configuration.shared.messageReceiverDelegate
|
|
||||||
switch message.kind! {
|
|
||||||
case .new: delegate.handleNewGroup(message, using: transaction)
|
|
||||||
case .info: delegate.handleGroupUpdate(message, using: transaction)
|
|
||||||
case .senderKeyRequest: delegate.handleSenderKeyRequest(message, using: transaction)
|
|
||||||
case .senderKey: delegate.handleSenderKey(message, using: transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func handleExpirationTimerUpdate(_ message: ExpirationTimerUpdate, using transaction: Any) {
|
|
||||||
let delegate = Configuration.shared.messageReceiverDelegate
|
|
||||||
if message.duration! > 0 {
|
|
||||||
delegate.setExpirationTimer(to: message.duration!, for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
|
|
||||||
} else {
|
|
||||||
delegate.disableExpirationTimer(for: message.sender!, groupPublicKey: message.groupPublicKey, using: transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static func handleVisibleMessage(_ message: VisibleMessage, associatedWithProto proto: SNProtoContent, using transaction: Any) throws {
|
|
||||||
let delegate = Configuration.shared.messageReceiverDelegate
|
|
||||||
let storage = Configuration.shared.storage
|
|
||||||
// Parse & persist attachments
|
|
||||||
let attachments: [VisibleMessage.Attachment] = proto.dataMessage!.attachments.compactMap { proto in
|
|
||||||
guard let attachment = VisibleMessage.Attachment.fromProto(proto) else { return nil }
|
|
||||||
return attachment.isValid ? attachment : nil
|
|
||||||
}
|
|
||||||
let attachmentIDs = storage.persist(attachments, using: transaction)
|
|
||||||
message.attachmentIDs = attachmentIDs
|
|
||||||
// Update profile if needed
|
|
||||||
if let profile = message.profile {
|
|
||||||
delegate.updateProfile(for: message.sender!, from: profile, using: transaction)
|
|
||||||
}
|
|
||||||
// Persist the message
|
|
||||||
guard let (threadID, tsIncomingMessageID) = storage.persist(message, groupPublicKey: message.groupPublicKey, using: transaction) else { throw Error.noThread }
|
|
||||||
message.threadID = threadID
|
|
||||||
// Start attachment downloads if needed
|
|
||||||
storage.withAsync({ transaction in
|
|
||||||
attachmentIDs.forEach { attachmentID in
|
|
||||||
let downloadJob = AttachmentDownloadJob(attachmentID: attachmentID, tsIncomingMessageID: tsIncomingMessageID)
|
|
||||||
if CurrentAppContext().isMainAppAndActive {
|
|
||||||
JobQueue.shared.add(downloadJob, using: transaction)
|
|
||||||
} else {
|
|
||||||
JobQueue.shared.addWithoutExecuting(downloadJob, using: transaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, completion: { })
|
|
||||||
// Cancel any typing indicators
|
|
||||||
delegate.cancelTypingIndicatorsIfNeeded(for: message.sender!)
|
|
||||||
// Notify the user if needed
|
|
||||||
delegate.notifyUserIfNeeded(forMessageWithID: tsIncomingMessageID, threadID: threadID)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
public protocol MessageReceiverDelegate {
|
|
||||||
|
|
||||||
func isBlocked(_ publicKey: String) -> Bool
|
|
||||||
func updateProfile(for publicKey: String, from profile: VisibleMessage.Profile, using transaction: Any)
|
|
||||||
func showTypingIndicatorIfNeeded(for senderPublicKey: String)
|
|
||||||
func hideTypingIndicatorIfNeeded(for senderPublicKey: String)
|
|
||||||
func cancelTypingIndicatorsIfNeeded(for senderPublicKey: String)
|
|
||||||
func notifyUserIfNeeded(forMessageWithID messageID: String, threadID: String)
|
|
||||||
func markMessagesAsRead(_ timestamps: [UInt64], from senderPublicKey: String, at timestamp: UInt64)
|
|
||||||
func setExpirationTimer(to duration: UInt32, for senderPublicKey: String, groupPublicKey: String?, using transaction: Any)
|
|
||||||
func disableExpirationTimer(for senderPublicKey: String, groupPublicKey: String?, using transaction: Any)
|
|
||||||
func handleNewGroup(_ message: ClosedGroupUpdate, using transaction: Any)
|
|
||||||
func handleGroupUpdate(_ message: ClosedGroupUpdate, using transaction: Any)
|
|
||||||
func handleSenderKeyRequest(_ message: ClosedGroupUpdate, using transaction: Any)
|
|
||||||
func handleSenderKey(_ message: ClosedGroupUpdate, using transaction: Any)
|
|
||||||
}
|
|
|
@ -11,10 +11,14 @@ public final class MessageSender : NSObject {
|
||||||
case protoConversionFailed
|
case protoConversionFailed
|
||||||
case proofOfWorkCalculationFailed
|
case proofOfWorkCalculationFailed
|
||||||
case noUserPublicKey
|
case noUserPublicKey
|
||||||
|
// Closed groups
|
||||||
|
case noThread
|
||||||
|
case noPrivateKey
|
||||||
|
case invalidClosedGroupUpdate
|
||||||
|
|
||||||
internal var isRetryable: Bool {
|
internal var isRetryable: Bool {
|
||||||
switch self {
|
switch self {
|
||||||
case .invalidMessage, .protoConversionFailed, .proofOfWorkCalculationFailed: return false
|
case .invalidMessage, .protoConversionFailed, .proofOfWorkCalculationFailed, .invalidClosedGroupUpdate: return false
|
||||||
default: return true
|
default: return true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +29,10 @@ public final class MessageSender : NSObject {
|
||||||
case .protoConversionFailed: return "Couldn't convert message to proto."
|
case .protoConversionFailed: return "Couldn't convert message to proto."
|
||||||
case .proofOfWorkCalculationFailed: return "Proof of work calculation failed."
|
case .proofOfWorkCalculationFailed: return "Proof of work calculation failed."
|
||||||
case .noUserPublicKey: return "Couldn't find user key pair."
|
case .noUserPublicKey: return "Couldn't find user key pair."
|
||||||
|
// Closed groups
|
||||||
|
case .noThread: return "Couldn't find a thread associated with the given group public key."
|
||||||
|
case .noPrivateKey: return "Couldn't find a private key associated with the given group public key."
|
||||||
|
case .invalidClosedGroupUpdate: return "Invalid group update."
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,6 +40,8 @@ public final class MessageSender : NSObject {
|
||||||
// MARK: Initialization
|
// MARK: Initialization
|
||||||
private override init() { }
|
private override init() { }
|
||||||
|
|
||||||
|
public static let shared = MessageSender() // FIXME: Remove once requestSenderKey is static
|
||||||
|
|
||||||
// MARK: Convenience
|
// MARK: Convenience
|
||||||
public static func send(_ message: Message, to destination: Message.Destination, using transaction: Any) -> Promise<Void> {
|
public static func send(_ message: Message, to destination: Message.Destination, using transaction: Any) -> Promise<Void> {
|
||||||
switch destination {
|
switch destination {
|
||||||
|
@ -56,7 +66,7 @@ public final class MessageSender : NSObject {
|
||||||
// Set the failure handler (for precondition failure handling)
|
// Set the failure handler (for precondition failure handling)
|
||||||
let _ = promise.catch(on: DispatchQueue.main) { error in
|
let _ = promise.catch(on: DispatchQueue.main) { error in
|
||||||
storage.withAsync({ transaction in
|
storage.withAsync({ transaction in
|
||||||
Configuration.shared.messageSenderDelegate.handleFailedMessageSend(message, with: error, using: transaction)
|
MessageSender.handleFailedMessageSend(message, with: error, using: transaction)
|
||||||
}, completion: { })
|
}, completion: { })
|
||||||
if case .contact(_) = destination {
|
if case .contact(_) = destination {
|
||||||
NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!))
|
NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!))
|
||||||
|
@ -157,7 +167,7 @@ public final class MessageSender : NSObject {
|
||||||
// Handle completion
|
// Handle completion
|
||||||
let _ = promise.done(on: DispatchQueue.main) {
|
let _ = promise.done(on: DispatchQueue.main) {
|
||||||
storage.withAsync({ transaction in
|
storage.withAsync({ transaction in
|
||||||
Configuration.shared.messageSenderDelegate.handleSuccessfulMessageSend(message, using: transaction)
|
MessageSender.handleSuccessfulMessageSend(message, using: transaction)
|
||||||
}, completion: { })
|
}, completion: { })
|
||||||
if case .contact(_) = destination {
|
if case .contact(_) = destination {
|
||||||
NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!))
|
NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!))
|
||||||
|
@ -186,7 +196,7 @@ public final class MessageSender : NSObject {
|
||||||
// Set the failure handler (for precondition failure handling)
|
// Set the failure handler (for precondition failure handling)
|
||||||
let _ = promise.catch(on: DispatchQueue.global(qos: .userInitiated)) { error in
|
let _ = promise.catch(on: DispatchQueue.global(qos: .userInitiated)) { error in
|
||||||
storage.withAsync({ transaction in
|
storage.withAsync({ transaction in
|
||||||
Configuration.shared.messageSenderDelegate.handleFailedMessageSend(message, with: error, using: transaction)
|
MessageSender.handleFailedMessageSend(message, with: error, using: transaction)
|
||||||
}, completion: { })
|
}, completion: { })
|
||||||
}
|
}
|
||||||
// Validate the message
|
// Validate the message
|
||||||
|
@ -210,10 +220,23 @@ public final class MessageSender : NSObject {
|
||||||
// Handle completion
|
// Handle completion
|
||||||
let _ = promise.done(on: DispatchQueue.global(qos: .userInitiated)) {
|
let _ = promise.done(on: DispatchQueue.global(qos: .userInitiated)) {
|
||||||
storage.withAsync({ transaction in
|
storage.withAsync({ transaction in
|
||||||
Configuration.shared.messageSenderDelegate.handleSuccessfulMessageSend(message, using: transaction)
|
MessageSender.handleSuccessfulMessageSend(message, using: transaction)
|
||||||
}, completion: { })
|
}, completion: { })
|
||||||
}
|
}
|
||||||
// Return
|
// Return
|
||||||
return promise
|
return promise
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: Result Handling
|
||||||
|
public static func handleSuccessfulMessageSend(_ message: Message, using transaction: Any) {
|
||||||
|
guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else { return }
|
||||||
|
tsMessage.openGroupServerMessageID = message.openGroupServerMessageID ?? 0
|
||||||
|
tsMessage.isOpenGroupMessage = tsMessage.openGroupServerMessageID != 0
|
||||||
|
tsMessage.update(withSentRecipient: message.recipient!, wasSentByUD: true, transaction: transaction as! YapDatabaseReadWriteTransaction)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func handleFailedMessageSend(_ message: Message, with error: Swift.Error, using transaction: Any) {
|
||||||
|
guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else { return }
|
||||||
|
tsMessage.update(sendingError: error, transaction: transaction as! YapDatabaseReadWriteTransaction)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
|
|
||||||
public protocol MessageSenderDelegate {
|
|
||||||
|
|
||||||
func handleSuccessfulMessageSend(_ message: Message, using transaction: Any)
|
|
||||||
func handleFailedMessageSend(_ message: Message, with error: Error, using transaction: Any)
|
|
||||||
}
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import SessionSnodeKit
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
|
||||||
@objc(LKPushNotificationAPI)
|
@objc(LKPushNotificationAPI)
|
|
@ -1,3 +1,4 @@
|
||||||
|
import SessionSnodeKit
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
|
||||||
@objc(LKClosedGroupPoller)
|
@objc(LKClosedGroupPoller)
|
||||||
|
@ -23,7 +24,9 @@ public final class ClosedGroupPoller : NSObject {
|
||||||
|
|
||||||
// MARK: Public API
|
// MARK: Public API
|
||||||
@objc public func startIfNeeded() {
|
@objc public func startIfNeeded() {
|
||||||
AssertIsOnMainThread() // Timers don't do well on background queues
|
#if DEBUG
|
||||||
|
assert(Thread.current.isMainThread) // Timers don't do well on background queues
|
||||||
|
#endif
|
||||||
guard !isPolling else { return }
|
guard !isPolling else { return }
|
||||||
isPolling = true
|
isPolling = true
|
||||||
timer = Timer.scheduledTimer(withTimeInterval: ClosedGroupPoller.pollInterval, repeats: true) { [weak self] _ in
|
timer = Timer.scheduledTimer(withTimeInterval: ClosedGroupPoller.pollInterval, repeats: true) { [weak self] _ in
|
|
@ -162,10 +162,10 @@ public final class OpenGroupPoller : NSObject {
|
||||||
private func pollForDeletedMessages() {
|
private func pollForDeletedMessages() {
|
||||||
let openGroup = self.openGroup
|
let openGroup = self.openGroup
|
||||||
let _ = OpenGroupAPI.getDeletedMessageServerIDs(for: openGroup.channel, on: openGroup.server).done(on: DispatchQueue.global(qos: .default)) { deletedMessageServerIDs in
|
let _ = OpenGroupAPI.getDeletedMessageServerIDs(for: openGroup.channel, on: openGroup.server).done(on: DispatchQueue.global(qos: .default)) { deletedMessageServerIDs in
|
||||||
|
let deletedMessageIDs = deletedMessageServerIDs.compactMap { Storage.shared.getIDForMessage(withServerID: UInt64($0)) }
|
||||||
Storage.writeSync { transaction in
|
Storage.writeSync { transaction in
|
||||||
let deletedMessageIDs = deletedMessageServerIDs.compactMap { OWSPrimaryStorage.shared().getIDForMessage(withServerID: UInt($0), in: transaction) }
|
|
||||||
deletedMessageIDs.forEach { messageID in
|
deletedMessageIDs.forEach { messageID in
|
||||||
TSMessage.fetch(uniqueId: messageID)?.remove(with: transaction)
|
TSMessage.fetch(uniqueId: String(messageID))?.remove(with: transaction)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,3 +1,4 @@
|
||||||
|
import SessionSnodeKit
|
||||||
import PromiseKit
|
import PromiseKit
|
||||||
|
|
||||||
@objc(LKPoller)
|
@objc(LKPoller)
|
|
@ -0,0 +1,13 @@
|
||||||
|
|
||||||
|
extension VisibleMessage.Quote {
|
||||||
|
|
||||||
|
@objc(from:)
|
||||||
|
public static func from(_ quote: OWSQuotedReplyModel?) -> VisibleMessage.Quote? {
|
||||||
|
guard let quote = quote else { return nil }
|
||||||
|
let result = VisibleMessage.Quote()
|
||||||
|
result.timestamp = quote.timestamp
|
||||||
|
result.publicKey = quote.authorId
|
||||||
|
result.text = quote.body
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,8 @@
|
||||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <SignalUtilitiesKit/TSQuotedMessage.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#import <SessionMessagingKit/TSQuotedMessage.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
|
@ -4,16 +4,15 @@
|
||||||
|
|
||||||
#import "OWSQuotedReplyModel.h"
|
#import "OWSQuotedReplyModel.h"
|
||||||
#import "ConversationViewItem.h"
|
#import "ConversationViewItem.h"
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
|
||||||
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
||||||
#import <SignalUtilitiesKit/TSAccountManager.h>
|
#import <SessionMessagingKit/TSAccountManager.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentPointer.h>
|
#import <SessionMessagingKit/TSAttachmentPointer.h>
|
||||||
#import <SessionMessagingKit/TSAttachmentStream.h>
|
#import <SessionMessagingKit/TSAttachmentStream.h>
|
||||||
#import <SignalUtilitiesKit/TSIncomingMessage.h>
|
#import <SessionMessagingKit/TSIncomingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSMessage.h>
|
#import <SessionMessagingKit/TSMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSOutgoingMessage.h>
|
#import <SessionMessagingKit/TSOutgoingMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSQuotedMessage.h>
|
#import <SessionMessagingKit/TSQuotedMessage.h>
|
||||||
#import <SignalUtilitiesKit/TSThread.h>
|
#import <SessionMessagingKit/TSThread.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -78,7 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
threadId:(NSString *)threadId
|
threadId:(NSString *)threadId
|
||||||
transaction:(YapDatabaseReadTransaction *)transaction
|
transaction:(YapDatabaseReadTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(quotedMessage.quotedAttachments.count <= 1);
|
|
||||||
OWSAttachmentInfo *attachmentInfo = quotedMessage.quotedAttachments.firstObject;
|
OWSAttachmentInfo *attachmentInfo = quotedMessage.quotedAttachments.firstObject;
|
||||||
|
|
||||||
BOOL thumbnailDownloadFailed = NO;
|
BOOL thumbnailDownloadFailed = NO;
|
||||||
|
@ -123,17 +121,12 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
threadId:(NSString *)threadId
|
threadId:(NSString *)threadId
|
||||||
transaction:(YapDatabaseReadTransaction *)transaction;
|
transaction:(YapDatabaseReadTransaction *)transaction;
|
||||||
{
|
{
|
||||||
OWSAssertDebug(conversationItem);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
TSMessage *message = (TSMessage *)conversationItem.interaction;
|
TSMessage *message = (TSMessage *)conversationItem.interaction;
|
||||||
if (![message isKindOfClass:[TSMessage class]]) {
|
if (![message isKindOfClass:[TSMessage class]]) {
|
||||||
OWSFailDebug(@"unexpected reply message: %@", message);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
TSThread *thread = [message threadWithTransaction:transaction];
|
TSThread *thread = [message threadWithTransaction:transaction];
|
||||||
OWSAssertDebug(thread);
|
|
||||||
|
|
||||||
uint64_t timestamp = message.timestamp;
|
uint64_t timestamp = message.timestamp;
|
||||||
|
|
||||||
|
@ -143,11 +136,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
} else if ([message isKindOfClass:[TSIncomingMessage class]]) {
|
} else if ([message isKindOfClass:[TSIncomingMessage class]]) {
|
||||||
return [(TSIncomingMessage *)message authorId];
|
return [(TSIncomingMessage *)message authorId];
|
||||||
} else {
|
} else {
|
||||||
OWSFailDebug(@"Unexpected message type: %@", message.class);
|
|
||||||
return (NSString * _Nullable) nil;
|
return (NSString * _Nullable) nil;
|
||||||
}
|
}
|
||||||
}();
|
}();
|
||||||
OWSAssertDebug(authorId.length > 0);
|
|
||||||
|
|
||||||
NSString *_Nullable quotedText = message.body;
|
NSString *_Nullable quotedText = message.body;
|
||||||
BOOL hasText = quotedText.length > 0;
|
BOOL hasText = quotedText.length > 0;
|
||||||
|
@ -192,8 +183,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
}
|
}
|
||||||
if ([truncatedText dataUsingEncoding:NSUTF8StringEncoding].length < kOversizeTextMessageSizeThreshold) {
|
if ([truncatedText dataUsingEncoding:NSUTF8StringEncoding].length < kOversizeTextMessageSizeThreshold) {
|
||||||
quotedText = truncatedText;
|
quotedText = truncatedText;
|
||||||
} else {
|
|
||||||
OWSFailDebug(@"Missing valid text snippet.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -209,7 +198,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
BOOL hasAttachment = quotedAttachment != nil;
|
BOOL hasAttachment = quotedAttachment != nil;
|
||||||
if (!hasText && !hasAttachment) {
|
if (!hasText && !hasAttachment) {
|
||||||
OWSFailDebug(@"quoted message has neither text nor attachment");
|
|
||||||
quotedText = @"";
|
quotedText = @"";
|
||||||
hasText = YES;
|
hasText = YES;
|
||||||
}
|
}
|
|
@ -1,17 +1,4 @@
|
||||||
|
|
||||||
extension VisibleMessage.Quote {
|
|
||||||
|
|
||||||
@objc(from:)
|
|
||||||
public static func from(_ quote: OWSQuotedReplyModel?) -> VisibleMessage.Quote? {
|
|
||||||
guard let quote = quote else { return nil }
|
|
||||||
let result = VisibleMessage.Quote()
|
|
||||||
result.timestamp = quote.timestamp
|
|
||||||
result.publicKey = quote.authorId
|
|
||||||
result.text = quote.body
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extension TSQuotedMessage {
|
extension TSQuotedMessage {
|
||||||
|
|
||||||
@objc(from:)
|
@objc(from:)
|
|
@ -11,8 +11,8 @@
|
||||||
#import "TSInteraction.h"
|
#import "TSInteraction.h"
|
||||||
#import "TSOutgoingMessage.h"
|
#import "TSOutgoingMessage.h"
|
||||||
#import "TSThread.h"
|
#import "TSThread.h"
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
|
||||||
#import <YapDatabase/YapDatabaseTransaction.h>
|
#import <YapDatabase/YapDatabaseTransaction.h>
|
||||||
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -20,10 +20,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (instancetype)initWithAttachmentStream:(TSAttachmentStream *)attachmentStream;
|
- (instancetype)initWithAttachmentStream:(TSAttachmentStream *)attachmentStream;
|
||||||
{
|
{
|
||||||
OWSAssertDebug([attachmentStream isKindOfClass:[TSAttachmentStream class]]);
|
|
||||||
OWSAssertDebug(attachmentStream.uniqueId);
|
|
||||||
OWSAssertDebug(attachmentStream.contentType);
|
|
||||||
|
|
||||||
return [self initWithAttachmentId:attachmentStream.uniqueId
|
return [self initWithAttachmentId:attachmentStream.uniqueId
|
||||||
contentType:attachmentStream.contentType
|
contentType:attachmentStream.contentType
|
||||||
sourceFilename:attachmentStream.sourceFilename];
|
sourceFilename:attachmentStream.sourceFilename];
|
||||||
|
@ -62,9 +58,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
bodySource:(TSQuotedMessageContentSource)bodySource
|
bodySource:(TSQuotedMessageContentSource)bodySource
|
||||||
receivedQuotedAttachmentInfos:(NSArray<OWSAttachmentInfo *> *)attachmentInfos
|
receivedQuotedAttachmentInfos:(NSArray<OWSAttachmentInfo *> *)attachmentInfos
|
||||||
{
|
{
|
||||||
OWSAssertDebug(timestamp > 0);
|
|
||||||
OWSAssertDebug(authorId.length > 0);
|
|
||||||
|
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (!self) {
|
if (!self) {
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -84,9 +77,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
body:(NSString *_Nullable)body
|
body:(NSString *_Nullable)body
|
||||||
quotedAttachmentsForSending:(NSArray<TSAttachmentStream *> *)attachments
|
quotedAttachmentsForSending:(NSArray<TSAttachmentStream *> *)attachments
|
||||||
{
|
{
|
||||||
OWSAssertDebug(timestamp > 0);
|
|
||||||
OWSAssertDebug(authorId.length > 0);
|
|
||||||
|
|
||||||
self = [super init];
|
self = [super init];
|
||||||
if (!self) {
|
if (!self) {
|
||||||
return nil;
|
return nil;
|
||||||
|
@ -110,8 +100,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
thread:(TSThread *)thread
|
thread:(TSThread *)thread
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(dataMessage);
|
|
||||||
|
|
||||||
if (!dataMessage.quote) {
|
if (!dataMessage.quote) {
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
@ -119,13 +107,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
SNProtoDataMessageQuote *quoteProto = [dataMessage quote];
|
SNProtoDataMessageQuote *quoteProto = [dataMessage quote];
|
||||||
|
|
||||||
if (quoteProto.id == 0) {
|
if (quoteProto.id == 0) {
|
||||||
OWSFailDebug(@"quoted message missing id");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
uint64_t timestamp = [quoteProto id];
|
uint64_t timestamp = [quoteProto id];
|
||||||
|
|
||||||
if (quoteProto.author.length == 0) {
|
if (quoteProto.author.length == 0) {
|
||||||
OWSFailDebug(@"quoted message missing author");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
// TODO: We could verify that this is a valid e164 value.
|
// TODO: We could verify that this is a valid e164 value.
|
||||||
|
@ -173,18 +159,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
transaction:transaction];
|
transaction:transaction];
|
||||||
|
|
||||||
if (localThumbnail) {
|
if (localThumbnail) {
|
||||||
OWSLogDebug(@"Generated local thumbnail for quoted quoted message: %@:%lu",
|
|
||||||
thread.uniqueId,
|
|
||||||
(unsigned long)timestamp);
|
|
||||||
|
|
||||||
[localThumbnail saveWithTransaction:transaction];
|
[localThumbnail saveWithTransaction:transaction];
|
||||||
|
|
||||||
attachmentInfo.thumbnailAttachmentStreamId = localThumbnail.uniqueId;
|
attachmentInfo.thumbnailAttachmentStreamId = localThumbnail.uniqueId;
|
||||||
} else if (quotedAttachment.thumbnail) {
|
} else if (quotedAttachment.thumbnail) {
|
||||||
OWSLogDebug(@"Saving reference for fetching remote thumbnail for quoted message: %@:%lu",
|
|
||||||
thread.uniqueId,
|
|
||||||
(unsigned long)timestamp);
|
|
||||||
|
|
||||||
SNProtoAttachmentPointer *thumbnailAttachmentProto = quotedAttachment.thumbnail;
|
SNProtoAttachmentPointer *thumbnailAttachmentProto = quotedAttachment.thumbnail;
|
||||||
TSAttachmentPointer *_Nullable thumbnailPointer =
|
TSAttachmentPointer *_Nullable thumbnailPointer =
|
||||||
[TSAttachmentPointer attachmentPointerFromProto:thumbnailAttachmentProto albumMessage:nil];
|
[TSAttachmentPointer attachmentPointerFromProto:thumbnailAttachmentProto albumMessage:nil];
|
||||||
|
@ -192,11 +170,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[thumbnailPointer saveWithTransaction:transaction];
|
[thumbnailPointer saveWithTransaction:transaction];
|
||||||
|
|
||||||
attachmentInfo.thumbnailAttachmentPointerId = thumbnailPointer.uniqueId;
|
attachmentInfo.thumbnailAttachmentPointerId = thumbnailPointer.uniqueId;
|
||||||
} else {
|
|
||||||
OWSFailDebug(@"Invalid thumbnail attachment.");
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
OWSLogDebug(@"No thumbnail for quoted message: %@:%lu", thread.uniqueId, (unsigned long)timestamp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[attachmentInfos addObject:attachmentInfo];
|
[attachmentInfos addObject:attachmentInfo];
|
||||||
|
@ -251,18 +225,13 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
authorId:(NSString *)authorId
|
authorId:(NSString *)authorId
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
if (timestamp <= 0) {
|
if (timestamp <= 0) {
|
||||||
OWSFailDebug(@"Invalid timestamp: %llu", timestamp);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if (threadId.length <= 0) {
|
if (threadId.length <= 0) {
|
||||||
OWSFailDebug(@"Invalid thread.");
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
if (authorId.length <= 0) {
|
if (authorId.length <= 0) {
|
||||||
OWSFailDebug(@"Invalid authorId: %@", authorId);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -284,7 +253,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
OWSLogWarn(@"Could not find quoted message: %llu", timestamp);
|
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,7 +260,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (nullable OWSAttachmentInfo *)firstAttachmentInfo
|
- (nullable OWSAttachmentInfo *)firstAttachmentInfo
|
||||||
{
|
{
|
||||||
OWSAssertDebug(self.quotedAttachments.count <= 1);
|
|
||||||
return self.quotedAttachments.firstObject;
|
return self.quotedAttachments.firstObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -326,9 +293,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
- (void)setThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream
|
- (void)setThumbnailAttachmentStream:(TSAttachmentStream *)attachmentStream
|
||||||
{
|
{
|
||||||
OWSAssertDebug([attachmentStream isKindOfClass:[TSAttachmentStream class]]);
|
|
||||||
OWSAssertDebug(self.quotedAttachments.count == 1);
|
|
||||||
|
|
||||||
OWSAttachmentInfo *firstAttachment = self.firstAttachmentInfo;
|
OWSAttachmentInfo *firstAttachment = self.firstAttachmentInfo;
|
||||||
firstAttachment.thumbnailAttachmentStreamId = attachmentStream.uniqueId;
|
firstAttachment.thumbnailAttachmentStreamId = attachmentStream.uniqueId;
|
||||||
}
|
}
|
||||||
|
@ -352,8 +316,6 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
NSMutableArray<TSAttachmentStream *> *thumbnailAttachments = [NSMutableArray new];
|
NSMutableArray<TSAttachmentStream *> *thumbnailAttachments = [NSMutableArray new];
|
||||||
|
|
||||||
for (OWSAttachmentInfo *info in self.quotedAttachments) {
|
for (OWSAttachmentInfo *info in self.quotedAttachments) {
|
||||||
|
|
||||||
OWSAssertDebug(info.attachmentId);
|
|
||||||
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:info.attachmentId transaction:transaction];
|
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:info.attachmentId transaction:transaction];
|
||||||
if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
|
if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
|
||||||
continue;
|
continue;
|
|
@ -3,16 +3,16 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "OWSOutgoingReceiptManager.h"
|
#import "OWSOutgoingReceiptManager.h"
|
||||||
#import "AppReadiness.h"
|
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
|
||||||
#import "OWSError.h"
|
|
||||||
#import <PromiseKit/PromiseKit.h>
|
|
||||||
#import "OWSPrimaryStorage.h"
|
|
||||||
#import "SSKEnvironment.h"
|
#import "SSKEnvironment.h"
|
||||||
|
#import "AppReadiness.h"
|
||||||
|
#import "OWSPrimaryStorage.h"
|
||||||
#import "TSContactThread.h"
|
#import "TSContactThread.h"
|
||||||
#import "TSYapDatabaseObject.h"
|
#import "TSYapDatabaseObject.h"
|
||||||
|
#import <PromiseKit/PromiseKit.h>
|
||||||
|
#import <YapDatabase/YapDatabase.h>
|
||||||
#import <Reachability/Reachability.h>
|
#import <Reachability/Reachability.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
||||||
#import "SSKAsserts.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -41,8 +41,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
|
|
||||||
+ (instancetype)sharedManager
|
+ (instancetype)sharedManager
|
||||||
{
|
{
|
||||||
OWSAssert(SSKEnvironment.shared.outgoingReceiptManager);
|
|
||||||
|
|
||||||
return SSKEnvironment.shared.outgoingReceiptManager;
|
return SSKEnvironment.shared.outgoingReceiptManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,8 +56,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
|
|
||||||
_dbConnection = primaryStorage.newDatabaseConnection;
|
_dbConnection = primaryStorage.newDatabaseConnection;
|
||||||
|
|
||||||
OWSSingletonAssert();
|
|
||||||
|
|
||||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||||
selector:@selector(reachabilityChanged)
|
selector:@selector(reachabilityChanged)
|
||||||
name:kReachabilityChangedNotification
|
name:kReachabilityChangedNotification
|
||||||
|
@ -93,15 +89,11 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
|
|
||||||
// Schedules a processing pass, unless one is already scheduled.
|
// Schedules a processing pass, unless one is already scheduled.
|
||||||
- (void)process {
|
- (void)process {
|
||||||
OWSAssertDebug(AppReadiness.isAppReady);
|
|
||||||
|
|
||||||
dispatch_async(self.serialQueue, ^{
|
dispatch_async(self.serialQueue, ^{
|
||||||
if (self.isProcessing) {
|
if (self.isProcessing) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
OWSLogVerbose(@"Processing outbound receipts.");
|
|
||||||
|
|
||||||
self.isProcessing = YES;
|
self.isProcessing = YES;
|
||||||
|
|
||||||
if (!self.reachability.isReachable) {
|
if (!self.reachability.isReachable) {
|
||||||
|
@ -159,7 +151,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
for (NSString *recipientId in queuedReceiptMap) {
|
for (NSString *recipientId in queuedReceiptMap) {
|
||||||
NSSet<NSNumber *> *timestamps = queuedReceiptMap[recipientId];
|
NSSet<NSNumber *> *timestamps = queuedReceiptMap[recipientId];
|
||||||
if (timestamps.count < 1) {
|
if (timestamps.count < 1) {
|
||||||
OWSFailDebug(@"Missing timestamps.");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,11 +227,9 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
NSString *collection = [self collectionForReceiptType:receiptType];
|
NSString *collection = [self collectionForReceiptType:receiptType];
|
||||||
|
|
||||||
if (recipientId.length < 1) {
|
if (recipientId.length < 1) {
|
||||||
OWSFailDebug(@"Invalid recipient id.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (timestamp < 1) {
|
if (timestamp < 1) {
|
||||||
OWSFailDebug(@"Invalid timestamp.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch_async(self.serialQueue, ^{
|
dispatch_async(self.serialQueue, ^{
|
||||||
|
@ -263,11 +252,9 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
NSString *collection = [self collectionForReceiptType:receiptType];
|
NSString *collection = [self collectionForReceiptType:receiptType];
|
||||||
|
|
||||||
if (recipientId.length < 1) {
|
if (recipientId.length < 1) {
|
||||||
OWSFailDebug(@"Invalid recipient id.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (timestamps.count < 1) {
|
if (timestamps.count < 1) {
|
||||||
OWSFailDebug(@"Invalid timestamps.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
dispatch_async(self.serialQueue, ^{
|
dispatch_async(self.serialQueue, ^{
|
||||||
|
@ -288,8 +275,6 @@ NSString *const kOutgoingReadReceiptManagerCollection = @"kOutgoingReadReceiptMa
|
||||||
|
|
||||||
- (void)reachabilityChanged
|
- (void)reachabilityChanged
|
||||||
{
|
{
|
||||||
OWSAssertIsOnMainThread();
|
|
||||||
|
|
||||||
[self process];
|
[self process];
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,15 +51,6 @@ extern NSString *const kIncomingMessageMarkedAsReadNotification;
|
||||||
- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message
|
- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||||
|
|
||||||
#pragma mark - Linked Device Read Receipts
|
|
||||||
|
|
||||||
- (void)processReadReceiptsFromLinkedDevice:(NSArray<SNProtoSyncMessageRead *> *)readReceiptProtos
|
|
||||||
readTimestamp:(uint64_t)readTimestamp
|
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
|
||||||
|
|
||||||
- (void)applyEarlyReadReceiptsForIncomingMessage:(TSIncomingMessage *)message
|
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
|
||||||
|
|
||||||
#pragma mark - Locally Read
|
#pragma mark - Locally Read
|
||||||
|
|
||||||
// This method cues this manager:
|
// This method cues this manager:
|
|
@ -10,13 +10,13 @@
|
||||||
#import "SSKEnvironment.h"
|
#import "SSKEnvironment.h"
|
||||||
#import "TSAccountManager.h"
|
#import "TSAccountManager.h"
|
||||||
#import "TSContactThread.h"
|
#import "TSContactThread.h"
|
||||||
|
#import "TSOutgoingMessage.h"
|
||||||
#import "TSDatabaseView.h"
|
#import "TSDatabaseView.h"
|
||||||
#import "TSIncomingMessage.h"
|
#import "TSIncomingMessage.h"
|
||||||
#import "YapDatabaseConnection+OWS.h"
|
#import "YapDatabaseConnection+OWS.h"
|
||||||
#import <SessionProtocolKit/SessionProtocolKit.h>
|
#import <SessionProtocolKit/SessionProtocolKit.h>
|
||||||
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
|
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
|
||||||
#import <YapDatabase/YapDatabase.h>
|
#import <YapDatabase/YapDatabase.h>
|
||||||
#import "SSKAsserts.h"
|
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@ -41,8 +41,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
|
||||||
|
|
||||||
- (instancetype)initWithSentTimestamp:(uint64_t)sentTimestamp
|
- (instancetype)initWithSentTimestamp:(uint64_t)sentTimestamp
|
||||||
{
|
{
|
||||||
OWSAssertDebug(sentTimestamp > 0);
|
|
||||||
|
|
||||||
self = [super initWithUniqueId:[TSRecipientReadReceipt uniqueIdForSentTimestamp:sentTimestamp]];
|
self = [super initWithUniqueId:[TSRecipientReadReceipt uniqueIdForSentTimestamp:sentTimestamp]];
|
||||||
|
|
||||||
if (self) {
|
if (self) {
|
||||||
|
@ -60,9 +58,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
|
||||||
|
|
||||||
- (void)addRecipientId:(NSString *)recipientId timestamp:(uint64_t)timestamp
|
- (void)addRecipientId:(NSString *)recipientId timestamp:(uint64_t)timestamp
|
||||||
{
|
{
|
||||||
OWSAssertDebug(recipientId.length > 0);
|
|
||||||
OWSAssertDebug(timestamp > 0);
|
|
||||||
|
|
||||||
NSMutableDictionary<NSString *, NSNumber *> *recipientMapCopy = [self.recipientMap mutableCopy];
|
NSMutableDictionary<NSString *, NSNumber *> *recipientMapCopy = [self.recipientMap mutableCopy];
|
||||||
recipientMapCopy[recipientId] = @(timestamp);
|
recipientMapCopy[recipientId] = @(timestamp);
|
||||||
_recipientMap = [recipientMapCopy copy];
|
_recipientMap = [recipientMapCopy copy];
|
||||||
|
@ -73,8 +68,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
|
||||||
readTimestamp:(uint64_t)readTimestamp
|
readTimestamp:(uint64_t)readTimestamp
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
TSRecipientReadReceipt *_Nullable recipientReadReceipt =
|
TSRecipientReadReceipt *_Nullable recipientReadReceipt =
|
||||||
[transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
|
[transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
|
||||||
if (!recipientReadReceipt) {
|
if (!recipientReadReceipt) {
|
||||||
|
@ -88,8 +81,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
|
||||||
transaction:
|
transaction:
|
||||||
(YapDatabaseReadWriteTransaction *)transaction
|
(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
TSRecipientReadReceipt *_Nullable recipientReadReceipt =
|
TSRecipientReadReceipt *_Nullable recipientReadReceipt =
|
||||||
[transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
|
[transaction objectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
|
||||||
return recipientReadReceipt.recipientMap;
|
return recipientReadReceipt.recipientMap;
|
||||||
|
@ -98,8 +89,6 @@ NSString *const kIncomingMessageMarkedAsReadNotification = @"kIncomingMessageMar
|
||||||
+ (void)removeRecipientIdsForTimestamp:(uint64_t)sentTimestamp
|
+ (void)removeRecipientIdsForTimestamp:(uint64_t)sentTimestamp
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
[transaction removeObjectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
|
[transaction removeObjectForKey:[self uniqueIdForSentTimestamp:sentTimestamp] inCollection:[self collection]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,8 +122,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
|
|
||||||
+ (instancetype)sharedManager
|
+ (instancetype)sharedManager
|
||||||
{
|
{
|
||||||
OWSAssert(SSKEnvironment.shared.readReceiptManager);
|
|
||||||
|
|
||||||
return SSKEnvironment.shared.readReceiptManager;
|
return SSKEnvironment.shared.readReceiptManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -148,8 +135,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
|
|
||||||
_dbConnection = primaryStorage.newDatabaseConnection;
|
_dbConnection = primaryStorage.newDatabaseConnection;
|
||||||
|
|
||||||
OWSSingletonAssert();
|
|
||||||
|
|
||||||
// Start processing.
|
// Start processing.
|
||||||
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
[AppReadiness runNowOrWhenAppDidBecomeReady:^{
|
||||||
[self scheduleProcessing];
|
[self scheduleProcessing];
|
||||||
|
@ -167,8 +152,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
|
|
||||||
- (OWSOutgoingReceiptManager *)outgoingReceiptManager
|
- (OWSOutgoingReceiptManager *)outgoingReceiptManager
|
||||||
{
|
{
|
||||||
OWSAssertDebug(SSKEnvironment.shared.outgoingReceiptManager);
|
|
||||||
|
|
||||||
return SSKEnvironment.shared.outgoingReceiptManager;
|
return SSKEnvironment.shared.outgoingReceiptManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,8 +160,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
// Schedules a processing pass, unless one is already scheduled.
|
// Schedules a processing pass, unless one is already scheduled.
|
||||||
- (void)scheduleProcessing
|
- (void)scheduleProcessing
|
||||||
{
|
{
|
||||||
OWSAssertDebug(AppReadiness.isAppReady);
|
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
|
@ -240,13 +221,11 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
|
|
||||||
- (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread
|
- (void)markAsReadLocallyBeforeSortId:(uint64_t)sortId thread:(TSThread *)thread
|
||||||
{
|
{
|
||||||
OWSAssertDebug(thread);
|
|
||||||
|
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||||
[self markAsReadBeforeSortId:sortId
|
[self markAsReadBeforeSortId:sortId
|
||||||
thread:thread
|
thread:thread
|
||||||
readTimestamp:[NSDate ows_millisecondTimeStamp]
|
readTimestamp:[NSDate millisecondTimestamp]
|
||||||
wasLocal:YES
|
wasLocal:YES
|
||||||
transaction:transaction];
|
transaction:transaction];
|
||||||
}];
|
}];
|
||||||
|
@ -303,11 +282,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
sentTimestamps:(NSArray<NSNumber *> *)sentTimestamps
|
sentTimestamps:(NSArray<NSNumber *> *)sentTimestamps
|
||||||
readTimestamp:(uint64_t)readTimestamp
|
readTimestamp:(uint64_t)readTimestamp
|
||||||
{
|
{
|
||||||
OWSAssertDebug(recipientId.length > 0);
|
|
||||||
OWSAssertDebug(sentTimestamps);
|
|
||||||
|
|
||||||
if (![self areReadReceiptsEnabled]) {
|
if (![self areReadReceiptsEnabled]) {
|
||||||
OWSLogInfo(@"Ignoring incoming receipt message as read receipts are disabled.");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -320,9 +295,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
= (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:sentTimestamp
|
= (NSArray<TSOutgoingMessage *> *)[TSInteraction interactionsWithTimestamp:sentTimestamp
|
||||||
ofClass:[TSOutgoingMessage class]
|
ofClass:[TSOutgoingMessage class]
|
||||||
withTransaction:transaction];
|
withTransaction:transaction];
|
||||||
if (messages.count > 1) {
|
|
||||||
OWSLogError(@"More than one matching message with timestamp: %llu.", sentTimestamp);
|
|
||||||
}
|
|
||||||
if (messages.count > 0) {
|
if (messages.count > 0) {
|
||||||
// TODO: We might also need to "mark as read by recipient" any older messages
|
// TODO: We might also need to "mark as read by recipient" any older messages
|
||||||
// from us in that thread. Or maybe this state should hang on the thread?
|
// from us in that thread. Or maybe this state should hang on the thread?
|
||||||
|
@ -344,124 +316,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applyEarlyReadReceiptsForOutgoingMessageFromLinkedDevice:(TSOutgoingMessage *)message
|
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
||||||
{
|
|
||||||
OWSAssertDebug(message);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
uint64_t sentTimestamp = message.timestamp;
|
|
||||||
NSDictionary<NSString *, NSNumber *> *recipientMap =
|
|
||||||
[TSRecipientReadReceipt recipientMapForSentTimestamp:sentTimestamp transaction:transaction];
|
|
||||||
if (!recipientMap) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
OWSAssertDebug(recipientMap.count > 0);
|
|
||||||
for (NSString *recipientId in recipientMap) {
|
|
||||||
NSNumber *nsReadTimestamp = recipientMap[recipientId];
|
|
||||||
OWSAssertDebug(nsReadTimestamp);
|
|
||||||
uint64_t readTimestamp = [nsReadTimestamp unsignedLongLongValue];
|
|
||||||
|
|
||||||
[message updateWithReadRecipientId:recipientId readTimestamp:readTimestamp transaction:transaction];
|
|
||||||
}
|
|
||||||
[TSRecipientReadReceipt removeRecipientIdsForTimestamp:message.timestamp transaction:transaction];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Linked Device Read Receipts
|
|
||||||
|
|
||||||
- (void)applyEarlyReadReceiptsForIncomingMessage:(TSIncomingMessage *)message
|
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
OWSAssertDebug(message);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
NSString *senderId = message.authorId;
|
|
||||||
uint64_t timestamp = message.timestamp;
|
|
||||||
if (senderId.length < 1 || timestamp < 1) {
|
|
||||||
OWSFailDebug(@"Invalid incoming message: %@ %llu", senderId, timestamp);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
OWSLinkedDeviceReadReceipt *_Nullable readReceipt =
|
|
||||||
[OWSLinkedDeviceReadReceipt findLinkedDeviceReadReceiptWithSenderId:senderId
|
|
||||||
messageIdTimestamp:timestamp
|
|
||||||
transaction:transaction];
|
|
||||||
if (!readReceipt) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
[message markAsReadAtTimestamp:readReceipt.readTimestamp sendReadReceipt:NO transaction:transaction];
|
|
||||||
[readReceipt removeWithTransaction:transaction];
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)processReadReceiptsFromLinkedDevice:(NSArray<SNProtoSyncMessageRead *> *)readReceiptProtos
|
|
||||||
readTimestamp:(uint64_t)readTimestamp
|
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
||||||
{
|
|
||||||
// TODO TODO TODO
|
|
||||||
|
|
||||||
/*
|
|
||||||
OWSAssertDebug(readReceiptProtos);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
for (SNProtoSyncMessageRead *readReceiptProto in readReceiptProtos) {
|
|
||||||
NSString *_Nullable senderId = readReceiptProto.sender;
|
|
||||||
uint64_t messageIdTimestamp = readReceiptProto.timestamp;
|
|
||||||
|
|
||||||
if (senderId.length == 0) {
|
|
||||||
OWSFailDebug(@"senderId was unexpectedly nil");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (messageIdTimestamp == 0) {
|
|
||||||
OWSFailDebug(@"messageIdTimestamp was unexpectedly 0");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
NSArray<TSIncomingMessage *> *messages
|
|
||||||
= (NSArray<TSIncomingMessage *> *)[TSInteraction interactionsWithTimestamp:messageIdTimestamp
|
|
||||||
ofClass:[TSIncomingMessage class]
|
|
||||||
withTransaction:transaction];
|
|
||||||
if (messages.count > 0) {
|
|
||||||
for (TSIncomingMessage *message in messages) {
|
|
||||||
NSTimeInterval secondsSinceRead = [NSDate new].timeIntervalSince1970 - readTimestamp / 1000;
|
|
||||||
OWSAssertDebug([message isKindOfClass:[TSIncomingMessage class]]);
|
|
||||||
OWSLogDebug(@"read on linked device %f seconds ago", secondsSinceRead);
|
|
||||||
[self markAsReadOnLinkedDevice:message readTimestamp:readTimestamp transaction:transaction];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Received read receipt for unknown incoming message.
|
|
||||||
// Persist in case we receive the incoming message later.
|
|
||||||
OWSLinkedDeviceReadReceipt *readReceipt =
|
|
||||||
[[OWSLinkedDeviceReadReceipt alloc] initWithSenderId:senderId
|
|
||||||
messageIdTimestamp:messageIdTimestamp
|
|
||||||
readTimestamp:readTimestamp];
|
|
||||||
[readReceipt saveWithTransaction:transaction];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void)markAsReadOnLinkedDevice:(TSIncomingMessage *)message
|
|
||||||
readTimestamp:(uint64_t)readTimestamp
|
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
|
||||||
{
|
|
||||||
OWSAssertDebug(message);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
// Always re-mark the message as read to ensure any earlier read time is applied to disappearing messages.
|
|
||||||
[message markAsReadAtTimestamp:readTimestamp sendReadReceipt:NO transaction:transaction];
|
|
||||||
|
|
||||||
// Also mark any unread messages appearing earlier in the thread as read as well.
|
|
||||||
[self markAsReadBeforeSortId:message.sortId
|
|
||||||
thread:[message threadWithTransaction:transaction]
|
|
||||||
readTimestamp:readTimestamp
|
|
||||||
wasLocal:NO
|
|
||||||
transaction:transaction];
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma mark - Mark As Read
|
#pragma mark - Mark As Read
|
||||||
|
|
||||||
- (void)markAsReadBeforeSortId:(uint64_t)sortId
|
- (void)markAsReadBeforeSortId:(uint64_t)sortId
|
||||||
|
@ -470,22 +324,12 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
wasLocal:(BOOL)wasLocal
|
wasLocal:(BOOL)wasLocal
|
||||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||||
{
|
{
|
||||||
OWSAssertDebug(sortId > 0);
|
|
||||||
OWSAssertDebug(thread);
|
|
||||||
OWSAssertDebug(transaction);
|
|
||||||
|
|
||||||
NSMutableArray<id<OWSReadTracking>> *newlyReadList = [NSMutableArray new];
|
NSMutableArray<id<OWSReadTracking>> *newlyReadList = [NSMutableArray new];
|
||||||
|
|
||||||
[[TSDatabaseView unseenDatabaseViewExtension:transaction]
|
[[TSDatabaseView unseenDatabaseViewExtension:transaction]
|
||||||
enumerateKeysAndObjectsInGroup:thread.uniqueId
|
enumerateKeysAndObjectsInGroup:thread.uniqueId
|
||||||
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
|
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
|
||||||
if (![object conformsToProtocol:@protocol(OWSReadTracking)]) {
|
if (![object conformsToProtocol:@protocol(OWSReadTracking)]) {
|
||||||
OWSFailDebug(
|
|
||||||
@"Expected to conform to OWSReadTracking: object with class: %@ collection: %@ "
|
|
||||||
@"key: %@",
|
|
||||||
[object class],
|
|
||||||
collection,
|
|
||||||
key);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
id<OWSReadTracking> possiblyRead = (id<OWSReadTracking>)object;
|
id<OWSReadTracking> possiblyRead = (id<OWSReadTracking>)object;
|
||||||
|
@ -498,7 +342,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
// there is a bug that can somehow cause it to be false leading to conversations permanently being
|
// there is a bug that can somehow cause it to be false leading to conversations permanently being
|
||||||
// stuck with "unread" messages.
|
// stuck with "unread" messages.
|
||||||
|
|
||||||
OWSAssertDebug(possiblyRead.expireStartedAt == 0);
|
|
||||||
if (!possiblyRead.read) {
|
if (!possiblyRead.read) {
|
||||||
[newlyReadList addObject:possiblyRead];
|
[newlyReadList addObject:possiblyRead];
|
||||||
}
|
}
|
||||||
|
@ -507,12 +350,7 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
if (newlyReadList.count < 1) {
|
if (newlyReadList.count < 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wasLocal) {
|
|
||||||
OWSLogError(@"Marking %lu messages as read locally.", (unsigned long)newlyReadList.count);
|
|
||||||
} else {
|
|
||||||
OWSLogError(@"Marking %lu messages as read by linked device.", (unsigned long)newlyReadList.count);
|
|
||||||
}
|
|
||||||
for (id<OWSReadTracking> readItem in newlyReadList) {
|
for (id<OWSReadTracking> readItem in newlyReadList) {
|
||||||
[readItem markAsReadAtTimestamp:readTimestamp sendReadReceipt:wasLocal transaction:transaction];
|
[readItem markAsReadAtTimestamp:readTimestamp sendReadReceipt:wasLocal transaction:transaction];
|
||||||
}
|
}
|
||||||
|
@ -539,8 +377,6 @@ NSString *const OWSReadReceiptManagerAreReadReceiptsEnabled = @"areReadReceiptsE
|
||||||
|
|
||||||
- (void)setAreReadReceiptsEnabled:(BOOL)value
|
- (void)setAreReadReceiptsEnabled:(BOOL)value
|
||||||
{
|
{
|
||||||
OWSLogInfo(@"setAreReadReceiptsEnabled: %d.", value);
|
|
||||||
|
|
||||||
[self.dbConnection setBool:value
|
[self.dbConnection setBool:value
|
||||||
forKey:OWSReadReceiptManagerAreReadReceiptsEnabled
|
forKey:OWSReadReceiptManagerAreReadReceiptsEnabled
|
||||||
inCollection:OWSReadReceiptManagerCollection];
|
inCollection:OWSReadReceiptManagerCollection];
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue