diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 287ea28df..0cc42ecac 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -163,6 +163,7 @@ 7BD477A827EC39F5004E2822 /* Atomic.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BD477A727EC39F5004E2822 /* Atomic.swift */; }; 7BDCFC08242186E700641C39 /* NotificationServiceExtensionContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */; }; 7BDCFC0B2421EB7600641C39 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = B6F509951AA53F760068F56A /* Localizable.strings */; }; + 7BF6F9FD293D64EA0099DEE0 /* Version.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BF6F9FC293D64EA0099DEE0 /* Version.swift */; }; 7BFA8AE32831D0D4001876F3 /* ContextMenuVC+EmojiReactsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFA8AE22831D0D4001876F3 /* ContextMenuVC+EmojiReactsView.swift */; }; 7BFD1A8A2745C4F000FB91B9 /* Permissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFD1A892745C4F000FB91B9 /* Permissions.swift */; }; 7BFD1A8C2747150E00FB91B9 /* TurnServerInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7BFD1A8B2747150E00FB91B9 /* TurnServerInfo.swift */; }; @@ -1239,6 +1240,7 @@ 7BD477A927F15F24004E2822 /* OpenGroupServerIdLookup.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OpenGroupServerIdLookup.swift; sourceTree = ""; }; 7BDCFC0424206E7300641C39 /* SessionNotificationServiceExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = SessionNotificationServiceExtension.entitlements; sourceTree = ""; }; 7BDCFC07242186E700641C39 /* NotificationServiceExtensionContext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NotificationServiceExtensionContext.swift; sourceTree = ""; }; + 7BF6F9FC293D64EA0099DEE0 /* Version.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Version.swift; sourceTree = ""; }; 7BFA8AE22831D0D4001876F3 /* ContextMenuVC+EmojiReactsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "ContextMenuVC+EmojiReactsView.swift"; sourceTree = ""; }; 7BFD1A892745C4F000FB91B9 /* Permissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Permissions.swift; sourceTree = ""; }; 7BFD1A8B2747150E00FB91B9 /* TurnServerInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TurnServerInfo.swift; sourceTree = ""; }; @@ -2559,6 +2561,7 @@ FD5D201D27B0D87C00FEA984 /* SessionId.swift */, 7B7CB191271508AD0079FF93 /* CallRingTonePlayer.swift */, 7B0EFDED274F598600FFAAE7 /* TimestampUtils.swift */, + 7BF6F9FC293D64EA0099DEE0 /* Version.swift */, ); path = General; sourceTree = ""; @@ -5393,6 +5396,7 @@ FD17D7E527F6A09900122BE0 /* Identity.swift in Sources */, FD9004142818AD0B00ABAAF6 /* _002_SetupStandardJobs.swift in Sources */, B87EF18126377A1D00124B3C /* Features.swift in Sources */, + 7BF6F9FD293D64EA0099DEE0 /* Version.swift in Sources */, FD09797727FAB7A600936362 /* Data+Image.swift in Sources */, C300A60D2554B31900555489 /* Logging.swift in Sources */, B8FF8EA625C11FEF004D1F22 /* IPv4.swift in Sources */, diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index f4781091d..ece7d77e5 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -687,8 +687,8 @@ final class ConversationVC: BaseVC, ConversationSearchControllerDelegate, UITabl } } - if initialLoad { - addOrRemoveOutdatedClientBanner(contactIsUsingOutdatedClient: true) + if initialLoad || viewModel.threadData.contactLastKnownClientVersion != updatedThreadData.contactLastKnownClientVersion { + addOrRemoveOutdatedClientBanner(contactIsUsingOutdatedClient: updatedThreadData.contactLastKnownClientVersion == .preDisappearingMessagesRedesign) } if initialLoad || viewModel.threadData.threadIsBlocked != updatedThreadData.threadIsBlocked { diff --git a/SessionMessagingKit/Database/Migrations/_011_DisappearingMessagesConfiguration.swift b/SessionMessagingKit/Database/Migrations/_011_DisappearingMessagesConfiguration.swift index d251c3e5e..10f690433 100644 --- a/SessionMessagingKit/Database/Migrations/_011_DisappearingMessagesConfiguration.swift +++ b/SessionMessagingKit/Database/Migrations/_011_DisappearingMessagesConfiguration.swift @@ -18,8 +18,7 @@ enum _011_DisappearingMessagesConfiguration: Migration { } try db.alter(table: Contact.self) { t in - t.add(.isUsingOutdatedClient, .boolean) - .defaults(to: false) + t.add(.lastKnownClientVersion, .integer) } func updateDisappearingMessageType(_ db: GRDB.Database, id: String, type: DisappearingMessagesConfiguration.DisappearingMessageType) throws { diff --git a/SessionMessagingKit/Database/Models/Contact.swift b/SessionMessagingKit/Database/Models/Contact.swift index 25cf3feac..0ea74fc36 100644 --- a/SessionMessagingKit/Database/Models/Contact.swift +++ b/SessionMessagingKit/Database/Models/Contact.swift @@ -16,7 +16,7 @@ public struct Contact: Codable, Identifiable, Equatable, FetchableRecord, Persis case isTrusted case isApproved case isBlocked - case isUsingOutdatedClient + case lastKnownClientVersion case didApproveMe case hasBeenBlocked } @@ -33,8 +33,8 @@ public struct Contact: Codable, Identifiable, Equatable, FetchableRecord, Persis /// This flag is used to determine whether message requests from this contact are blocked public let isBlocked: Bool - /// This flag is used to determine whether this contact is using an outdated client regarding disappearing messages configuration - public let isUsingOutdatedClient: Bool + /// The last known client version represented by pre defined enum values + public let lastKnownClientVersion: SessionVersion.FeatureVersion? /// This flag is used to determine whether this contact has approved the current users message request public let didApproveMe: Bool @@ -55,7 +55,7 @@ public struct Contact: Codable, Identifiable, Equatable, FetchableRecord, Persis isTrusted: Bool = false, isApproved: Bool = false, isBlocked: Bool = false, - isUsingOutdatedClient: Bool = false, + lastKnownClientVersion: SessionVersion.FeatureVersion? = nil, didApproveMe: Bool = false, hasBeenBlocked: Bool = false ) { @@ -66,7 +66,7 @@ public struct Contact: Codable, Identifiable, Equatable, FetchableRecord, Persis ) self.isApproved = isApproved self.isBlocked = isBlocked - self.isUsingOutdatedClient = isUsingOutdatedClient + self.lastKnownClientVersion = lastKnownClientVersion self.didApproveMe = didApproveMe self.hasBeenBlocked = (isBlocked || hasBeenBlocked) } @@ -79,7 +79,7 @@ public extension Contact { isTrusted: Updatable = .existing, isApproved: Updatable = .existing, isBlocked: Updatable = .existing, - isUsingOutdatedClient: Updatable = .existing, + lastKnownClientVersion: Updatable = .existing, didApproveMe: Updatable = .existing ) -> Contact { return Contact( @@ -90,7 +90,7 @@ public extension Contact { ), isApproved: (isApproved ?? self.isApproved), isBlocked: (isBlocked ?? self.isBlocked), - isUsingOutdatedClient: (isUsingOutdatedClient ?? self.isUsingOutdatedClient), + lastKnownClientVersion: (lastKnownClientVersion ?? self.lastKnownClientVersion), didApproveMe: (didApproveMe ?? self.didApproveMe), hasBeenBlocked: ((isBlocked ?? self.isBlocked) || self.hasBeenBlocked) ) diff --git a/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift b/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift index 68ff7aa8c..0b5273c62 100644 --- a/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift +++ b/SessionMessagingKit/Shared Models/SessionThreadViewModel.swift @@ -21,7 +21,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat public static let threadCreationDateTimestampKey: SQL = SQL(stringLiteral: CodingKeys.threadCreationDateTimestamp.stringValue) public static let threadMemberNamesKey: SQL = SQL(stringLiteral: CodingKeys.threadMemberNames.stringValue) public static let threadIsNoteToSelfKey: SQL = SQL(stringLiteral: CodingKeys.threadIsNoteToSelf.stringValue) - public static let contactIsUsingOutdatedClientKey: SQL = SQL(stringLiteral: CodingKeys.contactIsUsingOutdatedClient.stringValue) + public static let contactLastKnownClientVersionKey: SQL = SQL(stringLiteral: CodingKeys.contactLastKnownClientVersion.stringValue) public static let threadIsMessageRequestKey: SQL = SQL(stringLiteral: CodingKeys.threadIsMessageRequest.stringValue) public static let threadRequiresApprovalKey: SQL = SQL(stringLiteral: CodingKeys.threadRequiresApproval.stringValue) public static let threadShouldBeVisibleKey: SQL = SQL(stringLiteral: CodingKeys.threadShouldBeVisible.stringValue) @@ -86,10 +86,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat public let threadIsNoteToSelf: Bool - /// This flag indicated whether the contact in this thread is using an outdated client regarding - /// disappearing messages configuration. We can use this flag in the future for other features - /// as well. - public let contactIsUsingOutdatedClient: Bool + public let contactLastKnownClientVersion: SessionVersion.FeatureVersion? /// This flag indicates whether the thread is an outgoing message request public let threadIsMessageRequest: Bool? @@ -265,7 +262,7 @@ public extension SessionThreadViewModel { self.threadMemberNames = nil self.threadIsNoteToSelf = threadIsNoteToSelf - self.contactIsUsingOutdatedClient = false + self.contactLastKnownClientVersion = nil self.threadIsMessageRequest = false self.threadRequiresApproval = false self.threadShouldBeVisible = false @@ -334,7 +331,7 @@ public extension SessionThreadViewModel { threadCreationDateTimestamp: self.threadCreationDateTimestamp, threadMemberNames: self.threadMemberNames, threadIsNoteToSelf: self.threadIsNoteToSelf, - contactIsUsingOutdatedClient: self.contactIsUsingOutdatedClient, + contactLastKnownClientVersion: self.contactLastKnownClientVersion, threadIsMessageRequest: self.threadIsMessageRequest, threadRequiresApproval: self.threadRequiresApproval, threadShouldBeVisible: self.threadShouldBeVisible, @@ -391,7 +388,7 @@ public extension SessionThreadViewModel { threadCreationDateTimestamp: self.threadCreationDateTimestamp, threadMemberNames: self.threadMemberNames, threadIsNoteToSelf: self.threadIsNoteToSelf, - contactIsUsingOutdatedClient: self.contactIsUsingOutdatedClient, + contactLastKnownClientVersion: self.contactLastKnownClientVersion, threadIsMessageRequest: self.threadIsMessageRequest, threadRequiresApproval: self.threadRequiresApproval, threadShouldBeVisible: self.threadShouldBeVisible, @@ -751,7 +748,7 @@ public extension SessionThreadViewModel { /// parse and might throw /// /// Explicitly set default values for the fields ignored for search results - let numColumnsBeforeProfiles: Int = 15 + let numColumnsBeforeProfiles: Int = 16 let request: SQLRequest = """ SELECT \(thread.alias[Column.rowID]) AS \(ViewModel.rowIdKey), @@ -760,7 +757,7 @@ public extension SessionThreadViewModel { \(thread[.creationDateTimestamp]) AS \(ViewModel.threadCreationDateTimestampKey), (\(SQL("\(thread[.id]) = \(userPublicKey)"))) AS \(ViewModel.threadIsNoteToSelfKey), - \(contact[.isUsingOutdatedClient]) AS \(ViewModel.contactIsUsingOutdatedClientKey), + \(contact[.lastKnownClientVersion]) AS \(ViewModel.contactLastKnownClientVersionKey), ( \(SQL("\(thread[.variant]) = \(SessionThread.Variant.contact)")) AND \(SQL("\(thread[.id]) != \(userPublicKey)")) AND diff --git a/SessionUtilitiesKit/General/Version.swift b/SessionUtilitiesKit/General/Version.swift new file mode 100644 index 000000000..37ac08558 --- /dev/null +++ b/SessionUtilitiesKit/General/Version.swift @@ -0,0 +1,11 @@ +// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved. + +import Foundation +import DifferenceKit + +public class SessionVersion { + public enum FeatureVersion: Int, Codable, Equatable, Hashable { + case preDisappearingMessagesRedesign + case disappearingMessageRedesign + } +}