Skip to content

Commit 6569ab6

Browse files
committed
Support for quoted replies
1 parent a22a5de commit 6569ab6

File tree

5 files changed

+539
-96
lines changed

5 files changed

+539
-96
lines changed

libsignal-service-dotnet/SignalServiceMessageSender.cs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,32 @@ private byte[] CreateMessageContent(SignalServiceDataMessage message)// throws I
292292
dataMessage.ProfileKey = ByteString.CopyFrom(message.ProfileKey);
293293
}
294294

295+
if (message.Quote != null)
296+
{
297+
var quote = new DataMessage.Types.Quote()
298+
{
299+
Id = (ulong) message.Quote.Id,
300+
Author = message.Quote.Author.E164number,
301+
Text = message.Quote.Text
302+
};
303+
foreach (SignalServiceAttachment attachment in message.Quote.Attachments)
304+
{
305+
if (attachment.IsPointer())
306+
{
307+
var pointer = attachment.AsPointer();
308+
quote.Attachments.Add(new AttachmentPointer()
309+
{
310+
ContentType = pointer.ContentType
311+
});
312+
}
313+
else
314+
{
315+
quote.Attachments.Add(CreateAttachmentPointer(attachment.AsStream()));
316+
}
317+
}
318+
dataMessage.Quote = quote;
319+
}
320+
295321
dataMessage.Timestamp = (ulong) message.Timestamp;
296322

297323
content.DataMessage = dataMessage;

libsignal-service-dotnet/crypto/SignalServiceCipher.cs

Lines changed: 45 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
using System;
1212
using System.Collections.Generic;
13+
using static libsignalservice.push.DataMessage;
1314

1415
namespace libsignalservice.crypto
1516
{
@@ -97,7 +98,7 @@ public SignalServiceContent Decrypt(SignalServiceEnvelope envelope)
9798
{
9899
content = new SignalServiceContent()
99100
{
100-
ReadMessage = createReceiptMessage(envelope, message.ReceiptMessage)
101+
ReadMessage = CreateReceiptMessage(envelope, message.ReceiptMessage)
101102
};
102103
}
103104
}
@@ -142,19 +143,11 @@ private SignalServiceDataMessage CreateSignalServiceMessage(SignalServiceEnvelop
142143
bool endSession = ((content.Flags & (uint)DataMessage.Types.Flags.EndSession) != 0);
143144
bool expirationUpdate = ((content.Flags & (uint)DataMessage.Types.Flags.ExpirationTimerUpdate) != 0);
144145
bool profileKeyUpdate = ((content.Flags & (uint)DataMessage.Types.Flags.ProfileKeyUpdate) != 0);
146+
SignalServiceDataMessage.SignalServiceQuote quote = CreateQuote(envelope, content);
145147

146148
foreach (AttachmentPointer pointer in content.Attachments)
147149
{
148-
attachments.Add(new SignalServiceAttachmentPointer(pointer.Id,
149-
pointer.ContentType,
150-
pointer.Key.ToByteArray(),
151-
envelope.getRelay(),
152-
pointer.SizeOneofCase == AttachmentPointer.SizeOneofOneofCase.Size ? pointer.Size : 0,
153-
pointer.ThumbnailOneofCase == AttachmentPointer.ThumbnailOneofOneofCase.Thumbnail ? pointer.Thumbnail.ToByteArray() : null,
154-
(int) pointer.Width, (int) pointer.Height,
155-
pointer.DigestOneofCase == AttachmentPointer.DigestOneofOneofCase.Digest ? pointer.Digest.ToByteArray() : null,
156-
pointer.FileNameOneofCase == AttachmentPointer.FileNameOneofOneofCase.FileName ? pointer.FileName : null,
157-
pointer.FlagsOneofCase == AttachmentPointer.FlagsOneofOneofCase.Flags && (pointer.Flags & (uint) AttachmentPointer.Types.Flags.VoiceMessage) != 0));
150+
attachments.Add(CreateAttachmentPointer(envelope, pointer));
158151
}
159152

160153
if (content.TimestampOneofCase == DataMessage.TimestampOneofOneofCase.Timestamp && (long) content.Timestamp != envelope.getTimestamp())
@@ -172,7 +165,8 @@ private SignalServiceDataMessage CreateSignalServiceMessage(SignalServiceEnvelop
172165
ExpiresInSeconds = (int)content.ExpireTimer,
173166
ExpirationUpdate = expirationUpdate,
174167
ProfileKey = content.ProfileKeyOneofCase == DataMessage.ProfileKeyOneofOneofCase.ProfileKey ? content.ProfileKey.ToByteArray() : null,
175-
ProfileKeyUpdate = profileKeyUpdate
168+
ProfileKeyUpdate = profileKeyUpdate,
169+
Quote = quote
176170
};
177171
}
178172

@@ -306,7 +300,7 @@ private SignalServiceCallMessage CreateCallMessage(CallMessage content)
306300
return new SignalServiceCallMessage();
307301
}
308302

309-
private SignalServiceReceiptMessage createReceiptMessage(SignalServiceEnvelope envelope, ReceiptMessage content)
303+
private SignalServiceReceiptMessage CreateReceiptMessage(SignalServiceEnvelope envelope, ReceiptMessage content)
310304
{
311305
SignalServiceReceiptMessage.Type type;
312306

@@ -342,6 +336,44 @@ private SignalServiceReceiptMessage createReceiptMessage(SignalServiceEnvelope e
342336
};
343337
}
344338

339+
private SignalServiceDataMessage.SignalServiceQuote CreateQuote(SignalServiceEnvelope envelope, DataMessage content)
340+
{
341+
if (content.QuoteOneofCase != QuoteOneofOneofCase.Quote)
342+
return null;
343+
344+
List<SignalServiceAttachment> attachments = new List<SignalServiceAttachment>();
345+
346+
foreach (AttachmentPointer pointer in content.Quote.Attachments)
347+
{
348+
attachments.Add(CreateAttachmentPointer(envelope, pointer));
349+
}
350+
351+
return new SignalServiceDataMessage.SignalServiceQuote((long) content.Quote.Id,
352+
new SignalServiceAddress(content.Quote.Author),
353+
content.Quote.Text,
354+
attachments);
355+
}
356+
357+
private SignalServiceAttachmentPointer CreateAttachmentPointer(SignalServiceEnvelope envelope, AttachmentPointer pointer)
358+
{
359+
uint? size = null;
360+
if (pointer.SizeOneofCase == AttachmentPointer.SizeOneofOneofCase.Size)
361+
{
362+
size = pointer.Size;
363+
}
364+
return new SignalServiceAttachmentPointer(pointer.Id,
365+
pointer.ContentType,
366+
pointer.Key.ToByteArray(),
367+
envelope.getRelay(),
368+
size,
369+
pointer.ThumbnailOneofCase == AttachmentPointer.ThumbnailOneofOneofCase.Thumbnail ? pointer.Thumbnail.ToByteArray() : null,
370+
(int) pointer.Width,
371+
(int) pointer.Height,
372+
pointer.DigestOneofCase == AttachmentPointer.DigestOneofOneofCase.Digest ? pointer.Digest.ToByteArray() : null,
373+
pointer.FileNameOneofCase == AttachmentPointer.FileNameOneofOneofCase.FileName ? pointer.FileName : null,
374+
(pointer.Flags & (uint) AttachmentPointer.Types.Flags.VoiceMessage) != 0);
375+
}
376+
345377
private SignalServiceGroup CreateGroupInfo(SignalServiceEnvelope envelope, DataMessage content)
346378
{
347379
if (content.GroupOneofCase == DataMessage.GroupOneofOneofCase.None) return null;

libsignal-service-dotnet/messages/SignalServiceDataMessage.cs

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using libsignalservice.push;
12
using System.Collections.Generic;
23

34
namespace libsignalservice.messages
@@ -13,19 +14,37 @@ public class SignalServiceDataMessage
1314
public string Body { get; set; }
1415
public SignalServiceGroup Group { get; set; }
1516
public byte[] ProfileKey { get; set; }
16-
public bool ProfileKeyUpdate { get; set; }
1717
public bool EndSession { get; set; }
1818
public bool ExpirationUpdate { get; set; }
1919
public int ExpiresInSeconds { get; set; }
20+
public bool ProfileKeyUpdate { get; set; }
21+
public SignalServiceQuote Quote { get; set; }
2022

2123
public bool IsProfileKeyUpdate()
2224
{
2325
return ProfileKeyUpdate;
2426
}
27+
2528
public bool IsGroupUpdate()
2629
{
2730
return Group != null && Group.Type != SignalServiceGroup.GroupType.DELIVER;
2831
}
32+
33+
public class SignalServiceQuote
34+
{
35+
public long Id { get; }
36+
public SignalServiceAddress Author { get; }
37+
public string Text { get; }
38+
public List<SignalServiceAttachment> Attachments { get; }
39+
40+
public SignalServiceQuote(long id, SignalServiceAddress author, string text, List<SignalServiceAttachment> attachments)
41+
{
42+
Id = id;
43+
Author = author;
44+
Text = text;
45+
Attachments = attachments;
46+
}
47+
}
2948
}
3049
#pragma warning restore CS1591 // Missing XML comment for publicly visible type or member
3150
}

libsignal-service-dotnet/protobuf/SignalService.proto

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,13 +72,21 @@ message DataMessage {
7272
PROFILE_KEY_UPDATE = 4;
7373
}
7474

75+
message Quote {
76+
oneof id_oneof { uint64 id = 1; }
77+
oneof author_oneof { string author = 2; }
78+
oneof text_oneof { string text = 3; }
79+
repeated AttachmentPointer attachments = 4;
80+
}
81+
7582
oneof body_oneof { string body = 1; }
7683
repeated AttachmentPointer attachments = 2;
7784
oneof group_oneof { GroupContext group = 3; }
7885
oneof flags_oneof { uint32 flags = 4; }
7986
oneof expireTimer_oneof { uint32 expireTimer = 5; }
8087
oneof profileKey_oneof { bytes profileKey = 6; }
8188
oneof timestamp_oneof { uint64 timestamp = 7; }
89+
oneof quote_oneof { Quote quote = 8; }
8290
}
8391

8492
message NullMessage {

0 commit comments

Comments
 (0)