91 lines
4.1 KiB
Swift
91 lines
4.1 KiB
Swift
//
|
|
// Copyright 2022 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public extension TSPrivateStoryThread {
|
|
@objc
|
|
var distributionListIdentifier: Data? { UUID(uuidString: uniqueId)?.data }
|
|
|
|
@objc
|
|
class var myStoryUniqueId: String {
|
|
// My Story always uses a UUID of all 0s
|
|
"00000000-0000-0000-0000-000000000000"
|
|
}
|
|
|
|
class func getMyStory(transaction: SDSAnyReadTransaction) -> TSPrivateStoryThread! {
|
|
anyFetchPrivateStoryThread(uniqueId: myStoryUniqueId, transaction: transaction)
|
|
}
|
|
|
|
@discardableResult
|
|
class func getOrCreateMyStory(transaction: SDSAnyWriteTransaction) -> TSPrivateStoryThread! {
|
|
if let myStory = getMyStory(transaction: transaction) { return myStory }
|
|
|
|
let myStory = TSPrivateStoryThread(uniqueId: myStoryUniqueId, name: "", allowsReplies: true, addresses: [], viewMode: .blockList)
|
|
myStory.anyInsert(transaction: transaction)
|
|
return myStory
|
|
}
|
|
|
|
override func recipientAddresses(with transaction: SDSAnyReadTransaction) -> [SignalServiceAddress] {
|
|
switch storyViewMode {
|
|
case .default:
|
|
owsFailDebug("Unexpectedly have private story with no view mode")
|
|
return []
|
|
case .explicit, .disabled:
|
|
return addresses
|
|
case .blockList:
|
|
return profileManager.allWhitelistedRegisteredAddresses(tx: transaction).filter { !addresses.contains($0) && !$0.isLocalAddress }
|
|
}
|
|
}
|
|
|
|
private static let deletedAtTimestampKVS = SDSKeyValueStore(collection: "TSPrivateStoryThread+DeletedAtTimestamp")
|
|
private static let deletedAtTimestampThreshold = kMonthInterval
|
|
|
|
static func deletedAtTimestamp(forDistributionListIdentifier identifier: Data, transaction: SDSAnyReadTransaction) -> UInt64? {
|
|
guard let uniqueId = UUID(data: identifier)?.uuidString else { return nil }
|
|
return deletedAtTimestampKVS.getUInt64(uniqueId, transaction: transaction)
|
|
}
|
|
|
|
static func recordDeletedAtTimestamp(_ timestamp: UInt64, forDistributionListIdentifier identifier: Data, transaction: SDSAnyWriteTransaction) {
|
|
guard Date().timeIntervalSince(Date(millisecondsSince1970: timestamp)) < deletedAtTimestampThreshold else {
|
|
Logger.warn("Ignorning stale deleted at timestamp")
|
|
return
|
|
}
|
|
|
|
guard let uniqueId = UUID(data: identifier)?.uuidString else { return }
|
|
deletedAtTimestampKVS.setUInt64(timestamp, key: uniqueId, transaction: transaction)
|
|
}
|
|
|
|
static func allDeletedIdentifiers(transaction: SDSAnyReadTransaction) -> [Data] {
|
|
deletedAtTimestampKVS.allKeys(transaction: transaction).compactMap { UUID(uuidString: $0)?.data }
|
|
}
|
|
|
|
static func cleanupDeletedTimestamps(transaction tx: SDSAnyWriteTransaction) {
|
|
var deletedIdentifiers = [Data]()
|
|
for identifier in deletedAtTimestampKVS.allKeys(transaction: tx) {
|
|
guard let timestamp = deletedAtTimestampKVS.getUInt64(
|
|
identifier,
|
|
transaction: tx
|
|
) else { continue }
|
|
guard Date().timeIntervalSince(Date(millisecondsSince1970: timestamp)) > deletedAtTimestampThreshold else { continue }
|
|
deletedAtTimestampKVS.removeValue(forKey: identifier, transaction: tx)
|
|
|
|
// If we still have a private story thread for this deleted timestamp, it's
|
|
// now safe to purge it from the database.
|
|
if let thread = TSPrivateStoryThread.anyFetchPrivateStoryThread(uniqueId: identifier, transaction: tx) {
|
|
DependenciesBridge.shared.threadRemover.remove(thread, tx: tx.asV2Write)
|
|
}
|
|
|
|
UUID(uuidString: identifier).map { deletedIdentifiers.append($0.data) }
|
|
}
|
|
Self.storageServiceManager.recordPendingUpdates(updatedStoryDistributionListIds: deletedIdentifiers)
|
|
}
|
|
|
|
override func updateWithShouldThreadBeVisible(_ shouldThreadBeVisible: Bool, transaction: SDSAnyWriteTransaction) {
|
|
super.updateWithShouldThreadBeVisible(shouldThreadBeVisible, transaction: transaction)
|
|
updateWithStoryViewMode(.disabled, transaction: transaction)
|
|
}
|
|
}
|