fix: disappear after read for control messages

pull/941/head
ryanzhao 2 years ago
parent 14a853ab07
commit afbb60b66d

@ -396,11 +396,11 @@ public class ConversationViewModel: OWSAudioPlayerDelegate {
/// write queue when it isn't needed, in order to do this we:
///
/// - Don't bother marking anything as read if there are no unread interactions (we can rely on the
/// `threadData.threadUnreadCount` to always be accurate)
/// `threadData.threadHasUnreadMessagesOfAnyKind` to always be accurate)
/// - Don't bother marking anything as read if this was called with the same `interactionId` that we
/// previously marked as read (ie. when scrolling and the last message hasn't changed)
guard
(self.threadData.threadUnreadCount ?? 0) > 0,
self.threadData.threadHasUnreadMessagesOfAnyKind == true,
let targetInteractionId: Int64 = (interactionId ?? self.threadData.interactionId),
self.lastInteractionIdMarkedAsRead != targetInteractionId
else { return }

@ -102,11 +102,11 @@ public struct Interaction: Codable, Identifiable, Equatable, FetchableRecord, Mu
switch self {
case .standardIncoming: return true
case .infoCall: return true
case .infoDisappearingMessagesUpdate, .infoScreenshotNotification, .infoMediaSavedNotification: return true // Won't be count as unread messages
case .standardOutgoing, .standardIncomingDeleted: return false
case .infoClosedGroupCreated, .infoClosedGroupUpdated, .infoClosedGroupCurrentUserLeft,
.infoDisappearingMessagesUpdate, .infoScreenshotNotification, .infoMediaSavedNotification,
.infoMessageRequestAccepted:
return false
}
@ -559,23 +559,11 @@ public extension Interaction {
.asRequest(of: Int64.self)
.fetchAll(db)
let disappearingInteractionQuery = Interaction
.filter(Interaction.Columns.threadId == threadId)
.filter(Interaction.Columns.timestampMs <= interactionInfo.timestampMs)
.filter(Interaction.Columns.wasRead == true)
.filter(Interaction.Columns.expiresInSeconds != nil)
.filter(Interaction.Columns.expiresStartedAtMs == nil)
let disappearingInteractionIds: [Int64] = try disappearingInteractionQuery
.select(.id)
.asRequest(of: Int64.self)
.fetchAll(db)
// If there are no other interactions to mark as read then just schedule the jobs
// for this interaction (need to ensure the disapeparing messages run for sync'ed
// outgoing messages which will always have 'wasRead' as false)
guard !interactionIdsToMarkAsRead.isEmpty else {
scheduleJobs(interactionIds: [interactionId].appending(contentsOf: disappearingInteractionIds))
scheduleJobs(interactionIds: [interactionId])
return
}
@ -583,7 +571,7 @@ public extension Interaction {
try interactionQuery.updateAll(db, Columns.wasRead.set(to: true))
// Retrieve the interaction ids we want to update
scheduleJobs(interactionIds: interactionIdsToMarkAsRead.appending(contentsOf: disappearingInteractionIds))
scheduleJobs(interactionIds: interactionIdsToMarkAsRead)
}
/// This method flags sent messages as read for the specified recipients

@ -356,9 +356,8 @@ public enum MessageReceiver {
lastChangeTimestampMs: protoLastChangeTimestampMs
)
let expireInSeconds: TimeInterval? = (remoteConfig.isEnabled && message.openGroupServerMessageId == nil) ? remoteConfig.durationSeconds : nil
let expiresStartedAtMs: Double? = (remoteConfig.isEnabled && remoteConfig.type == .disappearAfterSend) ? Double(message.sentTimestamp ?? 0) : nil
_ = try remoteConfig.save(db)
_ = try Interaction(
serverHash: nil, // Intentionally null so sync messages are seen as duplicates
threadId: threadId,
@ -371,12 +370,8 @@ public enum MessageReceiver {
),
isPreviousOff: !localConfig.isEnabled
),
timestampMs: protoLastChangeTimestampMs,
expiresInSeconds: expireInSeconds,
expiresStartedAtMs: expiresStartedAtMs
timestampMs: protoLastChangeTimestampMs
).inserted(db)
try remoteConfig.save(db)
}
internal static func updateProfileIfNeeded(

@ -32,6 +32,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
public static let threadContactIsTypingKey: SQL = SQL(stringLiteral: CodingKeys.threadContactIsTyping.stringValue)
public static let threadUnreadCountKey: SQL = SQL(stringLiteral: CodingKeys.threadUnreadCount.stringValue)
public static let threadUnreadMentionCountKey: SQL = SQL(stringLiteral: CodingKeys.threadUnreadMentionCount.stringValue)
public static let threadHasUnreadMessagesOfAnyKindKey: SQL = SQL(stringLiteral: CodingKeys.threadHasUnreadMessagesOfAnyKind.stringValue)
public static let disappearingMessagesConfigurationKey: SQL = SQL(stringLiteral: CodingKeys.disappearingMessagesConfiguration.stringValue)
public static let contactProfileKey: SQL = SQL(stringLiteral: CodingKeys.contactProfile.stringValue)
public static let closedGroupNameKey: SQL = SQL(stringLiteral: CodingKeys.closedGroupName.stringValue)
@ -63,6 +64,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
public static let threadUnreadCountString: String = CodingKeys.threadUnreadCount.stringValue
public static let threadUnreadMentionCountString: String = CodingKeys.threadUnreadMentionCount.stringValue
public static let threadHasUnreadMessagesOfAnyKindString: String = CodingKeys.threadHasUnreadMessagesOfAnyKind.stringValue
public static let closedGroupUserCountString: String = CodingKeys.closedGroupUserCount.stringValue
public static let openGroupUserCountString: String = CodingKeys.openGroupUserCount.stringValue
public static let disappearingMessagesConfigurationString: String = CodingKeys.disappearingMessagesConfiguration.stringValue
@ -98,6 +100,7 @@ public struct SessionThreadViewModel: FetchableRecordWithRowId, Decodable, Equat
public let threadContactIsTyping: Bool?
public let threadUnreadCount: UInt?
public let threadUnreadMentionCount: UInt?
public let threadHasUnreadMessagesOfAnyKind: Bool?
public var canWrite: Bool {
switch threadVariant {
@ -246,6 +249,7 @@ public extension SessionThreadViewModel {
contactProfile: Profile? = nil,
currentUserIsClosedGroupMember: Bool? = nil,
unreadCount: UInt = 0,
hasUnreadMessagesOfAnyKind: Bool = false,
disappearingMessagesConfiguration: DisappearingMessagesConfiguration? = nil
) {
self.rowId = -1
@ -267,6 +271,7 @@ public extension SessionThreadViewModel {
self.threadContactIsTyping = nil
self.threadUnreadCount = unreadCount
self.threadUnreadMentionCount = nil
self.threadHasUnreadMessagesOfAnyKind = hasUnreadMessagesOfAnyKind
// Thread display info
@ -333,6 +338,7 @@ public extension SessionThreadViewModel {
threadContactIsTyping: self.threadContactIsTyping,
threadUnreadCount: self.threadUnreadCount,
threadUnreadMentionCount: self.threadUnreadMentionCount,
threadHasUnreadMessagesOfAnyKind: self.threadHasUnreadMessagesOfAnyKind,
disappearingMessagesConfiguration: self.disappearingMessagesConfiguration,
contactProfile: self.contactProfile,
closedGroupProfileFront: self.closedGroupProfileFront,
@ -388,6 +394,7 @@ public extension SessionThreadViewModel {
threadContactIsTyping: self.threadContactIsTyping,
threadUnreadCount: self.threadUnreadCount,
threadUnreadMentionCount: self.threadUnreadMentionCount,
threadHasUnreadMessagesOfAnyKind: self.threadHasUnreadMessagesOfAnyKind,
disappearingMessagesConfiguration: self.disappearingMessagesConfiguration,
contactProfile: self.contactProfile,
closedGroupProfileFront: self.closedGroupProfileFront,
@ -472,7 +479,7 @@ public extension SessionThreadViewModel {
/// parse and might throw
///
/// Explicitly set default values for the fields ignored for search results
let numColumnsBeforeProfiles: Int = 12
let numColumnsBeforeProfiles: Int = 13
let numColumnsBetweenProfilesAndAttachmentInfo: Int = 11 // The attachment info columns will be combined
let request: SQLRequest<ViewModel> = """
@ -491,6 +498,7 @@ public extension SessionThreadViewModel {
(\(typingIndicator[.threadId]) IS NOT NULL) AS \(ViewModel.threadContactIsTypingKey),
\(Interaction.self).\(ViewModel.threadUnreadCountKey),
\(Interaction.self).\(ViewModel.threadUnreadMentionCountKey),
\(Interaction.self).\(ViewModel.threadHasUnreadMessagesOfAnyKindKey),
\(ViewModel.contactProfileKey).*,
\(ViewModel.closedGroupProfileFrontKey).*,
@ -537,8 +545,9 @@ public extension SessionThreadViewModel {
\(interaction[.authorId]),
\(interaction[.linkPreviewUrl]),
SUM(\(interaction[.wasRead]) = false) AS \(ViewModel.threadUnreadCountKey),
SUM(\(interaction[.wasRead]) = false AND \(interaction[.hasMention]) = true) AS \(ViewModel.threadUnreadMentionCountKey)
SUM(\(interaction[.wasRead]) = false AND \(interaction[.variant]) IN (\(Interaction.Variant.standardIncoming), \(Interaction.Variant.infoCall))) AS \(ViewModel.threadUnreadCountKey),
SUM(\(interaction[.wasRead]) = false AND \(interaction[.hasMention]) = true) AS \(ViewModel.threadUnreadMentionCountKey),
(SUM(\(interaction[.wasRead]) = false) > 0) AS \(ViewModel.threadHasUnreadMessagesOfAnyKindKey)
FROM \(Interaction.self)
WHERE \(SQL("\(interaction[.variant]) != \(Interaction.Variant.standardIncomingDeleted)"))
@ -733,7 +742,7 @@ public extension SessionThreadViewModel {
/// parse and might throw
///
/// Explicitly set default values for the fields ignored for search results
let numColumnsBeforeProfiles: Int = 14
let numColumnsBeforeProfiles: Int = 15
let request: SQLRequest<ViewModel> = """
SELECT
\(thread.alias[Column.rowID]) AS \(ViewModel.rowIdKey),
@ -760,6 +769,7 @@ public extension SessionThreadViewModel {
\(thread[.messageDraft]) AS \(ViewModel.threadMessageDraftKey),
\(Interaction.self).\(ViewModel.threadUnreadCountKey),
\(Interaction.self).\(ViewModel.threadHasUnreadMessagesOfAnyKindKey),
\(ViewModel.disappearingMessagesConfigurationKey).*,
@ -788,7 +798,8 @@ public extension SessionThreadViewModel {
\(interaction[.threadId]),
MAX(\(interaction[.timestampMs])),
SUM(\(interaction[.wasRead]) = false) AS \(ViewModel.threadUnreadCountKey)
SUM(\(interaction[.wasRead]) = false AND \(interaction[.variant]) IN (\(Interaction.Variant.standardIncoming), \(Interaction.Variant.infoCall))) AS \(ViewModel.threadUnreadCountKey),
(SUM(\(interaction[.wasRead]) = false) > 0) AS \(ViewModel.threadHasUnreadMessagesOfAnyKindKey)
FROM \(Interaction.self)
WHERE \(SQL("\(interaction[.threadId]) = \(threadId)"))

Loading…
Cancel
Save