mirror of https://github.com/2dust/v2rayN
Improved log message display
parent
82eb3fd6bd
commit
d91b0afb9a
|
@ -39,6 +39,7 @@
|
||||||
DispatcherRefreshServersBiz,
|
DispatcherRefreshServersBiz,
|
||||||
DispatcherRefreshIcon,
|
DispatcherRefreshIcon,
|
||||||
DispatcherCheckUpdate,
|
DispatcherCheckUpdate,
|
||||||
DispatcherCheckUpdateFinished,
|
DispatcherCheckUpdateFinished,
|
||||||
|
DispatcherShowMsg,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -124,20 +124,16 @@ namespace ServiceLib.Handler
|
||||||
mtu = 9000,
|
mtu = 9000,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (config.guiItem == null)
|
config.guiItem ??= new()
|
||||||
{
|
{
|
||||||
config.guiItem = new()
|
enableStatistics = false,
|
||||||
{
|
};
|
||||||
enableStatistics = false,
|
config.msgUIItem ??= new();
|
||||||
};
|
|
||||||
}
|
config.uiItem ??= new UIItem()
|
||||||
if (config.uiItem == null)
|
|
||||||
{
|
{
|
||||||
config.uiItem = new UIItem()
|
enableAutoAdjustMainLvColWidth = true
|
||||||
{
|
};
|
||||||
enableAutoAdjustMainLvColWidth = true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (config.uiItem.mainColumnItem == null)
|
if (config.uiItem.mainColumnItem == null)
|
||||||
{
|
{
|
||||||
config.uiItem.mainColumnItem = new();
|
config.uiItem.mainColumnItem = new();
|
||||||
|
@ -174,11 +170,11 @@ namespace ServiceLib.Handler
|
||||||
}
|
}
|
||||||
|
|
||||||
config.mux4RayItem ??= new()
|
config.mux4RayItem ??= new()
|
||||||
{
|
{
|
||||||
concurrency = 8,
|
concurrency = 8,
|
||||||
xudpConcurrency = 16,
|
xudpConcurrency = 16,
|
||||||
xudpProxyUDP443 = "reject"
|
xudpProxyUDP443 = "reject"
|
||||||
};
|
};
|
||||||
|
|
||||||
if (config.mux4SboxItem == null)
|
if (config.mux4SboxItem == null)
|
||||||
{
|
{
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
public GrpcItem grpcItem { get; set; }
|
public GrpcItem grpcItem { get; set; }
|
||||||
public RoutingBasicItem routingBasicItem { get; set; }
|
public RoutingBasicItem routingBasicItem { get; set; }
|
||||||
public GUIItem guiItem { get; set; }
|
public GUIItem guiItem { get; set; }
|
||||||
|
public MsgUIItem msgUIItem { get; set; }
|
||||||
public UIItem uiItem { get; set; }
|
public UIItem uiItem { get; set; }
|
||||||
public ConstItem constItem { get; set; }
|
public ConstItem constItem { get; set; }
|
||||||
public SpeedTestItem speedTestItem { get; set; }
|
public SpeedTestItem speedTestItem { get; set; }
|
||||||
|
|
|
@ -107,6 +107,13 @@
|
||||||
public bool enableLog { get; set; } = true;
|
public bool enableLog { get; set; } = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
public class MsgUIItem
|
||||||
|
{
|
||||||
|
public string? mainMsgFilter { get; set; }
|
||||||
|
public bool? autoRefresh { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class UIItem
|
public class UIItem
|
||||||
{
|
{
|
||||||
|
@ -126,7 +133,6 @@
|
||||||
public bool enableDragDropSort { get; set; }
|
public bool enableDragDropSort { get; set; }
|
||||||
public bool doubleClick2Activate { get; set; }
|
public bool doubleClick2Activate { get; set; }
|
||||||
public bool autoHideStartup { get; set; }
|
public bool autoHideStartup { get; set; }
|
||||||
public string mainMsgFilter { get; set; }
|
|
||||||
public List<ColumnItem> mainColumnItem { get; set; }
|
public List<ColumnItem> mainColumnItem { get; set; }
|
||||||
public bool showInTaskbar { get; set; }
|
public bool showInTaskbar { get; set; }
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,112 @@
|
||||||
|
using ReactiveUI;
|
||||||
|
using ReactiveUI.Fody.Helpers;
|
||||||
|
using Splat;
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
|
namespace ServiceLib.ViewModels
|
||||||
|
{
|
||||||
|
public class MsgViewModel : MyReactiveObject
|
||||||
|
{
|
||||||
|
private ConcurrentQueue<string> _queueMsg = new();
|
||||||
|
private int _numMaxMsg = 500;
|
||||||
|
private string _lastMsgFilter = string.Empty;
|
||||||
|
private bool _lastMsgFilterNotAvailable;
|
||||||
|
private bool _blLockShow = false;
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public string MsgFilter { get; set; }
|
||||||
|
|
||||||
|
[Reactive]
|
||||||
|
public bool AutoRefresh { get; set; }
|
||||||
|
|
||||||
|
public MsgViewModel(Func<EViewAction, object?, Task<bool>>? updateView)
|
||||||
|
{
|
||||||
|
_config = LazyConfig.Instance.Config;
|
||||||
|
_updateView = updateView;
|
||||||
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
|
|
||||||
|
MessageBus.Current.Listen<string>(Global.CommandSendMsgView).Subscribe(async x => await AppendQueueMsg(x));
|
||||||
|
|
||||||
|
MsgFilter = _config.msgUIItem.mainMsgFilter ?? string.Empty;
|
||||||
|
AutoRefresh = _config.msgUIItem.autoRefresh ?? true;
|
||||||
|
|
||||||
|
this.WhenAnyValue(
|
||||||
|
x => x.MsgFilter)
|
||||||
|
.Subscribe(c => _config.msgUIItem.mainMsgFilter = MsgFilter);
|
||||||
|
|
||||||
|
this.WhenAnyValue(
|
||||||
|
x => x.AutoRefresh,
|
||||||
|
y => y == true)
|
||||||
|
.Subscribe(c => { _config.msgUIItem.autoRefresh = AutoRefresh; });
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task AppendQueueMsg(string msg)
|
||||||
|
{
|
||||||
|
//if (msg == Global.CommandClearMsg)
|
||||||
|
//{
|
||||||
|
// ClearMsg();
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
if (AutoRefresh == false)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_ = EnqueueQueueMsg(msg);
|
||||||
|
|
||||||
|
if (_blLockShow)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_blLockShow = true;
|
||||||
|
|
||||||
|
await Task.Delay(100);
|
||||||
|
var txt = string.Join("", _queueMsg.ToArray());
|
||||||
|
await _updateView?.Invoke(EViewAction.DispatcherShowMsg, txt);
|
||||||
|
|
||||||
|
_blLockShow = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async Task EnqueueQueueMsg(string msg)
|
||||||
|
{
|
||||||
|
//filter msg
|
||||||
|
if (MsgFilter != _lastMsgFilter) _lastMsgFilterNotAvailable = false;
|
||||||
|
if (!Utils.IsNullOrEmpty(MsgFilter) && !_lastMsgFilterNotAvailable)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (!Regex.IsMatch(msg, MsgFilter))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
_lastMsgFilterNotAvailable = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_lastMsgFilter = MsgFilter;
|
||||||
|
|
||||||
|
//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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ClearMsg()
|
||||||
|
{
|
||||||
|
_queueMsg.Clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,104 +1,54 @@
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Interactivity;
|
using Avalonia.Interactivity;
|
||||||
|
using Avalonia.ReactiveUI;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using System.Collections.Concurrent;
|
using System.Reactive.Disposables;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using v2rayN.Desktop.Common;
|
using v2rayN.Desktop.Common;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views
|
namespace v2rayN.Desktop.Views
|
||||||
{
|
{
|
||||||
public partial class MsgView : UserControl
|
public partial class MsgView : ReactiveUserControl<MsgViewModel>
|
||||||
{
|
{
|
||||||
private static Config? _config;
|
|
||||||
private ConcurrentQueue<string> _queueMsg = new();
|
|
||||||
private int _numMaxMsg = 500;
|
|
||||||
|
|
||||||
private string lastMsgFilter = string.Empty;
|
|
||||||
private bool lastMsgFilterNotAvailable;
|
|
||||||
|
|
||||||
public MsgView()
|
public MsgView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_config = LazyConfig.Instance.Config;
|
|
||||||
MessageBus.Current.Listen<string>(Global.CommandSendMsgView).Subscribe(x => DelegateAppendText(x));
|
ViewModel = new MsgViewModel(UpdateViewHandler);
|
||||||
//Global.PresetMsgFilters.ForEach(it =>
|
|
||||||
//{
|
this.WhenActivated(disposables =>
|
||||||
// cmbMsgFilter.Items.Add(it);
|
|
||||||
//});
|
|
||||||
if (!_config.uiItem.mainMsgFilter.IsNullOrEmpty())
|
|
||||||
{
|
{
|
||||||
cmbMsgFilter.Text = _config.uiItem.mainMsgFilter;
|
this.Bind(ViewModel, vm => vm.MsgFilter, v => v.cmbMsgFilter.Text).DisposeWith(disposables);
|
||||||
}
|
this.Bind(ViewModel, vm => vm.AutoRefresh, v => v.togAutoRefresh.IsChecked).DisposeWith(disposables);
|
||||||
cmbMsgFilter.TextChanged += (s, e) =>
|
});
|
||||||
{
|
|
||||||
_config.uiItem.mainMsgFilter = cmbMsgFilter.Text?.ToString();
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DelegateAppendText(string msg)
|
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||||
{
|
{
|
||||||
Dispatcher.UIThread.Post(() => AppendText(msg), DispatcherPriority.ApplicationIdle);
|
switch (action)
|
||||||
|
{
|
||||||
|
case EViewAction.DispatcherShowMsg:
|
||||||
|
if (obj is null) return false;
|
||||||
|
|
||||||
|
Dispatcher.UIThread.Post(() =>
|
||||||
|
ShowMsg(obj),
|
||||||
|
DispatcherPriority.ApplicationIdle);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return await Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AppendText(string msg)
|
private void ShowMsg(object msg)
|
||||||
{
|
{
|
||||||
if (msg == Global.CommandClearMsg)
|
txtMsg.Text = msg.ToString();
|
||||||
{
|
|
||||||
ClearMsg();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (togAutoRefresh.IsChecked == false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var MsgFilter = cmbMsgFilter.Text?.ToString();
|
|
||||||
if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false;
|
|
||||||
if (!Utils.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!Regex.IsMatch(msg, MsgFilter))
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
lastMsgFilterNotAvailable = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastMsgFilter = MsgFilter;
|
|
||||||
|
|
||||||
ShowMsg(msg);
|
|
||||||
|
|
||||||
if (togScrollToEnd.IsChecked ?? true)
|
if (togScrollToEnd.IsChecked ?? true)
|
||||||
{
|
{
|
||||||
txtMsg.CaretIndex = int.MaxValue;
|
txtMsg.CaretIndex = int.MaxValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ShowMsg(string msg)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
txtMsg.Text = string.Join("", _queueMsg.ToArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ClearMsg()
|
public void ClearMsg()
|
||||||
{
|
{
|
||||||
_queueMsg.Clear();
|
ViewModel?.ClearMsg();
|
||||||
txtMsg.Clear();
|
txtMsg.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,16 @@
|
||||||
<UserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.MsgView"
|
x:Class="v2rayN.Views.MsgView"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:reactiveui="http://reactiveui.net"
|
||||||
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
|
||||||
|
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
d:DesignWidth="800"
|
d:DesignWidth="800"
|
||||||
|
x:TypeArguments="vms:MsgViewModel"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<DockPanel Margin="2">
|
<DockPanel Margin="2">
|
||||||
<WrapPanel
|
<WrapPanel
|
||||||
|
@ -23,8 +26,7 @@
|
||||||
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgFilterTitle}"
|
materialDesign:HintAssist.Hint="{x:Static resx:ResUI.MsgFilterTitle}"
|
||||||
materialDesign:TextFieldAssist.HasClearButton="True"
|
materialDesign:TextFieldAssist.HasClearButton="True"
|
||||||
IsEditable="True"
|
IsEditable="True"
|
||||||
Style="{StaticResource DefComboBox}"
|
Style="{StaticResource DefComboBox}" />
|
||||||
TextBoxBase.TextChanged="cmbMsgFilter_TextChanged" />
|
|
||||||
<Button
|
<Button
|
||||||
x:Name="btnCopy"
|
x:Name="btnCopy"
|
||||||
Width="24"
|
Width="24"
|
||||||
|
@ -96,4 +98,4 @@
|
||||||
</TextBox.ContextMenu>
|
</TextBox.ContextMenu>
|
||||||
</TextBox>
|
</TextBox>
|
||||||
</DockPanel>
|
</DockPanel>
|
||||||
</UserControl>
|
</reactiveui:ReactiveUserControl>
|
|
@ -1,25 +1,23 @@
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using System.Collections.Concurrent;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Windows;
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace v2rayN.Views
|
namespace v2rayN.Views
|
||||||
{
|
{
|
||||||
public partial class MsgView
|
public partial class MsgView
|
||||||
{
|
{
|
||||||
private static Config? _config;
|
|
||||||
private ConcurrentQueue<string> _queueMsg = new();
|
|
||||||
private int _numMaxMsg = 500;
|
|
||||||
|
|
||||||
private string lastMsgFilter = string.Empty;
|
|
||||||
private bool lastMsgFilterNotAvailable;
|
|
||||||
|
|
||||||
public MsgView()
|
public MsgView()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_config = LazyConfig.Instance.Config;
|
|
||||||
MessageBus.Current.Listen<string>(Global.CommandSendMsgView).Subscribe(x => DelegateAppendText(x));
|
ViewModel = new MsgViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
|
this.WhenActivated(disposables =>
|
||||||
|
{
|
||||||
|
this.Bind(ViewModel, vm => vm.MsgFilter, v => v.cmbMsgFilter.Text).DisposeWith(disposables);
|
||||||
|
this.Bind(ViewModel, vm => vm.AutoRefresh, v => v.togAutoRefresh.IsChecked).DisposeWith(disposables);
|
||||||
|
});
|
||||||
|
|
||||||
btnCopy.Click += menuMsgViewCopyAll_Click;
|
btnCopy.Click += menuMsgViewCopyAll_Click;
|
||||||
btnClear.Click += menuMsgViewClear_Click;
|
btnClear.Click += menuMsgViewClear_Click;
|
||||||
|
@ -32,75 +30,37 @@ namespace v2rayN.Views
|
||||||
{
|
{
|
||||||
cmbMsgFilter.Items.Add(it);
|
cmbMsgFilter.Items.Add(it);
|
||||||
});
|
});
|
||||||
if (!_config.uiItem.mainMsgFilter.IsNullOrEmpty())
|
|
||||||
{
|
|
||||||
cmbMsgFilter.Text = _config.uiItem.mainMsgFilter;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DelegateAppendText(string msg)
|
private async Task<bool> UpdateViewHandler(EViewAction action, object? obj)
|
||||||
{
|
{
|
||||||
Dispatcher.BeginInvoke(AppendText, DispatcherPriority.ApplicationIdle, msg);
|
switch (action)
|
||||||
}
|
|
||||||
|
|
||||||
public void AppendText(string msg)
|
|
||||||
{
|
|
||||||
if (msg == Global.CommandClearMsg)
|
|
||||||
{
|
{
|
||||||
ClearMsg();
|
case EViewAction.DispatcherShowMsg:
|
||||||
return;
|
if (obj is null) return false;
|
||||||
}
|
Application.Current?.Dispatcher.Invoke((() =>
|
||||||
if (togAutoRefresh.IsChecked == false)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var MsgFilter = cmbMsgFilter.Text.TrimEx();
|
|
||||||
if (MsgFilter != lastMsgFilter) lastMsgFilterNotAvailable = false;
|
|
||||||
if (!Utils.IsNullOrEmpty(MsgFilter) && !lastMsgFilterNotAvailable)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!Regex.IsMatch(msg, MsgFilter)) // 如果不是正则表达式会异常
|
|
||||||
{
|
{
|
||||||
return;
|
ShowMsg(obj);
|
||||||
}
|
}), DispatcherPriority.ApplicationIdle);
|
||||||
}
|
break;
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
lastMsgFilterNotAvailable = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
lastMsgFilter = MsgFilter;
|
return await Task.FromResult(true);
|
||||||
|
}
|
||||||
ShowMsg(msg);
|
|
||||||
|
|
||||||
|
private void ShowMsg(object msg)
|
||||||
|
{
|
||||||
|
txtMsg.BeginChange();
|
||||||
|
txtMsg.Text = msg.ToString();
|
||||||
if (togScrollToEnd.IsChecked ?? true)
|
if (togScrollToEnd.IsChecked ?? true)
|
||||||
{
|
{
|
||||||
txtMsg.ScrollToEnd();
|
txtMsg.ScrollToEnd();
|
||||||
}
|
}
|
||||||
}
|
txtMsg.EndChange();
|
||||||
|
|
||||||
private void ShowMsg(string msg)
|
|
||||||
{
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
txtMsg.Text = string.Join("", _queueMsg.ToArray());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ClearMsg()
|
public void ClearMsg()
|
||||||
{
|
{
|
||||||
_queueMsg.Clear();
|
ViewModel?.ClearMsg();
|
||||||
txtMsg.Clear();
|
txtMsg.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,10 +86,5 @@ namespace v2rayN.Views
|
||||||
{
|
{
|
||||||
ClearMsg();
|
ClearMsg();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void cmbMsgFilter_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
|
||||||
{
|
|
||||||
_config.uiItem.mainMsgFilter = cmbMsgFilter.Text.TrimEx();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue