mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Fixed an issue where the DisappearingMessages job could incorrectly overwrite it's nextRunTimestamp Fixed an issue where sent/self-send messages wouldn't correctly trigger the disappearing messages job Fixed an issue where sending the mnemonic along with an attachment wasn't showing the warning prompt Fixed an issue where the home screen wasn't updating on launch if the displayed messages were removed disappearing messages Fixed a small UI glitch where the input field wouldn't immediately get cleared when sending a message (unfortunately there is a slight delay before the message appears still)
106 lines
4.6 KiB
Swift
106 lines
4.6 KiB
Swift
// Copyright © 2022 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import Foundation
|
|
import GRDB
|
|
import SessionUtilitiesKit
|
|
|
|
public enum DisappearingMessagesJob: JobExecutor {
|
|
public static let maxFailureCount: Int = -1
|
|
public static let requiresThreadId: Bool = false
|
|
public static let requiresInteractionId: Bool = false
|
|
|
|
public static func run(
|
|
_ job: Job,
|
|
queue: DispatchQueue,
|
|
success: @escaping (Job, Bool) -> (),
|
|
failure: @escaping (Job, Error?, Bool) -> (),
|
|
deferred: @escaping (Job) -> ()
|
|
) {
|
|
// The 'backgroundTask' gets captured and cleared within the 'completion' block
|
|
let timestampNowMs: TimeInterval = ceil(Date().timeIntervalSince1970 * 1000)
|
|
var backgroundTask: OWSBackgroundTask? = OWSBackgroundTask(label: #function)
|
|
|
|
let updatedJob: Job? = Storage.shared.write { db in
|
|
_ = try Interaction
|
|
.filter(Interaction.Columns.expiresStartedAtMs != nil)
|
|
.filter((Interaction.Columns.expiresStartedAtMs + (Interaction.Columns.expiresInSeconds * 1000)) <= timestampNowMs)
|
|
.deleteAll(db)
|
|
|
|
// Update the next run timestamp for the DisappearingMessagesJob (if the call
|
|
// to 'updateNextRunIfNeeded' returns 'nil' then it doesn't need to re-run so
|
|
// should have it's 'nextRunTimestamp' cleared)
|
|
return try updateNextRunIfNeeded(db)
|
|
.defaulting(to: job.with(nextRunTimestamp: 0))
|
|
.saved(db)
|
|
}
|
|
|
|
success(updatedJob ?? job, false)
|
|
|
|
// The 'if' is only there to prevent the "variable never read" warning from showing
|
|
if backgroundTask != nil { backgroundTask = nil }
|
|
}
|
|
}
|
|
|
|
// MARK: - Convenience
|
|
|
|
public extension DisappearingMessagesJob {
|
|
@discardableResult static func updateNextRunIfNeeded(_ db: Database) -> Job? {
|
|
// Don't run when inactive or not in main app
|
|
guard (UserDefaults.sharedLokiProject?[.isMainAppActive]).defaulting(to: false) else { return nil }
|
|
|
|
// If there is another expiring message then update the job to run 1 second after it's meant to expire
|
|
let nextExpirationTimestampMs: Double? = try? Interaction
|
|
.filter(Interaction.Columns.expiresStartedAtMs != nil)
|
|
.filter(Interaction.Columns.expiresInSeconds != nil)
|
|
.select(Interaction.Columns.expiresStartedAtMs + (Interaction.Columns.expiresInSeconds * 1000))
|
|
.order((Interaction.Columns.expiresStartedAtMs + (Interaction.Columns.expiresInSeconds * 1000)).asc)
|
|
.asRequest(of: Double.self)
|
|
.fetchOne(db)
|
|
|
|
guard let nextExpirationTimestampMs: Double = nextExpirationTimestampMs else { return nil }
|
|
|
|
return try? Job
|
|
.filter(Job.Columns.variant == Job.Variant.disappearingMessages)
|
|
.fetchOne(db)?
|
|
.with(nextRunTimestamp: ceil(nextExpirationTimestampMs / 1000))
|
|
.saved(db)
|
|
}
|
|
|
|
@discardableResult static func updateNextRunIfNeeded(_ db: Database, interactionIds: [Int64], startedAtMs: Double) -> Job? {
|
|
// Update the expiring messages expiresStartedAtMs value
|
|
let changeCount: Int? = try? Interaction
|
|
.filter(interactionIds.contains(Interaction.Columns.id))
|
|
.filter(
|
|
Interaction.Columns.expiresInSeconds != nil &&
|
|
Interaction.Columns.expiresStartedAtMs == nil
|
|
)
|
|
.updateAll(db, Interaction.Columns.expiresStartedAtMs.set(to: startedAtMs))
|
|
|
|
// If there were no changes then none of the provided `interactionIds` are expiring messages
|
|
guard (changeCount ?? 0) > 0 else { return nil }
|
|
|
|
return updateNextRunIfNeeded(db)
|
|
}
|
|
|
|
@discardableResult static func updateNextRunIfNeeded(_ db: Database, interaction: Interaction, startedAtMs: Double) -> Job? {
|
|
guard interaction.isExpiringMessage else { return nil }
|
|
|
|
// Don't clobber if multiple actions simultaneously triggered expiration
|
|
guard interaction.expiresStartedAtMs == nil || (interaction.expiresStartedAtMs ?? 0) > startedAtMs else {
|
|
return nil
|
|
}
|
|
|
|
do {
|
|
guard let interactionId: Int64 = try? (interaction.id ?? interaction.inserted(db).id) else {
|
|
throw StorageError.objectNotFound
|
|
}
|
|
|
|
return updateNextRunIfNeeded(db, interactionIds: [interactionId], startedAtMs: startedAtMs)
|
|
}
|
|
catch {
|
|
SNLog("Failed to update the expiring messages timer on an interaction")
|
|
return nil
|
|
}
|
|
}
|
|
}
|