mirror of https://github.com/2dust/v2rayN
Optimize and improve message function
parent
76dc14ee45
commit
e51b923d82
|
@ -10,10 +10,9 @@ namespace ServiceLib.ViewModels;
|
||||||
public class MsgViewModel : MyReactiveObject
|
public class MsgViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private readonly ConcurrentQueue<string> _queueMsg = new();
|
private readonly ConcurrentQueue<string> _queueMsg = new();
|
||||||
private readonly StringBuilder _msgBuilder = new();
|
private volatile bool _lastMsgFilterNotAvailable;
|
||||||
private readonly int _numMaxMsg = 500;
|
private int _showLock = 0; // 0 = unlocked, 1 = locked
|
||||||
private bool _lastMsgFilterNotAvailable;
|
public int NumMaxMsg { get; } = 50;
|
||||||
private bool _blLockShow = false;
|
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public string MsgFilter { get; set; }
|
public string MsgFilter { get; set; }
|
||||||
|
@ -35,12 +34,12 @@ public class MsgViewModel : MyReactiveObject
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.AutoRefresh,
|
x => x.AutoRefresh,
|
||||||
y => y == true)
|
y => y == true)
|
||||||
.Subscribe(c => { _config.MsgUIItem.AutoRefresh = AutoRefresh; });
|
.Subscribe(c => _config.MsgUIItem.AutoRefresh = AutoRefresh);
|
||||||
|
|
||||||
AppEvents.SendMsgViewRequested
|
AppEvents.SendMsgViewRequested
|
||||||
.AsObservable()
|
.AsObservable()
|
||||||
//.ObserveOn(RxApp.MainThreadScheduler)
|
//.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
.Subscribe(async content => await AppendQueueMsg(content));
|
.Subscribe(content => _ = AppendQueueMsg(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AppendQueueMsg(string msg)
|
private async Task AppendQueueMsg(string msg)
|
||||||
|
@ -49,36 +48,38 @@ public class MsgViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_ = EnqueueQueueMsg(msg);
|
|
||||||
|
|
||||||
if (_blLockShow)
|
EnqueueQueueMsg(msg);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!_config.UiItem.ShowInTaskbar)
|
if (!_config.UiItem.ShowInTaskbar)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_blLockShow = true;
|
if (Interlocked.CompareExchange(ref _showLock, 1, 0) != 0)
|
||||||
|
|
||||||
_msgBuilder.Clear();
|
|
||||||
//foreach (var it in _queueMsg)
|
|
||||||
//{
|
|
||||||
// _msgBuilder.Append(it);
|
|
||||||
//}
|
|
||||||
while (_queueMsg.TryDequeue(out var line))
|
|
||||||
{
|
{
|
||||||
_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
|
//filter msg
|
||||||
if (MsgFilter.IsNotEmpty() && !_lastMsgFilterNotAvailable)
|
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);
|
_queueMsg.Enqueue(msg);
|
||||||
if (!msg.EndsWith(Environment.NewLine))
|
if (!msg.EndsWith(Environment.NewLine))
|
||||||
{
|
{
|
||||||
_queueMsg.Enqueue(Environment.NewLine);
|
_queueMsg.Enqueue(Environment.NewLine);
|
||||||
}
|
}
|
||||||
await Task.CompletedTask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearMsg()
|
//public void ClearMsg()
|
||||||
{
|
//{
|
||||||
_queueMsg.Clear();
|
// _queueMsg.Clear();
|
||||||
}
|
//}
|
||||||
|
|
||||||
private void DoMsgFilter()
|
private void DoMsgFilter()
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,6 +5,7 @@ using Avalonia.Controls.Notifications;
|
||||||
using Avalonia.Controls.Primitives;
|
using Avalonia.Controls.Primitives;
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using Avalonia.Styling;
|
using Avalonia.Styling;
|
||||||
|
using AvaloniaEdit;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Semi.Avalonia;
|
using Semi.Avalonia;
|
||||||
|
@ -112,7 +113,8 @@ public class ThemeSettingViewModel : MyReactiveObject
|
||||||
x.OfType<ContextMenu>(),
|
x.OfType<ContextMenu>(),
|
||||||
x.OfType<DataGridRow>(),
|
x.OfType<DataGridRow>(),
|
||||||
x.OfType<ListBoxItem>(),
|
x.OfType<ListBoxItem>(),
|
||||||
x.OfType<HeaderedContentControl>()
|
x.OfType<HeaderedContentControl>(),
|
||||||
|
x.OfType<TextEditor>()
|
||||||
));
|
));
|
||||||
style.Add(new Setter()
|
style.Add(new Setter()
|
||||||
{
|
{
|
||||||
|
@ -153,7 +155,8 @@ public class ThemeSettingViewModel : MyReactiveObject
|
||||||
x.OfType<DataGridRow>(),
|
x.OfType<DataGridRow>(),
|
||||||
x.OfType<ListBoxItem>(),
|
x.OfType<ListBoxItem>(),
|
||||||
x.OfType<HeaderedContentControl>(),
|
x.OfType<HeaderedContentControl>(),
|
||||||
x.OfType<WindowNotificationManager>()
|
x.OfType<WindowNotificationManager>(),
|
||||||
|
x.OfType<TextEditor>()
|
||||||
));
|
));
|
||||||
style.Add(new Setter()
|
style.Add(new Setter()
|
||||||
{
|
{
|
||||||
|
|
|
@ -75,7 +75,8 @@
|
||||||
Name="txtMsg"
|
Name="txtMsg"
|
||||||
Margin="{StaticResource Margin8}"
|
Margin="{StaticResource Margin8}"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
VerticalScrollBarVisibility="Auto">
|
VerticalScrollBarVisibility="Auto"
|
||||||
|
WordWrap="True">
|
||||||
<avaloniaEdit:TextEditor.ContextFlyout>
|
<avaloniaEdit:TextEditor.ContextFlyout>
|
||||||
<MenuFlyout>
|
<MenuFlyout>
|
||||||
<MenuItem
|
<MenuItem
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.ReactiveUI;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
@ -10,12 +9,9 @@ namespace v2rayN.Desktop.Views;
|
||||||
|
|
||||||
public partial class MsgView : ReactiveUserControl<MsgViewModel>
|
public partial class MsgView : ReactiveUserControl<MsgViewModel>
|
||||||
{
|
{
|
||||||
private readonly ScrollViewer _scrollViewer;
|
|
||||||
|
|
||||||
public MsgView()
|
public MsgView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_scrollViewer = this.FindControl<ScrollViewer>("msgScrollViewer");
|
|
||||||
|
|
||||||
ViewModel = new MsgViewModel(UpdateViewHandler);
|
ViewModel = new MsgViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
|
@ -44,19 +40,23 @@ public partial class MsgView : ReactiveUserControl<MsgViewModel>
|
||||||
|
|
||||||
private void ShowMsg(object msg)
|
private void ShowMsg(object msg)
|
||||||
{
|
{
|
||||||
// txtMsg.Text = msg.ToString();
|
if (txtMsg.Document.LineCount > ViewModel?.NumMaxMsg)
|
||||||
txtMsg.AppendText(msg.ToString());
|
{
|
||||||
|
ClearMsg();
|
||||||
|
}
|
||||||
|
|
||||||
if (togScrollToEnd.IsChecked ?? true)
|
if (togScrollToEnd.IsChecked ?? true)
|
||||||
{
|
{
|
||||||
|
//txtMsg.ScrollToLine(txtMsg.Document.LineCount);
|
||||||
txtMsg.ScrollToEnd();
|
txtMsg.ScrollToEnd();
|
||||||
_scrollViewer?.ScrollToEnd();
|
|
||||||
}
|
}
|
||||||
|
txtMsg.AppendText(msg.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearMsg()
|
public void ClearMsg()
|
||||||
{
|
{
|
||||||
ViewModel?.ClearMsg();
|
txtMsg.Clear();
|
||||||
txtMsg.Text = "";
|
txtMsg.AppendText("----- Message cleared -----\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuMsgViewSelectAll_Click(object? sender, RoutedEventArgs e)
|
private void menuMsgViewSelectAll_Click(object? sender, RoutedEventArgs e)
|
||||||
|
|
|
@ -48,18 +48,25 @@ public partial class MsgView
|
||||||
private void ShowMsg(object msg)
|
private void ShowMsg(object msg)
|
||||||
{
|
{
|
||||||
txtMsg.BeginChange();
|
txtMsg.BeginChange();
|
||||||
txtMsg.Text = msg.ToString();
|
|
||||||
|
if (txtMsg.LineCount > ViewModel?.NumMaxMsg)
|
||||||
|
{
|
||||||
|
ClearMsg();
|
||||||
|
}
|
||||||
|
|
||||||
|
txtMsg.AppendText(msg.ToString());
|
||||||
if (togScrollToEnd.IsChecked ?? true)
|
if (togScrollToEnd.IsChecked ?? true)
|
||||||
{
|
{
|
||||||
txtMsg.ScrollToEnd();
|
txtMsg.ScrollToEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
txtMsg.EndChange();
|
txtMsg.EndChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearMsg()
|
public void ClearMsg()
|
||||||
{
|
{
|
||||||
ViewModel?.ClearMsg();
|
|
||||||
txtMsg.Clear();
|
txtMsg.Clear();
|
||||||
|
txtMsg.AppendText("----- Message cleared -----\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void menuMsgViewSelectAll_Click(object sender, System.Windows.RoutedEventArgs e)
|
private void menuMsgViewSelectAll_Click(object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
|
Loading…
Reference in New Issue