@@ -22,9 +22,7 @@ public sealed partial class Conversation : UserControl, INotifyPropertyChanged
22
22
public event PropertyChangedEventHandler PropertyChanged ;
23
23
private bool SendingMessage = false ;
24
24
private Dictionary < long , SignalMessageContainer > OutgoingCache = new Dictionary < long , SignalMessageContainer > ( ) ;
25
- //private SignalUnreadMarker UnreadMarker = new SignalUnreadMarker();
26
25
private SignalConversation SignalConversation ;
27
- //private bool UnreadMarkerAdded = false;
28
26
private VirtualizedCollection Collection ;
29
27
30
28
private string _ThreadDisplayName ;
@@ -128,7 +126,6 @@ private void UpdateHeader(SignalConversation thread)
128
126
public void Load ( SignalConversation conversation )
129
127
{
130
128
SignalConversation = conversation ;
131
- //UnreadMarkerAdded = false;
132
129
InputTextBox . IsEnabled = false ;
133
130
DisposeCurrentThread ( ) ;
134
131
UpdateHeader ( conversation ) ;
@@ -145,7 +142,7 @@ public void Load(SignalConversation conversation)
145
142
ConversationItemsControl . ItemsSource = Collection ;
146
143
UpdateLayout ( ) ;
147
144
InputTextBox . IsEnabled = conversation . CanReceive ;
148
- ScrollToBottom ( ) ;
145
+ ScrollToUnread ( ) ;
149
146
}
150
147
151
148
public void DisposeCurrentThread ( )
@@ -183,21 +180,27 @@ public void UpdateMessageBox(SignalMessage updatedMessage)
183
180
if ( OutgoingCache . ContainsKey ( updatedMessage . Id ) )
184
181
{
185
182
var m = OutgoingCache [ updatedMessage . Id ] ;
186
- var item = ( ListBoxItem ) ConversationItemsControl . ContainerFromIndex ( m . Index ) ;
187
- var message = FindElementByName < Message > ( item , "ListBoxItemContent" ) ;
188
- bool retain = message . HandleUpdate ( updatedMessage ) ;
189
- if ( ! retain )
183
+ var item = ( ListViewItem ) ConversationItemsControl . ContainerFromIndex ( Collection . GetVirtualIndex ( m . Index ) ) ;
184
+ if ( item != null )
190
185
{
191
- OutgoingCache . Remove ( m . Index ) ;
186
+ var message = FindElementByName < Message > ( item , "ListBoxItemContent" ) ;
187
+ bool retain = message . HandleUpdate ( updatedMessage ) ;
188
+ if ( ! retain )
189
+ {
190
+ OutgoingCache . Remove ( m . Index ) ;
191
+ }
192
192
}
193
193
}
194
194
}
195
195
196
196
public void Append ( SignalMessageContainer sm , bool forceScroll )
197
197
{
198
- Collection . Add ( sm ) ;
199
- if ( forceScroll || true ) //TODO
198
+ var sourcePanel = ( ItemsStackPanel ) ConversationItemsControl . ItemsPanelRoot ;
199
+ bool bottom = sourcePanel . LastVisibleIndex == Collection . Count - 2 ; /* -2 because we already incremented Count */
200
+ Collection . Add ( sm , true ) ;
201
+ if ( forceScroll || bottom )
200
202
{
203
+ UpdateLayout ( ) ;
201
204
ScrollToBottom ( ) ;
202
205
}
203
206
}
@@ -223,11 +226,11 @@ private async void TextBox_KeyDown(object sender, KeyRoutedEventArgs e)
223
226
224
227
private void ScrollToBottom ( )
225
228
{
226
- if ( ConversationItemsControl . Items . Count == 0 )
227
- return ;
228
- var lastMsg = ConversationItemsControl . Items [ ConversationItemsControl . Items . Count - 1 ] as SignalMessageContainer ;
229
- Debug . WriteLine ( $ "scroll to { lastMsg } " ) ;
230
- ConversationItemsControl . ScrollIntoView ( lastMsg ) ;
229
+ if ( Collection . Count > 0 )
230
+ {
231
+ var lastUnreadMsg = ConversationItemsControl . Items [ Collection . Count - 1 ] ;
232
+ ConversationItemsControl . ScrollIntoView ( lastUnreadMsg , ScrollIntoViewAlignment . Leading ) ;
233
+ }
231
234
}
232
235
233
236
private async void SendMessageButton_Click ( object sender , RoutedEventArgs e )
@@ -240,30 +243,48 @@ private void InputTextBox_TextChanged(object sender, TextChangedEventArgs e)
240
243
TextBox t = sender as TextBox ;
241
244
SendEnabled = t . Text != string . Empty ;
242
245
}
243
- }
244
246
245
- public class SignalUnreadMarker
246
- {
247
- public UnreadMarker View { get ; set ; }
247
+ private void ScrollToUnread ( )
248
+ {
249
+ if ( Collection . Count > 0 )
250
+ {
251
+ if ( Collection . UnreadMarkerIndex > 0 )
252
+ {
253
+ var lastUnreadMsg = ConversationItemsControl . Items [ Collection . UnreadMarkerIndex ] ;
254
+ ConversationItemsControl . ScrollIntoView ( lastUnreadMsg , ScrollIntoViewAlignment . Leading ) ;
255
+ }
256
+ else
257
+ {
258
+ var lastUnreadMsg = ConversationItemsControl . Items [ Collection . Count - 1 ] ;
259
+ ConversationItemsControl . ScrollIntoView ( lastUnreadMsg , ScrollIntoViewAlignment . Leading ) ;
260
+ }
261
+ }
262
+ }
248
263
}
249
- public class MessageStyleSelector : StyleSelector
264
+
265
+ public class MessageTemplateSelector : DataTemplateSelector
250
266
{
251
- public Style NormalMessage { get ; set ; }
252
- public Style UnreadMarker { get ; set ; }
253
- public Style IdentityKeyChangeMessage { get ; set ; }
267
+ public DataTemplate NormalMessage { get ; set ; }
268
+ public DataTemplate UnreadMarker { get ; set ; }
269
+ public DataTemplate IdentityKeyChangeMessage { get ; set ; }
254
270
255
- protected override Style SelectStyleCore ( object item , DependencyObject container )
271
+ protected override DataTemplate SelectTemplateCore ( object item , DependencyObject container )
256
272
{
257
273
FrameworkElement element = container as FrameworkElement ;
258
274
if ( item is SignalMessageContainer )
259
275
{
260
- SignalMessage sm = ( ( SignalMessageContainer ) item ) . Message ;
276
+ SignalMessageContainer smc = ( SignalMessageContainer ) item ;
277
+ SignalMessage sm = smc . Message ;
261
278
if ( sm . Type == SignalMessageType . IdentityKeyChange )
262
279
{
263
280
return IdentityKeyChangeMessage ;
264
281
}
265
282
return NormalMessage ;
266
283
}
284
+ if ( item is SignalUnreadMarker )
285
+ {
286
+ return UnreadMarker ;
287
+ }
267
288
return null ;
268
289
}
269
290
}
0 commit comments