diff --git a/src/Decho/Converters/StringConverters.cs b/src/Decho/Converters/StringConverters.cs
index 6500292..8ef34f0 100644
--- a/src/Decho/Converters/StringConverters.cs
+++ b/src/Decho/Converters/StringConverters.cs
@@ -33,4 +33,4 @@ public sealed class BoolToOpacityConverter : IValueConverter
{
throw new NotSupportedException();
}
-}
+}
\ No newline at end of file
diff --git a/src/Decho/ViewModels/MessageComposerViewModel.cs b/src/Decho/ViewModels/MessageComposerViewModel.cs
index ecabf44..7c074e8 100644
--- a/src/Decho/ViewModels/MessageComposerViewModel.cs
+++ b/src/Decho/ViewModels/MessageComposerViewModel.cs
@@ -202,6 +202,11 @@ public sealed class MessageComposerViewModel : ViewModelBase
ReplyTarget = null;
}
+ public void UpdateAutocomplete(string text, int caretIndex)
+ {
+ Autocomplete.Update(text, caretIndex);
+ }
+
internal void Send()
{
string text = Draft.Trim();
@@ -230,9 +235,4 @@ public sealed class MessageComposerViewModel : ViewModelBase
? $"{StagedFiles.Count} file(s) staged"
: string.Empty;
}
-
- public void UpdateAutocomplete(string text, int caretIndex)
- {
- Autocomplete.Update(text, caretIndex);
- }
}
\ No newline at end of file
diff --git a/src/Decho/Views/MessageItemView.axaml b/src/Decho/Views/MessageItemView.axaml
index 068fa3d..452dab2 100644
--- a/src/Decho/Views/MessageItemView.axaml
+++ b/src/Decho/Views/MessageItemView.axaml
@@ -50,10 +50,10 @@
Opacity="0.5"
IsVisible="{Binding HasReply}"
PointerPressed="OnReplyQuotePointerPressed" />
-
+
diff --git a/src/Decho/Views/MessageItemView.axaml.cs b/src/Decho/Views/MessageItemView.axaml.cs
index 384a24f..3f3ccfb 100644
--- a/src/Decho/Views/MessageItemView.axaml.cs
+++ b/src/Decho/Views/MessageItemView.axaml.cs
@@ -117,7 +117,7 @@ public partial class MessageItemView : UserControl
private void BuildMessageInlines(string content)
{
- TextBlock? tb = MessageContent;
+ SelectableTextBlock? tb = MessageContent;
if (tb is null)
{
return;
diff --git a/src/Decho/Views/MessageListView.axaml.cs b/src/Decho/Views/MessageListView.axaml.cs
index 5de4ec7..27bed58 100644
--- a/src/Decho/Views/MessageListView.axaml.cs
+++ b/src/Decho/Views/MessageListView.axaml.cs
@@ -17,12 +17,72 @@ public partial class MessageListView : UserControl
private bool _loadingMore;
private double _loadingMoreExtent;
+ private MessageViewModel? _highlightedMessage;
+
+ private CancellationTokenSource? _highlightCts;
+
public MessageListView()
{
InitializeComponent();
DataContextChanged += OnDataContextChanged;
}
+ public void ScrollToMessage(string messageId)
+ {
+ if (_chat is null) return;
+
+ MessageViewModel? target = _chat.Messages.FirstOrDefault(m => m.Model.Id == messageId);
+ if (target is null) return;
+
+ ScrollViewer? scroll = this.FindControl("MessageScrollViewer");
+ if (scroll is null) return;
+
+ ClearHighlight();
+ target.IsHighlighted = true;
+ _highlightedMessage = target;
+ _highlightCts = new CancellationTokenSource();
+ CancellationToken ct = _highlightCts.Token;
+
+ Dispatcher.UIThread.Post(() =>
+ {
+ double? targetY = FindItemY(scroll, target);
+ if (targetY is not null)
+ scroll.Offset = new Vector(scroll.Offset.X, targetY.Value);
+ }, DispatcherPriority.Render);
+
+ _ = Task.Run(async () =>
+ {
+ try
+ {
+ await Task.Delay(2000, ct);
+ Dispatcher.UIThread.Post(() =>
+ {
+ target.IsHighlighted = false;
+ if (_highlightedMessage == target)
+ _highlightedMessage = null;
+ });
+ }
+ catch (OperationCanceledException)
+ {
+ }
+ });
+ }
+
+ private static double? FindItemY(Visual parent, MessageViewModel target)
+ {
+ foreach (Visual child in parent.GetVisualChildren())
+ {
+ if (child.DataContext == target)
+ return child.Bounds.Y;
+
+ double? result = FindItemY(child, target);
+ if (result.HasValue)
+ return result;
+ }
+
+ return null;
+ }
+
private void OnDataContextChanged(object? sender, EventArgs args)
{
if (_chat is not null)
@@ -142,65 +202,6 @@ public partial class MessageListView : UserControl
Dispatcher.UIThread.Post(scroll.ScrollToEnd, DispatcherPriority.Background);
}
- public void ScrollToMessage(string messageId)
- {
- if (_chat is null) return;
-
- MessageViewModel? target = _chat.Messages.FirstOrDefault(m => m.Model.Id == messageId);
- if (target is null) return;
-
- ScrollViewer? scroll = this.FindControl("MessageScrollViewer");
- if (scroll is null) return;
-
- ClearHighlight();
- target.IsHighlighted = true;
- _highlightedMessage = target;
- _highlightCts = new CancellationTokenSource();
- CancellationToken ct = _highlightCts.Token;
-
- Dispatcher.UIThread.Post(() =>
- {
- double? targetY = FindItemY(scroll, target);
- if (targetY is not null)
- scroll.Offset = new Vector(scroll.Offset.X, targetY.Value);
- }, DispatcherPriority.Render);
-
- _ = Task.Run(async () =>
- {
- try
- {
- await Task.Delay(2000, ct);
- Dispatcher.UIThread.Post(() =>
- {
- target.IsHighlighted = false;
- if (_highlightedMessage == target)
- _highlightedMessage = null;
- });
- }
- catch (OperationCanceledException)
- {
- }
- });
- }
-
- private static double? FindItemY(Visual parent, MessageViewModel target)
- {
- foreach (Visual child in parent.GetVisualChildren())
- {
- if (child.DataContext == target)
- return child.Bounds.Y;
-
- double? result = FindItemY(child, target);
- if (result.HasValue)
- return result;
- }
-
- return null;
- }
-
- private MessageViewModel? _highlightedMessage;
- private CancellationTokenSource? _highlightCts;
-
private void ClearHighlight()
{
_highlightCts?.Cancel();