Add SendableMessage protocol
This commit is contained in:
parent
238588a6d6
commit
148b493903
@ -606,6 +606,7 @@
|
||||
500B25832DD6A08300E9ECAA /* BackgroundMessageFetcher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500B25822DD6A08300E9ECAA /* BackgroundMessageFetcher.swift */; };
|
||||
500BAD802C519F2D00B4CD7F /* MessageTimestampGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500BAD7E2C519F2D00B4CD7F /* MessageTimestampGenerator.swift */; };
|
||||
500BAD822C519F3600B4CD7F /* MessageTimestampGeneratorTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500BAD7F2C519F2D00B4CD7F /* MessageTimestampGeneratorTest.swift */; };
|
||||
500CC1E52F15661A001A86F7 /* SendableMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500CC1E42F15661A001A86F7 /* SendableMessage.swift */; };
|
||||
500CC1E72F15C20B001A86F7 /* ReceiptMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500CC1E62F15C20B001A86F7 /* ReceiptMessage.swift */; };
|
||||
500CC1E92F15C8A7001A86F7 /* OutgoingCallMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500CC1E82F15C8A7001A86F7 /* OutgoingCallMessage.swift */; };
|
||||
500CC1EB2F15D1E5001A86F7 /* StickerPackSyncMessage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 500CC1EA2F15D1E5001A86F7 /* StickerPackSyncMessage.swift */; };
|
||||
@ -4753,6 +4754,7 @@
|
||||
500B25822DD6A08300E9ECAA /* BackgroundMessageFetcher.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundMessageFetcher.swift; sourceTree = "<group>"; };
|
||||
500BAD7E2C519F2D00B4CD7F /* MessageTimestampGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageTimestampGenerator.swift; sourceTree = "<group>"; };
|
||||
500BAD7F2C519F2D00B4CD7F /* MessageTimestampGeneratorTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MessageTimestampGeneratorTest.swift; sourceTree = "<group>"; };
|
||||
500CC1E42F15661A001A86F7 /* SendableMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SendableMessage.swift; sourceTree = "<group>"; };
|
||||
500CC1E62F15C20B001A86F7 /* ReceiptMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReceiptMessage.swift; sourceTree = "<group>"; };
|
||||
500CC1E82F15C8A7001A86F7 /* OutgoingCallMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutgoingCallMessage.swift; sourceTree = "<group>"; };
|
||||
500CC1EA2F15D1E5001A86F7 /* StickerPackSyncMessage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StickerPackSyncMessage.swift; sourceTree = "<group>"; };
|
||||
@ -14393,6 +14395,7 @@
|
||||
66D13F092A731E590092D47B /* RecipientHidingManager+SignalServiceAddress.swift */,
|
||||
E1A090372A4B909B00F2BE8B /* RecipientHidingManager.swift */,
|
||||
50B0E9472AC73C3B005D46AB /* RecipientStateMerger.swift */,
|
||||
500CC1E42F15661A001A86F7 /* SendableMessage.swift */,
|
||||
504F98B22EB0270A00DF465B /* SendMessageFailure.swift */,
|
||||
50A5AA9A2A7449D000CF2ECC /* ServerReceiptEnvelope.swift */,
|
||||
506395802F2403BE00B2F772 /* TransientOutgoingMessage.swift */,
|
||||
@ -19322,6 +19325,7 @@
|
||||
66138FB6298326C7002E0CFE /* SecureValueRecovery.swift in Sources */,
|
||||
662C440B2A156DF7001F83E2 /* SecureValueRecovery2Impl.swift in Sources */,
|
||||
6691E7F72996EAD70032A68A /* SecureValueRecoveryMock.swift in Sources */,
|
||||
500CC1E52F15661A001A86F7 /* SendableMessage.swift in Sources */,
|
||||
725465392BA01FAA00EABFD2 /* SendGiftBadgeJobQueue.swift in Sources */,
|
||||
D9AE0AD5291877600063488B /* SendGiftBadgeJobRecord.swift in Sources */,
|
||||
504F98B32EB0270A00DF465B /* SendMessageFailure.swift in Sources */,
|
||||
|
||||
@ -770,8 +770,8 @@ public class GroupManager: NSObject {
|
||||
thread.groupModel.groupMembership.invitedMembers.compactMap(\.serviceId)
|
||||
}
|
||||
|
||||
public static func shouldMessageHaveAdditionalRecipients(
|
||||
_ message: TSOutgoingMessage,
|
||||
static func shouldMessageHaveAdditionalRecipients(
|
||||
_ message: any SendableMessage,
|
||||
groupThread: TSGroupThread,
|
||||
) -> Bool {
|
||||
guard groupThread.groupModel.groupsVersion == .V2 else {
|
||||
|
||||
@ -84,7 +84,7 @@ public class MessageSendLog {
|
||||
let uniqueId: String
|
||||
}
|
||||
|
||||
func recordPayload(_ plaintext: Data, for message: TSOutgoingMessage, tx: DBWriteTransaction) -> Int64? {
|
||||
func recordPayload(_ plaintext: Data, for message: any SendableMessage, tx: DBWriteTransaction) -> Int64? {
|
||||
guard !RemoteConfig.current.messageResendKillSwitch else {
|
||||
return nil
|
||||
}
|
||||
@ -134,7 +134,7 @@ public class MessageSendLog {
|
||||
plaintextContent: plaintext,
|
||||
contentHint: message.contentHint,
|
||||
sentTimestamp: message.timestamp,
|
||||
uniqueThreadId: message.uniqueThreadId,
|
||||
uniqueThreadId: message.threadUniqueId,
|
||||
sendComplete: false,
|
||||
)
|
||||
try payload.insert(tx.database)
|
||||
@ -197,7 +197,7 @@ public class MessageSendLog {
|
||||
return existingValue.payload
|
||||
}
|
||||
|
||||
public func sendComplete(message: TSOutgoingMessage, tx: DBWriteTransaction) {
|
||||
func sendComplete(message: any SendableMessage, tx: DBWriteTransaction) {
|
||||
guard !RemoteConfig.current.messageResendKillSwitch else {
|
||||
return
|
||||
}
|
||||
@ -221,10 +221,10 @@ public class MessageSendLog {
|
||||
}
|
||||
|
||||
private func fetchUniquePayload(
|
||||
for message: TSOutgoingMessage,
|
||||
for message: any SendableMessage,
|
||||
tx: DBReadTransaction,
|
||||
) throws -> (Int64, Payload)? {
|
||||
let query = fetchRequest(threadUniqueId: message.uniqueThreadId).filter(Column("sentTimestamp") == message.timestamp)
|
||||
let query = fetchRequest(threadUniqueId: message.threadUniqueId).filter(Column("sentTimestamp") == message.timestamp)
|
||||
return try fetchUniquePayload(query: query, tx: tx)
|
||||
}
|
||||
|
||||
@ -283,7 +283,7 @@ public class MessageSendLog {
|
||||
payloadId: Int64,
|
||||
recipientAci: Aci,
|
||||
recipientDeviceId: DeviceId,
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
tx: DBWriteTransaction,
|
||||
) {
|
||||
guard !RemoteConfig.current.messageResendKillSwitch else {
|
||||
@ -315,7 +315,7 @@ public class MessageSendLog {
|
||||
}
|
||||
|
||||
func recordSuccessfulDelivery(
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
recipientAci: Aci,
|
||||
recipientDeviceId: DeviceId,
|
||||
tx: DBWriteTransaction,
|
||||
|
||||
@ -55,7 +55,7 @@ extension MessageSender {
|
||||
func prepareSenderKeyMessageSend(
|
||||
for recipients: [ServiceId],
|
||||
in thread: TSThread,
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
serializedMessage: SerializedMessage,
|
||||
endorsements: GroupSendEndorsements?,
|
||||
udAccessMap: [Aci: OWSUDAccess],
|
||||
@ -219,7 +219,7 @@ extension MessageSender {
|
||||
private func sendSenderKeyMessage(
|
||||
to eligibleRecipients: Set<ServiceId>,
|
||||
in thread: TSThread,
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
serializedMessage: SerializedMessage,
|
||||
authBuilder: (_ readyRecipients: [ServiceId]) -> TSRequest.SealedSenderAuth,
|
||||
senderCertificate: SenderCertificate,
|
||||
@ -275,7 +275,7 @@ extension MessageSender {
|
||||
private func sendSenderKeyCiphertext(
|
||||
_ ciphertextResult: Result<Data, any Error>,
|
||||
to recipients: [Recipient],
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
payloadId: Int64?,
|
||||
authBuilder: () -> TSRequest.SealedSenderAuth,
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
@ -343,7 +343,7 @@ extension MessageSender {
|
||||
private func prepareSenderKeyDistributionMessages(
|
||||
for recipients: some Sequence<ServiceId>,
|
||||
in thread: TSThread,
|
||||
originalMessage: TSOutgoingMessage,
|
||||
originalMessage: any SendableMessage,
|
||||
endorsements: GroupSendEndorsements?,
|
||||
udAccessMap: [Aci: OWSUDAccess],
|
||||
senderCertificate: SenderCertificate,
|
||||
@ -475,7 +475,7 @@ extension MessageSender {
|
||||
/// *except* those returned as unregistered in the result.
|
||||
private func sendSenderKeyRequest(
|
||||
to recipients: [Recipient],
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
ciphertextResult: Result<Data, any Error>,
|
||||
authBuilder: () -> TSRequest.SealedSenderAuth,
|
||||
) async throws -> SenderKeySendResult {
|
||||
@ -585,7 +585,7 @@ extension MessageSender {
|
||||
|
||||
private func senderKeyMessageBody(
|
||||
plaintext: Data,
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
thread: TSThread,
|
||||
recipients: [Recipient],
|
||||
senderCertificate: SenderCertificate,
|
||||
|
||||
@ -8,7 +8,7 @@ import LibSignalClient
|
||||
|
||||
// MARK: - Message "isXYZ" properties
|
||||
|
||||
private extension TSOutgoingMessage {
|
||||
extension TSOutgoingMessage {
|
||||
var isTransientSKDM: Bool {
|
||||
(self as? OutgoingSenderKeyDistributionMessage)?.isSentOnBehalfOfOnlineMessage ?? false
|
||||
}
|
||||
@ -456,7 +456,7 @@ public class MessageSender {
|
||||
// * A recipient is unregistered.
|
||||
// * A recipient does not have the required capability.
|
||||
private func markSkippedRecipients(
|
||||
of message: TSOutgoingMessage,
|
||||
of message: any SendableMessage,
|
||||
sendingRecipients: [ServiceId],
|
||||
tx: DBWriteTransaction,
|
||||
) {
|
||||
@ -466,7 +466,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func unsentRecipients(
|
||||
of message: TSOutgoingMessage,
|
||||
of message: any SendableMessage,
|
||||
in thread: TSThread,
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
tx: DBReadTransaction,
|
||||
@ -578,7 +578,7 @@ public class MessageSender {
|
||||
)
|
||||
}
|
||||
|
||||
private func areAttachmentsUploadedWithSneakyTransaction(for message: TSOutgoingMessage) -> Bool {
|
||||
private func areAttachmentsUploadedWithSneakyTransaction(for message: any SendableMessage) -> Bool {
|
||||
if message.shouldBeSaved == false {
|
||||
// Unsaved attachments come in two types:
|
||||
// * no attachments
|
||||
@ -597,7 +597,7 @@ public class MessageSender {
|
||||
}
|
||||
}
|
||||
|
||||
private func sendPreparedMessage(_ message: TSOutgoingMessage) async throws -> SendMessageFailure? {
|
||||
private func sendPreparedMessage(_ message: any SendableMessage) async throws -> SendMessageFailure? {
|
||||
if !areAttachmentsUploadedWithSneakyTransaction(for: message) {
|
||||
throw OWSGenericError("attachments aren't uploaded")
|
||||
}
|
||||
@ -691,12 +691,13 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func sendPreparedMessage(
|
||||
_ message: TSOutgoingMessage,
|
||||
_ message: any SendableMessage,
|
||||
recoveryState: OuterRecoveryState,
|
||||
senderCertificates: SenderCertificates,
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
) async throws -> SendMessageFailure? {
|
||||
let nextAction = try await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { tx -> SendMessageNextAction? in
|
||||
let databaseStorage = SSKEnvironment.shared.databaseStorageRef
|
||||
let nextAction = try await databaseStorage.awaitableWrite { tx -> SendMessageNextAction? in
|
||||
guard let thread = message.thread(tx: tx) else {
|
||||
throw MessageSenderError.threadMissing
|
||||
}
|
||||
@ -906,7 +907,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func sendPreparedMessage(
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
serializedMessage: SerializedMessage,
|
||||
in thread: TSThread,
|
||||
viaFanoutTo fanoutRecipients: Set<ServiceId>,
|
||||
@ -1005,7 +1006,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func handleSendFailure(
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
thread: TSThread,
|
||||
perRecipientErrors allErrors: [(serviceId: ServiceId, error: any Error)],
|
||||
) async throws -> SendMessageFailure? {
|
||||
@ -1057,7 +1058,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func normalizeRecipientStatesIfNeeded(
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
recipientErrors: some Sequence<(serviceId: ServiceId, error: Error)>,
|
||||
tx: DBWriteTransaction,
|
||||
) {
|
||||
@ -1090,7 +1091,7 @@ public class MessageSender {
|
||||
/// It is important to be conservative about which messages unhide a
|
||||
/// recipient. It is far better to not unhide when should than to
|
||||
/// unhide when we should not.
|
||||
private func shouldMessageSendUnhideRecipient(_ message: TSOutgoingMessage, tx: DBReadTransaction) -> Bool {
|
||||
private func shouldMessageSendUnhideRecipient(_ message: any SendableMessage, tx: DBReadTransaction) -> Bool {
|
||||
if
|
||||
message.shouldBeSaved,
|
||||
let rowId = message.sqliteRowId,
|
||||
@ -1117,7 +1118,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func handleMessageSentLocally(
|
||||
_ message: TSOutgoingMessage,
|
||||
_ message: any SendableMessage,
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
) async throws {
|
||||
await SSKEnvironment.shared.databaseStorageRef.awaitableWrite { tx in
|
||||
@ -1181,7 +1182,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func sendSyncTranscriptIfNeeded(
|
||||
forMessage message: TSOutgoingMessage,
|
||||
forMessage message: any SendableMessage,
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
) async throws {
|
||||
guard message.shouldSyncTranscript() else {
|
||||
@ -1195,7 +1196,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
private func sendSyncTranscript(
|
||||
forMessage message: TSOutgoingMessage,
|
||||
forMessage message: any SendableMessage,
|
||||
localIdentifiers: LocalIdentifiers,
|
||||
) async throws {
|
||||
let databaseStorage = SSKEnvironment.shared.databaseStorageRef
|
||||
@ -1228,7 +1229,7 @@ public class MessageSender {
|
||||
}
|
||||
|
||||
func buildAndRecordMessage(
|
||||
_ message: TSOutgoingMessage,
|
||||
_ message: any SendableMessage,
|
||||
in thread: TSThread,
|
||||
tx: DBWriteTransaction,
|
||||
) throws -> SerializedMessage {
|
||||
@ -1615,7 +1616,7 @@ public class MessageSender {
|
||||
messageSend: OWSMessageSend,
|
||||
sealedSenderParameters: SealedSenderParameters?,
|
||||
) async throws -> [SentDeviceMessage] {
|
||||
let message: TSOutgoingMessage = messageSend.message
|
||||
let message = messageSend.message
|
||||
|
||||
let requestMaker = RequestMaker(
|
||||
label: "Message Send",
|
||||
@ -1659,7 +1660,7 @@ public class MessageSender {
|
||||
deviceMessages: [DeviceMessage],
|
||||
wasSentByUD: Bool,
|
||||
) async -> [SentDeviceMessage] {
|
||||
let message: TSOutgoingMessage = messageSend.message
|
||||
let message = messageSend.message
|
||||
|
||||
Logger.info("Successfully sent message: \(type(of: message)), serviceId: \(messageSend.serviceId), timestamp: \(message.timestamp), wasSentByUD: \(wasSentByUD)")
|
||||
|
||||
@ -1722,7 +1723,7 @@ public class MessageSender {
|
||||
responseError: Error,
|
||||
sealedSenderParameters: SealedSenderParameters?,
|
||||
) async throws -> [SentDeviceMessage] {
|
||||
let message: TSOutgoingMessage = messageSend.message
|
||||
let message = messageSend.message
|
||||
|
||||
Logger.warn("\(type(of: message)) to \(messageSend.serviceId), timestamp: \(message.timestamp), error: \(responseError)")
|
||||
|
||||
|
||||
@ -8,13 +8,13 @@ import LibSignalClient
|
||||
|
||||
/// Provides parameters required for assembling a Sealed Sender message.
|
||||
final class SealedSenderParameters {
|
||||
let message: TSOutgoingMessage
|
||||
let message: any SendableMessage
|
||||
let senderCertificate: SenderCertificate
|
||||
let accessKey: OWSUDAccess?
|
||||
let endorsement: GroupSendFullTokenBuilder?
|
||||
|
||||
init?(
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
senderCertificate: SenderCertificate,
|
||||
accessKey: OWSUDAccess?,
|
||||
endorsement: GroupSendFullTokenBuilder?,
|
||||
@ -45,7 +45,7 @@ final class SealedSenderParameters {
|
||||
// to multiple recipients and therefore require multiple instances of
|
||||
// OWSMessageSend.
|
||||
final class OWSMessageSend {
|
||||
let message: TSOutgoingMessage
|
||||
let message: any SendableMessage
|
||||
let plaintextContent: Data
|
||||
let plaintextPayloadId: Int64?
|
||||
let thread: TSThread
|
||||
@ -53,7 +53,7 @@ final class OWSMessageSend {
|
||||
let localIdentifiers: LocalIdentifiers
|
||||
|
||||
init(
|
||||
message: TSOutgoingMessage,
|
||||
message: any SendableMessage,
|
||||
plaintextContent: Data,
|
||||
plaintextPayloadId: Int64?,
|
||||
thread: TSThread,
|
||||
|
||||
@ -25,7 +25,7 @@ final class OutgoingSenderKeyDistributionMessage: TransientOutgoingMessage {
|
||||
init(
|
||||
recipientThread: TSContactThread,
|
||||
senderKeyDistributionMessage: SenderKeyDistributionMessage,
|
||||
onBehalfOfMessage originalMessage: TSOutgoingMessage,
|
||||
onBehalfOfMessage originalMessage: any SendableMessage,
|
||||
inThread originalThread: TSThread,
|
||||
tx: DBReadTransaction,
|
||||
) {
|
||||
|
||||
88
SignalServiceKit/Messages/SendableMessage.swift
Normal file
88
SignalServiceKit/Messages/SendableMessage.swift
Normal file
@ -0,0 +1,88 @@
|
||||
//
|
||||
// Copyright 2026 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import LibSignalClient
|
||||
|
||||
protocol SendableMessage {
|
||||
var threadUniqueId: String { get }
|
||||
|
||||
var sqliteRowId: Int64? { get }
|
||||
|
||||
var uniqueId: String { get }
|
||||
|
||||
var timestamp: UInt64 { get }
|
||||
|
||||
var isSyncMessage: Bool { get }
|
||||
|
||||
var isStorySend: Bool { get }
|
||||
|
||||
var isOnline: Bool { get }
|
||||
|
||||
var isTransientSKDM: Bool { get }
|
||||
|
||||
var isUrgent: Bool { get }
|
||||
|
||||
var isResendRequest: Bool { get }
|
||||
|
||||
var canSendToLocalAddress: Bool { get }
|
||||
|
||||
var contentHint: SealedSenderContentHint { get }
|
||||
|
||||
var encryptionStyle: EncryptionStyle { get }
|
||||
|
||||
func buildPlainTextData(_ thread: TSThread, transaction: DBWriteTransaction) -> Data?
|
||||
|
||||
var wasSentToAnyRecipient: Bool { get }
|
||||
|
||||
func recipientAddresses() -> [SignalServiceAddress]
|
||||
|
||||
func sendingRecipientAddresses() -> [SignalServiceAddress]
|
||||
|
||||
func sentRecipientAddresses() -> [SignalServiceAddress]
|
||||
|
||||
func insertedMessageHasRenderableContent(rowId: Int64, tx: DBReadTransaction) -> Bool
|
||||
|
||||
func anyUpdateOutgoingMessage(transaction: DBWriteTransaction, block: (TSOutgoingMessage) -> Void)
|
||||
|
||||
func updateWithSkippedRecipients(_ skippedRecipients: some Sequence<SignalServiceAddress>, tx: DBWriteTransaction)
|
||||
|
||||
func updateWithFailedRecipients(_ recipientErrors: some Collection<(serviceId: ServiceId, error: Error)>, tx: DBWriteTransaction)
|
||||
|
||||
func updateWithSentRecipients(_ serviceIds: [ServiceId], wasSentByUD: Bool, transaction: DBWriteTransaction)
|
||||
|
||||
func update(withReadRecipient recipientAddress: SignalServiceAddress, deviceId: DeviceId, readTimestamp timestamp: UInt64, tx: DBWriteTransaction)
|
||||
|
||||
func update(withViewedRecipient recipientAddress: SignalServiceAddress, deviceId: DeviceId, viewedTimestamp timestamp: UInt64, tx: DBWriteTransaction)
|
||||
|
||||
func shouldSyncTranscript() -> Bool
|
||||
|
||||
func thread(tx: DBReadTransaction) -> TSThread?
|
||||
|
||||
var shouldBeSaved: Bool { get }
|
||||
|
||||
var shouldRecordSendLog: Bool { get }
|
||||
|
||||
var relatedUniqueIds: Set<String> { get }
|
||||
|
||||
func envelopeGroupIdWithTransaction(_ transaction: DBReadTransaction) -> Data?
|
||||
|
||||
var isVoiceMessage: Bool { get }
|
||||
|
||||
var isViewOnceMessage: Bool { get }
|
||||
|
||||
func buildTranscriptSyncMessage(
|
||||
localThread: TSContactThread,
|
||||
transaction: DBWriteTransaction,
|
||||
) -> OutgoingSyncMessage?
|
||||
|
||||
func update(withHasSyncedTranscript: Bool, transaction: DBWriteTransaction)
|
||||
|
||||
func allAttachments(transaction: DBReadTransaction) -> [ReferencedAttachment]
|
||||
}
|
||||
|
||||
extension TSOutgoingMessage: SendableMessage {
|
||||
var threadUniqueId: String { self.uniqueThreadId }
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user