diff --git a/SessionMessagingKit/Database/Models/Interaction.swift b/SessionMessagingKit/Database/Models/Interaction.swift index 0bb534c18..34f89d704 100644 --- a/SessionMessagingKit/Database/Models/Interaction.swift +++ b/SessionMessagingKit/Database/Models/Interaction.swift @@ -150,6 +150,7 @@ public struct Interaction: Codable, Identifiable, Equatable, FetchableRecord, Mu case .standardIncoming, .standardOutgoing, .infoCall, .infoDisappearingMessagesUpdate, + .infoClosedGroupCreated, .infoClosedGroupUpdated, .infoClosedGroupCurrentUserLeft, .infoClosedGroupCurrentUserLeaving, .infoScreenshotNotification, .infoMediaSavedNotification: return true @@ -374,16 +375,19 @@ public struct Interaction: Codable, Identifiable, Equatable, FetchableRecord, Mu self.wasRead = (self.wasRead || !self.variant.canBeUnread) // Automatically add disapeparing messages configuration - if self.variant.shouldFollowDisappearingMessagesConfiguration { + if self.variant.shouldFollowDisappearingMessagesConfiguration, + self.expiresInSeconds == nil, + self.expiresStartedAtMs == nil + { guard let disappearingMessagesConfiguration = try? DisappearingMessagesConfiguration.fetchOne(db, id: self.threadId), disappearingMessagesConfiguration.isEnabled else { - self.expiresInSeconds = self.expiresInSeconds ?? 0 + self.expiresInSeconds = 0 return } - self.expiresInSeconds = self.expiresInSeconds ?? disappearingMessagesConfiguration.durationSeconds + self.expiresInSeconds = disappearingMessagesConfiguration.durationSeconds self.expiresStartedAtMs = disappearingMessagesConfiguration.type == .disappearAfterSend ? Double(self.timestampMs) : nil } } diff --git a/SessionMessagingKit/Messages/Message.swift b/SessionMessagingKit/Messages/Message.swift index 0255d650a..79acfc9c3 100644 --- a/SessionMessagingKit/Messages/Message.swift +++ b/SessionMessagingKit/Messages/Message.swift @@ -18,6 +18,10 @@ public class Message: Codable { public var isSelfSendValid: Bool { false } public var shouldBeRetryable: Bool { false } + + // MARK: - Disappearing Messages + public var expiresInSeconds: TimeInterval? + public var expiresStartedAtMs: Double? // MARK: - Validation @@ -37,7 +41,9 @@ public class Message: Codable { sender: String? = nil, groupPublicKey: String? = nil, openGroupServerMessageId: UInt64? = nil, - serverHash: String? = nil + serverHash: String? = nil, + expiresInSeconds: TimeInterval? = nil, + expiresStartedAtMs: Double? = nil ) { self.id = id self.sentTimestamp = sentTimestamp @@ -46,6 +52,8 @@ public class Message: Codable { self.sender = sender self.openGroupServerMessageId = openGroupServerMessageId self.serverHash = serverHash + self.expiresInSeconds = expiresInSeconds + self.expiresStartedAtMs = expiresStartedAtMs } // MARK: - Proto Conversion @@ -72,6 +80,19 @@ public class Message: Codable { proto.setExpirationType(type.toProto()) } } + + public func attachDisappearingMessagesConfiguration(from proto: SNProtoContent) { + let expiresInSeconds: TimeInterval? = proto.hasExpirationTimer ? TimeInterval(proto.expirationTimer) : nil + let expiresStartedAtMs: Double? = { + if proto.expirationType == .deleteAfterSend, let timestamp = self.sentTimestamp { + return Double(timestamp) + } + return nil + }() + + self.expiresInSeconds = expiresInSeconds + self.expiresStartedAtMs = expiresStartedAtMs + } } // MARK: - Message Parsing/Processing @@ -173,7 +194,10 @@ public extension Message { .reduce(nil) { prev, variant in guard prev == nil else { return prev } - return variant.messageType.fromProto(proto, sender: sender) + let message: Message? = variant.messageType.fromProto(proto, sender: sender) + message?.attachDisappearingMessagesConfiguration(from: proto) + + return message } } diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift index 270e27d41..784b91437 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+Calls.swift @@ -301,7 +301,9 @@ extension MessageReceiver { timestampMs: (timestampMs * 1000), userPublicKey: currentUserPublicKey, openGroup: nil - ) + ), + expiresInSeconds: message.expiresInSeconds, + expiresStartedAtMs: message.expiresStartedAtMs ).inserted(db) } } diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift index 8ff057f59..6adc6e5b4 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ClosedGroups.swift @@ -680,7 +680,9 @@ extension MessageReceiver { timestampMs: ( message.sentTimestamp.map { Int64($0) } ?? SnodeAPI.currentOffsetTimestampMs() - ) + ), + expiresInSeconds: message.expiresInSeconds, + expiresStartedAtMs: message.expiresStartedAtMs ).inserted(db) } } diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+DataExtractionNotification.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+DataExtractionNotification.swift index db91fb8ea..254270670 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+DataExtractionNotification.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+DataExtractionNotification.swift @@ -39,7 +39,9 @@ extension MessageReceiver { timestampMs: (timestampMs * 1000), userPublicKey: getUserHexEncodedPublicKey(db), openGroup: nil - ) + ), + expiresInSeconds: message.expiresInSeconds, + expiresStartedAtMs: message.expiresStartedAtMs ).inserted(db) } } diff --git a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+VisibleMessages.swift b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+VisibleMessages.swift index f07f30d3a..2d1d2edf0 100644 --- a/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+VisibleMessages.swift +++ b/SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+VisibleMessages.swift @@ -23,7 +23,6 @@ extension MessageReceiver { // seconds to maintain the accuracy) let messageSentTimestamp: TimeInterval = (TimeInterval(message.sentTimestamp ?? 0) / 1000) let isMainAppActive: Bool = (UserDefaults.sharedLokiProject?[.isMainAppActive]).defaulting(to: false) - let expiresInSeconds: TimeInterval? = proto.hasExpirationTimer ? TimeInterval(proto.expirationTimer) : nil // Update profile if needed (want to do this regardless of whether the message exists or // not to ensure the profile info gets sync between a users devices at every chance) @@ -167,7 +166,8 @@ extension MessageReceiver { quoteAuthorId: dataMessage.quote?.author, using: dependencies ), - expiresInSeconds: expiresInSeconds, + expiresInSeconds: message.expiresInSeconds, + expiresStartedAtMs: message.expiresStartedAtMs, // OpenGroupInvitations are stored as LinkPreview's in the database linkPreviewUrl: (message.linkPreview?.url ?? message.openGroupInvitation?.url), // Keep track of the open group server message ID ↔ message ID relationship @@ -214,7 +214,7 @@ extension MessageReceiver { threadId: threadId, variant: variant, serverHash: message.serverHash, - expireInSeconds: expiresInSeconds + expireInSeconds: message.expiresInSeconds ) default: break @@ -240,7 +240,7 @@ extension MessageReceiver { threadId: threadId, variant: variant, serverHash: message.serverHash, - expireInSeconds: expiresInSeconds + expireInSeconds: message.expiresInSeconds ) // Parse & persist attachments