68 lines
2.6 KiB
Swift
68 lines
2.6 KiB
Swift
//
|
|
// Copyright 2023 Signal Messenger, LLC
|
|
// SPDX-License-Identifier: AGPL-3.0-only
|
|
//
|
|
|
|
import Foundation
|
|
public import LibSignalClient
|
|
|
|
/// Used to uniquely identify one iteration of an interaction even if edits are applied.
|
|
/// Note that the interaction's uniqueId, rowId, and sortId always point to the latest edit,
|
|
/// so when an edit is applied they point to the new version not the old version.
|
|
/// This is used instead to continue to point to the old version.
|
|
///
|
|
/// authorAci is allowed to be null for outgoing or system messages because timestamp can
|
|
/// be considered unique on its own for messages generated by oneself.
|
|
/// Incoming messages should always have non-null authorAci.
|
|
/// NOTE: be careful using this for messages from before the introduction of uuids.
|
|
/// Currently used for text formatting spoilers which were introduced after uuids.
|
|
public struct InteractionSnapshotIdentifier: Equatable, Hashable {
|
|
let timestamp: UInt64
|
|
// Note: this will always be the aci for incoming messages
|
|
// and nil for local/outgoing messages.
|
|
let authorAci: Aci?
|
|
|
|
public init(timestamp: UInt64, authorAci: Aci?) {
|
|
self.timestamp = timestamp
|
|
self.authorAci = authorAci
|
|
}
|
|
|
|
public static func fromInteraction(_ interaction: TSInteraction) -> Self {
|
|
return .init(timestamp: interaction.timestamp, authorAci: Aci.parseFrom(aciString: (interaction as? TSIncomingMessage)?.authorUUID))
|
|
}
|
|
|
|
// Not strictly an interaction, but can contain spoilers.
|
|
public static func fromStoryMessage(_ storyMessage: StoryMessage) -> Self {
|
|
return .init(timestamp: storyMessage.timestamp, authorAci: storyMessage.authorAci)
|
|
}
|
|
}
|
|
|
|
// MARK: -
|
|
|
|
@objc
|
|
public class SpoilerRevealState: NSObject {
|
|
private var revealedSpoilerIdsByMessage = [InteractionSnapshotIdentifier: Set<StyleIdType>]()
|
|
|
|
/// Returns the set of IDs in the ordered list of spoiler ranges for a given message that
|
|
/// should be revealed.
|
|
public func revealedSpoilerIds(
|
|
interactionIdentifier: InteractionSnapshotIdentifier
|
|
) -> Set<StyleIdType> {
|
|
return revealedSpoilerIdsByMessage[interactionIdentifier] ?? []
|
|
}
|
|
|
|
public func setSpoilerRevealed(
|
|
withID id: StyleIdType,
|
|
interactionIdentifier: InteractionSnapshotIdentifier
|
|
) {
|
|
var revealedIds = revealedSpoilerIdsByMessage[interactionIdentifier] ?? Set()
|
|
revealedIds.insert(id)
|
|
revealedSpoilerIdsByMessage[interactionIdentifier] = revealedIds
|
|
}
|
|
|
|
public typealias Snapshot = [InteractionSnapshotIdentifier: Set<StyleIdType>]
|
|
|
|
public func snapshot() -> Snapshot {
|
|
return revealedSpoilerIdsByMessage
|
|
}
|
|
}
|