Skip to content

Commit 4536054

Browse files
committed
Cleanup our cache mess
Our ID-based caches turned out to be messy, were problematic when implementing disappearing messages, and they were not contained in a single class. This commit simplifies things: The one and only storage of messages in the app's memory is now the VirtualizedMessagesCollection, which maintains DbIdToMessageMap so that we get a reference to a SignalMessage's Message. closes #74
1 parent e950c39 commit 4536054

File tree

10 files changed

+91
-169
lines changed

10 files changed

+91
-169
lines changed

Signal-Windows.Lib/Signal-Windows.Lib.csproj

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,6 @@
159159
<Compile Include="Properties\AssemblyInfo.cs" />
160160
<Compile Include="SignalLibHandle.cs" />
161161
<Compile Include="SignalLogging.cs" />
162-
<Compile Include="SignalMessageContainer.cs" />
163162
<Compile Include="Storage\DB.cs" />
164163
<Compile Include="Storage\Store.cs" />
165164
<Compile Include="Util\NotificationsUtils.cs" />

Signal-Windows.Lib/SignalLibHandle.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ public interface ISignalLibHandle
6060
Task SendBlockedMessage();
6161
Task SetMessageRead(long index, SignalMessage message, SignalConversation conversation);
6262
void ResendMessage(SignalMessage message);
63-
List<SignalMessageContainer> GetMessages(SignalConversation thread, int startIndex, int count);
63+
IEnumerable<SignalMessage> GetMessages(SignalConversation thread, int startIndex, int count);
6464
Task SaveAndDispatchSignalConversation(SignalConversation updatedConversation, SignalMessage updateMessage);
6565
void PurgeAccountData();
6666
Task<bool> Acquire(CoreDispatcher d, ISignalFrontend w);
@@ -402,7 +402,7 @@ public void ResendMessage(SignalMessage message)
402402
OutgoingQueue.Add(message);
403403
}
404404

405-
public List<SignalMessageContainer> GetMessages(SignalConversation thread, int startIndex, int count)
405+
public IEnumerable<SignalMessage> GetMessages(SignalConversation thread, int startIndex, int count)
406406
{
407407
return SignalDBContext.GetMessagesLocked(thread, startIndex, count);
408408
}

Signal-Windows.Lib/SignalMessageContainer.cs

Lines changed: 0 additions & 20 deletions
This file was deleted.

Signal-Windows.Lib/Storage/DB.cs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -832,7 +832,7 @@ private static SignalConversation SaveMessage(SignalDBContext ctx, SignalMessage
832832
return conversation;
833833
}
834834

835-
public static List<SignalMessageContainer> GetMessagesLocked(SignalConversation thread, int startIndex, int count)
835+
public static IEnumerable<SignalMessage> GetMessagesLocked(SignalConversation thread, int startIndex, int count)
836836
{
837837
Logger.LogTrace("GetMessagesLocked() skip {0} take {1}", startIndex, count);
838838
lock (DBLock)
@@ -846,15 +846,10 @@ public static List<SignalMessageContainer> GetMessagesLocked(SignalConversation
846846
.Include(m => m.Attachments)
847847
.OrderBy(m => m.Id)
848848
.Skip(startIndex)
849-
.Take(count);
850-
851-
var containers = new List<SignalMessageContainer>(count);
852-
foreach (var message in messages)
853-
{
854-
containers.Add(new SignalMessageContainer(message, startIndex));
855-
startIndex++;
856-
}
857-
return containers;
849+
.AsNoTracking()
850+
.Take(count)
851+
.ToList();
852+
return messages;
858853
}
859854
}
860855
}

Signal-Windows/Controls/Conversation.xaml

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -77,16 +77,6 @@
7777
</Setter.Value>
7878
</Setter>
7979
</Style>
80-
<DataTemplate x:Key="NormalMessageTemplate" x:DataType="models:SignalMessage">
81-
<local:Message x:Name="ListBoxItemContent" />
82-
</DataTemplate>
83-
<DataTemplate x:Key="UnreadMarkerTemplate">
84-
<local:UnreadMarker />
85-
</DataTemplate>
86-
<DataTemplate x:Key="IdentityKeyChangeTemplate">
87-
<local:IdentityKeyChangeMessage />
88-
</DataTemplate>
89-
<local:MessageTemplateSelector x:Key="MessageDataTemplateSelector" NormalMessage="{StaticResource NormalMessageTemplate}" UnreadMarker="{StaticResource UnreadMarkerTemplate}" IdentityKeyChangeMessage="{StaticResource IdentityKeyChangeTemplate}" />
9080
</Control.Resources>
9181
<Grid Background="White">
9282
<Grid.RowDefinitions>
@@ -120,7 +110,7 @@
120110
</Button>
121111
</Grid>
122112
</Border>
123-
<ListView Style="{StaticResource ConversationStyle}" Grid.Row="1" Name="ConversationItemsControl" VirtualizingStackPanel.VirtualizationMode="Recycling" Background="White" ScrollViewer.VerticalScrollBarVisibility="Visible" Padding="0 0 15 0" ItemTemplateSelector="{StaticResource MessageDataTemplateSelector}" SelectionMode="None">
113+
<ListView Style="{StaticResource ConversationStyle}" Grid.Row="1" Name="ConversationItemsControl" VirtualizingStackPanel.VirtualizationMode="Recycling" Background="White" ScrollViewer.VerticalScrollBarVisibility="Visible" Padding="0 0 15 0" SelectionMode="None">
124114
<ListView.ItemContainerStyle>
125115
<Style TargetType="ListViewItem">
126116
<Setter Property="HorizontalContentAlignment" Value="Stretch" />

Signal-Windows/Controls/Conversation.xaml.cs

Lines changed: 16 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,6 @@ public sealed partial class Conversation : UserControl, INotifyPropertyChanged
3030
private readonly ILogger Logger = LibsignalLogging.CreateLogger<Conversation>();
3131
public event PropertyChangedEventHandler PropertyChanged;
3232
private bool SendingMessage = false;
33-
private Dictionary<long, SignalMessageContainer> OutgoingCache = new Dictionary<long, SignalMessageContainer>();
34-
private Dictionary<long, SignalAttachmentContainer> UnfinishedAttachmentsCache = new Dictionary<long, SignalAttachmentContainer>();
3533
private SignalConversation SignalConversation;
3634
public VirtualizedCollection Collection;
3735
private CoreWindowActivationState ActivationState = CoreWindowActivationState.Deactivated;
@@ -207,8 +205,7 @@ public void Load(SignalConversation conversation)
207205

208206
public void DisposeCurrentThread()
209207
{
210-
OutgoingCache.Clear();
211-
UnfinishedAttachmentsCache.Clear();
208+
Collection?.Dispose();
212209
}
213210

214211
public T FindElementByName<T>(FrameworkElement element, string sChildName) where T : FrameworkElement
@@ -236,67 +233,46 @@ public T FindElementByName<T>(FrameworkElement element, string sChildName) where
236233

237234
public void UpdateMessageBox(SignalMessage updatedMessage)
238235
{
239-
if (OutgoingCache.ContainsKey(updatedMessage.Id))
236+
if (Collection != null)
240237
{
241-
var m = OutgoingCache[updatedMessage.Id];
242-
var item = (ListViewItem) ConversationItemsControl.ContainerFromIndex(Collection.GetVirtualIndex(m.Index));
243-
if (item != null)
238+
Message m = Collection.GetMessageByDbId(updatedMessage.Id);
239+
if (m != null)
244240
{
245-
var message = FindElementByName<Message>(item, "ListBoxItemContent");
246-
bool retain = message.HandleUpdate(updatedMessage);
247-
if (!retain)
248-
{
249-
OutgoingCache.Remove(m.Index);
250-
}
241+
var attachment = FindElementByName<Attachment>(m, "Attachment");
242+
m.HandleUpdate(updatedMessage);
251243
}
252244
}
253245
}
254246

255247
public void UpdateAttachment(SignalAttachment sa)
256248
{
257-
if (UnfinishedAttachmentsCache.ContainsKey(sa.Id))
249+
if (Collection != null)
258250
{
259-
var a = UnfinishedAttachmentsCache[sa.Id];
260-
var messageItem = (ListViewItem)ConversationItemsControl.ContainerFromIndex(Collection.GetVirtualIndex(a.MessageIndex));
261-
if (messageItem != null)
251+
Message m = Collection.GetMessageByDbId(sa.Message.Id);
252+
if (m != null)
262253
{
263-
var message = FindElementByName<Message>(messageItem, "ListBoxItemContent");
264-
var attachment = FindElementByName<Attachment>(message, "Attachment");
265-
bool retain = attachment.HandleUpdate(sa);
266-
if (!retain)
267-
{
268-
OutgoingCache.Remove(sa.Id);
269-
}
254+
var attachment = FindElementByName<Attachment>(m, "Attachment");
255+
attachment.HandleUpdate(sa);
270256
}
271257
}
272258
}
273259

274-
public AppendResult Append(SignalMessageContainer sm)
260+
public AppendResult Append(Message sm)
275261
{
276262
AppendResult result = null;
277263
bool bottom = GetBottommostIndex() == Collection.Count - 2; // -2 because we already incremented Count
278-
Collection.Add(sm, sm.Message.Author == null);
264+
Collection.Add(sm, sm.Model.Author == null);
279265
if (bottom)
280266
{
281267
UpdateLayout();
282268
ScrollToBottom();
283269
if (ActivationState != CoreWindowActivationState.Deactivated)
284270
{
285-
result = new AppendResult(sm.Index);
271+
result = new AppendResult(GetBottommostIndex()); //TODO correct?
286272
}
287273
}
288274
return result;
289275
}
290-
291-
public void AddToOutgoingMessagesCache(SignalMessageContainer m)
292-
{
293-
OutgoingCache[m.Message.Id] = m;
294-
}
295-
296-
public void AddToUnfinishedAttachmentsCache(SignalAttachmentContainer m)
297-
{
298-
UnfinishedAttachmentsCache[m.Attachment.Id] = m;
299-
}
300276

301277
private async void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
302278
{
@@ -398,9 +374,10 @@ private void MarkBottommostMessageRead()
398374
if (lastSeenIndex <= rawBottomIndex && LastMarkReadRequest < rawBottomIndex)
399375
{
400376
LastMarkReadRequest = rawBottomIndex;
377+
var msg = ((Message)Collection[bottomIndex]).Model;
401378
Task.Run(async () =>
402379
{
403-
await App.Handle.SetMessageRead(rawBottomIndex, ((SignalMessageContainer)Collection[bottomIndex]).Message, SignalConversation);
380+
await App.Handle.SetMessageRead(rawBottomIndex, msg, SignalConversation);
404381
});
405382
}
406383
}
@@ -421,30 +398,4 @@ await Task.Run(() =>
421398
}
422399
}
423400
}
424-
425-
public class MessageTemplateSelector : DataTemplateSelector
426-
{
427-
public DataTemplate NormalMessage { get; set; }
428-
public DataTemplate UnreadMarker { get; set; }
429-
public DataTemplate IdentityKeyChangeMessage { get; set; }
430-
431-
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
432-
{
433-
FrameworkElement element = container as FrameworkElement;
434-
if (item is SignalMessageContainer smc)
435-
{
436-
SignalMessage sm = smc.Message;
437-
if (sm.Type == SignalMessageType.IdentityKeyChange)
438-
{
439-
return IdentityKeyChangeMessage;
440-
}
441-
return NormalMessage;
442-
}
443-
if (item is SignalUnreadMarker)
444-
{
445-
return UnreadMarker;
446-
}
447-
return null;
448-
}
449-
}
450401
}

Signal-Windows/Controls/IdentityKeyChangeMessage.xaml.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,11 @@ public IdentityKeyChangeMessage()
2626
this.InitializeComponent();
2727
DataContextChanged += IdentityKeyChangeMessage_DataContextChanged;
2828
}
29-
public SignalMessageContainer Model
29+
public Message Model
3030
{
3131
get
3232
{
33-
return this.DataContext as SignalMessageContainer;
33+
return this.DataContext as Message;
3434
}
3535
set
3636
{
@@ -42,7 +42,7 @@ private void IdentityKeyChangeMessage_DataContextChanged(FrameworkElement sender
4242
{
4343
if (Model != null)
4444
{
45-
MessageTextBlock.Text = Model.Message.Content.Content;
45+
MessageTextBlock.Text = Model.Model.Content.Content;
4646
}
4747
else
4848
{

Signal-Windows/Controls/Message.xaml.cs

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ public sealed partial class Message : UserControl, INotifyPropertyChanged
2424

2525
public event PropertyChangedEventHandler PropertyChanged;
2626

27-
public SignalMessageContainer Model
27+
public SignalMessage Model
2828
{
2929
get
3030
{
31-
return DataContext as SignalMessageContainer;
31+
return DataContext as SignalMessage;
3232
}
3333
set
3434
{
@@ -61,27 +61,27 @@ private void UpdateUI()
6161
if (Model != null)
6262
{
6363
UpdateMessageTextBlock();
64-
if (Model.Message.Author == null)
64+
if (Model.Author == null)
6565
{
6666
MessageAuthor.Visibility = Visibility.Collapsed;
6767
MessageBoxBorder.Background = Utils.BackgroundOutgoing;
6868
MessageContentTextBlock.Foreground = Utils.ForegroundOutgoing;
6969
FancyTimestampBlock.Foreground = Utils.GetSolidColorBrush(127, "#454545");
7070
HorizontalAlignment = HorizontalAlignment.Right;
7171
FooterPanel.HorizontalAlignment = HorizontalAlignment.Right;
72-
if (Model.Message.Status == SignalMessageStatus.Pending)
72+
if (Model.Status == SignalMessageStatus.Pending)
7373
{
7474
CheckImage.Visibility = Visibility.Collapsed;
7575
DoubleCheckImage.Visibility = Visibility.Collapsed;
7676
ResendTextBlock.Visibility = Visibility.Collapsed;
7777
}
78-
else if (Model.Message.Status == SignalMessageStatus.Confirmed)
78+
else if (Model.Status == SignalMessageStatus.Confirmed)
7979
{
8080
CheckImage.Visibility = Visibility.Visible;
8181
DoubleCheckImage.Visibility = Visibility.Collapsed;
8282
ResendTextBlock.Visibility = Visibility.Collapsed;
8383
}
84-
else if (Model.Message.Status == SignalMessageStatus.Received)
84+
else if (Model.Status == SignalMessageStatus.Received)
8585
{
8686
CheckImage.Visibility = Visibility.Collapsed;
8787
DoubleCheckImage.Visibility = Visibility.Visible;
@@ -99,36 +99,36 @@ private void UpdateUI()
9999
CheckImage.Visibility = Visibility.Collapsed;
100100
DoubleCheckImage.Visibility = Visibility.Collapsed;
101101
ResendTextBlock.Visibility = Visibility.Collapsed;
102-
if (Model.Message.ThreadId.EndsWith("="))
102+
if (Model.ThreadId.EndsWith("="))
103103
{
104104
MessageAuthor.Visibility = Visibility.Visible;
105-
MessageAuthor.Text = Model.Message.Author.ThreadDisplayName;
105+
MessageAuthor.Text = Model.Author.ThreadDisplayName;
106106
}
107107
else
108108
{
109109
MessageAuthor.Visibility = Visibility.Collapsed;
110110
}
111-
MessageBoxBorder.Background = Model.Message.Author.Color != null ? Utils.GetBrushFromColor(Model.Message.Author.Color) : Utils.GetBrushFromColor(Utils.CalculateDefaultColor(Model.Message.Author.ThreadDisplayName));
111+
MessageBoxBorder.Background = Model.Author.Color != null ? Utils.GetBrushFromColor(Model.Author.Color) : Utils.GetBrushFromColor(Utils.CalculateDefaultColor(Model.Author.ThreadDisplayName));
112112
MessageAuthor.Foreground = Utils.GetSolidColorBrush(204, "#ffffff");
113113
MessageContentTextBlock.Foreground = Utils.ForegroundIncoming;
114114
FancyTimestampBlock.Foreground = Utils.GetSolidColorBrush(127, "#ffffff");
115115
HorizontalAlignment = HorizontalAlignment.Left;
116116
FooterPanel.HorizontalAlignment = HorizontalAlignment.Left;
117117
}
118-
FancyTimestampBlock.Text = Utils.GetTimestamp(Model.Message.ComposedTimestamp);
118+
FancyTimestampBlock.Text = Utils.GetTimestamp(Model.ComposedTimestamp);
119119

120120
HasAttachment = false;
121-
if (Model.Message.Attachments?.Count > 0)
121+
if (Model.Attachments?.Count > 0)
122122
{
123123
HasAttachment = true;
124-
Attachment = Model.Message.Attachments[0];
124+
Attachment = Model.Attachments[0];
125125
}
126126
}
127127
}
128128

129129
private void UpdateMessageTextBlock()
130130
{
131-
string messageText = Model.Message.Content.Content;
131+
string messageText = Model.Content.Content;
132132
var matches = urlRegex.Matches(messageText);
133133
if (matches.Count == 0)
134134
{
@@ -195,12 +195,12 @@ private void MessageBox_DataContextChanged(FrameworkElement sender, DataContextC
195195

196196
private void ResendTextBlock_Tapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
197197
{
198-
App.Handle.ResendMessage(Model.Message);
198+
App.Handle.ResendMessage(Model);
199199
}
200200

201201
internal bool HandleUpdate(SignalMessage updatedMessage)
202202
{
203-
Model.Message.Status = updatedMessage.Status;
203+
Model.Status = updatedMessage.Status;
204204
UpdateUI();
205205
return updatedMessage.Status != SignalMessageStatus.Received;
206206
}

0 commit comments

Comments
 (0)