Optimization and improvement, using event subscribers

pull/8020/head
2dust 2025-09-24 10:57:06 +08:00
parent e96a4818c4
commit 671678724b
10 changed files with 95 additions and 97 deletions

View File

@ -12,7 +12,6 @@ public enum EViewAction
ProfilesFocus,
ShareSub,
ShareServer,
ShowHideWindow,
ScanScreenTask,
ScanImageTask,
BrowseServer,

View File

@ -5,6 +5,12 @@ namespace ServiceLib.Handler;
public static class AppEvents
{
public static readonly Subject<Unit> ReloadRequested = new();
public static readonly Subject<bool?> ShowHideWindowRequested = new();
public static readonly Subject<Unit> AddServerViaScanRequested = new();
public static readonly Subject<Unit> AddServerViaClipboardRequested = new();
public static readonly Subject<bool> SubscriptionsUpdateRequested = new();
public static readonly Subject<Unit> ProfilesRefreshRequested = new();
public static readonly Subject<Unit> SubscriptionsRefreshRequested = new();
public static readonly Subject<Unit> ProxiesReloadRequested = new();

View File

@ -122,6 +122,12 @@ public sealed class AppManager
AppEvents.ShutdownRequested.OnNext(byUser);
}
public async Task RebootAsAdmin()
{
ProcUtils.RebootAsAdmin();
await AppManager.Instance.AppExitAsync(true);
}
#endregion App
#region Config

View File

@ -2,11 +2,9 @@ using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Runtime.InteropServices;
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels;
@ -225,11 +223,11 @@ public class CheckUpdateViewModel : MyReactiveObject
{
if (blReload)
{
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
AppEvents.ReloadRequested.OnNext(Unit.Default);
}
else
{
Locator.Current.GetService<MainWindowViewModel>()?.CloseCore();
await CoreManager.Instance.CoreStop();
}
}

View File

@ -1,5 +1,6 @@
using System.Reactive;
using System.Reactive.Concurrency;
using System.Reactive.Linq;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
@ -183,7 +184,7 @@ public class MainWindowViewModel : MyReactiveObject
});
RebootAsAdminCmd = ReactiveCommand.CreateFromTask(async () =>
{
await RebootAsAdmin();
await AppManager.Instance.RebootAsAdmin();
});
ClearServerStatisticsCmd = ReactiveCommand.CreateFromTask(async () =>
{
@ -216,6 +217,30 @@ public class MainWindowViewModel : MyReactiveObject
#endregion WhenAnyValue && ReactiveCommand
#region AppEvents
AppEvents.ReloadRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await Reload());
AppEvents.AddServerViaScanRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await AddServerViaScanAsync());
AppEvents.AddServerViaClipboardRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await AddServerViaClipboardAsync(null));
AppEvents.SubscriptionsUpdateRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async blProxy => await UpdateSubscriptionProcess("", blProxy));
#endregion AppEvents
_ = Init();
}
@ -281,11 +306,6 @@ public class MainWindowViewModel : MyReactiveObject
AppEvents.DispatcherStatisticsRequested.OnNext(update);
}
public void ShowHideWindow(bool? blShow)
{
_updateView?.Invoke(EViewAction.ShowHideWindow, blShow);
}
#endregion Actions
#region Servers && Groups
@ -465,12 +485,6 @@ public class MainWindowViewModel : MyReactiveObject
}
}
public async Task RebootAsAdmin()
{
ProcUtils.RebootAsAdmin();
await AppManager.Instance.AppExitAsync(true);
}
private async Task ClearServerStatistics()
{
await StatisticsManager.Instance.ClearAllServerStatistics();
@ -547,17 +561,11 @@ public class MainWindowViewModel : MyReactiveObject
await CoreManager.Instance.LoadCore(node);
}
public async Task CloseCore()
{
await ConfigHandler.SaveConfig(_config);
await CoreManager.Instance.CoreStop();
}
private async Task AutoHideStartup()
{
if (_config.UiItem.AutoHideStartup)
{
ShowHideWindow(false);
AppEvents.ShowHideWindowRequested.OnNext(false);
}
await Task.CompletedTask;
}

View File

@ -6,7 +6,6 @@ using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels;
@ -276,7 +275,7 @@ public class ProfilesViewModel : MyReactiveObject
private void Reload()
{
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
AppEvents.ReloadRequested.OnNext(Unit.Default);
}
public async Task SetSpeedTestResult(SpeedTestResult result)

View File

@ -5,7 +5,6 @@ using System.Text;
using DynamicData.Binding;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels;
@ -149,17 +148,17 @@ public class StatusBarViewModel : MyReactiveObject
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
{
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(null);
AppEvents.ShowHideWindowRequested.OnNext(null);
await Task.CompletedTask;
});
ShowWindowCmd = ReactiveCommand.CreateFromTask(async () =>
{
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(true);
AppEvents.ShowHideWindowRequested.OnNext(true);
await Task.CompletedTask;
});
HideWindowCmd = ReactiveCommand.CreateFromTask(async () =>
{
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(false);
AppEvents.ShowHideWindowRequested.OnNext(false);
await Task.CompletedTask;
});
@ -275,23 +274,20 @@ public class StatusBarViewModel : MyReactiveObject
private async Task AddServerViaClipboard()
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null)
await service.AddServerViaClipboardAsync(null);
AppEvents.AddServerViaClipboardRequested.OnNext(Unit.Default);
await Task.Delay(1000);
}
private async Task AddServerViaScan()
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null)
await service.AddServerViaScanAsync();
AppEvents.AddServerViaScanRequested.OnNext(Unit.Default);
await Task.Delay(1000);
}
private async Task UpdateSubscriptionProcess(bool blProxy)
{
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null)
await service.UpdateSubscriptionProcess("", blProxy);
AppEvents.SubscriptionsUpdateRequested.OnNext(blProxy);
await Task.Delay(1000);
}
private async Task RefreshServersBiz()
@ -453,7 +449,7 @@ public class StatusBarViewModel : MyReactiveObject
if (await ConfigHandler.SetDefaultRouting(_config, item) == 0)
{
NoticeManager.Instance.SendMessageEx(ResUI.TipChangeRouting);
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
AppEvents.ReloadRequested.OnNext(Unit.Default);
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
}
}
@ -486,7 +482,7 @@ public class StatusBarViewModel : MyReactiveObject
if (Utils.IsWindows())
{
_config.TunModeItem.EnableTun = false;
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
await AppManager.Instance.RebootAsAdmin();
return;
}
else
@ -500,7 +496,7 @@ public class StatusBarViewModel : MyReactiveObject
}
}
await ConfigHandler.SaveConfig(_config);
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
AppEvents.ReloadRequested.OnNext(Unit.Default);
}
private bool AllowEnableTun()

View File

@ -1,8 +1,7 @@
using System.Reactive;
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using Splat;
using v2rayN.Desktop.Common;
using v2rayN.Desktop.Views;
namespace v2rayN.Desktop;
@ -55,16 +54,8 @@ public partial class App : Application
{
if (desktop.MainWindow != null)
{
var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow);
if (clipboardData.IsNullOrEmpty())
{
return;
}
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null)
{
_ = service.AddServerViaClipboardAsync(clipboardData);
}
AppEvents.AddServerViaClipboardRequested.OnNext(Unit.Default);
await Task.Delay(1000);
}
}
}

View File

@ -10,7 +10,6 @@ using Avalonia.Threading;
using DialogHostAvalonia;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using Splat;
using v2rayN.Desktop.Base;
using v2rayN.Desktop.Common;
using v2rayN.Desktop.Manager;
@ -40,7 +39,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
menuClose.Click += MenuClose_Click;
ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
switch (_config.UiItem.MainGirdOrientation)
{
@ -153,6 +151,12 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(content => Shutdown(content))
.DisposeWith(disposables);
AppEvents.ShowHideWindowRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(blShow => ShowHideWindow(blShow))
.DisposeWith(disposables);
});
if (Utils.IsWindows())
@ -221,12 +225,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
case EViewAction.SubSettingWindow:
return await new SubSettingWindow().ShowDialog<bool>(this);
case EViewAction.ShowHideWindow:
Dispatcher.UIThread.Post(() =>
ShowHideWindow((bool?)obj),
DispatcherPriority.Default);
break;
case EViewAction.ScanScreenTask:
await ScanScreenTaskAsync();
break;
@ -236,11 +234,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
break;
case EViewAction.AddServerViaClipboard:
var clipboardData = await AvaUtils.GetClipboardData(this);
if (clipboardData.IsNotEmpty() && ViewModel != null)
{
await ViewModel.AddServerViaClipboardAsync(clipboardData);
}
await AddServerViaClipboardAsync();
break;
}
@ -295,11 +289,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
switch (e.Key)
{
case Key.V:
var clipboardData = await AvaUtils.GetClipboardData(this);
if (clipboardData.IsNotEmpty() && ViewModel != null)
{
await ViewModel.AddServerViaClipboardAsync(clipboardData);
}
await AddServerViaClipboardAsync();
break;
case Key.S:
@ -326,6 +316,15 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
}
public async Task AddServerViaClipboardAsync()
{
var clipboardData = await AvaUtils.GetClipboardData(this);
if (clipboardData.IsNotEmpty() && ViewModel != null)
{
await ViewModel.AddServerViaClipboardAsync(clipboardData);
}
}
public async Task ScanScreenTaskAsync()
{
//ShowHideWindow(false);

View File

@ -6,10 +6,8 @@ using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Interop;
using System.Windows.Media;
using System.Windows.Threading;
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using Splat;
using v2rayN.Manager;
namespace v2rayN.Views;
@ -37,7 +35,6 @@ public partial class MainWindow
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
switch (_config.UiItem.MainGirdOrientation)
{
@ -146,10 +143,16 @@ public partial class MainWindow
.DisposeWith(disposables);
AppEvents.ShutdownRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(content => Shutdown(content))
.DisposeWith(disposables);
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(content => Shutdown(content))
.DisposeWith(disposables);
AppEvents.ShowHideWindowRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(blShow => ShowHideWindow(blShow))
.DisposeWith(disposables);
});
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
@ -210,13 +213,6 @@ public partial class MainWindow
case EViewAction.SubSettingWindow:
return (new SubSettingWindow().ShowDialog() ?? false);
case EViewAction.ShowHideWindow:
Application.Current?.Dispatcher.Invoke((() =>
{
ShowHideWindow((bool?)obj);
}), DispatcherPriority.Normal);
break;
case EViewAction.ScanScreenTask:
await ScanScreenTaskAsync();
break;
@ -226,11 +222,7 @@ public partial class MainWindow
break;
case EViewAction.AddServerViaClipboard:
var clipboardData = WindowsUtils.GetClipboardData();
if (clipboardData.IsNotEmpty())
{
ViewModel?.AddServerViaClipboardAsync(clipboardData);
}
await AddServerViaClipboardAsync();
break;
}
@ -283,12 +275,7 @@ public partial class MainWindow
{
return;
}
var clipboardData = WindowsUtils.GetClipboardData();
if (clipboardData.IsNotEmpty())
{
ViewModel?.AddServerViaClipboardAsync(clipboardData);
}
AddServerViaClipboardAsync().ContinueWith(_ => { });
break;
@ -322,6 +309,15 @@ public partial class MainWindow
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
}
public async Task AddServerViaClipboardAsync()
{
var clipboardData = WindowsUtils.GetClipboardData();
if (clipboardData.IsNotEmpty() && ViewModel != null)
{
await ViewModel.AddServerViaClipboardAsync(clipboardData);
}
}
private async Task ScanScreenTaskAsync()
{
ShowHideWindow(false);