Skip to content

Commit c122538

Browse files
committed
mark messages read if a window reports it as read
Check whether a frontend reports a message read, and dispatch the notification only if not
1 parent bd08fe5 commit c122538

File tree

5 files changed

+136
-17
lines changed

5 files changed

+136
-17
lines changed

Signal-Windows.Lib/SignalLibHandle.cs

+60-3
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,21 @@
2323

2424
namespace Signal_Windows.Lib
2525
{
26+
public class AppendResult
27+
{
28+
public long Index { get; }
29+
public AppendResult(long index)
30+
{
31+
Index = index;
32+
}
33+
}
34+
2635
public interface ISignalFrontend
2736
{
2837
void AddOrUpdateConversation(SignalConversation conversation, SignalMessage updateMessage);
29-
void HandleMessage(SignalMessage message, SignalConversation conversation);
38+
AppendResult HandleMessage(SignalMessage message, SignalConversation conversation);
39+
void HandleUnreadMessage(SignalMessage message);
40+
void HandleMessageRead(long messageIndex, SignalConversation conversation);
3041
void HandleIdentitykeyChange(LinkedList<SignalMessage> messages);
3142
void HandleMessageUpdate(SignalMessage updatedMessage);
3243
void ReplaceConversationList(List<SignalConversation> conversations);
@@ -435,16 +446,62 @@ internal void DispatchAddOrUpdateConversation(SignalConversation conversation, S
435446
}
436447

437448
internal void DispatchHandleMessage(SignalMessage message, SignalConversation conversation)
449+
{
450+
List<TaskCompletionSource<AppendResult>> operations = new List<TaskCompletionSource<AppendResult>>();
451+
foreach (var dispatcher in Frames.Keys)
452+
{
453+
TaskCompletionSource<AppendResult> b = new TaskCompletionSource<AppendResult>();
454+
var a = dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
455+
{
456+
b.SetResult(Frames[dispatcher].HandleMessage(message, conversation));
457+
});
458+
operations.Add(b);
459+
}
460+
SignalMessageEvent?.Invoke(this, new SignalMessageEventArgs(message, Events.SignalMessageType.NormalMessage));
461+
if (message.Author != null)
462+
{
463+
bool wasInstantlyRead = false;
464+
foreach (var b in operations)
465+
{
466+
AppendResult result = b.Task.Result;
467+
if (result != null)
468+
{
469+
SignalDBContext.UpdateMessageRead(result.Index, conversation);
470+
DispatchMessageRead(result.Index, conversation);
471+
wasInstantlyRead = true;
472+
break;
473+
}
474+
}
475+
if (!wasInstantlyRead)
476+
{
477+
DispatchHandleUnreadMessage(message);
478+
}
479+
}
480+
}
481+
482+
internal void DispatchHandleUnreadMessage(SignalMessage message)
438483
{
439484
List<Task> operations = new List<Task>();
440485
foreach (var dispatcher in Frames.Keys)
441486
{
442487
operations.Add(dispatcher.RunTaskAsync(() =>
443488
{
444-
Frames[dispatcher].HandleMessage(message, conversation);
489+
Frames[dispatcher].HandleUnreadMessage(message);
490+
}));
491+
}
492+
Task.WaitAll(operations.ToArray());
493+
}
494+
495+
internal void DispatchMessageRead(long messageIndex, SignalConversation conversation)
496+
{
497+
List<Task> operations = new List<Task>();
498+
foreach (var dispatcher in Frames.Keys)
499+
{
500+
operations.Add(dispatcher.RunTaskAsync(() =>
501+
{
502+
Frames[dispatcher].HandleMessageRead(messageIndex, conversation);
445503
}));
446504
}
447-
SignalMessageEvent?.Invoke(this, new SignalMessageEventArgs(message, Events.SignalMessageType.NormalMessage));
448505
Task.WaitAll(operations.ToArray());
449506
}
450507

Signal-Windows.Lib/Storage/DB.cs

+34
Original file line numberDiff line numberDiff line change
@@ -985,6 +985,40 @@ public static void UpdateExpiresInLocked(SignalConversation thread, uint exp)
985985
}
986986
}
987987

988+
989+
internal static void UpdateMessageRead(long index, SignalConversation conversation)
990+
{
991+
lock (DBLock)
992+
{
993+
using (var ctx = new SignalDBContext())
994+
{
995+
if (!conversation.ThreadId.EndsWith("="))
996+
{
997+
var contact = ctx.Contacts
998+
.Where(c => c.ThreadId == conversation.ThreadId)
999+
.SingleOrDefault();
1000+
if (contact != null)
1001+
{
1002+
contact.LastSeenMessageIndex = index;
1003+
contact.UnreadCount = (uint)(contact.MessagesCount - index);
1004+
}
1005+
}
1006+
else
1007+
{
1008+
var group = ctx.Groups
1009+
.Where(c => c.ThreadId == conversation.ThreadId)
1010+
.SingleOrDefault();
1011+
if (group != null)
1012+
{
1013+
group.LastSeenMessageIndex = index;
1014+
group.UnreadCount = (uint)(group.MessagesCount - index);
1015+
}
1016+
}
1017+
ctx.SaveChanges();
1018+
}
1019+
}
1020+
}
1021+
9881022
#endregion Threads
9891023

9901024
#region Groups

Signal-Windows/Controls/Conversation.xaml.cs

+10-1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
using System.Threading.Tasks;
1515
using Windows.Foundation;
1616
using Windows.Storage;
17+
using Windows.UI.Core;
1718
using Windows.UI.ViewManagement;
1819
using Windows.UI.Xaml;
1920
using Windows.UI.Xaml.Controls;
@@ -26,6 +27,7 @@ namespace Signal_Windows.Controls
2627
{
2728
public sealed partial class Conversation : UserControl, INotifyPropertyChanged
2829
{
30+
private readonly ILogger Logger = LibsignalLogging.CreateLogger<Conversation>();
2931
public event PropertyChangedEventHandler PropertyChanged;
3032
private bool SendingMessage = false;
3133
private Dictionary<long, SignalMessageContainer> OutgoingCache = new Dictionary<long, SignalMessageContainer>();
@@ -220,16 +222,23 @@ public void UpdateAttachment(SignalAttachment sa)
220222
}
221223
}
222224

223-
public void Append(SignalMessageContainer sm)
225+
public AppendResult Append(SignalMessageContainer sm)
224226
{
227+
AppendResult result = null;
225228
var sourcePanel = (ItemsStackPanel)ConversationItemsControl.ItemsPanelRoot;
226229
bool bottom = sourcePanel.LastVisibleIndex == Collection.Count - 2; // -2 because we already incremented Count
227230
Collection.Add(sm, sm.Message.Author == null);
228231
if (bottom)
229232
{
230233
UpdateLayout();
231234
ScrollToBottom();
235+
if (Window.Current.CoreWindow.ActivationMode == CoreWindowActivationMode.ActivatedInForeground)
236+
{
237+
Logger.LogTrace("Append at no-virt-index {0}", sm.Index);
238+
result = new AppendResult(sm.Index + 1);
239+
}
232240
}
241+
return result;
233242
}
234243

235244
public void AddToOutgoingMessagesCache(SignalMessageContainer m)

Signal-Windows/SignalWindowsFrontend.cs

+20-2
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ public void HandleIdentitykeyChange(LinkedList<SignalMessage> messages)
3939
Locator.MainPageInstance.HandleIdentitykeyChange(messages);
4040
}
4141

42-
public void HandleMessage(SignalMessage message, SignalConversation conversation)
42+
public AppendResult HandleMessage(SignalMessage message, SignalConversation conversation)
4343
{
44-
Locator.MainPageInstance.HandleMessage(message, conversation);
44+
return Locator.MainPageInstance.HandleMessage(message, conversation);
4545
}
4646

4747
public void HandleMessageUpdate(SignalMessage updatedMessage)
@@ -74,5 +74,23 @@ public void HandleAttachmentStatusChanged(SignalAttachment sa)
7474
{
7575
Locator.MainPageInstance.HandleAttachmentStatusChanged(sa);
7676
}
77+
78+
public void HandleMessageRead(long messageIndex, SignalConversation conversation)
79+
{
80+
Locator.MainPageInstance.HandleMessageRead(messageIndex, conversation);
81+
}
82+
83+
public void HandleUnreadMessage(SignalMessage message)
84+
{
85+
if (ApplicationView.GetForCurrentView().Id == App.MainViewId)
86+
{
87+
if (message.Author != null)
88+
{
89+
SignalNotifications.TryVibrate(true);
90+
SignalNotifications.SendMessageNotification(message);
91+
SignalNotifications.SendTileNotification(message);
92+
}
93+
}
94+
}
7795
}
7896
}

Signal-Windows/ViewModels/MainPageViewModel.cs

+12-11
Original file line numberDiff line numberDiff line change
@@ -219,8 +219,9 @@ public void AddOrUpdateConversation(SignalConversation conversation, SignalMessa
219219
RepositionConversation(uiConversation);
220220
}
221221

222-
public void HandleMessage(SignalMessage message, SignalConversation conversation)
222+
public AppendResult HandleMessage(SignalMessage message, SignalConversation conversation)
223223
{
224+
AppendResult result = null;
224225
var localConversation = ConversationsDictionary[conversation.ThreadId];
225226
localConversation.LastMessage = message;
226227
localConversation.MessagesCount = conversation.MessagesCount;
@@ -231,18 +232,18 @@ public void HandleMessage(SignalMessage message, SignalConversation conversation
231232
if (SelectedThread != null && SelectedThread == localConversation)
232233
{
233234
var container = new SignalMessageContainer(message, (int)SelectedThread.MessagesCount - 1);
234-
View.Thread.Append(container);
235+
result = View.Thread.Append(container);
235236
}
236237
RepositionConversation(localConversation);
237-
if (ApplicationView.GetForCurrentView().Id == App.MainViewId)
238-
{
239-
if (message.Author != null)
240-
{
241-
SignalNotifications.TryVibrate(true);
242-
SignalNotifications.SendMessageNotification(message);
243-
SignalNotifications.SendTileNotification(message);
244-
}
245-
}
238+
return result;
239+
}
240+
241+
public void HandleMessageRead(long messageIndex, SignalConversation conversation)
242+
{
243+
var localConversation = ConversationsDictionary[conversation.ThreadId];
244+
Logger.LogTrace("LastSeenMessageIndex = {0}", messageIndex);
245+
localConversation.LastSeenMessageIndex = messageIndex;
246+
localConversation.UpdateUI();
246247
}
247248

248249
public void HandleIdentitykeyChange(LinkedList<SignalMessage> messages)

0 commit comments

Comments
 (0)