Optimize and improve message function

Test_AvaloniaEdit
2dust 2025-09-26 11:19:40 +08:00
parent 76dc14ee45
commit e51b923d82
5 changed files with 54 additions and 51 deletions

View File

@ -10,10 +10,9 @@ namespace ServiceLib.ViewModels;
public class MsgViewModel : MyReactiveObject
{
private readonly ConcurrentQueue<string> _queueMsg = new();
private readonly StringBuilder _msgBuilder = new();
private readonly int _numMaxMsg = 500;
private bool _lastMsgFilterNotAvailable;
private bool _blLockShow = false;
private volatile bool _lastMsgFilterNotAvailable;
private int _showLock = 0; // 0 = unlocked, 1 = locked
public int NumMaxMsg { get; } = 50;
[Reactive]
public string MsgFilter { get; set; }
@ -35,12 +34,12 @@ public class MsgViewModel : MyReactiveObject
this.WhenAnyValue(
x => x.AutoRefresh,
y => y == true)
.Subscribe(c => { _config.MsgUIItem.AutoRefresh = AutoRefresh; });
.Subscribe(c => _config.MsgUIItem.AutoRefresh = AutoRefresh);
AppEvents.SendMsgViewRequested
.AsObservable()
//.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async content => await AppendQueueMsg(content));
.Subscribe(content => _ = AppendQueueMsg(content));
}
private async Task AppendQueueMsg(string msg)
@ -49,36 +48,38 @@ public class MsgViewModel : MyReactiveObject
{
return;
}
_ = EnqueueQueueMsg(msg);
if (_blLockShow)
{
return;
}
EnqueueQueueMsg(msg);
if (!_config.UiItem.ShowInTaskbar)
{
return;
}
_blLockShow = true;
_msgBuilder.Clear();
//foreach (var it in _queueMsg)
//{
// _msgBuilder.Append(it);
//}
while (_queueMsg.TryDequeue(out var line))
if (Interlocked.CompareExchange(ref _showLock, 1, 0) != 0)
{
_msgBuilder.Append(line);
return;
}
try
{
await Task.Delay(500).ConfigureAwait(false);
await _updateView?.Invoke(EViewAction.DispatcherShowMsg, _msgBuilder.ToString());
var sb = new StringBuilder();
while (_queueMsg.TryDequeue(out var line))
{
sb.Append(line);
}
_blLockShow = false;
await _updateView?.Invoke(EViewAction.DispatcherShowMsg, sb.ToString());
}
finally
{
Interlocked.Exchange(ref _showLock, 0);
}
}
private async Task EnqueueQueueMsg(string msg)
private void EnqueueQueueMsg(string msg)
{
//filter msg
if (MsgFilter.IsNotEmpty() && !_lastMsgFilterNotAvailable)
@ -97,26 +98,17 @@ public class MsgViewModel : MyReactiveObject
}
}
//Enqueue
if (_queueMsg.Count > _numMaxMsg)
{
for (int k = 0; k < _queueMsg.Count - _numMaxMsg; k++)
{
_queueMsg.TryDequeue(out _);
}
}
_queueMsg.Enqueue(msg);
if (!msg.EndsWith(Environment.NewLine))
{
_queueMsg.Enqueue(Environment.NewLine);
}
await Task.CompletedTask;
}
public void ClearMsg()
{
_queueMsg.Clear();
}
//public void ClearMsg()
//{
// _queueMsg.Clear();
//}
private void DoMsgFilter()
{

View File

@ -5,6 +5,7 @@ using Avalonia.Controls.Notifications;
using Avalonia.Controls.Primitives;
using Avalonia.Media;
using Avalonia.Styling;
using AvaloniaEdit;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Semi.Avalonia;
@ -112,7 +113,8 @@ public class ThemeSettingViewModel : MyReactiveObject
x.OfType<ContextMenu>(),
x.OfType<DataGridRow>(),
x.OfType<ListBoxItem>(),
x.OfType<HeaderedContentControl>()
x.OfType<HeaderedContentControl>(),
x.OfType<TextEditor>()
));
style.Add(new Setter()
{
@ -153,7 +155,8 @@ public class ThemeSettingViewModel : MyReactiveObject
x.OfType<DataGridRow>(),
x.OfType<ListBoxItem>(),
x.OfType<HeaderedContentControl>(),
x.OfType<WindowNotificationManager>()
x.OfType<WindowNotificationManager>(),
x.OfType<TextEditor>()
));
style.Add(new Setter()
{

View File

@ -75,7 +75,8 @@
Name="txtMsg"
Margin="{StaticResource Margin8}"
IsReadOnly="True"
VerticalScrollBarVisibility="Auto">
VerticalScrollBarVisibility="Auto"
WordWrap="True">
<avaloniaEdit:TextEditor.ContextFlyout>
<MenuFlyout>
<MenuItem

View File

@ -1,5 +1,4 @@
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.ReactiveUI;
using Avalonia.Threading;
@ -10,12 +9,9 @@ namespace v2rayN.Desktop.Views;
public partial class MsgView : ReactiveUserControl<MsgViewModel>
{
private readonly ScrollViewer _scrollViewer;
public MsgView()
{
InitializeComponent();
_scrollViewer = this.FindControl<ScrollViewer>("msgScrollViewer");
ViewModel = new MsgViewModel(UpdateViewHandler);
@ -44,19 +40,23 @@ public partial class MsgView : ReactiveUserControl<MsgViewModel>
private void ShowMsg(object msg)
{
// txtMsg.Text = msg.ToString();
txtMsg.AppendText(msg.ToString());
if (txtMsg.Document.LineCount > ViewModel?.NumMaxMsg)
{
ClearMsg();
}
if (togScrollToEnd.IsChecked ?? true)
{
//txtMsg.ScrollToLine(txtMsg.Document.LineCount);
txtMsg.ScrollToEnd();
_scrollViewer?.ScrollToEnd();
}
txtMsg.AppendText(msg.ToString());
}
public void ClearMsg()
{
ViewModel?.ClearMsg();
txtMsg.Text = "";
txtMsg.Clear();
txtMsg.AppendText("----- Message cleared -----\n");
}
private void menuMsgViewSelectAll_Click(object? sender, RoutedEventArgs e)

View File

@ -48,18 +48,25 @@ public partial class MsgView
private void ShowMsg(object msg)
{
txtMsg.BeginChange();
txtMsg.Text = msg.ToString();
if (txtMsg.LineCount > ViewModel?.NumMaxMsg)
{
ClearMsg();
}
txtMsg.AppendText(msg.ToString());
if (togScrollToEnd.IsChecked ?? true)
{
txtMsg.ScrollToEnd();
}
txtMsg.EndChange();
}
public void ClearMsg()
{
ViewModel?.ClearMsg();
txtMsg.Clear();
txtMsg.AppendText("----- Message cleared -----\n");
}
private void menuMsgViewSelectAll_Click(object sender, System.Windows.RoutedEventArgs e)