@ -17,7 +17,6 @@ public final class MessageSender {
let message : Message ?
let interactionId : Int64 ?
let isSyncMessage : Bool ?
let totalAttachmentsUploaded : Int
let snodeMessage : SnodeMessage ?
@ -30,7 +29,6 @@ public final class MessageSender {
destination : Message . Destination ,
namespace : SnodeAPI . Namespace ? ,
interactionId : Int64 ? ,
isSyncMessage : Bool ? ,
totalAttachmentsUploaded : Int = 0 ,
snodeMessage : SnodeMessage ? ,
plaintext : Data ? ,
@ -42,7 +40,6 @@ public final class MessageSender {
self . destination = destination
self . namespace = namespace
self . interactionId = interactionId
self . isSyncMessage = isSyncMessage
self . totalAttachmentsUploaded = totalAttachmentsUploaded
self . snodeMessage = snodeMessage
@ -56,7 +53,6 @@ public final class MessageSender {
destination : Message . Destination ,
namespace : SnodeAPI . Namespace ,
interactionId : Int64 ? ,
isSyncMessage : Bool ? ,
snodeMessage : SnodeMessage
) {
self . shouldSend = true
@ -65,7 +61,6 @@ public final class MessageSender {
self . destination = destination
self . namespace = namespace
self . interactionId = interactionId
self . isSyncMessage = isSyncMessage
self . totalAttachmentsUploaded = 0
self . snodeMessage = snodeMessage
@ -86,7 +81,6 @@ public final class MessageSender {
self . destination = destination
self . namespace = nil
self . interactionId = interactionId
self . isSyncMessage = false
self . totalAttachmentsUploaded = 0
self . snodeMessage = nil
@ -107,7 +101,6 @@ public final class MessageSender {
self . destination = destination
self . namespace = nil
self . interactionId = interactionId
self . isSyncMessage = false
self . totalAttachmentsUploaded = 0
self . snodeMessage = nil
@ -124,7 +117,6 @@ public final class MessageSender {
destination : destination . with ( fileIds : fileIds ) ,
namespace : namespace ,
interactionId : interactionId ,
isSyncMessage : isSyncMessage ,
totalAttachmentsUploaded : fileIds . count ,
snodeMessage : snodeMessage ,
plaintext : plaintext ,
@ -139,7 +131,6 @@ public final class MessageSender {
to destination : Message . Destination ,
namespace : SnodeAPI . Namespace ? ,
interactionId : Int64 ? ,
isSyncMessage : Bool = false ,
using dependencies : Dependencies = Dependencies ( )
) throws -> PreparedSendData {
// C o m m o n l o g i c f o r a l l d e s t i n a t i o n s
@ -154,7 +145,7 @@ public final class MessageSender {
)
switch destination {
case . contact , . closedGroup:
case . contact , . syncMessage, . closedGroup:
return try prepareSendToSnodeDestination (
db ,
message : updatedMessage ,
@ -163,7 +154,6 @@ public final class MessageSender {
interactionId : interactionId ,
userPublicKey : currentUserPublicKey ,
messageSendTimestamp : messageSendTimestamp ,
isSyncMessage : isSyncMessage ,
using : dependencies
)
@ -198,13 +188,13 @@ public final class MessageSender {
interactionId : Int64 ? ,
userPublicKey : String ,
messageSendTimestamp : Int64 ,
isSyncMessage : Bool = false ,
using dependencies : Dependencies
) throws -> PreparedSendData {
message . sender = userPublicKey
message . recipient = {
switch destination {
case . contact ( let publicKey ) : return publicKey
case . syncMessage : return userPublicKey
case . closedGroup ( let groupPublicKey ) : return groupPublicKey
case . openGroup , . openGroupInbox : preconditionFailure ( )
}
@ -215,6 +205,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . invalidMessage ,
interactionId : interactionId ,
using : dependencies
@ -223,25 +214,25 @@ public final class MessageSender {
// A t t a c h t h e u s e r ' s p r o f i l e i f n e e d e d ( n o n e e d t o d o s o f o r ' N o t e t o S e l f ' o r s y n c
// m e s s a g e s a s t h e y w i l l b e m a n a g e d b y t h e u s e r c o n f i g h a n d l i n g
let isSelfSend : Bool = ( message . recipient = = userPublicKey )
if ! isSelfSend , ! isSyncMessage , var messageWithProfile : MessageWithProfile = message as ? MessageWithProfile {
let profile : Profile = Profile . fetchOrCreateCurrentUser ( db )
if let profileKey : Data = profile . profileEncryptionKey , let profilePictureUrl : String = profile . profilePictureUrl {
messageWithProfile . profile = VisibleMessage . VMProfile (
displayName : profile . name ,
profileKey : profileKey ,
profilePictureUrl : profilePictureUrl
)
}
else {
messageWithProfile . profile = VisibleMessage . VMProfile ( displayName : profile . name )
}
switch ( destination , ( message . recipient = = userPublicKey ) , message as ? MessageWithProfile ) {
case ( . syncMessage , _ , _ ) , ( _ , true , _ ) , ( _ , _ , . none ) : break
case ( _ , _ , . some ( var messageWithProfile ) ) :
let profile : Profile = Profile . fetchOrCreateCurrentUser ( db )
if let profileKey : Data = profile . profileEncryptionKey , let profilePictureUrl : String = profile . profilePictureUrl {
messageWithProfile . profile = VisibleMessage . VMProfile (
displayName : profile . name ,
profileKey : profileKey ,
profilePictureUrl : profilePictureUrl
)
}
else {
messageWithProfile . profile = VisibleMessage . VMProfile ( displayName : profile . name )
}
}
// P e r f o r m a n y p r e - s e n d a c t i o n s
handleMessageWillSend ( db , message : message , interactionId: interactionId , isSyncMessage : isSyncMessage )
handleMessageWillSend ( db , message : message , destination: destination , interactionId : interactionId )
// C o n v e r t i t t o p r o t o b u f
let threadId : String = Message . threadId ( forMessage : message , destination : destination )
@ -250,6 +241,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . protoConversionFailed ,
interactionId : interactionId ,
using : dependencies
@ -267,6 +259,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . other ( error ) ,
interactionId : interactionId ,
using : dependencies
@ -280,6 +273,9 @@ public final class MessageSender {
case . contact ( let publicKey ) :
ciphertext = try encryptWithSessionProtocol ( db , plaintext : plaintext , for : publicKey , using : dependencies )
case . syncMessage :
ciphertext = try encryptWithSessionProtocol ( db , plaintext : plaintext , for : userPublicKey , using : dependencies )
case . closedGroup ( let groupPublicKey ) :
guard let encryptionKeyPair : ClosedGroupKeyPair = try ? ClosedGroupKeyPair . fetchLatestKeyPair ( db , threadId : groupPublicKey ) else {
throw MessageSenderError . noKeyPair
@ -300,6 +296,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . other ( error ) ,
interactionId : interactionId ,
using : dependencies
@ -311,7 +308,7 @@ public final class MessageSender {
let senderPublicKey : String
switch destination {
case . contact :
case . contact , . syncMessage :
kind = . sessionMessage
senderPublicKey = " "
@ -336,6 +333,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . other ( error ) ,
interactionId : interactionId ,
using : dependencies
@ -350,13 +348,7 @@ public final class MessageSender {
data : base64EncodedData ,
ttl : Message . getSpecifiedTTL (
message : message ,
isGroupMessage : {
switch destination {
case . closedGroup : return true
default : return false
}
} ( ) ,
isSyncMessage : isSyncMessage
destination : destination
) ,
timestampMs : UInt64 ( messageSendTimestamp )
)
@ -366,7 +358,6 @@ public final class MessageSender {
destination : destination ,
namespace : namespace ,
interactionId : interactionId ,
isSyncMessage : isSyncMessage ,
snodeMessage : snodeMessage
)
}
@ -382,7 +373,7 @@ public final class MessageSender {
let threadId : String
switch destination {
case . contact , . closedGroup, . openGroupInbox : preconditionFailure ( )
case . contact , . syncMessage, . closedGroup, . openGroupInbox : preconditionFailure ( )
case . openGroup ( let roomToken , let server , let whisperTo , let whisperMods , _ ) :
threadId = OpenGroup . idFor ( roomToken : roomToken , server : server )
message . recipient = [
@ -439,6 +430,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . invalidMessage ,
interactionId : interactionId ,
using : dependencies
@ -455,6 +447,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . noUsername ,
interactionId : interactionId ,
using : dependencies
@ -462,13 +455,14 @@ public final class MessageSender {
}
// P e r f o r m a n y p r e - s e n d a c t i o n s
handleMessageWillSend ( db , message : message , interactionId: interactionId )
handleMessageWillSend ( db , message : message , destination: destination , interactionId: interactionId )
// C o n v e r t i t t o p r o t o b u f
guard let proto = message . toProto ( db , threadId : threadId ) else {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . protoConversionFailed ,
interactionId : interactionId ,
using : dependencies
@ -486,6 +480,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . other ( error ) ,
interactionId : interactionId ,
using : dependencies
@ -533,13 +528,14 @@ public final class MessageSender {
}
// P e r f o r m a n y p r e - s e n d a c t i o n s
handleMessageWillSend ( db , message : message , interactionId: interactionId )
handleMessageWillSend ( db , message : message , destination: destination , interactionId: interactionId )
// C o n v e r t i t t o p r o t o b u f
guard let proto = message . toProto ( db , threadId : recipientBlindedPublicKey ) else {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . protoConversionFailed ,
interactionId : interactionId ,
using : dependencies
@ -557,6 +553,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . other ( error ) ,
interactionId : interactionId ,
using : dependencies
@ -580,6 +577,7 @@ public final class MessageSender {
throw MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : destination ,
with : . other ( error ) ,
interactionId : interactionId ,
using : dependencies
@ -628,9 +626,9 @@ public final class MessageSender {
MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : data . destination ,
with : . attachmentsNotUploaded ,
interactionId : data . interactionId ,
isSyncMessage : ( data . isSyncMessage = = true ) ,
using : dependencies
)
}
@ -646,7 +644,7 @@ public final class MessageSender {
}
switch data . destination {
case . contact , . closedGroup: return sendToSnodeDestination ( data : data , using : dependencies )
case . contact , . syncMessage, . closedGroup: return sendToSnodeDestination ( data : data , using : dependencies )
case . openGroup : return sendToOpenGroupDestination ( data : data , using : dependencies )
case . openGroupInbox : return sendToOpenGroupInbox ( data : data , using : dependencies )
}
@ -661,7 +659,6 @@ public final class MessageSender {
guard
let message : Message = data . message ,
let namespace : SnodeAPI . Namespace = data . namespace ,
let isSyncMessage : Bool = data . isSyncMessage ,
let snodeMessage : SnodeMessage = data . snodeMessage
else {
return Fail ( error : MessageSenderError . invalidMessage )
@ -680,9 +677,10 @@ public final class MessageSender {
details : NotifyPushServerJob . Details ( message : snodeMessage )
)
let shouldNotify : Bool = {
switch updatedMessage {
case is VisibleMessage , is UnsendRequest : return ! isSyncMessage
case let callMessage as CallMessage :
switch ( updatedMessage , data . destination ) {
case ( is VisibleMessage , . syncMessage ) , ( is UnsendRequest , . syncMessage ) : return false
case ( is VisibleMessage , _ ) , ( is UnsendRequest , _ ) : return true
case ( let callMessage as CallMessage , _ ) :
// N o t e : O t h e r ' C a l l M e s s a g e ' t y p e s a r e t o o b i g t o s e n d a s p u s h n o t i f i c a t i o n s
// s o o n l y s e n d t h e ' p r e O f f e r ' m e s s a g e a s a n o t i f i c a t i o n
switch callMessage . kind {
@ -701,7 +699,6 @@ public final class MessageSender {
message : updatedMessage ,
to : data . destination ,
interactionId : data . interactionId ,
isSyncMessage : isSyncMessage ,
using : dependencies
)
@ -758,6 +755,7 @@ public final class MessageSender {
MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : data . destination ,
with : . other ( error ) ,
interactionId : data . interactionId ,
using : dependencies
@ -829,6 +827,7 @@ public final class MessageSender {
MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : data . destination ,
with : . other ( error ) ,
interactionId : data . interactionId ,
using : dependencies
@ -893,6 +892,7 @@ public final class MessageSender {
MessageSender . handleFailedMessageSend (
db ,
message : message ,
destination : data . destination ,
with : . other ( error ) ,
interactionId : data . interactionId ,
using : dependencies
@ -909,27 +909,33 @@ public final class MessageSender {
public static func handleMessageWillSend (
_ db : Database ,
message : Message ,
interactionId: Int64 ? ,
i sSyncMessage: Bool = false
destination: Message . Destination ,
i nteractionId: Int64 ?
) {
// I f t h e m e s s a g e w a s a r e a c t i o n t h e n w e d o n ' t w a n t t o d o a n y t h i n g t o t h e o r i g i n a l
// i n t e r a c t i o n ( w h i c h t h e ' i n t e r a c t i o n I d ' i s p o i n t i n g t o
guard ( message as ? VisibleMessage ) ? . reaction = = nil else { return }
// M a r k m e s s a g e s a s " s e n d i n g " / " s y n c i n g " i f n e e d e d ( t h i s i s f o r r e t r i e s )
_ = try ? RecipientState
. filter ( RecipientState . Columns . interactionId = = interactionId )
. filter ( isSyncMessage ?
RecipientState . Columns . state = = RecipientState . State . failedToSync :
RecipientState . Columns . state = = RecipientState . State . failed
)
. updateAll (
db ,
RecipientState . Columns . state . set ( to : isSyncMessage ?
RecipientState . State . syncing :
RecipientState . State . sending
)
)
switch destination {
case . syncMessage :
_ = try ? RecipientState
. filter ( RecipientState . Columns . interactionId = = interactionId )
. filter ( RecipientState . Columns . state = = RecipientState . State . failedToSync )
. updateAll (
db ,
RecipientState . Columns . state . set ( to : RecipientState . State . syncing )
)
default :
_ = try ? RecipientState
. filter ( RecipientState . Columns . interactionId = = interactionId )
. filter ( RecipientState . Columns . state = = RecipientState . State . failed )
. updateAll (
db ,
RecipientState . Columns . state . set ( to : RecipientState . State . sending )
)
}
}
private static func handleSuccessfulMessageSend (
@ -938,7 +944,6 @@ public final class MessageSender {
to destination : Message . Destination ,
interactionId : Int64 ? ,
serverTimestampMs : UInt64 ? = nil ,
isSyncMessage : Bool = false ,
using dependencies : Dependencies
) throws {
// I f t h e m e s s a g e w a s a r e a c t i o n t h e n w e w a n t t o u p d a t e t h e r e a c t i o n i n s t e a d o f t h e o r i g i n a l
@ -957,59 +962,61 @@ public final class MessageSender {
// G e t t h e v i s i b l e m e s s a g e i f p o s s i b l e
if let interaction : Interaction = interaction {
// O n l y s t o r e t h e s e r v e r h a s h o f a s y n c m e s s a g e i f t h e m e s s a g e i s s e l f s e n d v a l i d
if ( message . isSelfSendValid && isSyncMessage || ! isSyncMessage ) {
try interaction . with (
serverHash : message . serverHash ,
// T r a c k t h e o p e n g r o u p s e r v e r m e s s a g e I D a n d u p d a t e s e r v e r t i m e s t a m p ( u s e s e r v e r
// t i m e s t a m p f o r o p e n g r o u p m e s s a g e s o t h e r w i s e t h e q u o t e m e s s a g e s m a y n o t b e a b l e
// t o b e f o u n d b y t h e t i m e s t a m p o n o t h e r d e v i c e s
timestampMs : ( message . openGroupServerMessageId = = nil ?
nil :
serverTimestampMs . map { Int64 ( $0 ) }
) ,
openGroupServerMessageId : message . openGroupServerMessageId . map { Int64 ( $0 ) }
) . update ( db )
if interaction . isExpiringMessage {
// S t a r t d i s a p p e a r i n g m e s s a g e s j o b a f t e r a m e s s a g e i s s u c c e s s f u l l y s e n t .
// F o r D A R a n d D A S o u t g o i n g m e s s a g e s , t h e e x p i r a t i o n s t a r t t i m e a r e t h e
// s a m e a s m e s s a g e s e n t T i m e s t a m p . S o d o t h i s o n c e , D A R a n d D A S m e s s a g e s
// s h o u l d a l l b e c o v e r e d .
dependencies . jobRunner . upsert (
db ,
job : DisappearingMessagesJob . updateNextRunIfNeeded (
db ,
interaction : interaction ,
startedAtMs : Double ( interaction . timestampMs )
switch ( message . isSelfSendValid , destination ) {
case ( false , . syncMessage ) : break
case ( true , . syncMessage ) , ( _ , . contact ) , ( _ , . closedGroup ) , ( _ , . openGroup ) , ( _ , . openGroupInbox ) :
try interaction . with (
serverHash : message . serverHash ,
// T r a c k t h e o p e n g r o u p s e r v e r m e s s a g e I D a n d u p d a t e s e r v e r t i m e s t a m p ( u s e s e r v e r
// t i m e s t a m p f o r o p e n g r o u p m e s s a g e s o t h e r w i s e t h e q u o t e m e s s a g e s m a y n o t b e a b l e
// t o b e f o u n d b y t h e t i m e s t a m p o n o t h e r d e v i c e s
timestampMs : ( message . openGroupServerMessageId = = nil ?
nil :
serverTimestampMs . map { Int64 ( $0 ) }
) ,
canStartJob : true ,
using : dependencies
)
openGroupServerMessageId : message . openGroupServerMessageId . map { Int64 ( $0 ) }
) . update ( db )
if
isSyncMessage ,
let startedAtMs : Double = interaction . expiresStartedAtMs ,
let expiresInSeconds : TimeInterval = interaction . expiresInSeconds ,
let serverHash : String = message . serverHash
{
let expirationTimestampMs : Int64 = Int64 ( startedAtMs + expiresInSeconds * 1000 )
dependencies . jobRunner . add (
if interaction . isExpiringMessage {
// S t a r t d i s a p p e a r i n g m e s s a g e s j o b a f t e r a m e s s a g e i s s u c c e s s f u l l y s e n t .
// F o r D A R a n d D A S o u t g o i n g m e s s a g e s , t h e e x p i r a t i o n s t a r t t i m e a r e t h e
// s a m e a s m e s s a g e s e n t T i m e s t a m p . S o d o t h i s o n c e , D A R a n d D A S m e s s a g e s
// s h o u l d a l l b e c o v e r e d .
dependencies . jobRunner . upsert (
db ,
job : Job (
variant : . expirationUpdate ,
behaviour : . runOnce ,
threadId : interaction . threadId ,
details : ExpirationUpdateJob . Details (
serverHashes : [ serverHash ] ,
expirationTimestampMs : expirationTimestampMs
)
job : DisappearingMessagesJob . updateNextRunIfNeeded (
db ,
interaction : interaction ,
startedAtMs : Double ( interaction . timestampMs )
) ,
canStartJob : true ,
using : dependencies
)
if
case . syncMessage = destination ,
let startedAtMs : Double = interaction . expiresStartedAtMs ,
let expiresInSeconds : TimeInterval = interaction . expiresInSeconds ,
let serverHash : String = message . serverHash
{
let expirationTimestampMs : Int64 = Int64 ( startedAtMs + expiresInSeconds * 1000 )
dependencies . jobRunner . add (
db ,
job : Job (
variant : . expirationUpdate ,
behaviour : . runOnce ,
threadId : interaction . threadId ,
details : ExpirationUpdateJob . Details (
serverHashes : [ serverHash ] ,
expirationTimestampMs : expirationTimestampMs
)
) ,
canStartJob : true ,
using : dependencies
)
}
}
}
}
// M a r k t h e m e s s a g e a s s e n t
try interaction . recipientStates
@ -1038,7 +1045,6 @@ public final class MessageSender {
destination : destination ,
threadId : threadId ,
interactionId : interactionId ,
isAlreadySyncMessage : isSyncMessage ,
using : dependencies
)
}
@ -1046,9 +1052,9 @@ public final class MessageSender {
@ discardableResult internal static func handleFailedMessageSend (
_ db : Database ,
message : Message ,
destination : Message . Destination ? ,
with error : MessageSenderError ,
interactionId : Int64 ? ,
isSyncMessage : Bool = false ,
using dependencies : Dependencies
) -> Error {
// I f t h e m e s s a g e w a s a r e a c t i o n t h e n w e d o n ' t w a n t t o d o a n y t h i n g t o t h e o r i g i n a l
@ -1060,18 +1066,27 @@ public final class MessageSender {
// N o t e : T h e ' d b ' c o u l d b e e i t h e r r e a d - o n l y o r w r i t e a b l e s o w e d e t e r m i n e
// i f a c h a n g e i s r e q u i r e d , a n d i f s o d i s p a t c h t o a s e p a r a t e q u e u e f o r t h e
// a c t u a l w r i t e
let rowIds : [ Int64 ] = ( try ? RecipientState
. select ( Column . rowID )
. filter ( RecipientState . Columns . interactionId = = interactionId )
. filter ( ! isSyncMessage ?
RecipientState . Columns . state = = RecipientState . State . sending : (
RecipientState . Columns . state = = RecipientState . State . syncing ||
RecipientState . Columns . state = = RecipientState . State . sent
)
)
. asRequest ( of : Int64 . self )
. fetchAll ( db ) )
. defaulting ( to : [ ] )
let rowIds : [ Int64 ] = ( try ? {
switch destination {
case . syncMessage :
return RecipientState
. select ( Column . rowID )
. filter ( RecipientState . Columns . interactionId = = interactionId )
. filter (
RecipientState . Columns . state = = RecipientState . State . syncing ||
RecipientState . Columns . state = = RecipientState . State . sent
)
default :
return RecipientState
. select ( Column . rowID )
. filter ( RecipientState . Columns . interactionId = = interactionId )
. filter ( RecipientState . Columns . state = = RecipientState . State . sending )
}
} ( )
. asRequest ( of : Int64 . self )
. fetchAll ( db ) )
. defaulting ( to : [ ] )
guard ! rowIds . isEmpty else { return error }
@ -1079,15 +1094,25 @@ public final class MessageSender {
// i s s u e f r o m o c c u r i n g i n s o m e c a s e s
DispatchQueue . global ( qos : . background ) . async {
dependencies . storage . write { db in
try RecipientState
. filter ( rowIds . contains ( Column . rowID ) )
. updateAll (
db ,
RecipientState . Columns . state . set (
to : ( isSyncMessage ? RecipientState . State . failedToSync : RecipientState . State . failed )
) ,
RecipientState . Columns . mostRecentFailureText . set ( to : error . localizedDescription )
)
switch destination {
case . syncMessage :
try RecipientState
. filter ( rowIds . contains ( Column . rowID ) )
. updateAll (
db ,
RecipientState . Columns . state . set ( to : RecipientState . State . failedToSync ) ,
RecipientState . Columns . mostRecentFailureText . set ( to : " \( error ) " )
)
default :
try RecipientState
. filter ( rowIds . contains ( Column . rowID ) )
. updateAll (
db ,
RecipientState . Columns . state . set ( to : RecipientState . State . failed ) ,
RecipientState . Columns . mostRecentFailureText . set ( to : " \( error ) " )
)
}
}
}
@ -1116,7 +1141,6 @@ public final class MessageSender {
destination : Message . Destination ,
threadId : String ? ,
interactionId : Int64 ? ,
isAlreadySyncMessage : Bool ,
using dependencies : Dependencies
) {
// S y n c t h e m e s s a g e i f i t ' s n o t a s y n c m e s s a g e , w a s n ' t a l r e a d y s e n t t o t h e c u r r e n t u s e r a n d
@ -1125,7 +1149,6 @@ public final class MessageSender {
if
case . contact ( let publicKey ) = destination ,
! isAlreadySyncMessage ,
publicKey != currentUserPublicKey ,
Message . shouldSync ( message : message )
{
@ -1139,9 +1162,8 @@ public final class MessageSender {
threadId : threadId ,
interactionId : interactionId ,
details : MessageSendJob . Details (
destination : . contact ( publicKey : currentUserPublicKey ) ,
message : message ,
isSyncMessage : true
destination : . syncMessage ( originalRecipientPublicKey : publicKey ) ,
message : message
)
) ,
canStartJob : true ,