Files
2dust_v2rayN/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs
T
DHR60 9664ee380e ViewModel-First (#9621)
* Interaction

* Remove view action

* ViewModel-first

* MainGirdOrientation Hot Reload

* Fix avalonia preview

* Remove CloseWindowInteraction

* Fix

* Avoid threading issues

* Fix

* ProfilesSelect

* Try fix previewer

* Remove AppEvents.ProfilesRefreshRequested

* Remove AppEvents.SubscriptionsRefreshRequested

* Remove AppEvents.ProxiesReloadRequested

* Remove AppEvents.AdjustMainLvColWidthRequested

* Remove AppEvents.SetDefaultServerRequested

* Remove AppEvents.RoutingsMenuRefreshRequested

* Remove AppEvents.TestServerRequested

* Remove AppEvents.InboundDisplayRequested

* Remove AppEvents.SubscriptionsUpdateRequested

* Remove AppEvents.ShowHideWindowRequested

* Remove AppEvents.ReloadRequested

* Remove AppEvents.AddServerRequested

* Fix
2026-07-14 09:05:05 +08:00

123 lines
2.9 KiB
C#

namespace ServiceLib.ViewModels;
public class MsgViewModel : MyReactiveObject
{
public Interaction<string, Unit> DispatcherShowMsgInteraction { get; } = new();
private readonly ConcurrentQueue<string> _queueMsg = new();
private volatile bool _lastMsgFilterNotAvailable;
private int _showLock = 0; // 0 = unlocked, 1 = locked
public int NumMaxMsg { get; } = 500;
[Reactive]
public string MsgFilter { get; set; }
[Reactive]
public bool AutoRefresh { get; set; }
public MsgViewModel()
{
_config = AppManager.Instance.Config;
MsgFilter = _config.MsgUIItem.MainMsgFilter ?? string.Empty;
AutoRefresh = _config.MsgUIItem.AutoRefresh ?? true;
this.WhenAnyValue(
x => x.MsgFilter)
.Subscribe(c => DoMsgFilter());
this.WhenAnyValue(
x => x.AutoRefresh,
y => y == true)
.Subscribe(c => _config.MsgUIItem.AutoRefresh = AutoRefresh);
AppEvents.SendMsgViewRequested
.AsObservable()
//.ObserveOn(RxSchedulers.MainThreadScheduler)
.Subscribe(content => _ = AppendQueueMsg(content));
}
private async Task AppendQueueMsg(string msg)
{
if (AutoRefresh == false)
{
return;
}
EnqueueQueueMsg(msg);
if (!AppManager.Instance.ShowInTaskbar)
{
return;
}
if (Interlocked.CompareExchange(ref _showLock, 1, 0) != 0)
{
return;
}
try
{
await Task.Delay(500).ConfigureAwait(false);
var sb = new StringBuilder();
while (_queueMsg.TryDequeue(out var line))
{
sb.Append(line);
}
await DispatcherShowMsgInteraction.Handle(sb.ToString());
}
finally
{
Interlocked.Exchange(ref _showLock, 0);
}
}
private void EnqueueQueueMsg(string msg)
{
//filter msg
if (MsgFilter.IsNotEmpty() && !_lastMsgFilterNotAvailable)
{
try
{
if (!Regex.IsMatch(msg, MsgFilter))
{
return;
}
}
catch (Exception ex)
{
EnqueueWithLimit(ex.Message);
_lastMsgFilterNotAvailable = true;
}
}
EnqueueWithLimit(msg);
if (!msg.EndsWith(Environment.NewLine))
{
EnqueueWithLimit(Environment.NewLine);
}
}
private void EnqueueWithLimit(string item)
{
_queueMsg.Enqueue(item);
while (_queueMsg.Count > NumMaxMsg)
{
_queueMsg.TryDequeue(out _);
}
}
//public void ClearMsg()
//{
// _queueMsg.Clear();
//}
private void DoMsgFilter()
{
_config.MsgUIItem.MainMsgFilter = MsgFilter;
_lastMsgFilterNotAvailable = false;
}
}