Removed a bunch of legacy code

Renamed the 'Legacy' classes to have their library prefix (avoid confusion)
Removed the legacy Objective C Thread code (pulled only the NSCoding stuff into the 'SMKLegacy' type)
This commit is contained in:
Morgan Pretty 2022-05-21 12:25:10 +10:00
parent aabf656d89
commit 9ada8b84e0
43 changed files with 514 additions and 1633 deletions

View File

@ -283,14 +283,6 @@
C32A026C25A801AF000ED5D4 /* NSData+messagePadding.h in Headers */ = {isa = PBXBuildFile; fileRef = C3A71D4E25589FF30043A11F /* NSData+messagePadding.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C598A256D0664003C73A2 /* SNProtoEnvelope+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = C38EEF09255B49A8007E1867 /* SNProtoEnvelope+Conversion.swift */; };
C32C599E256DB02B003C73A2 /* TypingIndicators.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDA87255A57FC00E217F9 /* TypingIndicators.swift */; };
C32C59C0256DB41F003C73A2 /* TSThread.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAD3255A580300E217F9 /* TSThread.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C59C1256DB41F003C73A2 /* TSGroupThread.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC01255A581C00E217F9 /* TSGroupThread.m */; };
C32C59C2256DB41F003C73A2 /* TSContactThread.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDAB3255A580000E217F9 /* TSContactThread.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C59C3256DB41F003C73A2 /* TSGroupModel.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB73255A581000E217F9 /* TSGroupModel.m */; };
C32C59C4256DB41F003C73A2 /* TSContactThread.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDAF9255A580600E217F9 /* TSContactThread.m */; };
C32C59C5256DB41F003C73A2 /* TSGroupModel.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB0A255A580700E217F9 /* TSGroupModel.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C59C6256DB41F003C73A2 /* TSGroupThread.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDA79255A57FB00E217F9 /* TSGroupThread.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C59C7256DB41F003C73A2 /* TSThread.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBB8255A581600E217F9 /* TSThread.m */; };
C32C5A13256DB7A5003C73A2 /* PushNotificationAPI.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBDE255A581900E217F9 /* PushNotificationAPI.swift */; };
C32C5A24256DB7DB003C73A2 /* SNUserDefaults.swift in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB6B255A580F00E217F9 /* SNUserDefaults.swift */; };
C32C5A2D256DB849003C73A2 /* LKGroupUtilities.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDBE1255A581A00E217F9 /* LKGroupUtilities.m */; };
@ -353,7 +345,6 @@
C32C5FAA256DFED9003C73A2 /* NSArray+Functional.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB5C255A580E00E217F9 /* NSArray+Functional.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C5FBB256E0206003C73A2 /* OWSBackgroundTask.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDC1B255A581F00E217F9 /* OWSBackgroundTask.m */; };
C32C5FC4256E0209003C73A2 /* OWSBackgroundTask.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB38255A580B00E217F9 /* OWSBackgroundTask.h */; settings = {ATTRIBUTES = (Public, ); }; };
C32C5FD6256E0346003C73A2 /* Notification+Thread.swift in Sources */ = {isa = PBXBuildFile; fileRef = C32C5FD5256E0346003C73A2 /* Notification+Thread.swift */; };
C32C600F256E07F5003C73A2 /* NSUserDefaults+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = C33FDB77255A581000E217F9 /* NSUserDefaults+OWS.m */; };
C32C6018256E07F9003C73A2 /* NSUserDefaults+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = C33FDB51255A580D00E217F9 /* NSUserDefaults+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; };
C33100082558FF6D00070591 /* NewConversationButtonSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = B83F2B85240C7B8F000A54AB /* NewConversationButtonSet.swift */; };
@ -709,12 +700,12 @@
FD09C5EA282A1BB2000CE219 /* ThreadTypingIndicator.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD09C5E9282A1BB2000CE219 /* ThreadTypingIndicator.swift */; };
FD09C5EC282B8F18000CE219 /* AttachmentError.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD09C5EB282B8F17000CE219 /* AttachmentError.swift */; };
FD17D79927F40AB800122BE0 /* _003_YDBToGRDBMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79827F40AB800122BE0 /* _003_YDBToGRDBMigration.swift */; };
FD17D79C27F40B2E00122BE0 /* SMKLegacyModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79B27F40B2E00122BE0 /* SMKLegacyModels.swift */; };
FD17D79C27F40B2E00122BE0 /* SMKLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79B27F40B2E00122BE0 /* SMKLegacy.swift */; };
FD17D7A027F40CC800122BE0 /* _001_InitialSetupMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79F27F40CC800122BE0 /* _001_InitialSetupMigration.swift */; };
FD17D7A127F40D2500122BE0 /* GRDBStorage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD28A4F527EAD44C00FF65E7 /* GRDBStorage.swift */; };
FD17D7A227F40F0500122BE0 /* _001_InitialSetupMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D79527F3E04600122BE0 /* _001_InitialSetupMigration.swift */; };
FD17D7A427F40F8100122BE0 /* _003_YDBToGRDBMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7A327F40F8100122BE0 /* _003_YDBToGRDBMigration.swift */; };
FD17D7A727F41AF000122BE0 /* SSKLegacyModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7A627F41AF000122BE0 /* SSKLegacyModels.swift */; };
FD17D7A727F41AF000122BE0 /* SSKLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7A627F41AF000122BE0 /* SSKLegacy.swift */; };
FD17D7AA27F41BF500122BE0 /* SnodeSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7A927F41BF500122BE0 /* SnodeSet.swift */; };
FD17D7AE27F41C4300122BE0 /* SnodeReceivedMessageInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7AD27F41C4300122BE0 /* SnodeReceivedMessageInfo.swift */; };
FD17D7B027F4225C00122BE0 /* Set+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7AF27F4225C00122BE0 /* Set+Utilities.swift */; };
@ -735,7 +726,7 @@
FD17D7E127F67BD400122BE0 /* SnodeReceivedMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E027F67BD400122BE0 /* SnodeReceivedMessage.swift */; };
FD17D7E527F6A09900122BE0 /* Identity.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E427F6A09900122BE0 /* Identity.swift */; };
FD17D7E727F6A16700122BE0 /* _003_YDBToGRDBMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E627F6A16700122BE0 /* _003_YDBToGRDBMigration.swift */; };
FD17D7EA27F6A1C600122BE0 /* SUKLegacyModels.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E927F6A1C600122BE0 /* SUKLegacyModels.swift */; };
FD17D7EA27F6A1C600122BE0 /* SUKLegacy.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD17D7E927F6A1C600122BE0 /* SUKLegacy.swift */; };
FD1C98E4282E3C5B00B76F9E /* UINavigationBar+Utilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD1C98E3282E3C5B00B76F9E /* UINavigationBar+Utilities.swift */; };
FD28A4F227E990E800FF65E7 /* BlockingManagerRemovalMigration.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD28A4F127E990E800FF65E7 /* BlockingManagerRemovalMigration.swift */; };
FD28A4F427EA79F800FF65E7 /* BlockListUIUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = FD28A4F327EA79F800FF65E7 /* BlockListUIUtils.swift */; };
@ -1304,7 +1295,6 @@
C328255125CA64470062D0A7 /* ContextMenuVC+ActionView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContextMenuVC+ActionView.swift"; sourceTree = "<group>"; };
C32C5A87256DBCF9003C73A2 /* MessageReceiver+Handling.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MessageReceiver+Handling.swift"; sourceTree = "<group>"; };
C32C5B3E256DC1DF003C73A2 /* TSQuotedMessage+Conversion.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSQuotedMessage+Conversion.swift"; sourceTree = "<group>"; };
C32C5FD5256E0346003C73A2 /* Notification+Thread.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+Thread.swift"; sourceTree = "<group>"; };
C33100132558FFC200070591 /* UIImage+Tinting.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIImage+Tinting.swift"; sourceTree = "<group>"; };
C33100272559000A00070591 /* UIView+Rendering.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIView+Rendering.swift"; sourceTree = "<group>"; };
C3310032255900A400070591 /* Notification+AppMode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Notification+AppMode.swift"; sourceTree = "<group>"; };
@ -1319,7 +1309,6 @@
C33FDA6F255A57FA00E217F9 /* ReachabilityManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReachabilityManager.swift; sourceTree = "<group>"; };
C33FDA70255A57FA00E217F9 /* TSMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSMessage.h; sourceTree = "<group>"; };
C33FDA73255A57FA00E217F9 /* ECKeyPair+Hexadecimal.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ECKeyPair+Hexadecimal.swift"; sourceTree = "<group>"; };
C33FDA79255A57FB00E217F9 /* TSGroupThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSGroupThread.h; sourceTree = "<group>"; };
C33FDA7A255A57FB00E217F9 /* NSRegularExpression+SSK.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "NSRegularExpression+SSK.swift"; sourceTree = "<group>"; };
C33FDA86255A57FC00E217F9 /* OWSDisappearingMessagesFinder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDisappearingMessagesFinder.m; sourceTree = "<group>"; };
C33FDA87255A57FC00E217F9 /* TypingIndicators.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TypingIndicators.swift; sourceTree = "<group>"; };
@ -1336,7 +1325,6 @@
C33FDAA8255A57FF00E217F9 /* BuildConfiguration.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BuildConfiguration.swift; sourceTree = "<group>"; };
C33FDAAA255A580000E217F9 /* NSObject+Casting.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSObject+Casting.m"; sourceTree = "<group>"; };
C33FDAB1255A580000E217F9 /* OWSStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSStorage.m; sourceTree = "<group>"; };
C33FDAB3255A580000E217F9 /* TSContactThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSContactThread.h; sourceTree = "<group>"; };
C33FDAB8255A580100E217F9 /* NSArray+Functional.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+Functional.m"; sourceTree = "<group>"; };
C33FDAB9255A580100E217F9 /* OWSStorage+Subclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSStorage+Subclass.h"; sourceTree = "<group>"; };
C33FDABE255A580100E217F9 /* TSConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSConstants.m; sourceTree = "<group>"; };
@ -1345,7 +1333,6 @@
C33FDAC2255A580200E217F9 /* TSAttachment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachment.m; sourceTree = "<group>"; };
C33FDAC3255A580200E217F9 /* OWSDispatch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSDispatch.m; sourceTree = "<group>"; };
C33FDAC4255A580200E217F9 /* TSAttachmentStream.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSAttachmentStream.m; sourceTree = "<group>"; };
C33FDAD3255A580300E217F9 /* TSThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSThread.h; sourceTree = "<group>"; };
C33FDAD5255A580300E217F9 /* TSQuotedMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSQuotedMessage.h; sourceTree = "<group>"; };
C33FDADC255A580400E217F9 /* NSObject+Casting.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSObject+Casting.h"; sourceTree = "<group>"; };
C33FDADD255A580400E217F9 /* TSInfoMessage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSInfoMessage.h; sourceTree = "<group>"; };
@ -1358,13 +1345,11 @@
C33FDAF1255A580500E217F9 /* OWSThumbnailService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSThumbnailService.swift; sourceTree = "<group>"; };
C33FDAF2255A580500E217F9 /* ProxiedContentDownloader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProxiedContentDownloader.swift; sourceTree = "<group>"; };
C33FDAF4255A580600E217F9 /* SSKEnvironment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SSKEnvironment.m; sourceTree = "<group>"; };
C33FDAF9255A580600E217F9 /* TSContactThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSContactThread.m; sourceTree = "<group>"; };
C33FDAFC255A580600E217F9 /* MIMETypeUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MIMETypeUtil.h; sourceTree = "<group>"; };
C33FDAFD255A580600E217F9 /* LRUCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LRUCache.swift; sourceTree = "<group>"; };
C33FDAFE255A580600E217F9 /* OWSStorage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSStorage.h; sourceTree = "<group>"; };
C33FDB01255A580700E217F9 /* AppReadiness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppReadiness.h; sourceTree = "<group>"; };
C33FDB07255A580700E217F9 /* OWSBackupFragment.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBackupFragment.m; sourceTree = "<group>"; };
C33FDB0A255A580700E217F9 /* TSGroupModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSGroupModel.h; sourceTree = "<group>"; };
C33FDB0D255A580800E217F9 /* NSArray+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSArray+OWS.m"; sourceTree = "<group>"; };
C33FDB12255A580800E217F9 /* NSString+SSK.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+SSK.h"; sourceTree = "<group>"; };
C33FDB14255A580800E217F9 /* OWSMath.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMath.h; sourceTree = "<group>"; };
@ -1403,7 +1388,6 @@
C33FDB69255A580F00E217F9 /* FeatureFlags.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FeatureFlags.swift; sourceTree = "<group>"; };
C33FDB6B255A580F00E217F9 /* SNUserDefaults.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SNUserDefaults.swift; sourceTree = "<group>"; };
C33FDB6C255A580F00E217F9 /* NSNotificationCenter+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSNotificationCenter+OWS.m"; sourceTree = "<group>"; };
C33FDB73255A581000E217F9 /* TSGroupModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGroupModel.m; sourceTree = "<group>"; };
C33FDB75255A581000E217F9 /* AppReadiness.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppReadiness.m; sourceTree = "<group>"; };
C33FDB77255A581000E217F9 /* NSUserDefaults+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSUserDefaults+OWS.m"; sourceTree = "<group>"; };
C33FDB78255A581000E217F9 /* OWSOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSOperation.m; sourceTree = "<group>"; };
@ -1424,7 +1408,6 @@
C33FDBAB255A581500E217F9 /* OWSFileSystem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSFileSystem.h; sourceTree = "<group>"; };
C33FDBB4255A581600E217F9 /* NSURLSessionDataTask+StatusCode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURLSessionDataTask+StatusCode.m"; sourceTree = "<group>"; };
C33FDBB6255A581600E217F9 /* DataSource.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DataSource.m; sourceTree = "<group>"; };
C33FDBB8255A581600E217F9 /* TSThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSThread.m; sourceTree = "<group>"; };
C33FDBBA255A581600E217F9 /* OWSPrimaryStorage+keyFromIntLong.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OWSPrimaryStorage+keyFromIntLong.h"; sourceTree = "<group>"; };
C33FDBBC255A581600E217F9 /* SSKKeychainStorage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSKKeychainStorage.swift; sourceTree = "<group>"; };
C33FDBC2255A581700E217F9 /* SSKAsserts.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SSKAsserts.h; sourceTree = "<group>"; };
@ -1439,7 +1422,6 @@
C33FDBF8255A581C00E217F9 /* NSArray+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSArray+OWS.h"; sourceTree = "<group>"; };
C33FDBF9255A581C00E217F9 /* OWSError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSError.h; sourceTree = "<group>"; };
C33FDBFE255A581C00E217F9 /* NSSet+Functional.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSSet+Functional.h"; sourceTree = "<group>"; };
C33FDC01255A581C00E217F9 /* TSGroupThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGroupThread.m; sourceTree = "<group>"; };
C33FDC02255A581D00E217F9 /* OWSPrimaryStorage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSPrimaryStorage.m; sourceTree = "<group>"; };
C33FDC03255A581D00E217F9 /* ByteParser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ByteParser.h; sourceTree = "<group>"; };
C33FDC05255A581D00E217F9 /* OWSDisappearingMessagesFinder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSDisappearingMessagesFinder.h; sourceTree = "<group>"; };
@ -1756,10 +1738,10 @@
FD09C5EB282B8F17000CE219 /* AttachmentError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AttachmentError.swift; sourceTree = "<group>"; };
FD17D79527F3E04600122BE0 /* _001_InitialSetupMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _001_InitialSetupMigration.swift; sourceTree = "<group>"; };
FD17D79827F40AB800122BE0 /* _003_YDBToGRDBMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _003_YDBToGRDBMigration.swift; sourceTree = "<group>"; };
FD17D79B27F40B2E00122BE0 /* SMKLegacyModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SMKLegacyModels.swift; sourceTree = "<group>"; };
FD17D79B27F40B2E00122BE0 /* SMKLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SMKLegacy.swift; sourceTree = "<group>"; };
FD17D79F27F40CC800122BE0 /* _001_InitialSetupMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _001_InitialSetupMigration.swift; sourceTree = "<group>"; };
FD17D7A327F40F8100122BE0 /* _003_YDBToGRDBMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _003_YDBToGRDBMigration.swift; sourceTree = "<group>"; };
FD17D7A627F41AF000122BE0 /* SSKLegacyModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSKLegacyModels.swift; sourceTree = "<group>"; };
FD17D7A627F41AF000122BE0 /* SSKLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SSKLegacy.swift; sourceTree = "<group>"; };
FD17D7A927F41BF500122BE0 /* SnodeSet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnodeSet.swift; sourceTree = "<group>"; };
FD17D7AD27F41C4300122BE0 /* SnodeReceivedMessageInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnodeReceivedMessageInfo.swift; sourceTree = "<group>"; };
FD17D7AF27F4225C00122BE0 /* Set+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Set+Utilities.swift"; sourceTree = "<group>"; };
@ -1780,7 +1762,7 @@
FD17D7E027F67BD400122BE0 /* SnodeReceivedMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SnodeReceivedMessage.swift; sourceTree = "<group>"; };
FD17D7E427F6A09900122BE0 /* Identity.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Identity.swift; sourceTree = "<group>"; };
FD17D7E627F6A16700122BE0 /* _003_YDBToGRDBMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = _003_YDBToGRDBMigration.swift; sourceTree = "<group>"; };
FD17D7E927F6A1C600122BE0 /* SUKLegacyModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SUKLegacyModels.swift; sourceTree = "<group>"; };
FD17D7E927F6A1C600122BE0 /* SUKLegacy.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SUKLegacy.swift; sourceTree = "<group>"; };
FD1C98E3282E3C5B00B76F9E /* UINavigationBar+Utilities.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationBar+Utilities.swift"; sourceTree = "<group>"; };
FD28A4F127E990E800FF65E7 /* BlockingManagerRemovalMigration.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockingManagerRemovalMigration.swift; sourceTree = "<group>"; };
FD28A4F327EA79F800FF65E7 /* BlockListUIUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlockListUIUtils.swift; sourceTree = "<group>"; };
@ -2573,22 +2555,6 @@
path = "Typing Indicators";
sourceTree = "<group>";
};
C32C59AF256DB31A003C73A2 /* Threads */ = {
isa = PBXGroup;
children = (
C32C5FD5256E0346003C73A2 /* Notification+Thread.swift */,
C33FDAB3255A580000E217F9 /* TSContactThread.h */,
C33FDAF9255A580600E217F9 /* TSContactThread.m */,
C33FDB0A255A580700E217F9 /* TSGroupModel.h */,
C33FDB73255A581000E217F9 /* TSGroupModel.m */,
C33FDA79255A57FB00E217F9 /* TSGroupThread.h */,
C33FDC01255A581C00E217F9 /* TSGroupThread.m */,
C33FDAD3255A580300E217F9 /* TSThread.h */,
C33FDBB8255A581600E217F9 /* TSThread.m */,
);
path = Threads;
sourceTree = "<group>";
};
C32C59F8256DB5A6003C73A2 /* Pollers */ = {
isa = PBXGroup;
children = (
@ -3234,7 +3200,6 @@
C3BBE07F2554CDD70050F1E3 /* Storage.swift */,
C32C5BCB256DC818003C73A2 /* Database */,
C300A5BB2554AFFB00555489 /* Messages */,
C32C59AF256DB31A003C73A2 /* Threads */,
C300A5F02554B08500555489 /* Sending & Receiving */,
C352A2F325574B3300338F3E /* Jobs */,
C3A7215C2558C0AC0043A11F /* File Server */,
@ -3564,7 +3529,7 @@
FD17D79A27F40ADA00122BE0 /* LegacyDatabase */ = {
isa = PBXGroup;
children = (
FD17D79B27F40B2E00122BE0 /* SMKLegacyModels.swift */,
FD17D79B27F40B2E00122BE0 /* SMKLegacy.swift */,
);
path = LegacyDatabase;
sourceTree = "<group>";
@ -3593,7 +3558,7 @@
FD17D7A527F41ADE00122BE0 /* LegacyDatabase */ = {
isa = PBXGroup;
children = (
FD17D7A627F41AF000122BE0 /* SSKLegacyModels.swift */,
FD17D7A627F41AF000122BE0 /* SSKLegacy.swift */,
);
path = LegacyDatabase;
sourceTree = "<group>";
@ -3684,7 +3649,7 @@
FD17D7E827F6A1B800122BE0 /* LegacyDatabase */ = {
isa = PBXGroup;
children = (
FD17D7E927F6A1C600122BE0 /* SUKLegacyModels.swift */,
FD17D7E927F6A1C600122BE0 /* SUKLegacy.swift */,
);
path = LegacyDatabase;
sourceTree = "<group>";
@ -3860,18 +3825,14 @@
C32C5EE5256DF506003C73A2 /* YapDatabaseConnection+OWS.h in Headers */,
C32C5AAF256DBE8F003C73A2 /* TSMessage.h in Headers */,
C32C5B8D256DC565003C73A2 /* SSKEnvironment.h in Headers */,
C32C59C6256DB41F003C73A2 /* TSGroupThread.h in Headers */,
C3C2A6F425539DE700C340D1 /* SessionMessagingKit.h in Headers */,
C32C59C2256DB41F003C73A2 /* TSContactThread.h in Headers */,
C32C5B2D256DC1A1003C73A2 /* TSQuotedMessage.h in Headers */,
C32C59C5256DB41F003C73A2 /* TSGroupModel.h in Headers */,
C32C5C46256DCBB2003C73A2 /* AppReadiness.h in Headers */,
C3D9E487256775D20040E4F3 /* TSAttachmentStream.h in Headers */,
B8856CB1256F0F47001CE70E /* OWSBackupFragment.h in Headers */,
C3A3A122256E1A97004D228D /* OWSDisappearingMessagesFinder.h in Headers */,
C3A3A12B256E1AD5004D228D /* TSDatabaseSecondaryIndexes.h in Headers */,
C32C5FC4256E0209003C73A2 /* OWSBackgroundTask.h in Headers */,
C32C59C0256DB41F003C73A2 /* TSThread.h in Headers */,
C32C5AB3256DBE8F003C73A2 /* TSInteraction.h in Headers */,
C3D9E486256775D20040E4F3 /* TSAttachmentPointer.h in Headers */,
C32C5EF7256DF567003C73A2 /* TSDatabaseView.h in Headers */,
@ -4716,7 +4677,7 @@
C3C2A5DE2553860B00C340D1 /* String+Trimming.swift in Sources */,
C3C2A5DB2553860B00C340D1 /* Promise+Hashing.swift in Sources */,
C3C2A5E42553860B00C340D1 /* Data+Utilities.swift in Sources */,
FD17D7A727F41AF000122BE0 /* SSKLegacyModels.swift in Sources */,
FD17D7A727F41AF000122BE0 /* SSKLegacy.swift in Sources */,
C3C2A5C2255385EE00C340D1 /* Configuration.swift in Sources */,
FD17D7D827F658E200122BE0 /* SSKDestination.swift in Sources */,
FD6A7A6D2818C61500035AC1 /* _002_SetupStandardJobs.swift in Sources */,
@ -4742,7 +4703,7 @@
C3D9E39B256763C20040E4F3 /* AppContext.m in Sources */,
C3BBE0A82554D4DE0050F1E3 /* JSON.swift in Sources */,
FD17D7C127F5200100122BE0 /* TypedTableDefinition.swift in Sources */,
FD17D7EA27F6A1C600122BE0 /* SUKLegacyModels.swift in Sources */,
FD17D7EA27F6A1C600122BE0 /* SUKLegacy.swift in Sources */,
FDA8EB10280F8238002B68E5 /* Codable+Utilities.swift in Sources */,
C352A36D2557858E00338F3E /* NSTimer+Proxying.m in Sources */,
FD09797B27FBB25900936362 /* Updatable.swift in Sources */,
@ -4862,7 +4823,6 @@
FD09798927FD1C5A00936362 /* OpenGroup.swift in Sources */,
C32C5CA4256DD1DC003C73A2 /* TSAccountManager.m in Sources */,
C3BBE0B52554F0E10050F1E3 /* ProofOfWork.swift in Sources */,
C32C59C1256DB41F003C73A2 /* TSGroupThread.m in Sources */,
C3A3A08F256E1728004D228D /* FullTextSearchFinder.swift in Sources */,
FDF0B7472804F0CE004C14C5 /* DisappearingMessagesJob.swift in Sources */,
B8856D1A256F114D001CE70E /* ProximityMonitoringManager.swift in Sources */,
@ -4883,7 +4843,6 @@
FD09798727FD1B7800936362 /* GroupMember.swift in Sources */,
FD09799127FD499200936362 /* BoxKeyPair+Utilities.swift in Sources */,
FDF0B7552807C4BB004C14C5 /* SSKEnvironment.swift in Sources */,
C32C59C3256DB41F003C73A2 /* TSGroupModel.m in Sources */,
B8856ECE256F1E58001CE70E /* OWSPreferences.m in Sources */,
FD09C5EC282B8F18000CE219 /* AttachmentError.swift in Sources */,
FD17D79927F40AB800122BE0 /* _003_YDBToGRDBMigration.swift in Sources */,
@ -4966,17 +4925,14 @@
C352A35B2557824E00338F3E /* AttachmentUploadJob.swift in Sources */,
FD09797027FA6FF300936362 /* Profile.swift in Sources */,
C32C5AAE256DBE8F003C73A2 /* TSInteraction.m in Sources */,
C32C5FD6256E0346003C73A2 /* Notification+Thread.swift in Sources */,
FD09798B27FD1CFE00936362 /* Capability.swift in Sources */,
C3BBE0C72554F1570050F1E3 /* FixedWidthInteger+BigEndian.swift in Sources */,
C32C5C88256DD0D2003C73A2 /* Storage+Messaging.swift in Sources */,
FD17D79C27F40B2E00122BE0 /* SMKLegacyModels.swift in Sources */,
C32C59C7256DB41F003C73A2 /* TSThread.m in Sources */,
FD17D79C27F40B2E00122BE0 /* SMKLegacy.swift in Sources */,
C300A5B22554AF9800555489 /* VisibleMessage+Profile.swift in Sources */,
FD09798127FCFEE800936362 /* SessionThread.swift in Sources */,
C32C5A75256DBBCF003C73A2 /* TSAttachmentPointer+Conversion.swift in Sources */,
C32C5EBA256DE130003C73A2 /* OWSQuotedReplyModel.m in Sources */,
C32C59C4256DB41F003C73A2 /* TSContactThread.m in Sources */,
FD09C5EA282A1BB2000CE219 /* ThreadTypingIndicator.swift in Sources */,
FDF0B75E280AAF35004C14C5 /* Preferences.swift in Sources */,
C32C5AB0256DBE8F003C73A2 /* TSOutgoingMessage.m in Sources */,

View File

@ -13,9 +13,7 @@
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
#import <SignalUtilitiesKit/UIUtil.h>
#import <SessionMessagingKit/OWSPrimaryStorage.h>
#import <SessionMessagingKit/TSGroupThread.h>
#import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SessionMessagingKit/TSThread.h>
@import ContactsUI;
@import PromiseKit;

View File

@ -9,7 +9,6 @@ NS_ASSUME_NONNULL_BEGIN
@protocol OWSConversationSettingsViewDelegate <NSObject>
- (void)groupWasUpdated:(TSGroupModel *)groupModel;
- (void)conversationSettingsDidRequestConversationSearch:(OWSConversationSettingsViewController *)conversationSettingsViewController;
- (void)popAllConversationSettingsViewsWithCompletion:(void (^_Nullable)(void))completionBlock;

View File

@ -395,8 +395,11 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD
PushNotificationAPI.unregister(data).retainUntilComplete()
}
ThreadUtil.deleteAllContent()
Identity.clearAll()
GRDBStorage.shared.write { db in
_ = try SessionThread.deleteAll(db)
_ = try Identity.deleteAll(db)
}
SnodeAPI.clearSnodePool()
stopPollers()

View File

@ -62,12 +62,9 @@
#import <SessionMessagingKit/TSAttachment.h>
#import <SessionMessagingKit/TSAttachmentPointer.h>
#import <SessionMessagingKit/TSAttachmentStream.h>
#import <SessionMessagingKit/TSContactThread.h>
#import <SessionMessagingKit/TSGroupThread.h>
#import <SessionMessagingKit/TSIncomingMessage.h>
#import <SessionMessagingKit/TSInfoMessage.h>
#import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SessionMessagingKit/TSThread.h>
#import <SessionUtilitiesKit/LKGroupUtilities.h>
#import <SessionUtilitiesKit/UIImage+OWS.h>
#import <YYImage/YYImage.h>

View File

@ -212,7 +212,7 @@ static NSString *const kSealedSenderInfoURL = @"https://signal.org/blog/sealed-s
- (void)deleteThreadsAndMessages
{
[ThreadUtil deleteAllContent];
[SMKThread deleteAll];
}
- (void)didToggleScreenSecuritySwitch:(UISwitch *)sender

View File

@ -8,7 +8,6 @@ NS_ASSUME_NONNULL_BEGIN
@class AvatarViewHelper;
@class OWSContactsManager;
@class TSThread;
@protocol AvatarViewHelperDelegate <NSObject>

View File

@ -9,9 +9,6 @@
#import <SignalUtilitiesKit/UIUtil.h>
#import <SessionMessagingKit/TSGroupModel.h>
#import <SessionMessagingKit/TSGroupThread.h>
#import <SessionMessagingKit/TSThread.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN

View File

@ -7,9 +7,7 @@ import YapDatabase
import SignalCoreKit
import SessionUtilitiesKit
public typealias SMKLegacy = Legacy
public enum Legacy {
public enum SMKLegacy {
// MARK: - Collections and Keys
internal static let contactThreadPrefix = "c"
@ -18,7 +16,7 @@ public enum Legacy {
internal static let closedGroupKeyPairPrefix = "SNClosedGroupEncryptionKeyPairCollection-"
public static let contactCollection = "LokiContactCollection"
internal static let threadCollection = "TSThread"
public static let threadCollection = "TSThread"
internal static let disappearingMessagesCollection = "OWSDisappearingMessagesConfiguration"
internal static let closedGroupPublicKeyCollection = "SNClosedGroupPublicKeyCollection"
@ -32,6 +30,7 @@ public enum Legacy {
internal static let openGroupLastDeletionServerIDCollection = "SNLastDeletionServerIDCollection"
internal static let openGroupServerIdToUniqueIdLookupCollection = "SNOpenGroupServerIdToUniqueIdLookup"
public static let messageDatabaseViewExtensionName = "TSMessageDatabaseViewExtensionName_Monotonic"
internal static let interactionCollection = "TSInteraction"
internal static let attachmentsCollection = "TSAttachements" // Note: This is how it was previously spelt
internal static let outgoingReadReceiptManagerCollection = "kOutgoingReadReceiptManagerCollection"
@ -54,6 +53,7 @@ public enum Legacy {
internal static let preferencesKeyNotificationPreviewType = "preferencesKeyNotificationPreviewType"
internal static let preferencesKeyNotificationSoundInForeground = "NotificationSoundInForeground"
internal static let preferencesKeyHasSavedThreadKey = "hasSavedThread"
internal static let preferencesKeyHasSentAMessageKey = "User has sent a message"
internal static let readReceiptManagerCollection = "OWSReadReceiptManagerCollection"
internal static let readReceiptManagerAreReadReceiptsEnabled = "areReadReceiptsEnabled"
@ -74,18 +74,18 @@ public enum Legacy {
@objc(SNContact)
public class _Contact: NSObject, NSCoding {
@objc public let sessionID: String
@objc public var profilePictureURL: String?
@objc public var profilePictureFileName: String?
@objc public var profileEncryptionKey: OWSAES256Key?
@objc public var threadID: String?
@objc public var isTrusted = false
@objc public var isApproved = false
@objc public var isBlocked = false
@objc public var didApproveMe = false
@objc public var hasBeenBlocked = false
@objc public var name: String?
@objc public var nickname: String?
public let sessionID: String
public var profilePictureURL: String?
public var profilePictureFileName: String?
public var profileEncryptionKey: OWSAES256Key?
public var threadID: String?
public var isTrusted = false
public var isApproved = false
public var isBlocked = false
public var didApproveMe = false
public var hasBeenBlocked = false
public var name: String?
public var nickname: String?
// MARK: Coding
@ -114,9 +114,9 @@ public enum Legacy {
@objc(OWSDisappearingMessagesConfiguration)
internal class _DisappearingMessagesConfiguration: MTLModel {
@objc public let uniqueId: String
@objc public var isEnabled: Bool
@objc public var durationSeconds: UInt32
public let uniqueId: String
public var isEnabled: Bool
public var durationSeconds: UInt32
// MARK: - NSCoder
@ -829,27 +829,139 @@ public enum Legacy {
)
}
}
// MARK: - Threads
@objc(TSThread)
public class _Thread: NSObject, NSCoding {
public var uniqueId: String
public var creationDate: Date
public var shouldBeVisible: Bool
public var isPinned: Bool
public var mutedUntilDate: Date?
public var messageDraft: String?
// MARK: - Convenience
open var isClosedGroup: Bool { false }
open var isOpenGroup: Bool { false }
// MARK: - NSCoder
public required init(coder: NSCoder) {
self.uniqueId = coder.decodeObject(forKey: "uniqueId") as! String
self.creationDate = coder.decodeObject(forKey: "creationDate") as! Date
// Legacy version of 'shouldBeVisible'
if let hasEverHadMessage: Bool = (coder.decodeObject(forKey: "hasEverHadMessage") as? NSNumber)?.boolValue {
self.shouldBeVisible = hasEverHadMessage
}
else {
self.shouldBeVisible = ((coder.decodeObject(forKey: "shouldBeVisible") as? NSNumber)?
.boolValue)
.defaulting(to: false)
}
self.isPinned = ((coder.decodeObject(forKey: "isPinned") as? NSNumber)?
.boolValue)
.defaulting(to: false)
self.mutedUntilDate = coder.decodeObject(forKey: "mutedUntilDate") as? Date
self.messageDraft = coder.decodeObject(forKey: "messageDraft") as? String // TODO: Test this
}
public func encode(with coder: NSCoder) {
fatalError("encode(with:) should never be called for legacy types")
}
}
@objc(TSContactThread)
public class _ContactThread: _Thread {
// MARK: - NSCoder
public required init(coder: NSCoder) {
super.init(coder: coder)
}
// MARK: - Functions
internal static func threadId(from sessionId: String) -> String {
return "\(SMKLegacy.contactThreadPrefix)\(sessionId)"
}
public static func contactSessionId(fromThreadId threadId: String) -> String {
return String(threadId.substring(from: SMKLegacy.contactThreadPrefix.count))
}
}
@objc(TSGroupThread)
public class _GroupThread: _Thread {
public var groupModel: _GroupModel
public var isOnlyNotifyingForMentions: Bool
// MARK: - Convenience
public override var isClosedGroup: Bool { (groupModel.groupType == .closedGroup) }
public override var isOpenGroup: Bool { (groupModel.groupType == .openGroup) }
// MARK: - NSCoder
public required init(coder: NSCoder) {
self.groupModel = coder.decodeObject(forKey: "groupModel") as! _GroupModel
self.isOnlyNotifyingForMentions = ((coder.decodeObject(forKey: "isOnlyNotifyingForMentions") as? NSNumber)?
.boolValue)
.defaulting(to: false)
super.init(coder: coder)
}
}
@objc(TSGroupModel)
public class _GroupModel: NSObject, NSCoding {
public enum _GroupType: Int {
case closedGroup
case openGroup
}
public var groupId: Data
public var groupType: _GroupType
public var groupName: String?
public var groupMemberIds: [String]
public var groupAdminIds: [String]
// MARK: - NSCoder
public required init(coder: NSCoder) {
self.groupId = coder.decodeObject(forKey: "groupId") as! Data
self.groupType = _GroupType(rawValue: coder.decodeObject(forKey: "groupType") as! Int)!
self.groupName = ((coder.decodeObject(forKey: "groupName") as? String) ?? "Group")
self.groupMemberIds = coder.decodeObject(forKey: "groupMemberIds") as! [String]
self.groupAdminIds = coder.decodeObject(forKey: "groupAdminIds") as! [String]
}
public func encode(with coder: NSCoder) {
fatalError("encode(with:) should never be called for legacy types")
}
}
// MARK: - Attachments
@objc(TSAttachment)
internal class _Attachment: NSObject, NSCoding {
@objc(TSAttachmentType)
public enum _AttachmentType: Int {
case `default`
case voiceMessage
}
@objc public var serverId: UInt64
@objc public var encryptionKey: Data?
@objc public var contentType: String
@objc public var isDownloaded: Bool
@objc public var attachmentType: _AttachmentType
@objc public var downloadURL: String
@objc public var byteCount: UInt32
@objc public var sourceFilename: String?
@objc public var caption: String?
@objc public var albumMessageId: String?
public var serverId: UInt64
public var encryptionKey: Data?
public var contentType: String
public var isDownloaded: Bool
public var attachmentType: _AttachmentType
public var downloadURL: String
public var byteCount: UInt32
public var sourceFilename: String?
public var caption: String?
public var albumMessageId: String?
public var isImage: Bool { return MIMETypeUtil.isImage(contentType) }
public var isVideo: Bool { return MIMETypeUtil.isVideo(contentType) }
@ -879,18 +991,17 @@ public enum Legacy {
@objc(TSAttachmentPointer)
internal class _AttachmentPointer: _Attachment {
@objc(TSAttachmentPointerState)
public enum _State: Int {
case enqueued
case downloading
case failed
}
@objc public var state: _State
@objc public var mostRecentFailureLocalizedText: String?
@objc public var digest: Data?
@objc public var mediaSize: CGSize
@objc public var lazyRestoreFragmentId: String?
public var state: _State
public var mostRecentFailureLocalizedText: String?
public var digest: Data?
public var mediaSize: CGSize
public var lazyRestoreFragmentId: String?
// MARK: - NSCoder
@ -913,15 +1024,15 @@ public enum Legacy {
@objc(TSAttachmentStream)
internal class _AttachmentStream: _Attachment {
@objc public var digest: Data?
@objc public var isUploaded: Bool
@objc public var creationTimestamp: Date
@objc public var localRelativeFilePath: String?
@objc public var cachedImageWidth: NSNumber?
@objc public var cachedImageHeight: NSNumber?
@objc public var cachedAudioDurationSeconds: NSNumber?
@objc public var isValidImageCached: NSNumber?
@objc public var isValidVideoCached: NSNumber?
public var digest: Data?
public var isUploaded: Bool
public var creationTimestamp: Date
public var localRelativeFilePath: String?
public var cachedImageWidth: NSNumber?
public var cachedImageHeight: NSNumber?
public var cachedAudioDurationSeconds: NSNumber?
public var isValidImageCached: NSNumber?
public var isValidVideoCached: NSNumber?
public var isValidImage: Bool { return (isValidImageCached?.boolValue == true) }
public var isValidVideo: Bool { return (isValidVideoCached?.boolValue == true) }

View File

@ -16,18 +16,18 @@ enum _003_YDBToGRDBMigration: Migration {
// MARK: - Process Contacts, Threads & Interactions
print("RAWR [\(Date().timeIntervalSince1970)] - SessionMessagingKit migration - Start")
var shouldFailMigration: Bool = false
var contacts: Set<Legacy._Contact> = []
var contacts: Set<SMKLegacy._Contact> = []
var validProfileIds: Set<String> = []
var contactThreadIds: Set<String> = []
var legacyThreadIdToIdMap: [String: String] = [:]
var threads: Set<TSThread> = []
var disappearingMessagesConfiguration: [String: Legacy._DisappearingMessagesConfiguration] = [:]
var legacyThreads: Set<SMKLegacy._Thread> = []
var disappearingMessagesConfiguration: [String: SMKLegacy._DisappearingMessagesConfiguration] = [:]
var closedGroupKeys: [String: [TimeInterval: SUKLegacy.KeyPair]] = [:]
var closedGroupName: [String: String] = [:]
var closedGroupFormation: [String: UInt64] = [:]
var closedGroupModel: [String: TSGroupModel] = [:]
var closedGroupModel: [String: SMKLegacy._GroupModel] = [:]
var closedGroupZombieMemberIds: [String: Set<String>] = [:]
var openGroupInfo: [String: OpenGroupV2] = [:]
@ -38,37 +38,53 @@ enum _003_YDBToGRDBMigration: Migration {
// var openGroupServerToUniqueIdLookup: [String: [String]] = [:] // TODO: Not needed????
var interactions: [String: [TSInteraction]] = [:]
var attachments: [String: Legacy._Attachment] = [:]
var attachments: [String: SMKLegacy._Attachment] = [:]
var processedAttachmentIds: Set<String> = []
var outgoingReadReceiptsTimestampsMs: [String: Set<Int64>] = [:]
var receivedMessageTimestamps: Set<UInt64> = []
// Map the Legacy types for the NSKeyedUnarchiver
NSKeyedUnarchiver.setClass(
Legacy._Contact.self,
SMKLegacy._Thread.self,
forClassName: "TSThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._ContactThread.self,
forClassName: "TSContactThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._GroupThread.self,
forClassName: "TSGroupThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._GroupModel.self,
forClassName: "TSGroupModel"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._Contact.self,
forClassName: "SNContact"
)
NSKeyedUnarchiver.setClass(
Legacy._Attachment.self,
SMKLegacy._Attachment.self,
forClassName: "TSAttachment"
)
NSKeyedUnarchiver.setClass(
Legacy._AttachmentStream.self,
SMKLegacy._AttachmentStream.self,
forClassName: "TSAttachmentStream"
)
NSKeyedUnarchiver.setClass(
Legacy._AttachmentPointer.self,
SMKLegacy._AttachmentPointer.self,
forClassName: "TSAttachmentPointer"
)
NSKeyedUnarchiver.setClass(
Legacy._DisappearingConfigurationUpdateInfoMessage.self,
SMKLegacy._DisappearingConfigurationUpdateInfoMessage.self,
forClassName: "OWSDisappearingConfigurationUpdateInfoMessage"
)
Storage.read { transaction in
// Process the Contacts
transaction.enumerateRows(inCollection: Legacy.contactCollection) { _, object, _, _ in
guard let contact = object as? Legacy._Contact else { return }
transaction.enumerateRows(inCollection: SMKLegacy.contactCollection) { _, object, _, _ in
guard let contact = object as? SMKLegacy._Contact else { return }
contacts.insert(contact)
validProfileIds.insert(contact.sessionID)
}
@ -76,26 +92,27 @@ enum _003_YDBToGRDBMigration: Migration {
print("RAWR [\(Date().timeIntervalSince1970)] - Process threads - Start")
// Process the threads
transaction.enumerateKeysAndObjects(inCollection: Legacy.threadCollection) { key, object, _ in
guard let thread: TSThread = object as? TSThread else { return }
guard let threadId: String = thread.uniqueId else { return }
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.threadCollection) { key, object, _ in
guard let thread: SMKLegacy._Thread = object as? SMKLegacy._Thread else { return }
threads.insert(thread)
legacyThreads.insert(thread)
// Want to exclude threads which aren't visible (ie. threads which we started
// but the user never ended up sending a message)
if key.starts(with: Legacy.contactThreadPrefix) && thread.shouldBeVisible {
if key.starts(with: SMKLegacy.contactThreadPrefix) && thread.shouldBeVisible {
contactThreadIds.insert(key)
}
// Get the disappearing messages config
disappearingMessagesConfiguration[threadId] = transaction
.object(forKey: threadId, inCollection: Legacy.disappearingMessagesCollection)
.asType(Legacy._DisappearingMessagesConfiguration.self)
disappearingMessagesConfiguration[thread.uniqueId] = transaction
.object(forKey: thread.uniqueId, inCollection: SMKLegacy.disappearingMessagesCollection)
.asType(SMKLegacy._DisappearingMessagesConfiguration.self)
// Process group-specific info
guard let groupThread: TSGroupThread = thread as? TSGroupThread else {
legacyThreadIdToIdMap[threadId] = threadId.substring(from: Legacy.contactThreadPrefix.count)
guard let groupThread: SMKLegacy._GroupThread = thread as? SMKLegacy._GroupThread else {
legacyThreadIdToIdMap[thread.uniqueId] = thread.uniqueId.substring(
from: SMKLegacy.contactThreadPrefix.count
)
return
}
@ -104,7 +121,7 @@ enum _003_YDBToGRDBMigration: Migration {
// really need the unnecessary complexity so process the key and extract
// the publicKey from it
// `g{base64String(Data(__textsecure_group__!{publicKey}))}
let base64GroupId: String = String(threadId.suffix(from: threadId.index(after: threadId.startIndex)))
let base64GroupId: String = String(thread.uniqueId.suffix(from: thread.uniqueId.index(after: thread.uniqueId.startIndex)))
guard
let groupIdData: Data = Data(base64Encoded: base64GroupId),
let groupId: String = String(data: groupIdData, encoding: .utf8),
@ -115,18 +132,18 @@ enum _003_YDBToGRDBMigration: Migration {
return
}
legacyThreadIdToIdMap[threadId] = publicKey
closedGroupName[threadId] = groupThread.name(with: transaction)
closedGroupModel[threadId] = groupThread.groupModel
closedGroupFormation[threadId] = ((transaction.object(forKey: publicKey, inCollection: Legacy.closedGroupFormationTimestampCollection) as? UInt64) ?? 0)
closedGroupZombieMemberIds[threadId] = transaction.object(
legacyThreadIdToIdMap[thread.uniqueId] = publicKey
closedGroupName[thread.uniqueId] = groupThread.groupModel.groupName
closedGroupModel[thread.uniqueId] = groupThread.groupModel
closedGroupFormation[thread.uniqueId] = ((transaction.object(forKey: publicKey, inCollection: SMKLegacy.closedGroupFormationTimestampCollection) as? UInt64) ?? 0)
closedGroupZombieMemberIds[thread.uniqueId] = transaction.object(
forKey: publicKey,
inCollection: Legacy.closedGroupZombieMembersCollection
inCollection: SMKLegacy.closedGroupZombieMembersCollection
) as? Set<String>
// Note: If the user is no longer in a closed group then the group will still exist but the user
// won't have the closed group public key anymore
let keyCollection: String = "\(Legacy.closedGroupKeyPairPrefix)\(publicKey)"
let keyCollection: String = "\(SMKLegacy.closedGroupKeyPairPrefix)\(publicKey)"
transaction.enumerateKeysAndObjects(inCollection: keyCollection) { key, object, _ in
guard
@ -134,33 +151,33 @@ enum _003_YDBToGRDBMigration: Migration {
let keyPair: SUKLegacy.KeyPair = object as? SUKLegacy.KeyPair
else { return }
closedGroupKeys[threadId] = (closedGroupKeys[threadId] ?? [:])
closedGroupKeys[thread.uniqueId] = (closedGroupKeys[thread.uniqueId] ?? [:])
.setting(timestamp, keyPair)
}
}
else if groupThread.isOpenGroup {
guard let openGroup: OpenGroupV2 = transaction.object(forKey: threadId, inCollection: Legacy.openGroupCollection) as? OpenGroupV2 else {
guard let openGroup: OpenGroupV2 = transaction.object(forKey: thread.uniqueId, inCollection: SMKLegacy.openGroupCollection) as? OpenGroupV2 else {
SNLog("[Migration Error] Unable to find open group info")
shouldFailMigration = true
return
}
legacyThreadIdToIdMap[threadId] = OpenGroup.idFor(
legacyThreadIdToIdMap[thread.uniqueId] = OpenGroup.idFor(
room: openGroup.room,
server: openGroup.server
)
openGroupInfo[threadId] = openGroup
openGroupUserCount[threadId] = ((transaction.object(forKey: openGroup.id, inCollection: Legacy.openGroupUserCountCollection) as? Int) ?? 0)
openGroupImage[threadId] = transaction.object(forKey: openGroup.id, inCollection: Legacy.openGroupImageCollection) as? Data
openGroupLastMessageServerId[threadId] = transaction.object(forKey: openGroup.id, inCollection: Legacy.openGroupLastMessageServerIDCollection) as? Int64
openGroupLastDeletionServerId[threadId] = transaction.object(forKey: openGroup.id, inCollection: Legacy.openGroupLastDeletionServerIDCollection) as? Int64
openGroupInfo[thread.uniqueId] = openGroup
openGroupUserCount[thread.uniqueId] = ((transaction.object(forKey: openGroup.id, inCollection: SMKLegacy.openGroupUserCountCollection) as? Int) ?? 0)
openGroupImage[thread.uniqueId] = transaction.object(forKey: openGroup.id, inCollection: SMKLegacy.openGroupImageCollection) as? Data
openGroupLastMessageServerId[thread.uniqueId] = transaction.object(forKey: openGroup.id, inCollection: SMKLegacy.openGroupLastMessageServerIDCollection) as? Int64
openGroupLastDeletionServerId[thread.uniqueId] = transaction.object(forKey: openGroup.id, inCollection: SMKLegacy.openGroupLastDeletionServerIDCollection) as? Int64
}
}
print("RAWR [\(Date().timeIntervalSince1970)] - Process threads - End")
// Process interactions
print("RAWR [\(Date().timeIntervalSince1970)] - Process interactions - Start")
transaction.enumerateKeysAndObjects(inCollection: Legacy.interactionCollection) { _, object, _ in
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.interactionCollection) { _, object, _ in
guard let interaction: TSInteraction = object as? TSInteraction else {
SNLog("[Migration Error] Unable to process interaction")
shouldFailMigration = true
@ -174,8 +191,8 @@ enum _003_YDBToGRDBMigration: Migration {
// Process attachments
print("RAWR [\(Date().timeIntervalSince1970)] - Process attachments - Start")
transaction.enumerateKeysAndObjects(inCollection: Legacy.attachmentsCollection) { key, object, _ in
guard let attachment: Legacy._Attachment = object as? Legacy._Attachment else {
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.attachmentsCollection) { key, object, _ in
guard let attachment: SMKLegacy._Attachment = object as? SMKLegacy._Attachment else {
SNLog("[Migration Error] Unable to process attachment")
shouldFailMigration = true
return
@ -186,7 +203,7 @@ enum _003_YDBToGRDBMigration: Migration {
print("RAWR [\(Date().timeIntervalSince1970)] - Process attachments - End")
// Process read receipts
transaction.enumerateKeysAndObjects(inCollection: Legacy.outgoingReadReceiptManagerCollection) { key, object, _ in
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.outgoingReadReceiptManagerCollection) { key, object, _ in
guard let timestampsMs: Set<Int64> = object as? Set<Int64> else { return }
outgoingReadReceiptsTimestampsMs[key] = (outgoingReadReceiptsTimestampsMs[key] ?? Set())
@ -196,8 +213,8 @@ enum _003_YDBToGRDBMigration: Migration {
receivedMessageTimestamps = receivedMessageTimestamps.inserting(
contentsOf: transaction
.object(
forKey: Legacy.receivedMessageTimestampsKey,
inCollection: Legacy.receivedMessageTimestampsCollection
forKey: SMKLegacy.receivedMessageTimestampsKey,
inCollection: SMKLegacy.receivedMessageTimestampsCollection
)
.asType([UInt64].self)
.defaulting(to: [])
@ -217,19 +234,18 @@ enum _003_YDBToGRDBMigration: Migration {
try autoreleasepool {
let currentUserPublicKey: String = getUserHexEncodedPublicKey(db)
try contacts.forEach { contact in
let isCurrentUser: Bool = (contact.sessionID == currentUserPublicKey)
let contactThreadId: String = TSContactThread.threadID(fromContactSessionID: contact.sessionID)
try contacts.forEach { legacyContact in
let isCurrentUser: Bool = (legacyContact.sessionID == currentUserPublicKey)
let contactThreadId: String = SMKLegacy._ContactThread.threadId(from: legacyContact.sessionID)
// TODO: Contact 'hasOne' profile???
// Create the "Profile" for the legacy contact
try Profile(
id: contact.sessionID,
name: (contact.name ?? contact.sessionID),
nickname: contact.nickname,
profilePictureUrl: contact.profilePictureURL,
profilePictureFileName: contact.profilePictureFileName,
profileEncryptionKey: contact.profileEncryptionKey
id: legacyContact.sessionID,
name: (legacyContact.name ?? legacyContact.sessionID),
nickname: legacyContact.nickname,
profilePictureUrl: legacyContact.profilePictureURL,
profilePictureFileName: legacyContact.profilePictureFileName,
profileEncryptionKey: legacyContact.profileEncryptionKey
).insert(db)
// Determine if this contact is a "real" contact (don't want to create contacts for
@ -237,19 +253,19 @@ enum _003_YDBToGRDBMigration: Migration {
if
isCurrentUser ||
contactThreadIds.contains(contactThreadId) ||
contact.isApproved ||
contact.didApproveMe ||
contact.isBlocked ||
contact.hasBeenBlocked {
legacyContact.isApproved ||
legacyContact.didApproveMe ||
legacyContact.isBlocked ||
legacyContact.hasBeenBlocked {
// Create the contact
// TODO: Closed group admins???
try Contact(
id: contact.sessionID,
isTrusted: (isCurrentUser || contact.isTrusted),
isApproved: (isCurrentUser || contact.isApproved),
isBlocked: (!isCurrentUser && contact.isBlocked),
didApproveMe: (isCurrentUser || contact.didApproveMe),
hasBeenBlocked: (!isCurrentUser && (contact.hasBeenBlocked || contact.isBlocked))
id: legacyContact.sessionID,
isTrusted: (isCurrentUser || legacyContact.isTrusted),
isApproved: (isCurrentUser || legacyContact.isApproved),
isBlocked: (!isCurrentUser && legacyContact.isBlocked),
didApproveMe: (isCurrentUser || legacyContact.didApproveMe),
hasBeenBlocked: (!isCurrentUser && (legacyContact.hasBeenBlocked || legacyContact.isBlocked))
).insert(db)
}
}
@ -296,11 +312,8 @@ enum _003_YDBToGRDBMigration: Migration {
}
// Sort by id just so we can make the migration process more determinstic
try threads.sorted(by: { lhs, rhs in (lhs.uniqueId ?? "") < (rhs.uniqueId ?? "") }).forEach { thread in
guard
let legacyThreadId: String = thread.uniqueId,
let threadId: String = legacyThreadIdToIdMap[legacyThreadId]
else {
try legacyThreads.sorted(by: { lhs, rhs in lhs.uniqueId < rhs.uniqueId }).forEach { legacyThread in
guard let threadId: String = legacyThreadIdToIdMap[legacyThread.uniqueId] else {
SNLog("[Migration Error] Unable to migrate thread with no id mapping")
throw GRDBStorageError.migrationFailed
}
@ -308,8 +321,8 @@ enum _003_YDBToGRDBMigration: Migration {
let threadVariant: SessionThread.Variant
let onlyNotifyForMentions: Bool
switch thread {
case let groupThread as TSGroupThread:
switch legacyThread {
case let groupThread as SMKLegacy._GroupThread:
threadVariant = (groupThread.isOpenGroup ? .openGroup : .closedGroup)
onlyNotifyForMentions = groupThread.isOnlyNotifyingForMentions
@ -322,19 +335,19 @@ enum _003_YDBToGRDBMigration: Migration {
try SessionThread(
id: threadId,
variant: threadVariant,
creationDateTimestamp: thread.creationDate.timeIntervalSince1970,
shouldBeVisible: thread.shouldBeVisible,
isPinned: thread.isPinned,
messageDraft: ((thread.messageDraft ?? "").isEmpty ?
creationDateTimestamp: legacyThread.creationDate.timeIntervalSince1970,
shouldBeVisible: legacyThread.shouldBeVisible,
isPinned: legacyThread.isPinned,
messageDraft: ((legacyThread.messageDraft ?? "").isEmpty ?
nil :
thread.messageDraft
legacyThread.messageDraft
),
mutedUntilTimestamp: thread.mutedUntilDate?.timeIntervalSince1970,
mutedUntilTimestamp: legacyThread.mutedUntilDate?.timeIntervalSince1970,
onlyNotifyForMentions: onlyNotifyForMentions
).insert(db)
// Disappearing Messages Configuration
if let config: Legacy._DisappearingMessagesConfiguration = disappearingMessagesConfiguration[threadId] {
if let config: SMKLegacy._DisappearingMessagesConfiguration = disappearingMessagesConfiguration[threadId] {
try DisappearingMessagesConfiguration(
threadId: threadId,
isEnabled: config.isEnabled,
@ -348,11 +361,11 @@ enum _003_YDBToGRDBMigration: Migration {
}
// Closed Groups
if (thread as? TSGroupThread)?.isClosedGroup == true {
if legacyThread.isClosedGroup {
guard
let name: String = closedGroupName[legacyThreadId],
let groupModel: TSGroupModel = closedGroupModel[legacyThreadId],
let formationTimestamp: UInt64 = closedGroupFormation[legacyThreadId]
let name: String = closedGroupName[legacyThread.uniqueId],
let groupModel: SMKLegacy._GroupModel = closedGroupModel[legacyThread.uniqueId],
let formationTimestamp: UInt64 = closedGroupFormation[legacyThread.uniqueId]
else {
SNLog("[Migration Error] Closed group missing required data")
throw GRDBStorageError.migrationFailed
@ -367,7 +380,7 @@ enum _003_YDBToGRDBMigration: Migration {
// Note: If a user has left a closed group then they won't actually have any keys
// but they should still be able to browse the old messages so we do want to allow
// this case and migrate the rest of the info
try closedGroupKeys[legacyThreadId]?.forEach { timestamp, legacyKeys in
try closedGroupKeys[legacyThread.uniqueId]?.forEach { timestamp, legacyKeys in
try ClosedGroupKeyPair(
threadId: threadId,
publicKey: legacyKeys.publicKey,
@ -396,7 +409,7 @@ enum _003_YDBToGRDBMigration: Migration {
).insert(db)
}
try (closedGroupZombieMemberIds[legacyThreadId] ?? []).forEach { zombieId in
try (closedGroupZombieMemberIds[legacyThread.uniqueId] ?? []).forEach { zombieId in
try GroupMember(
groupId: threadId,
profileId: zombieId,
@ -407,8 +420,8 @@ enum _003_YDBToGRDBMigration: Migration {
}
// Open Groups
if (thread as? TSGroupThread)?.isOpenGroup == true {
guard let openGroup: OpenGroupV2 = openGroupInfo[legacyThreadId] else {
if legacyThread.isOpenGroup {
guard let openGroup: OpenGroupV2 = openGroupInfo[legacyThread.uniqueId] else {
SNLog("[Migration Error] Open group missing required data")
throw GRDBStorageError.migrationFailed
}
@ -420,15 +433,15 @@ enum _003_YDBToGRDBMigration: Migration {
name: openGroup.name,
groupDescription: nil, // TODO: Add with SOGS V4.
imageId: nil, // TODO: Add with SOGS V4.
imageData: openGroupImage[legacyThreadId],
userCount: (openGroupUserCount[legacyThreadId] ?? 0), // Will be updated next poll
imageData: openGroupImage[legacyThread.uniqueId],
userCount: (openGroupUserCount[legacyThread.uniqueId] ?? 0), // Will be updated next poll
infoUpdates: 0 // TODO: Add with SOGS V4.
).insert(db)
}
}
try autoreleasepool {
try interactions[legacyThreadId]?
try interactions[legacyThread.uniqueId]?
.sorted(by: { lhs, rhs in lhs.timestamp < rhs.timestamp }) // Maintain sort order
.forEach { legacyInteraction in
let serverHash: String?
@ -530,7 +543,7 @@ enum _003_YDBToGRDBMigration: Migration {
// a string at display time so we want to continue that behaviour
guard
infoMessage.messageType == .disappearingMessagesUpdate,
let updateMessage: Legacy._DisappearingConfigurationUpdateInfoMessage = infoMessage as? Legacy._DisappearingConfigurationUpdateInfoMessage,
let updateMessage: SMKLegacy._DisappearingConfigurationUpdateInfoMessage = infoMessage as? SMKLegacy._DisappearingConfigurationUpdateInfoMessage,
let infoMessageData: Data = try? JSONEncoder().encode(
DisappearingMessagesConfiguration.MessageInfo(
senderName: updateMessage.createdByRemoteName,
@ -713,7 +726,7 @@ enum _003_YDBToGRDBMigration: Migration {
// original interaction and re-create the attachment link before
// falling back to having no attachment in the quote
if quoteAttachmentId == nil && !quotedMessage.quotedAttachments.isEmpty {
quoteAttachmentId = interactions[legacyThreadId]?
quoteAttachmentId = interactions[legacyThread.uniqueId]?
.first(where: {
$0.timestamp == quotedMessage.timestamp &&
(
@ -827,7 +840,7 @@ enum _003_YDBToGRDBMigration: Migration {
contacts = []
contactThreadIds = []
threads = []
legacyThreads = []
disappearingMessagesConfiguration = [:]
closedGroupKeys = [:]
@ -850,137 +863,137 @@ enum _003_YDBToGRDBMigration: Migration {
print("RAWR [\(Date().timeIntervalSince1970)] - Process jobs - Start")
var notifyPushServerJobs: Set<Legacy._NotifyPNServerJob> = []
var messageReceiveJobs: Set<Legacy._MessageReceiveJob> = []
var messageSendJobs: Set<Legacy._MessageSendJob> = []
var attachmentUploadJobs: Set<Legacy._AttachmentUploadJob> = []
var attachmentDownloadJobs: Set<Legacy._AttachmentDownloadJob> = []
var notifyPushServerJobs: Set<SMKLegacy._NotifyPNServerJob> = []
var messageReceiveJobs: Set<SMKLegacy._MessageReceiveJob> = []
var messageSendJobs: Set<SMKLegacy._MessageSendJob> = []
var attachmentUploadJobs: Set<SMKLegacy._AttachmentUploadJob> = []
var attachmentDownloadJobs: Set<SMKLegacy._AttachmentDownloadJob> = []
// Map the Legacy types for the NSKeyedUnarchiver
NSKeyedUnarchiver.setClass(
Legacy._NotifyPNServerJob.self,
SMKLegacy._NotifyPNServerJob.self,
forClassName: "SessionMessagingKit.NotifyPNServerJob"
)
NSKeyedUnarchiver.setClass(
Legacy._NotifyPNServerJob._SnodeMessage.self,
SMKLegacy._NotifyPNServerJob._SnodeMessage.self,
forClassName: "SessionSnodeKit.SnodeMessage"
)
NSKeyedUnarchiver.setClass(
Legacy._MessageSendJob.self,
SMKLegacy._MessageSendJob.self,
forClassName: "SessionMessagingKit.SNMessageSendJob"
)
NSKeyedUnarchiver.setClass(
Legacy._MessageReceiveJob.self,
SMKLegacy._MessageReceiveJob.self,
forClassName: "SessionMessagingKit.MessageReceiveJob"
)
NSKeyedUnarchiver.setClass(
Legacy._AttachmentUploadJob.self,
SMKLegacy._AttachmentUploadJob.self,
forClassName: "SessionMessagingKit.AttachmentUploadJob"
)
NSKeyedUnarchiver.setClass(
Legacy._AttachmentDownloadJob.self,
SMKLegacy._AttachmentDownloadJob.self,
forClassName: "SessionMessagingKit.AttachmentDownloadJob"
)
NSKeyedUnarchiver.setClass(
Legacy._Message.self,
SMKLegacy._Message.self,
forClassName: "SNMessage"
)
NSKeyedUnarchiver.setClass(
Legacy._VisibleMessage.self,
SMKLegacy._VisibleMessage.self,
forClassName: "SNVisibleMessage"
)
NSKeyedUnarchiver.setClass(
Legacy._Quote.self,
SMKLegacy._Quote.self,
forClassName: "SNQuote"
)
NSKeyedUnarchiver.setClass(
Legacy._LinkPreview.self,
SMKLegacy._LinkPreview.self,
forClassName: "SessionServiceKit.OWSLinkPreview" // Very old legacy name
)
NSKeyedUnarchiver.setClass(
Legacy._LinkPreview.self,
SMKLegacy._LinkPreview.self,
forClassName: "SNLinkPreview"
)
NSKeyedUnarchiver.setClass(
Legacy._Profile.self,
SMKLegacy._Profile.self,
forClassName: "SNProfile"
)
NSKeyedUnarchiver.setClass(
Legacy._OpenGroupInvitation.self,
SMKLegacy._OpenGroupInvitation.self,
forClassName: "SNOpenGroupInvitation"
)
NSKeyedUnarchiver.setClass(
Legacy._ControlMessage.self,
SMKLegacy._ControlMessage.self,
forClassName: "SNControlMessage"
)
NSKeyedUnarchiver.setClass(
Legacy._ReadReceipt.self,
SMKLegacy._ReadReceipt.self,
forClassName: "SNReadReceipt"
)
NSKeyedUnarchiver.setClass(
Legacy._TypingIndicator.self,
SMKLegacy._TypingIndicator.self,
forClassName: "SNTypingIndicator"
)
NSKeyedUnarchiver.setClass(
Legacy._ClosedGroupControlMessage.self,
SMKLegacy._ClosedGroupControlMessage.self,
forClassName: "SessionMessagingKit.ClosedGroupControlMessage"
)
NSKeyedUnarchiver.setClass(
Legacy._ClosedGroupControlMessage._KeyPairWrapper.self,
SMKLegacy._ClosedGroupControlMessage._KeyPairWrapper.self,
forClassName: "ClosedGroupControlMessage.SNKeyPairWrapper"
)
NSKeyedUnarchiver.setClass(
Legacy._DataExtractionNotification.self,
SMKLegacy._DataExtractionNotification.self,
forClassName: "SessionMessagingKit.DataExtractionNotification"
)
NSKeyedUnarchiver.setClass(
Legacy._ExpirationTimerUpdate.self,
SMKLegacy._ExpirationTimerUpdate.self,
forClassName: "SNExpirationTimerUpdate"
)
NSKeyedUnarchiver.setClass(
Legacy._ConfigurationMessage.self,
SMKLegacy._ConfigurationMessage.self,
forClassName: "SNConfigurationMessage"
)
NSKeyedUnarchiver.setClass(
Legacy._CMClosedGroup.self,
SMKLegacy._CMClosedGroup.self,
forClassName: "SNClosedGroup"
)
NSKeyedUnarchiver.setClass(
Legacy._CMContact.self,
SMKLegacy._CMContact.self,
forClassName: "SNConfigurationMessage.SNConfigurationMessageContact"
)
NSKeyedUnarchiver.setClass(
Legacy._UnsendRequest.self,
SMKLegacy._UnsendRequest.self,
forClassName: "SNUnsendRequest"
)
NSKeyedUnarchiver.setClass(
Legacy._MessageRequestResponse.self,
SMKLegacy._MessageRequestResponse.self,
forClassName: "SNMessageRequestResponse"
)
Storage.read { transaction in
transaction.enumerateRows(inCollection: Legacy.notifyPushServerJobCollection) { _, object, _, _ in
guard let job = object as? Legacy._NotifyPNServerJob else { return }
transaction.enumerateRows(inCollection: SMKLegacy.notifyPushServerJobCollection) { _, object, _, _ in
guard let job = object as? SMKLegacy._NotifyPNServerJob else { return }
notifyPushServerJobs.insert(job)
}
transaction.enumerateRows(inCollection: Legacy.messageReceiveJobCollection) { _, object, _, _ in
guard let job = object as? Legacy._MessageReceiveJob else { return }
transaction.enumerateRows(inCollection: SMKLegacy.messageReceiveJobCollection) { _, object, _, _ in
guard let job = object as? SMKLegacy._MessageReceiveJob else { return }
messageReceiveJobs.insert(job)
}
transaction.enumerateRows(inCollection: Legacy.messageSendJobCollection) { _, object, _, _ in
guard let job = object as? Legacy._MessageSendJob else { return }
transaction.enumerateRows(inCollection: SMKLegacy.messageSendJobCollection) { _, object, _, _ in
guard let job = object as? SMKLegacy._MessageSendJob else { return }
messageSendJobs.insert(job)
}
transaction.enumerateRows(inCollection: Legacy.attachmentUploadJobCollection) { _, object, _, _ in
guard let job = object as? Legacy._AttachmentUploadJob else { return }
transaction.enumerateRows(inCollection: SMKLegacy.attachmentUploadJobCollection) { _, object, _, _ in
guard let job = object as? SMKLegacy._AttachmentUploadJob else { return }
attachmentUploadJobs.insert(job)
}
transaction.enumerateRows(inCollection: Legacy.attachmentDownloadJobCollection) { _, object, _, _ in
guard let job = object as? Legacy._AttachmentDownloadJob else { return }
transaction.enumerateRows(inCollection: SMKLegacy.attachmentDownloadJobCollection) { _, object, _, _ in
guard let job = object as? SMKLegacy._AttachmentDownloadJob else { return }
attachmentDownloadJobs.insert(job)
}
}
@ -1110,7 +1123,7 @@ enum _003_YDBToGRDBMigration: Migration {
destination: legacyJob.destination,
variant: {
switch legacyJob.message {
case is Legacy._ExpirationTimerUpdate:
case is SMKLegacy._ExpirationTimerUpdate:
return .infoDisappearingMessagesUpdate
default: return nil
}
@ -1229,73 +1242,74 @@ enum _003_YDBToGRDBMigration: Migration {
var legacyPreferences: [String: Any] = [:]
Storage.read { transaction in
transaction.enumerateKeysAndObjects(inCollection: Legacy.preferencesCollection) { key, object, _ in
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.preferencesCollection) { key, object, _ in
legacyPreferences[key] = object
}
// Note: The 'int(forKey:inCollection:)' defaults to `0` which is an incorrect value
// for the notification sound so catch it and default
let globalNotificationSoundValue: Int32 = transaction.int(
forKey: Legacy.soundsGlobalNotificationKey,
inCollection: Legacy.soundsStorageNotificationCollection
forKey: SMKLegacy.soundsGlobalNotificationKey,
inCollection: SMKLegacy.soundsStorageNotificationCollection
)
legacyPreferences[Legacy.soundsGlobalNotificationKey] = (globalNotificationSoundValue > 0 ?
legacyPreferences[SMKLegacy.soundsGlobalNotificationKey] = (globalNotificationSoundValue > 0 ?
Int(globalNotificationSoundValue) :
Preferences.Sound.defaultNotificationSound.rawValue
)
legacyPreferences[Legacy.readReceiptManagerAreReadReceiptsEnabled] = transaction.bool(
forKey: Legacy.readReceiptManagerAreReadReceiptsEnabled,
inCollection: Legacy.readReceiptManagerCollection,
legacyPreferences[SMKLegacy.readReceiptManagerAreReadReceiptsEnabled] = transaction.bool(
forKey: SMKLegacy.readReceiptManagerAreReadReceiptsEnabled,
inCollection: SMKLegacy.readReceiptManagerCollection,
defaultValue: false
)
legacyPreferences[Legacy.typingIndicatorsEnabledKey] = transaction.bool(
forKey: Legacy.typingIndicatorsEnabledKey,
inCollection: Legacy.typingIndicatorsCollection,
legacyPreferences[SMKLegacy.typingIndicatorsEnabledKey] = transaction.bool(
forKey: SMKLegacy.typingIndicatorsEnabledKey,
inCollection: SMKLegacy.typingIndicatorsCollection,
defaultValue: false
)
legacyPreferences[Legacy.screenLockIsScreenLockEnabledKey] = transaction.bool(
forKey: Legacy.screenLockIsScreenLockEnabledKey,
inCollection: Legacy.screenLockCollection,
legacyPreferences[SMKLegacy.screenLockIsScreenLockEnabledKey] = transaction.bool(
forKey: SMKLegacy.screenLockIsScreenLockEnabledKey,
inCollection: SMKLegacy.screenLockCollection,
defaultValue: false
)
legacyPreferences[Legacy.screenLockScreenLockTimeoutSecondsKey] = transaction.double(
forKey: Legacy.screenLockScreenLockTimeoutSecondsKey,
inCollection: Legacy.screenLockCollection,
legacyPreferences[SMKLegacy.screenLockScreenLockTimeoutSecondsKey] = transaction.double(
forKey: SMKLegacy.screenLockScreenLockTimeoutSecondsKey,
inCollection: SMKLegacy.screenLockCollection,
defaultValue: (15 * 60)
)
}
db[.defaultNotificationSound] = Preferences.Sound(rawValue: legacyPreferences[Legacy.soundsGlobalNotificationKey] as? Int ?? -1)
db[.defaultNotificationSound] = Preferences.Sound(rawValue: legacyPreferences[SMKLegacy.soundsGlobalNotificationKey] as? Int ?? -1)
.defaulting(to: Preferences.Sound.defaultNotificationSound)
db[.playNotificationSoundInForeground] = (legacyPreferences[Legacy.preferencesKeyNotificationSoundInForeground] as? Bool == true)
db[.preferencesNotificationPreviewType] = Preferences.NotificationPreviewType(rawValue: legacyPreferences[Legacy.preferencesKeyNotificationPreviewType] as? Int ?? -1)
db[.playNotificationSoundInForeground] = (legacyPreferences[SMKLegacy.preferencesKeyNotificationSoundInForeground] as? Bool == true)
db[.preferencesNotificationPreviewType] = Preferences.NotificationPreviewType(rawValue: legacyPreferences[SMKLegacy.preferencesKeyNotificationPreviewType] as? Int ?? -1)
.defaulting(to: .nameAndPreview)
if let lastPushToken: String = legacyPreferences[Legacy.preferencesKeyLastRecordedPushToken] as? String {
if let lastPushToken: String = legacyPreferences[SMKLegacy.preferencesKeyLastRecordedPushToken] as? String {
db[.lastRecordedPushToken] = lastPushToken
}
if let lastVoipToken: String = legacyPreferences[Legacy.preferencesKeyLastRecordedVoipToken] as? String {
if let lastVoipToken: String = legacyPreferences[SMKLegacy.preferencesKeyLastRecordedVoipToken] as? String {
db[.lastRecordedVoipToken] = lastVoipToken
}
// Note: The 'preferencesKeyScreenSecurityDisabled' value previously controlled whether the
// setting was disabled, this has been inverted to 'appSwitcherPreviewEnabled' so it can default
// to 'false' (as most Bool values do)
db[.areReadReceiptsEnabled] = (legacyPreferences[Legacy.readReceiptManagerAreReadReceiptsEnabled] as? Bool == true)
db[.typingIndicatorsEnabled] = (legacyPreferences[Legacy.typingIndicatorsEnabledKey] as? Bool == true)
db[.isScreenLockEnabled] = (legacyPreferences[Legacy.screenLockIsScreenLockEnabledKey] as? Bool == true)
db[.screenLockTimeoutSeconds] = (legacyPreferences[Legacy.screenLockScreenLockTimeoutSecondsKey] as? Double)
db[.areReadReceiptsEnabled] = (legacyPreferences[SMKLegacy.readReceiptManagerAreReadReceiptsEnabled] as? Bool == true)
db[.typingIndicatorsEnabled] = (legacyPreferences[SMKLegacy.typingIndicatorsEnabledKey] as? Bool == true)
db[.isScreenLockEnabled] = (legacyPreferences[SMKLegacy.screenLockIsScreenLockEnabledKey] as? Bool == true)
db[.screenLockTimeoutSeconds] = (legacyPreferences[SMKLegacy.screenLockScreenLockTimeoutSecondsKey] as? Double)
.defaulting(to: (15 * 60))
db[.appSwitcherPreviewEnabled] = (legacyPreferences[Legacy.preferencesKeyScreenSecurityDisabled] as? Bool == false)
db[.areLinkPreviewsEnabled] = (legacyPreferences[Legacy.preferencesKeyAreLinkPreviewsEnabled] as? Bool == true)
db[.appSwitcherPreviewEnabled] = (legacyPreferences[SMKLegacy.preferencesKeyScreenSecurityDisabled] as? Bool == false)
db[.areLinkPreviewsEnabled] = (legacyPreferences[SMKLegacy.preferencesKeyAreLinkPreviewsEnabled] as? Bool == true)
db[.hasHiddenMessageRequests] = CurrentAppContext().appUserDefaults()
.bool(forKey: Legacy.userDefaultsHasHiddenMessageRequests)
db[.hasSavedThreadKey] = (legacyPreferences[Legacy.preferencesKeyHasSavedThreadKey] as? Bool == true)
.bool(forKey: SMKLegacy.userDefaultsHasHiddenMessageRequests)
db[.hasSavedThread] = (legacyPreferences[SMKLegacy.preferencesKeyHasSavedThreadKey] as? Bool == true)
db[.hasSentAMessage] = (legacyPreferences[SMKLegacy.preferencesKeyHasSentAMessageKey] as? Bool == true)
print("RAWR [\(Date().timeIntervalSince1970)] - Process preferences inserts - End")
@ -1309,7 +1323,7 @@ enum _003_YDBToGRDBMigration: Migration {
for legacyAttachmentId: String?,
interactionVariant: Interaction.Variant? = nil,
isQuotedMessage: Bool = false,
attachments: [String: Legacy._Attachment],
attachments: [String: SMKLegacy._Attachment],
processedAttachmentIds: inout Set<String>
) throws -> String? {
guard let legacyAttachmentId: String = legacyAttachmentId else { return nil }
@ -1322,12 +1336,12 @@ enum _003_YDBToGRDBMigration: Migration {
return legacyAttachmentId
}
guard let legacyAttachment: Legacy._Attachment = attachments[legacyAttachmentId] else {
guard let legacyAttachment: SMKLegacy._Attachment = attachments[legacyAttachmentId] else {
SNLog("[Migration Warning] Missing attachment - interaction will appear as blank")
return nil
}
let processedLocalRelativeFilePath: String? = (legacyAttachment as? Legacy._AttachmentStream)?
let processedLocalRelativeFilePath: String? = (legacyAttachment as? SMKLegacy._AttachmentStream)?
.localRelativeFilePath
.map { filePath -> String in
// The old 'localRelativeFilePath' seemed to have a leading forward slash (want
@ -1338,7 +1352,7 @@ enum _003_YDBToGRDBMigration: Migration {
}
let state: Attachment.State = {
switch legacyAttachment {
case let stream as Legacy._AttachmentStream: // Outgoing or already downloaded
case let stream as SMKLegacy._AttachmentStream: // Outgoing or already downloaded
switch interactionVariant {
case .standardOutgoing: return (stream.isUploaded ? .uploaded : .pending)
default: return .downloaded
@ -1350,7 +1364,7 @@ enum _003_YDBToGRDBMigration: Migration {
}()
let size: CGSize = {
switch legacyAttachment {
case let stream as Legacy._AttachmentStream:
case let stream as SMKLegacy._AttachmentStream:
// First try to get an image size using the 'localRelativeFilePath' value
if
let localRelativeFilePath: String = processedLocalRelativeFilePath,
@ -1377,13 +1391,13 @@ enum _003_YDBToGRDBMigration: Migration {
)
.defaulting(to: .zero)
case let pointer as Legacy._AttachmentPointer: return pointer.mediaSize
case let pointer as SMKLegacy._AttachmentPointer: return pointer.mediaSize
default: return CGSize.zero
}
}()
let (isValid, duration): (Bool, TimeInterval?) = {
guard
let stream: Legacy._AttachmentStream = legacyAttachment as? Legacy._AttachmentStream,
let stream: SMKLegacy._AttachmentStream = legacyAttachment as? SMKLegacy._AttachmentStream,
let originalFilePath: String = Attachment.originalFilePath(
id: legacyAttachmentId,
mimeType: stream.contentType,
@ -1435,7 +1449,7 @@ enum _003_YDBToGRDBMigration: Migration {
state: state,
contentType: legacyAttachment.contentType,
byteCount: UInt(legacyAttachment.byteCount),
creationTimestamp: (legacyAttachment as? Legacy._AttachmentStream)?
creationTimestamp: (legacyAttachment as? SMKLegacy._AttachmentStream)?
.creationTimestamp.timeIntervalSince1970,
sourceFilename: legacyAttachment.sourceFilename,
downloadUrl: legacyAttachment.downloadURL,
@ -1445,7 +1459,7 @@ enum _003_YDBToGRDBMigration: Migration {
duration: duration,
isValid: isValid,
encryptionKey: legacyAttachment.encryptionKey,
digest: (legacyAttachment as? Legacy._AttachmentStream)?.digest,
digest: (legacyAttachment as? SMKLegacy._AttachmentStream)?.digest,
caption: legacyAttachment.caption
).inserted(db)

View File

@ -127,7 +127,7 @@ public struct SessionThread: Codable, Identifiable, Equatable, FetchableRecord,
public func insert(_ db: Database) throws {
try performInsert(db)
db[.hasSavedThreadKey] = true
db[.hasSavedThread] = true
}
public func delete(_ db: Database) throws -> Bool {
@ -311,6 +311,13 @@ public extension SessionThread {
@objc(SMKThread)
public class SMKThread: NSObject {
@objc(deleteAll)
public static func deleteAll() {
GRDBStorage.shared.writeAsync { db in
_ = try SessionThread.deleteAll(db)
}
}
@objc(isThreadMuted:)
public static func isThreadMuted(_ threadId: String) -> Bool {
return GRDBStorage.shared.read { db in

View File

@ -4,7 +4,6 @@
#import "OWSPrimaryStorage.h"
#import "AppContext.h"
#import "OWSDisappearingMessagesFinder.h"
#import "OWSFileSystem.h"
#import "OWSIncomingMessageFinder.h"
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>

View File

@ -7,7 +7,6 @@
#import "TSAttachmentPointer.h"
#import "TSIncomingMessage.h"
#import "TSOutgoingMessage.h"
#import "TSThread.h"
#import <YapDatabase/YapDatabaseAutoView.h>
#import <YapDatabase/YapDatabaseCrossProcessNotification.h>
#import <YapDatabase/YapDatabaseViewTypes.h>

View File

@ -67,7 +67,7 @@ public class Message: Codable {
guard
let threadId: String = threadId,
(try? ClosedGroup.exists(db, id: threadId)) == true,
let legacyGroupId: Data = "\(Legacy.closedGroupIdPrefix)\(threadId)".data(using: .utf8)
let legacyGroupId: Data = "\(SMKLegacy.closedGroupIdPrefix)\(threadId)".data(using: .utf8)
else { return }
// Android needs a group context or it'll interpret the message as a one-to-one message

View File

@ -5,9 +5,7 @@
#import "TSIncomingMessage.h"
#import "NSNotificationCenter+OWS.h"
#import "TSAttachmentPointer.h"
#import "TSContactThread.h"
#import "TSDatabaseSecondaryIndexes.h"
#import "TSGroupThread.h"
#import <YapDatabase/YapDatabaseConnection.h>
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>

View File

@ -4,8 +4,6 @@
#import "TSInteraction.h"
#import "TSDatabaseSecondaryIndexes.h"
#import "TSThread.h"
#import "TSGroupThread.h"
#import <SignalCoreKit/NSDate+OWS.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>

View File

@ -8,12 +8,10 @@
#import "TSAttachment.h"
#import "TSAttachmentStream.h"
#import "TSQuotedMessage.h"
#import "TSThread.h"
#import <SignalCoreKit/NSDate+OWS.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseTransaction.h>
#import "TSContactThread.h"
#import <SignalCoreKit/NSString+OWS.h>
NS_ASSUME_NONNULL_BEGIN

View File

@ -10,8 +10,6 @@
#import "SSKEnvironment.h"
#import "TSAccountManager.h"
#import "TSAttachmentStream.h"
#import "TSContactThread.h"
#import "TSGroupThread.h"
#import "TSQuotedMessage.h"
#import <SignalCoreKit/NSDate+OWS.h>
#import <YapDatabase/YapDatabase.h>

View File

@ -9,7 +9,6 @@ FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[];
#import <SessionMessagingKit/OWSAudioPlayer.h>
#import <SessionMessagingKit/OWSBackgroundTask.h>
#import <SessionMessagingKit/OWSBackupFragment.h>
#import <SessionMessagingKit/OWSDisappearingMessagesFinder.h>
#import <SessionMessagingKit/OWSIncomingMessageFinder.h>
#import <SessionMessagingKit/OWSPreferences.h>
#import <SessionMessagingKit/OWSPrimaryStorage.h>
@ -24,16 +23,12 @@ FOUNDATION_EXPORT const unsigned char SessionMessagingKitVersionString[];
#import <SessionMessagingKit/TSAttachment.h>
#import <SessionMessagingKit/TSAttachmentPointer.h>
#import <SessionMessagingKit/TSAttachmentStream.h>
#import <SessionMessagingKit/TSContactThread.h>
#import <SessionMessagingKit/TSDatabaseSecondaryIndexes.h>
#import <SessionMessagingKit/TSDatabaseView.h>
#import <SessionMessagingKit/TSGroupModel.h>
#import <SessionMessagingKit/TSGroupThread.h>
#import <SessionMessagingKit/TSIncomingMessage.h>
#import <SessionMessagingKit/TSInfoMessage.h>
#import <SessionMessagingKit/TSInteraction.h>
#import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SessionMessagingKit/TSQuotedMessage.h>
#import <SessionMessagingKit/TSThread.h>
#import <SessionMessagingKit/YapDatabaseConnection+OWS.h>
#import <SessionMessagingKit/YapDatabaseTransaction+OWS.h>

View File

@ -217,7 +217,7 @@ public final class ClosedGroupPoller: NSObject {
)
}
SNLog("Received \(messageCount) message(s) in closed group with public key: \(groupPublicKey).")
SNLog("Received \(messageCount) new message\(messageCount == 1 ? "" : "s") in closed group with public key: \(groupPublicKey) (\(messages.count - messageCount) duplicates)")
}
}
.map { _ in }

View File

@ -12,7 +12,6 @@
#import <SessionMessagingKit/TSMessage.h>
#import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SessionMessagingKit/TSQuotedMessage.h>
#import <SessionMessagingKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN

View File

@ -10,7 +10,6 @@
#import "TSIncomingMessage.h"
#import "TSInteraction.h"
#import "TSOutgoingMessage.h"
#import "TSThread.h"
#import <YapDatabase/YapDatabaseTransaction.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>

View File

@ -1,12 +0,0 @@
public extension Notification.Name {
static let groupThreadUpdated = Notification.Name("groupThreadUpdated")
static let muteSettingUpdated = Notification.Name("muteSettingUpdated")
}
@objc public extension NSNotification {
@objc static let groupThreadUpdated = Notification.Name.groupThreadUpdated.rawValue as NSString
@objc static let muteSettingUpdated = Notification.Name.muteSettingUpdated.rawValue as NSString
}

View File

@ -1,31 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <SessionMessagingKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN
extern NSString *const TSContactThreadPrefix;
@interface TSContactThread : TSThread
- (instancetype)initWithContactSessionID:(NSString *)contactSessionID;
+ (instancetype)getOrCreateThreadWithContactSessionID:(NSString *)contactSessionID NS_SWIFT_NAME(getOrCreateThread(contactSessionID:));
+ (instancetype)getOrCreateThreadWithContactSessionID:(NSString *)contactSessionID
transaction:(YapDatabaseReadWriteTransaction *)transaction;
// Unlike getOrCreateThreadWithContactSessionID, this will _NOT_ create a thread if one does not already exist.
+ (nullable instancetype)getThreadWithContactSessionID:(NSString *)contactSessionID transaction:(YapDatabaseReadTransaction *)transaction;
- (NSString *)contactSessionID;
+ (NSString *)contactSessionIDFromThreadID:(NSString *)threadId;
+ (NSString *)threadIDFromContactSessionID:(NSString *)contactSessionID;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,127 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSContactThread.h"
#import <YapDatabase/YapDatabase.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const TSContactThreadPrefix = @"c";
@implementation TSContactThread
- (instancetype)initWithContactSessionID:(NSString *)contactSessionID {
NSString *uniqueIdentifier = [[self class] threadIDFromContactSessionID:contactSessionID];
self = [super initWithUniqueId:uniqueIdentifier];
return self;
}
+ (instancetype)getOrCreateThreadWithContactSessionID:(NSString *)contactSessionID
transaction:(YapDatabaseReadWriteTransaction *)transaction {
TSContactThread *thread =
[self fetchObjectWithUniqueID:[self threadIDFromContactSessionID:contactSessionID] transaction:transaction];
if (!thread) {
thread = [[TSContactThread alloc] initWithContactSessionID:contactSessionID];
[thread saveWithTransaction:transaction];
}
return thread;
}
+ (instancetype)getOrCreateThreadWithContactSessionID:(NSString *)contactSessionID
{
__block TSContactThread *thread;
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
thread = [self getOrCreateThreadWithContactSessionID:contactSessionID transaction:transaction];
}];
return thread;
}
+ (nullable instancetype)getThreadWithContactSessionID:(NSString *)contactSessionID transaction:(YapDatabaseReadTransaction *)transaction;
{
return [TSContactThread fetchObjectWithUniqueID:[self threadIDFromContactSessionID:contactSessionID] transaction:transaction];
}
- (NSString *)contactSessionID {
return [[self class] contactSessionIDFromThreadID:self.uniqueId];
}
- (NSArray<NSString *> *)recipientIdentifiers
{
return @[ self.contactSessionID ];
}
- (BOOL)isMessageRequest {
NSString *sessionID = self.contactSessionID;
SMKContact *contact = [SMKContact fetchOrCreateWithId: sessionID];
return (
self.shouldBeVisible &&
!self.isNoteToSelf && (
contact == nil ||
!contact.isApproved
)
);
}
- (BOOL)isMessageRequestUsingTransaction:(YapDatabaseReadTransaction *)transaction {
NSString *sessionID = self.contactSessionID;
SMKContact *contact = [SMKContact fetchOrCreateWithId: sessionID];
return (
self.shouldBeVisible &&
!self.isNoteToSelf && (
contact == nil ||
!contact.isApproved
)
);
}
- (BOOL)isBlocked {
NSString *sessionID = self.contactSessionID;
SMKContact *contact = [SMKContact fetchOrCreateWithId: sessionID];
return (contact.isBlocked == YES);
}
- (BOOL)isBlockedUsingTransaction:(YapDatabaseReadTransaction *)transaction {
NSString *sessionID = self.contactSessionID;
SMKContact *contact = [SMKContact fetchOrCreateWithId: sessionID];
return (contact.isBlocked == YES);
}
- (BOOL)isGroupThread
{
return NO;
}
- (NSString *)name
{
NSString *sessionID = self.contactSessionID;
return [SMKProfile displayNameWithId:sessionID];
}
- (NSString *)nameWithTransaction:(YapDatabaseReadTransaction *)transaction
{
NSString *sessionID = self.contactSessionID;
return [SMKProfile displayNameWithId:sessionID];
}
+ (NSString *)threadIDFromContactSessionID:(NSString *)contactSessionID {
return [TSContactThreadPrefix stringByAppendingString:contactSessionID];
}
+ (NSString *)contactSessionIDFromThreadID:(NSString *)threadId {
return [threadId substringWithRange:NSMakeRange(1, threadId.length - 1)];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,43 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <UIKit/UIKit.h>
#import <SessionUtilitiesKit/TSYapDatabaseObject.h>
NS_ASSUME_NONNULL_BEGIN
typedef NS_ENUM(NSInteger, GroupType) {
closedGroup = 0,
openGroup = 1,
};
extern const int32_t kGroupIdLength;
@interface TSGroupModel : TSYapDatabaseObject
@property (nonatomic) NSArray<NSString *> *groupMemberIds;
@property (nonatomic) NSArray<NSString *> *groupAdminIds;
@property (nullable, readonly, nonatomic) NSString *groupName;
@property (readonly, nonatomic) NSData *groupId;
@property (nonatomic) GroupType groupType;
#if TARGET_OS_IOS
@property (nullable, nonatomic, strong) UIImage *groupImage;
- (instancetype)initWithTitle:(nullable NSString *)title
memberIds:(NSArray<NSString *> *)memberIds
image:(nullable UIImage *)image
groupId:(NSData *)groupId
groupType:(GroupType)groupType
adminIds:(NSArray<NSString *> *)adminIds;
- (BOOL)isEqual:(id)other;
- (BOOL)isEqualToGroupModel:(TSGroupModel *)model;
- (NSString *)getInfoStringAboutUpdateTo:(TSGroupModel *)model;
#endif
@end
NS_ASSUME_NONNULL_END

View File

@ -1,159 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSGroupModel.h"
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import <SignalCoreKit/NSString+OWS.h>
NS_ASSUME_NONNULL_BEGIN
const int32_t kGroupIdLength = 16;
@interface TSGroupModel ()
@property (nullable, nonatomic) NSString *groupName;
@end
#pragma mark -
@implementation TSGroupModel
- (nullable NSString *)groupName
{
return _groupName.filterStringForDisplay;
}
#if TARGET_OS_IOS
- (instancetype)initWithTitle:(nullable NSString *)title
memberIds:(NSArray<NSString *> *)memberIds
image:(nullable UIImage *)image
groupId:(NSData *)groupId
groupType:(GroupType)groupType
adminIds:(NSArray<NSString *> *)adminIds
{
_groupName = title;
_groupMemberIds = [memberIds copy];
_groupImage = image;
_groupType = groupType;
_groupId = groupId;
_groupAdminIds = [adminIds copy];
return self;
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
// Occasionally seeing this as nil in legacy data,
// which causes crashes.
if (_groupMemberIds == nil) {
_groupMemberIds = [NSArray new];
}
if (_groupAdminIds == nil) {
_groupAdminIds = [NSArray new];
}
return self;
}
- (BOOL)isEqual:(id)other {
if (other == self) {
return YES;
}
if (!other || ![other isKindOfClass:[self class]]) {
return NO;
}
return [self isEqualToGroupModel:other];
}
- (BOOL)isEqualToGroupModel:(TSGroupModel *)other {
if (self == other)
return YES;
if (![_groupId isEqualToData:other.groupId]) {
return NO;
}
if (![_groupName isEqual:other.groupName]) {
return NO;
}
if (!(_groupImage != nil && other.groupImage != nil &&
[UIImagePNGRepresentation(_groupImage) isEqualToData:UIImagePNGRepresentation(other.groupImage)])) {
return NO;
}
if (_groupType != other.groupType) {
return NO;
}
NSMutableArray *compareMyGroupMemberIds = [NSMutableArray arrayWithArray:_groupMemberIds];
[compareMyGroupMemberIds removeObjectsInArray:other.groupMemberIds];
if ([compareMyGroupMemberIds count] > 0) {
return NO;
}
return YES;
}
- (NSString *)getInfoStringAboutUpdateTo:(TSGroupModel *)newModel {
// This is only invoked for group * changes *, i.e. not when a group is created.
NSString *userPublicKey = [SNGeneralUtilities getUserPublicKey];
NSString *updatedGroupInfoString = @"";
if (self == newModel) {
return NSLocalizedString(@"GROUP_UPDATED", @"");
}
// Name change
if (![_groupName isEqual:newModel.groupName]) {
updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:[NSString stringWithFormat:NSLocalizedString(@"GROUP_TITLE_CHANGED", @""), newModel.groupName]];
}
// Added & removed members
NSSet *oldMembers = [NSSet setWithArray:_groupMemberIds];
NSSet *newMembers = [NSSet setWithArray:newModel.groupMemberIds];
NSMutableSet *addedMembers = newMembers.mutableCopy;
[addedMembers minusSet:oldMembers];
NSMutableSet *removedMembers = oldMembers.mutableCopy;
[removedMembers minusSet:newMembers];
NSMutableSet *removedMembersMinusSelf = removedMembers.mutableCopy;
[removedMembersMinusSelf minusSet:[NSSet setWithObject:userPublicKey]];
if (removedMembersMinusSelf.count > 0) {
NSArray *removedMemberNames = [removedMembers.allObjects map:^NSString *(NSString *publicKey) {
return [SMKProfile displayNameWithId:publicKey];
}];
NSString *format = removedMembers.count > 1 ? NSLocalizedString(@"GROUP_MEMBERS_REMOVED", @"") : NSLocalizedString(@"GROUP_MEMBER_REMOVED", @"");
updatedGroupInfoString = [updatedGroupInfoString
stringByAppendingString:[NSString
stringWithFormat: format,
[removedMemberNames componentsJoinedByString:@", "]]];
}
if (addedMembers.count > 0) {
NSArray *addedMemberNames = [[addedMembers allObjects] map:^NSString*(NSString* publicKey) {
return [SMKProfile displayNameWithId:publicKey];
}];
updatedGroupInfoString = [updatedGroupInfoString
stringByAppendingString:[NSString
stringWithFormat:NSLocalizedString(@"GROUP_MEMBER_JOINED", @""),
[addedMemberNames componentsJoinedByString:@", "]]];
}
if ([removedMembers containsObject:userPublicKey]) {
updatedGroupInfoString = [updatedGroupInfoString stringByAppendingString:NSLocalizedString(@"YOU_WERE_REMOVED", @"")];
}
// Return
if ([updatedGroupInfoString length] == 0) {
updatedGroupInfoString = NSLocalizedString(@"GROUP_UPDATED", @"");
}
return updatedGroupInfoString;
}
#endif
@end
NS_ASSUME_NONNULL_END

View File

@ -1,63 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <SessionMessagingKit/TSGroupModel.h>
#import <SessionMessagingKit/TSThread.h>
NS_ASSUME_NONNULL_BEGIN
@class TSAttachmentStream;
@class YapDatabaseReadWriteTransaction;
extern NSString *const TSGroupThreadAvatarChangedNotification;
extern NSString *const TSGroupThread_NotificationKey_UniqueId;
@interface TSGroupThread : TSThread
@property (nonatomic, strong) TSGroupModel *groupModel;
@property (nonatomic, readonly) BOOL isOpenGroup;
@property (nonatomic, readonly) BOOL isClosedGroup;
@property (nonatomic) BOOL isOnlyNotifyingForMentions;
+ (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel;
+ (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel
transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (instancetype)getOrCreateThreadWithGroupId:(NSData *)groupId
groupType:(GroupType) groupType;
+ (instancetype)getOrCreateThreadWithGroupId:(NSData *)groupId
groupType:(GroupType) groupType
transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (nullable instancetype)threadWithGroupId:(NSData *)groupId transaction:(YapDatabaseReadTransaction *)transaction
NS_SWIFT_NAME(fetch(groupId:transaction:));
+ (NSString *)threadIdFromGroupId:(NSData *)groupId;
+ (NSString *)defaultGroupName;
- (BOOL)isCurrentUserMemberInGroup;
- (BOOL)isUserMemberInGroup:(NSString *)publicKey;
- (BOOL)isUserAdminInGroup:(NSString *)publicKey;
// all group threads containing recipient as a member
+ (NSArray<TSGroupThread *> *)groupThreadsWithRecipientId:(NSString *)recipientId
transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)setGroupModel:(TSGroupModel *)newGroupModel withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)setIsOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)leaveGroupWithSneakyTransaction;
- (void)leaveGroupWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
#pragma mark - Avatar
- (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream;
- (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream
transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)fireAvatarChangedNotification;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,283 +0,0 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSGroupThread.h"
#import "TSAttachmentStream.h"
#import <SignalCoreKit/NSData+OWS.h>
#import <YapDatabase/YapDatabase.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import <SessionUtilitiesKit/SessionUtilitiesKit.h>
#import <Curve25519Kit/Curve25519.h>
NS_ASSUME_NONNULL_BEGIN
NSString *const TSGroupThreadAvatarChangedNotification = @"TSGroupThreadAvatarChangedNotification";
NSString *const TSGroupThread_NotificationKey_UniqueId = @"TSGroupThread_NotificationKey_UniqueId";
@implementation TSGroupThread
#define TSGroupThreadPrefix @"g"
- (instancetype)initWithGroupModel:(TSGroupModel *)groupModel
{
NSString *uniqueIdentifier = [[self class] threadIdFromGroupId:groupModel.groupId];
self = [super initWithUniqueId:uniqueIdentifier];
if (!self) {
return self;
}
_groupModel = groupModel;
return self;
}
- (instancetype)initWithGroupId:(NSData *)groupId groupType:(GroupType)groupType
{
NSString *localNumber = [TSAccountManager localNumber];
TSGroupModel *groupModel = [[TSGroupModel alloc] initWithTitle:nil
memberIds:@[ localNumber ]
image:nil
groupId:groupId
groupType:groupType
adminIds:@[ localNumber ]];
self = [self initWithGroupModel:groupModel];
if (!self) {
return self;
}
return self;
}
+ (nullable instancetype)threadWithGroupId:(NSData *)groupId transaction:(YapDatabaseReadTransaction *)transaction
{
return [self fetchObjectWithUniqueID:[self threadIdFromGroupId:groupId] transaction:transaction];
}
+ (instancetype)getOrCreateThreadWithGroupId:(NSData *)groupId
groupType:(GroupType)groupType
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
TSGroupThread *thread = [self fetchObjectWithUniqueID:[self threadIdFromGroupId:groupId] transaction:transaction];
if (!thread) {
thread = [[self alloc] initWithGroupId:groupId groupType:groupType];
[thread saveWithTransaction:transaction];
}
return thread;
}
+ (instancetype)getOrCreateThreadWithGroupId:(NSData *)groupId groupType:(GroupType)groupType
{
__block TSGroupThread *thread;
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
thread = [self getOrCreateThreadWithGroupId:groupId groupType:groupType transaction:transaction];
}];
return thread;
}
+ (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel
transaction:(YapDatabaseReadWriteTransaction *)transaction {
TSGroupThread *thread =
[self fetchObjectWithUniqueID:[self threadIdFromGroupId:groupModel.groupId] transaction:transaction];
if (!thread) {
thread = [[TSGroupThread alloc] initWithGroupModel:groupModel];
[thread saveWithTransaction:transaction];
}
return thread;
}
+ (instancetype)getOrCreateThreadWithGroupModel:(TSGroupModel *)groupModel
{
__block TSGroupThread *thread;
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
thread = [self getOrCreateThreadWithGroupModel:groupModel transaction:transaction];
}];
return thread;
}
+ (NSString *)threadIdFromGroupId:(NSData *)groupId
{
return [TSGroupThreadPrefix stringByAppendingString:[[LKGroupUtilities getDecodedGroupIDAsData:groupId] base64EncodedString]];
}
+ (NSData *)groupIdFromThreadId:(NSString *)threadId
{
return [NSData dataFromBase64String:[threadId substringWithRange:NSMakeRange(1, threadId.length - 1)]];
}
- (NSArray<NSString *> *)recipientIdentifiers
{
if (self.isClosedGroup) {
NSMutableArray<NSString *> *groupMemberIds = [self.groupModel.groupMemberIds mutableCopy];
if (groupMemberIds == nil) { return @[]; }
[groupMemberIds removeObject:TSAccountManager.localNumber];
return [groupMemberIds copy];
} else {
return @[ [LKGroupUtilities getDecodedGroupID:self.groupModel.groupId] ];
}
}
// @returns all threads to which the recipient is a member.
//
// @note If this becomes a hotspot we can extract into a YapDB View.
// As is, the number of groups should be small (dozens, *maybe* hundreds), and we only enumerate them upon SN changes.
+ (NSArray<TSGroupThread *> *)groupThreadsWithRecipientId:(NSString *)recipientId
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
NSMutableArray<TSGroupThread *> *groupThreads = [NSMutableArray new];
[self enumerateCollectionObjectsWithTransaction:transaction usingBlock:^(id obj, BOOL *stop) {
if ([obj isKindOfClass:[TSGroupThread class]]) {
TSGroupThread *groupThread = (TSGroupThread *)obj;
if ([groupThread.groupModel.groupMemberIds containsObject:recipientId]) {
[groupThreads addObject:groupThread];
}
}
}];
return [groupThreads copy];
}
- (BOOL)isGroupThread
{
return true;
}
- (BOOL)isClosedGroup
{
return (self.groupModel.groupType == closedGroup);
}
- (BOOL)isOpenGroup
{
return (self.groupModel.groupType == openGroup);
}
- (BOOL)isCurrentUserMemberInGroup
{
NSString *userPublicKey = [SNGeneralUtilities getUserPublicKey];
return [self isUserMemberInGroup:userPublicKey];
}
- (BOOL)isUserMemberInGroup:(NSString *)publicKey
{
if (publicKey == nil) { return NO; }
return [self.groupModel.groupMemberIds containsObject:publicKey];
}
- (BOOL)isUserAdminInGroup:(NSString *)publicKey
{
if (publicKey == nil) { return NO; }
return [self.groupModel.groupAdminIds containsObject:publicKey];
}
- (NSString *)name
{
// TODO sometimes groupName is set to the empty string. I'm hesitent to change
// the semantics here until we have time to thouroughly test the fallout.
// Instead, see the `groupNameOrDefault` which is appropriate for use when displaying
// text corresponding to a group.
return self.groupModel.groupName ?: self.class.defaultGroupName;
}
- (NSString *)nameWithTransaction:(YapDatabaseReadTransaction *)transaction
{
return [self name];
}
+ (NSString *)defaultGroupName
{
return @"Group";
}
- (void)setGroupModel:(TSGroupModel *)newGroupModel withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
self.groupModel = newGroupModel;
[self saveWithTransaction:transaction];
[transaction addCompletionQueue:dispatch_get_main_queue() completionBlock:^{
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.groupThreadUpdated object:self.uniqueId];
}];
}
- (void)setIsOnlyNotifyingForMentions:(BOOL)isOnlyNotifyingForMentions withTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
self.isOnlyNotifyingForMentions = isOnlyNotifyingForMentions;
[self saveWithTransaction:transaction];
[transaction addCompletionQueue:dispatch_get_main_queue() completionBlock:^{
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.groupThreadUpdated object:self.uniqueId];
}];
}
- (void)leaveGroupWithSneakyTransaction
{
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
[self leaveGroupWithTransaction:transaction];
}];
}
- (void)leaveGroupWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
NSMutableSet<NSString *> *newGroupMemberIDs = [NSMutableSet setWithArray:self.groupModel.groupMemberIds];
NSString *userPublicKey = TSAccountManager.localNumber;
if (userPublicKey == nil) { return; }
[newGroupMemberIDs removeObject:userPublicKey];
self.groupModel.groupMemberIds = newGroupMemberIDs.allObjects;
[self saveWithTransaction:transaction];
[transaction addCompletionQueue:dispatch_get_main_queue() completionBlock:^{
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.groupThreadUpdated object:self.uniqueId];
}];
}
#pragma mark - Avatar
- (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream
{
[LKStorage writeSyncWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
[self updateAvatarWithAttachmentStream:attachmentStream transaction:transaction];
}];
}
- (void)updateAvatarWithAttachmentStream:(TSAttachmentStream *)attachmentStream
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
self.groupModel.groupImage = [attachmentStream thumbnailImageSmallSync];
[self saveWithTransaction:transaction];
[transaction addCompletionQueue:nil
completionBlock:^{
[self fireAvatarChangedNotification];
}];
// Avatars are stored directly in the database, so there's no need
// to keep the attachment around after assigning the image.
[attachmentStream removeWithTransaction:transaction];
}
- (void)fireAvatarChangedNotification
{
NSDictionary *userInfo = @{ TSGroupThread_NotificationKey_UniqueId : self.uniqueId };
[[NSNotificationCenter defaultCenter] postNotificationName:TSGroupThreadAvatarChangedNotification
object:self.uniqueId
userInfo:userInfo];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -1,137 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import <SessionUtilitiesKit/TSYapDatabaseObject.h>
NS_ASSUME_NONNULL_BEGIN
BOOL IsNoteToSelfEnabled(void);
@class TSInteraction;
/**
* TSThread is the superclass of TSContactThread and TSGroupThread
*/
@interface TSThread : TSYapDatabaseObject
@property (nonatomic) BOOL isPinned;
@property (nonatomic) BOOL shouldBeVisible;
@property (nonatomic, readonly) NSDate *creationDate;
@property (nonatomic, readonly, nullable) NSDate *lastInteractionDate;
@property (nonatomic, readonly) TSInteraction *lastInteraction;
@property (atomic, readonly) BOOL isMuted;
@property (nonatomic, copy, nullable) NSString *messageDraft;
@property (atomic, readonly, nullable) NSDate *mutedUntilDate;
/**
* Whether the object is a group thread or not.
*
* @return YES if is a group thread, NO otherwise.
*/
- (BOOL)isGroupThread;
/**
* Returns the name of the thread.
*
* @return The name of the thread.
*/
- (NSString *)name;
- (NSString *)nameWithTransaction:(YapDatabaseReadTransaction *)transaction;
/**
* @returns recipientId for each recipient in the thread
*/
@property (nonatomic, readonly) NSArray<NSString *> *recipientIdentifiers;
- (BOOL)isNoteToSelf;
/**
* Whether the thread is a message request.
*
* @return YES if the combination of thread and contact approval means this thread should appear in the message requests section, NO otherwise.
*/
- (BOOL)isMessageRequest;
- (BOOL)isMessageRequestUsingTransaction:(YapDatabaseReadTransaction *)transaction;
- (BOOL)isBlocked;
- (BOOL)isBlockedUsingTransaction:(YapDatabaseReadTransaction *)transaction;
#pragma mark Interactions
- (void)enumerateInteractionsWithTransaction:(YapDatabaseReadTransaction *)transaction usingBlock:(void (^)(TSInteraction *interaction, BOOL *stop))block;
- (void)enumerateInteractionsUsingBlock:(void (^)(TSInteraction *interaction))block;
/**
* @return The number of interactions in this thread.
*/
- (NSUInteger)numberOfInteractions;
- (NSUInteger)numberOfInteractionsWithTransaction:(YapDatabaseReadTransaction *)transaction;
/**
* @return If there is any message mentioning current user in this thread.
*/
- (NSUInteger)unreadMentionMessageCount;
- (NSUInteger)unreadMentionMessageCountWithTransaction:(YapDatabaseReadTransaction *)transaction;
/**
* Returns the string that will be displayed typically in a conversations view as a preview of the last message
* received in this thread.
*
* @return Thread preview string.
*/
- (NSString *)lastMessageTextWithTransaction:(YapDatabaseReadTransaction *)transaction
NS_SWIFT_NAME(lastMessageText(transaction:));
- (nullable TSInteraction *)lastInteractionForInboxWithTransaction:(YapDatabaseReadTransaction *)transaction
NS_SWIFT_NAME(lastInteractionForInbox(transaction:));
/**
* Updates the thread's caches of the latest interaction.
*
* @param lastMessage Latest Interaction to take into consideration.
* @param transaction Database transaction.
*/
- (void)updateWithLastMessage:(TSInteraction *)lastMessage transaction:(YapDatabaseReadWriteTransaction *)transaction;
- (void)removeAllThreadInteractionsWithTransaction:(YapDatabaseReadWriteTransaction *)transaction;
- (TSInteraction *)getLastInteractionWithTransaction:(YapDatabaseReadTransaction *)transaction;
#pragma mark Disappearing Messages
- (OWSDisappearingMessagesConfiguration *)disappearingMessagesConfigurationWithTransaction:
(YapDatabaseReadTransaction *)transaction;
- (uint32_t)disappearingMessagesDurationWithTransaction:(YapDatabaseReadTransaction *)transaction;
#pragma mark Drafts
/**
* Returns the last known draft for that thread. Always returns a string. Empty string if nil.
*
* @param transaction Database transaction.
*
* @return Last known draft for that thread.
*/
- (NSString *)currentDraftWithTransaction:(YapDatabaseReadTransaction *)transaction;
/**
* Sets the draft of a thread. Typically called when leaving a conversation view.
*
* @param draftString Draft string to be saved.
* @param transaction Database transaction.
*/
- (void)setDraft:(NSString *)draftString transaction:(YapDatabaseReadWriteTransaction *)transaction;
#pragma mark Muting
- (void)updateWithMutedUntilDate:(NSDate * _Nullable)mutedUntilDate transaction:(YapDatabaseReadWriteTransaction *)transaction;
@end
NS_ASSUME_NONNULL_END

View File

@ -1,375 +0,0 @@
//
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
//
#import "TSThread.h"
#import <SignalCoreKit/Cryptography.h>
#import <SignalCoreKit/NSDate+OWS.h>
#import <SignalCoreKit/NSString+OWS.h>
#import <YapDatabase/YapDatabase.h>
#import <SessionMessagingKit/SessionMessagingKit-Swift.h>
#import <Curve25519Kit/Curve25519.h>
NS_ASSUME_NONNULL_BEGIN
BOOL IsNoteToSelfEnabled(void)
{
return YES;
}
@interface TSThread ()
@property (nonatomic) NSDate *creationDate;
@property (nonatomic, nullable) NSDate *lastInteractionDate;
@property (nonatomic, nullable) NSNumber *archivedAsOfMessageSortId;
@property (atomic, nullable) NSDate *mutedUntilDate;
@end
@implementation TSThread
#pragma mark Initialization
+ (NSString *)collection {
return @"TSThread";
}
- (instancetype)initWithUniqueId:(NSString *_Nullable)uniqueId
{
self = [super initWithUniqueId:uniqueId];
if (self) {
_creationDate = [NSDate date];
_messageDraft = nil;
}
return self;
}
- (nullable instancetype)initWithCoder:(NSCoder *)coder
{
self = [super initWithCoder:coder];
if (!self) {
return self;
}
// renamed `hasEverHadMessage` -> `shouldBeVisible`
if (!_shouldBeVisible) {
NSNumber *_Nullable legacy_hasEverHadMessage = [coder decodeObjectForKey:@"hasEverHadMessage"];
if (legacy_hasEverHadMessage != nil) {
_shouldBeVisible = legacy_hasEverHadMessage.boolValue;
}
}
NSDate *_Nullable lastMessageDate = [coder decodeObjectOfClass:NSDate.class forKey:@"lastMessageDate"];
NSDate *_Nullable archivalDate = [coder decodeObjectOfClass:NSDate.class forKey:@"archivalDate"];
return self;
}
- (void)saveWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[super saveWithTransaction:transaction];
[SSKPreferences setHasSavedThreadWithValue:YES transaction:transaction];
}
- (void)removeWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self removeAllThreadInteractionsWithTransaction:transaction];
[super removeWithTransaction:transaction];
}
- (void)removeAllThreadInteractionsWithTransaction:(YapDatabaseReadWriteTransaction *)transaction
{
// We can't safely delete interactions while enumerating them, so
// we collect and delete separately.
//
// We don't want to instantiate the interactions when collecting them
// or when deleting them.
NSMutableArray<NSString *> *interactionIds = [NSMutableArray new];
YapDatabaseViewTransaction *interactionsByThread = [transaction ext:TSMessageDatabaseViewExtensionName];
__block BOOL didDetectCorruption = NO;
[interactionsByThread enumerateKeysInGroup:self.uniqueId
usingBlock:^(NSString *collection, NSString *key, NSUInteger index, BOOL *stop) {
if (![key isKindOfClass:[NSString class]] || key.length < 1) {
didDetectCorruption = YES;
return;
}
[interactionIds addObject:key];
}];
if (didDetectCorruption) {
[OWSPrimaryStorage incrementVersionOfDatabaseExtension:TSMessageDatabaseViewExtensionName];
}
for (NSString *interactionId in interactionIds) {
// We need to fetch each interaction, since [TSInteraction removeWithTransaction:] does important work.
TSInteraction *_Nullable interaction =
[TSInteraction fetchObjectWithUniqueID:interactionId transaction:transaction];
if (!interaction) {
continue;
}
[interaction removeWithTransaction:transaction];
}
}
- (BOOL)isNoteToSelf
{
if (!IsNoteToSelfEnabled()) { return NO; }
if (![self isKindOfClass:TSContactThread.class]) { return NO; }
return [self.contactSessionID isEqual:[SNGeneralUtilities getUserPublicKey]];
}
// Override in ContactThread
- (BOOL)isMessageRequest {
return NO;
}
// Override in ContactThread
- (BOOL)isMessageRequestUsingTransaction:(YapDatabaseReadTransaction *)transaction {
return NO;
}
// Override in ContactThread
- (BOOL)isBlocked {
return NO;
}
// Override in ContactThread
- (BOOL)isBlockedUsingTransaction:(YapDatabaseReadTransaction *)transaction {
return NO;
}
#pragma mark To be subclassed.
- (BOOL)isGroupThread {
return NO;
}
// Override in ContactThread
- (nullable NSString *)contactSessionID
{
return nil;
}
- (NSString *)name {
return nil;
}
- (NSString *)nameWithTransaction:(YapDatabaseReadTransaction *)transaction
{
return nil;
}
- (NSArray<NSString *> *)recipientIdentifiers
{
return @[];
}
#pragma mark Interactions
/**
* Iterate over this thread's interactions
*/
- (void)enumerateInteractionsWithTransaction:(YapDatabaseReadTransaction *)transaction
usingBlock:(void (^)(TSInteraction *interaction, BOOL *stop))block
{
YapDatabaseViewTransaction *interactionsByThread = [transaction ext:TSMessageDatabaseViewExtensionName];
[interactionsByThread
enumerateKeysAndObjectsInGroup:self.uniqueId
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
TSInteraction *interaction = object;
block(interaction, stop);
}];
}
/**
* Enumerates all the threads interactions. Note this will explode if you try to create a transaction in the block.
* If you need a transaction, use the sister method: `enumerateInteractionsWithTransaction:usingBlock`
*/
- (void)enumerateInteractionsUsingBlock:(void (^)(TSInteraction *interaction))block
{
[self.dbReadWriteConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
[self enumerateInteractionsWithTransaction:transaction
usingBlock:^(
TSInteraction *interaction, BOOL *stop) {
block(interaction);
}];
}];
}
- (TSInteraction *)lastInteraction
{
__block TSInteraction *interaction;
[self.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
interaction = [self getLastInteractionWithTransaction:transaction];
}];
return interaction;
}
- (TSInteraction *)getLastInteractionWithTransaction:(YapDatabaseReadTransaction *)transaction
{
YapDatabaseViewTransaction *interactions = [transaction ext:TSMessageDatabaseViewExtensionName];
return [interactions lastObjectInGroup:self.uniqueId];
}
/**
* Useful for tests and debugging. In production use an enumeration method.
*/
- (NSArray<TSInteraction *> *)allInteractions
{
NSMutableArray<TSInteraction *> *interactions = [NSMutableArray new];
[self enumerateInteractionsUsingBlock:^(TSInteraction *interaction) {
[interactions addObject:interaction];
}];
return [interactions copy];
}
- (NSUInteger)numberOfInteractions
{
__block NSUInteger count;
[[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) {
count = [self numberOfInteractionsWithTransaction:transaction];
}];
return count;
}
- (NSUInteger)numberOfInteractionsWithTransaction:(YapDatabaseReadTransaction *)transaction
{
YapDatabaseViewTransaction *interactionsByThread = [transaction ext:TSMessageDatabaseViewExtensionName];
return [interactionsByThread numberOfItemsInGroup:self.uniqueId];
}
- (NSUInteger)unreadMentionMessageCount
{
__block NSUInteger unreadMentionMessageCount;
[[self dbReadConnection] readWithBlock:^(YapDatabaseReadTransaction *transaction) {
unreadMentionMessageCount = [self unreadMentionMessageCountWithTransaction:transaction];
}];
return unreadMentionMessageCount;
}
- (NSUInteger)unreadMentionMessageCountWithTransaction:(YapDatabaseReadTransaction *)transaction
{
YapDatabaseViewTransaction *unreadMentions = [transaction ext:TSUnreadMentionDatabaseViewExtensionName];
return [unreadMentions numberOfItemsInGroup:self.uniqueId];
}
- (nullable TSInteraction *)lastInteractionForInboxWithTransaction:(YapDatabaseReadTransaction *)transaction
{
__block NSUInteger missedCount = 0;
__block TSInteraction *last = nil;
[[transaction ext:TSMessageDatabaseViewExtensionName]
enumerateKeysAndObjectsInGroup:self.uniqueId
withOptions:NSEnumerationReverse
usingBlock:^(NSString *collection, NSString *key, id object, NSUInteger index, BOOL *stop) {
missedCount++;
TSInteraction *interaction = (TSInteraction *)object;
if ([TSThread shouldInteractionAppearInInbox:interaction]) {
last = interaction;
// For long ignored threads, with lots of SN changes this can get really slow.
// I see this in development because I have a lot of long forgotten threads with
// members who's test devices are constantly reinstalled. We could add a
// purpose-built DB view, but I think in the real world this is rare to be a
// hotspot.
*stop = YES;
}
}];
return last;
}
- (NSString *)lastMessageTextWithTransaction:(YapDatabaseReadTransaction *)transaction
{
TSInteraction *interaction = [self lastInteractionForInboxWithTransaction:transaction];
if ([interaction conformsToProtocol:@protocol(OWSPreviewText)]) {
id<OWSPreviewText> previewable = (id<OWSPreviewText>)interaction;
return [previewable previewTextWithTransaction:transaction].filterStringForDisplay;
} else {
return @"";
}
}
// Returns YES IFF the interaction should show up in the inbox as the last message.
+ (BOOL)shouldInteractionAppearInInbox:(TSInteraction *)interaction
{
if (interaction.isDynamicInteraction) {
return NO;
}
if ([interaction isKindOfClass:[TSMessage class]]) {
TSMessage *message = (TSMessage *)interaction;
if (message.isDeleted) {
return NO;
}
}
return YES;
}
- (void)updateWithLastMessage:(TSInteraction *)lastMessage transaction:(YapDatabaseReadWriteTransaction *)transaction {
if (![self.class shouldInteractionAppearInInbox:lastMessage]) {
return;
}
if ([_lastInteractionDate compare: lastMessage.receivedAtDate] == NSOrderedAscending) {
_lastInteractionDate = lastMessage.receivedAtDate;
[super saveWithTransaction:transaction];
}
if (!self.shouldBeVisible) {
self.shouldBeVisible = YES;
[self saveWithTransaction:transaction];
} else {
[self touchWithTransaction:transaction];
}
}
#pragma mark Drafts
- (NSString *)currentDraftWithTransaction:(YapDatabaseReadTransaction *)transaction {
TSThread *thread = [TSThread fetchObjectWithUniqueID:self.uniqueId transaction:transaction];
if (thread.messageDraft) {
return thread.messageDraft;
} else {
return @"";
}
}
- (void)setDraft:(NSString *)draftString transaction:(YapDatabaseReadWriteTransaction *)transaction {
TSThread *thread = [TSThread fetchObjectWithUniqueID:self.uniqueId transaction:transaction];
thread.messageDraft = draftString;
[thread saveWithTransaction:transaction];
}
#pragma mark Muting
- (BOOL)isMuted
{
NSDate *mutedUntilDate = self.mutedUntilDate;
NSDate *now = [NSDate date];
return (mutedUntilDate != nil && [mutedUntilDate timeIntervalSinceDate:now] > 0);
}
- (void)updateWithMutedUntilDate:(NSDate * _Nullable)mutedUntilDate transaction:(YapDatabaseReadWriteTransaction *)transaction
{
[self applyChangeToSelfAndLatestCopy:transaction
changeBlock:^(TSThread *thread) {
[thread setMutedUntilDate:mutedUntilDate];
}];
[transaction addCompletionQueue:dispatch_get_main_queue() completionBlock:^{
[NSNotificationCenter.defaultCenter postNotificationName:NSNotification.muteSettingUpdated object:self.uniqueId];
}];
}
@end
NS_ASSUME_NONNULL_END

View File

@ -45,7 +45,10 @@ public extension Setting.BoolKey {
static let playNotificationSoundInForeground: Setting.BoolKey = "playNotificationSoundInForeground"
/// A flag indicating whether the user has ever saved a thread
static let hasSavedThreadKey: Setting.BoolKey = "hasSavedThread"
static let hasSavedThread: Setting.BoolKey = "hasSavedThread"
/// A flag indicating whether the user has ever send a message
static let hasSentAMessage: Setting.BoolKey = "hasSentAMessageKey"
}
public extension Setting.StringKey {

View File

@ -2,7 +2,7 @@
import Foundation
public enum Legacy {
public enum SSKLegacy {
// MARK: - Collections and Keys
internal static let swarmCollectionPrefix = "LokiSwarmCollection-"

View File

@ -11,28 +11,28 @@ enum _003_YDBToGRDBMigration: Migration {
// MARK: - OnionRequestPath, Snode Pool & Swarm
// Note: Want to exclude the Snode's we already added from the 'onionRequestPathResult'
var snodeResult: Set<Legacy.Snode> = []
var snodeSetResult: [String: Set<Legacy.Snode>] = [:]
var snodeResult: Set<SSKLegacy.Snode> = []
var snodeSetResult: [String: Set<SSKLegacy.Snode>] = [:]
var lastSnodePoolRefreshDate: Date? = nil
// Map the Legacy types for the NSKeyedUnarchiver
NSKeyedUnarchiver.setClass(
Legacy.Snode.self,
SSKLegacy.Snode.self,
forClassName: "SessionSnodeKit.Snode"
)
Storage.read { transaction in
// Process the lastSnodePoolRefreshDate
lastSnodePoolRefreshDate = transaction.object(
forKey: Legacy.lastSnodePoolRefreshDateKey,
inCollection: Legacy.lastSnodePoolRefreshDateCollection
forKey: SSKLegacy.lastSnodePoolRefreshDateKey,
inCollection: SSKLegacy.lastSnodePoolRefreshDateCollection
) as? Date
// Process the OnionRequestPaths
if
let path0Snode0 = transaction.object(forKey: "0-0", inCollection: Legacy.onionRequestPathCollection) as? Legacy.Snode,
let path0Snode1 = transaction.object(forKey: "0-1", inCollection: Legacy.onionRequestPathCollection) as? Legacy.Snode,
let path0Snode2 = transaction.object(forKey: "0-2", inCollection: Legacy.onionRequestPathCollection) as? Legacy.Snode
let path0Snode0 = transaction.object(forKey: "0-0", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path0Snode1 = transaction.object(forKey: "0-1", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path0Snode2 = transaction.object(forKey: "0-2", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode
{
snodeResult.insert(path0Snode0)
snodeResult.insert(path0Snode1)
@ -40,9 +40,9 @@ enum _003_YDBToGRDBMigration: Migration {
snodeSetResult["\(SnodeSet.onionRequestPathPrefix)0"] = [ path0Snode0, path0Snode1, path0Snode2 ]
if
let path1Snode0 = transaction.object(forKey: "1-0", inCollection: Legacy.onionRequestPathCollection) as? Legacy.Snode,
let path1Snode1 = transaction.object(forKey: "1-1", inCollection: Legacy.onionRequestPathCollection) as? Legacy.Snode,
let path1Snode2 = transaction.object(forKey: "1-2", inCollection: Legacy.onionRequestPathCollection) as? Legacy.Snode
let path1Snode0 = transaction.object(forKey: "1-0", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path1Snode1 = transaction.object(forKey: "1-1", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode,
let path1Snode2 = transaction.object(forKey: "1-2", inCollection: SSKLegacy.onionRequestPathCollection) as? SSKLegacy.Snode
{
snodeResult.insert(path1Snode0)
snodeResult.insert(path1Snode1)
@ -52,8 +52,8 @@ enum _003_YDBToGRDBMigration: Migration {
}
// Process the SnodePool
transaction.enumerateKeysAndObjects(inCollection: Legacy.snodePoolCollection) { _, object, _ in
guard let snode = object as? Legacy.Snode else { return }
transaction.enumerateKeysAndObjects(inCollection: SSKLegacy.snodePoolCollection) { _, object, _ in
guard let snode = object as? SSKLegacy.Snode else { return }
snodeResult.insert(snode)
}
@ -61,16 +61,16 @@ enum _003_YDBToGRDBMigration: Migration {
var swarmCollections: Set<String> = []
transaction.enumerateCollections { collectionName, _ in
if collectionName.starts(with: Legacy.swarmCollectionPrefix) {
swarmCollections.insert(collectionName.substring(from: Legacy.swarmCollectionPrefix.count))
if collectionName.starts(with: SSKLegacy.swarmCollectionPrefix) {
swarmCollections.insert(collectionName.substring(from: SSKLegacy.swarmCollectionPrefix.count))
}
}
for swarmCollection in swarmCollections {
let collection: String = "\(Legacy.swarmCollectionPrefix)\(swarmCollection)"
let collection: String = "\(SSKLegacy.swarmCollectionPrefix)\(swarmCollection)"
transaction.enumerateKeysAndObjects(inCollection: collection) { _, object, _ in
guard let snode = object as? Legacy.Snode else { return }
guard let snode = object as? SSKLegacy.Snode else { return }
snodeResult.insert(snode)
snodeSetResult[swarmCollection] = (snodeSetResult[swarmCollection] ?? Set()).inserting(snode)
}
@ -112,13 +112,13 @@ enum _003_YDBToGRDBMigration: Migration {
// TODO: Move into the top read block???
Storage.read { transaction in
// Extract the received message hashes
transaction.enumerateKeysAndObjects(inCollection: Legacy.receivedMessagesCollection) { key, object, _ in
transaction.enumerateKeysAndObjects(inCollection: SSKLegacy.receivedMessagesCollection) { key, object, _ in
guard let hashSet = object as? Set<String> else { return }
receivedMessageResults[key] = hashSet
}
// Retrieve the last message info
transaction.enumerateKeysAndObjects(inCollection: Legacy.lastMessageHashCollection) { key, object, _ in
transaction.enumerateKeysAndObjects(inCollection: SSKLegacy.lastMessageHashCollection) { key, object, _ in
guard let lastMessageJson = object as? JSON else { return }
guard let lastMessageHash: String = lastMessageJson["hash"] as? String else { return }

View File

@ -2,9 +2,7 @@
import Foundation
public typealias SUKLegacy = Legacy
public enum Legacy {
public enum SUKLegacy {
// MARK: - Collections and Keys
internal static let userAccountRegisteredNumberKey = "TSStorageRegisteredNumberKey"

View File

@ -14,42 +14,42 @@ enum _003_YDBToGRDBMigration: Migration {
var seedHexString: String?
var userEd25519SecretKeyHexString: String?
var userEd25519PublicKeyHexString: String?
var userX25519KeyPair: Legacy.KeyPair?
var userX25519KeyPair: SUKLegacy.KeyPair?
// Map the Legacy types for the NSKeyedUnarchiver
NSKeyedUnarchiver.setClass(
Legacy.KeyPair.self,
SUKLegacy.KeyPair.self,
forClassName: "ECKeyPair"
)
Storage.read { transaction in
registeredNumber = transaction.object(
forKey: Legacy.userAccountRegisteredNumberKey,
inCollection: Legacy.userAccountCollection
forKey: SUKLegacy.userAccountRegisteredNumberKey,
inCollection: SUKLegacy.userAccountCollection
) as? String
// Note: The 'seed', 'ed25519SecretKey' and 'ed25519PublicKey' were
// all previously stored as hex strings, so we need to convert them
// to data before we store them in the new database
seedHexString = transaction.object(
forKey: Legacy.identityKeyStoreSeedKey,
inCollection: Legacy.identityKeyStoreCollection
forKey: SUKLegacy.identityKeyStoreSeedKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userEd25519SecretKeyHexString = transaction.object(
forKey: Legacy.identityKeyStoreEd25519SecretKey,
inCollection: Legacy.identityKeyStoreCollection
forKey: SUKLegacy.identityKeyStoreEd25519SecretKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userEd25519PublicKeyHexString = transaction.object(
forKey: Legacy.identityKeyStoreEd25519PublicKey,
inCollection: Legacy.identityKeyStoreCollection
forKey: SUKLegacy.identityKeyStoreEd25519PublicKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? String
userX25519KeyPair = transaction.object(
forKey: Legacy.identityKeyStoreIdentityKey,
inCollection: Legacy.identityKeyStoreCollection
) as? Legacy.KeyPair
forKey: SUKLegacy.identityKeyStoreIdentityKey,
inCollection: SUKLegacy.identityKeyStoreCollection
) as? SUKLegacy.KeyPair
}
// No need to continue if the user isn't registered
@ -60,7 +60,7 @@ enum _003_YDBToGRDBMigration: Migration {
let seedHexString: String = seedHexString,
let userEd25519SecretKeyHexString: String = userEd25519SecretKeyHexString,
let userEd25519PublicKeyHexString: String = userEd25519PublicKeyHexString,
let userX25519KeyPair: Legacy.KeyPair = userX25519KeyPair
let userX25519KeyPair: SUKLegacy.KeyPair = userX25519KeyPair
else {
// If this is a fresh install then we would have created all of the Identity
// values directly within the 'Identity' table so this is actually a valid

View File

@ -127,18 +127,4 @@ public extension Identity {
return data.toHexString()
}
}
static func clearAll() {
GRDBStorage.shared.write { db in
try Identity.deleteAll(db)
}
}
}
@objc(SUKIdentity)
public class objc_Identity: NSObject {
@objc(clearAll)
public static func objc_clearAll() {
Identity.clearAll()
}
}

View File

@ -1,6 +1,7 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import YapDatabase
import SessionMessagingKit
@objc(SNBlockingManagerRemovalMigration)
@ -19,6 +20,12 @@ public class BlockingManagerRemovalMigration: OWSDatabaseMigration {
let kOWSBlockingManager_BlockListCollection: String = "kOWSBlockingManager_BlockedPhoneNumbersCollection"
let kOWSBlockingManager_BlockedPhoneNumbersKey: String = "kOWSBlockingManager_BlockedPhoneNumbersKey"
// Note: These will be done in the YDB to GRDB migration but have added it here to be safe
NSKeyedUnarchiver.setClass(
SMKLegacy._Contact.self,
forClassName: "SNContact"
)
let dbConnection: YapDatabaseConnection = primaryStorage.newDatabaseConnection()
let blockedSessionIds: Set<String> = Set(dbConnection.object(
@ -28,10 +35,10 @@ public class BlockingManagerRemovalMigration: OWSDatabaseMigration {
Storage.write(
with: { transaction in
var result: Set<SessionMessagingKit.Legacy._Contact> = []
var result: Set<SMKLegacy._Contact> = []
transaction.enumerateRows(inCollection: Legacy.contactCollection) { _, object, _, _ in
guard let contact = object as? SessionMessagingKit.Legacy._Contact else { return }
transaction.enumerateRows(inCollection: SMKLegacy.contactCollection) { _, object, _, _ in
guard let contact = object as? SMKLegacy._Contact else { return }
result.insert(contact)
}
@ -39,7 +46,7 @@ public class BlockingManagerRemovalMigration: OWSDatabaseMigration {
.filter { contact -> Bool in blockedSessionIds.contains(contact.sessionID) }
.forEach { contact in
contact.isBlocked = true
transaction.setObject(contact, forKey: contact.sessionID, inCollection: Legacy.contactCollection)
transaction.setObject(contact, forKey: contact.sessionID, inCollection: SMKLegacy.contactCollection)
}
// Now that the values have been migrated we can clear out the old collection

View File

@ -1,10 +1,11 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import YapDatabase
import SessionMessagingKit
@objc(SNContactsMigration)
public class ContactsMigration : OWSDatabaseMigration {
public class ContactsMigration: OWSDatabaseMigration {
@objc
class func migrationId() -> String {
@ -17,20 +18,33 @@ public class ContactsMigration : OWSDatabaseMigration {
private func doMigrationAsync(completion: @escaping OWSDatabaseMigrationCompletion) {
var contacts: [SMKLegacy._Contact] = []
TSContactThread.enumerateCollectionObjects { object, _ in
guard let thread = object as? TSContactThread else { return }
let sessionID = thread.contactSessionID()
var contact: SMKLegacy._Contact?
Storage.read { transaction in
contact = transaction.object(forKey: sessionID, inCollection: SMKLegacy.contactCollection) as? SMKLegacy._Contact
}
if let contact: SMKLegacy._Contact = contact {
contact.isTrusted = true
contacts.append(contact)
// Note: These will be done in the YDB to GRDB migration but have added it here to be safe
NSKeyedUnarchiver.setClass(
SMKLegacy._Thread.self,
forClassName: "TSThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._ContactThread.self,
forClassName: "TSContactThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._Contact.self,
forClassName: "SNContact"
)
Storage.read { transaction in
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.threadCollection) { _, object, _ in
guard let thread = object as? SMKLegacy._ContactThread else { return }
let sessionId: String = SMKLegacy._ContactThread.contactSessionId(fromThreadId: thread.uniqueId)
let contact: SMKLegacy._Contact? = transaction.object(forKey: sessionId, inCollection: SMKLegacy.contactCollection) as? SMKLegacy._Contact
contact?.isTrusted = true
contacts = contacts.appending(contact)
}
}
Storage.write(with: { transaction in
contacts.forEach { contact in
transaction.setObject(contact, forKey: contact.sessionID, inCollection: SMKLegacy.contactCollection)

View File

@ -1,10 +1,11 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import YapDatabase
import SessionMessagingKit
@objc(SNMessageRequestsMigration)
public class MessageRequestsMigration : OWSDatabaseMigration {
public class MessageRequestsMigration: OWSDatabaseMigration {
@objc
class func migrationId() -> String {
@ -16,42 +17,61 @@ public class MessageRequestsMigration : OWSDatabaseMigration {
}
private func doMigrationAsync(completion: @escaping OWSDatabaseMigrationCompletion) {
let userPublicKey: String = getUserHexEncodedPublicKey()
var contacts: Set<SMKLegacy._Contact> = Set()
var threads: [TSThread] = []
var threads: [SMKLegacy._Thread] = []
// Note: These will be done in the YDB to GRDB migration but have added it here to be safe
NSKeyedUnarchiver.setClass(
SMKLegacy._Thread.self,
forClassName: "TSThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._ContactThread.self,
forClassName: "TSContactThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._GroupThread.self,
forClassName: "TSGroupThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._GroupModel.self,
forClassName: "TSGroupModel"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._Contact.self,
forClassName: "SNContact"
)
TSThread.enumerateCollectionObjects { object, _ in
guard let thread: TSThread = object as? TSThread else { return }
Storage.read { transaction in
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.threadCollection) { _, object, _ in
guard let thread: SMKLegacy._Thread = object as? SMKLegacy._Thread else { return }
Storage.read { transaction in
if let contactThread: TSContactThread = thread as? TSContactThread {
let sessionId: String = contactThread.contactSessionID()
if thread is SMKLegacy._ContactThread {
let sessionId: String = SMKLegacy._ContactThread.contactSessionId(fromThreadId: thread.uniqueId)
if let contact: SMKLegacy._Contact = transaction.object(forKey: sessionId, inCollection: Legacy.contactCollection) as? SMKLegacy._Contact {
if let contact: SMKLegacy._Contact = transaction.object(forKey: sessionId, inCollection: SMKLegacy.contactCollection) as? SMKLegacy._Contact {
contact.isApproved = true
contact.didApproveMe = true
contacts.insert(contact)
}
}
else if let groupThread: TSGroupThread = thread as? TSGroupThread, groupThread.isClosedGroup {
else if let groupThread: SMKLegacy._GroupThread = thread as? SMKLegacy._GroupThread, groupThread.isClosedGroup {
let groupAdmins: [String] = groupThread.groupModel.groupAdminIds
groupAdmins.forEach { sessionId in
if let contact: SMKLegacy._Contact = transaction.object(forKey: sessionId, inCollection: Legacy.contactCollection) as? SMKLegacy._Contact {
if let contact: SMKLegacy._Contact = transaction.object(forKey: sessionId, inCollection: SMKLegacy.contactCollection) as? SMKLegacy._Contact {
contact.isApproved = true
contact.didApproveMe = true
contacts.insert(contact)
}
}
}
threads.append(thread)
}
threads.append(thread)
}
let userPublicKey: String = getUserHexEncodedPublicKey()
Storage.read { transaction in
if let user = transaction.object(forKey: userPublicKey, inCollection: Legacy.contactCollection) as? SMKLegacy._Contact {
if let user = transaction.object(forKey: userPublicKey, inCollection: SMKLegacy.contactCollection) as? SMKLegacy._Contact {
user.isApproved = true
user.didApproveMe = true
contacts.insert(user)
@ -60,10 +80,10 @@ public class MessageRequestsMigration : OWSDatabaseMigration {
Storage.write(with: { transaction in
contacts.forEach { contact in
transaction.setObject(contact, forKey: contact.sessionID, inCollection: Legacy.contactCollection)
transaction.setObject(contact, forKey: contact.sessionID, inCollection: SMKLegacy.contactCollection)
}
threads.forEach { thread in
thread.save(with: transaction)
transaction.setObject(thread, forKey: thread.uniqueId, inCollection: SMKLegacy.threadCollection)
}
self.save(with: transaction) // Intentionally capture self
}, completion: {

View File

@ -1,6 +1,8 @@
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
import Foundation
import YapDatabase
import SessionMessagingKit
@objc(SNOpenGroupServerIdLookupMigration)
public class OpenGroupServerIdLookupMigration: OWSDatabaseMigration {
@ -16,14 +18,35 @@ public class OpenGroupServerIdLookupMigration: OWSDatabaseMigration {
private func doMigrationAsync(completion: @escaping OWSDatabaseMigrationCompletion) {
var lookups: [OpenGroupServerIdLookup] = []
// Note: These will be done in the YDB to GRDB migration but have added it here to be safe
NSKeyedUnarchiver.setClass(
SMKLegacy._Thread.self,
forClassName: "TSThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._ContactThread.self,
forClassName: "TSContactThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._GroupThread.self,
forClassName: "TSGroupThread"
)
NSKeyedUnarchiver.setClass(
SMKLegacy._GroupModel.self,
forClassName: "TSGroupModel"
)
// TODO: Add, SMKLegacy._OpenGroup, SMKLegacy._TSMessage (and related)
Storage.write(with: { transaction in
TSGroupThread.enumerateCollectionObjects(with: transaction) { object, _ in
guard let thread: TSGroupThread = object as? TSGroupThread else { return }
guard let threadId: String = thread.uniqueId else { return }
guard let openGroup: OpenGroupV2 = Storage.shared.getV2OpenGroup(for: threadId) else { return }
transaction.enumerateKeysAndObjects(inCollection: SMKLegacy.threadCollection) { _, object, _ in
guard let thread = object as? SMKLegacy._GroupThread else { return }
guard let openGroup: OpenGroupV2 = Storage.shared.getV2OpenGroup(for: thread.uniqueId) else { return }
guard let interactionsByThread: YapDatabaseViewTransaction = transaction.ext(SMKLegacy.messageDatabaseViewExtensionName) as? YapDatabaseViewTransaction else {
return
}
thread.enumerateInteractions(with: transaction) { interaction, _ in
guard let tsMessage: TSMessage = interaction as? TSMessage else { return }
interactionsByThread.enumerateKeysAndObjects(inGroup: thread.uniqueId) { _, _, object, _, _ in
guard let tsMessage: TSMessage = object as? TSMessage else { return }
guard let tsMessageId: String = tsMessage.uniqueId else { return }
lookups.append(

View File

@ -8,11 +8,9 @@
#import <SignalUtilitiesKit/OWSProfileManager.h>
#import <SessionMessagingKit/SSKEnvironment.h>
#import <SessionMessagingKit/TSAccountManager.h>
#import <SessionMessagingKit/TSContactThread.h>
#import <SessionMessagingKit/TSDatabaseView.h>
#import <SessionMessagingKit/TSIncomingMessage.h>
#import <SessionMessagingKit/TSOutgoingMessage.h>
#import <SessionMessagingKit/TSThread.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>

View File

@ -8,8 +8,6 @@
#import <SignalUtilitiesKit/AppVersion.h>
#import <SessionUtilitiesKit/NSUserDefaults+OWS.h>
#import <SessionMessagingKit/TSAccountManager.h>
#import <SessionMessagingKit/TSThread.h>
#import <SessionMessagingKit/TSGroupThread.h>
#import <YapDatabase/YapDatabase.h>
#import <SignalUtilitiesKit/SignalUtilitiesKit-Swift.h>