Compare commits

..

1 commit

Author SHA1 Message Date
Wydy
377670eff8
Merge 7816c1dcca into 18ac76e683 2025-09-21 10:17:58 +00:00
15 changed files with 56 additions and 87 deletions

View file

@ -20,11 +20,11 @@
<PackageVersion Include="ReactiveUI.WPF" Version="20.4.1" />
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.10" />
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.10" />
<PackageVersion Include="Splat.NLog" Version="17.0.1" />
<PackageVersion Include="Splat.NLog" Version="16.2.1" />
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
<PackageVersion Include="TaskScheduler" Version="2.12.2" />
<PackageVersion Include="WebDav.Client" Version="2.9.0" />
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
</ItemGroup>
</Project>
</Project>

View file

@ -6,22 +6,16 @@ namespace ServiceLib.Handler;
public static class AppEvents
{
public static readonly Subject<Unit> ProfilesRefreshRequested = new();
public static readonly Subject<Unit> SubscriptionsRefreshRequested = new();
public static readonly Subject<Unit> ProxiesReloadRequested = new();
public static readonly Subject<ServerSpeedItem> DispatcherStatisticsRequested = new();
public static readonly Subject<string> SendSnackMsgRequested = new();
public static readonly Subject<string> SendMsgViewRequested = new();
public static readonly Subject<Unit> AppExitRequested = new();
public static readonly Subject<bool> ShutdownRequested = new();
public static readonly Subject<Unit> AdjustMainLvColWidthRequested = new();
public static readonly Subject<string> SetDefaultServerRequested = new();
public static readonly Subject<Unit> RoutingsMenuRefreshRequested = new();
public static readonly Subject<Unit> TestServerRequested = new();
public static readonly Subject<Unit> InboundDisplayRequested = new();
public static readonly Subject<ESysProxyType> SysProxyChangeRequested = new();
public static readonly Subject<ServerSpeedItem> DispatcherStatisticsRequested = new();
}

View file

@ -69,8 +69,6 @@ public class ClashProxiesViewModel : MyReactiveObject
SortingSelected = _config.ClashUIItem.ProxiesSorting;
RuleModeSelected = (int)_config.ClashUIItem.RuleMode;
#region WhenAnyValue && ReactiveCommand
this.WhenAnyValue(
x => x.SelectedGroup,
y => y != null && y.Name.IsNotEmpty())
@ -91,17 +89,6 @@ public class ClashProxiesViewModel : MyReactiveObject
y => y == true)
.Subscribe(c => { _config.ClashUIItem.ProxiesAutoRefresh = AutoRefresh; });
#endregion WhenAnyValue && ReactiveCommand
#region AppEvents
AppEvents.ProxiesReloadRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await ProxiesReload());
#endregion AppEvents
_ = Init();
}

View file

@ -2,6 +2,7 @@ using System.Reactive;
using System.Reactive.Concurrency;
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
namespace ServiceLib.ViewModels;
@ -239,6 +240,7 @@ public class MainWindowViewModel : MyReactiveObject
BlReloadEnabled = true;
await Reload();
await AutoHideStartup();
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
}
#endregion Init
@ -299,7 +301,7 @@ public class MainWindowViewModel : MyReactiveObject
private void RefreshSubscriptions()
{
AppEvents.SubscriptionsRefreshRequested.OnNext(Unit.Default);
Locator.Current.GetService<ProfilesViewModel>()?.RefreshSubscriptions();
}
#endregion Servers && Groups
@ -431,7 +433,7 @@ public class MainWindowViewModel : MyReactiveObject
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
if (ret == true)
{
AppEvents.InboundDisplayRequested.OnNext(Unit.Default);
Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStatus();
await Reload();
}
}
@ -442,7 +444,7 @@ public class MainWindowViewModel : MyReactiveObject
if (ret == true)
{
await ConfigHandler.InitBuiltinRouting(_config);
AppEvents.RoutingsMenuRefreshRequested.OnNext(Unit.Default);
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
await Reload();
}
}
@ -516,15 +518,9 @@ public class MainWindowViewModel : MyReactiveObject
await SysProxyHandler.UpdateSysProxy(_config, false);
await Task.Delay(1000);
});
AppEvents.TestServerRequested.OnNext(Unit.Default);
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
var showClashUI = _config.IsRunningCore(ECoreType.sing_box);
if (showClashUI)
{
AppEvents.ProxiesReloadRequested.OnNext(Unit.Default);
}
RxApp.MainThreadScheduler.Schedule(() => ReloadResult(showClashUI));
RxApp.MainThreadScheduler.Schedule(() => _ = ReloadResult());
BlReloadEnabled = true;
if (_hasNextReloadJob)
@ -534,11 +530,19 @@ public class MainWindowViewModel : MyReactiveObject
}
}
private void ReloadResult(bool showClashUI)
public async Task ReloadResult()
{
// BlReloadEnabled = true;
ShowClashUI = showClashUI;
TabMainSelectedIndex = showClashUI ? TabMainSelectedIndex : 0;
//Locator.Current.GetService<StatusBarViewModel>()?.ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, false);
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
if (ShowClashUI)
{
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
}
else
{
TabMainSelectedIndex = 0;
}
}
private async Task LoadCore()
@ -570,7 +574,7 @@ public class MainWindowViewModel : MyReactiveObject
{
await ConfigHandler.ApplyRegionalPreset(_config, type);
await ConfigHandler.InitRouting(_config);
AppEvents.RoutingsMenuRefreshRequested.OnNext(Unit.Default);
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
await ConfigHandler.SaveConfig(_config);
await new UpdateService().UpdateGeoFileAll(_config, UpdateTaskHandler);

View file

@ -240,21 +240,11 @@ public class ProfilesViewModel : MyReactiveObject
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await RefreshServersBiz());
AppEvents.SubscriptionsRefreshRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await RefreshSubscriptions());
AppEvents.DispatcherStatisticsRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async result => await UpdateStatistics(result));
AppEvents.SetDefaultServerRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async indexId => await SetDefaultServer(indexId));
#endregion AppEvents
_ = Init();
@ -390,7 +380,7 @@ public class ProfilesViewModel : MyReactiveObject
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
}
private async Task RefreshSubscriptions()
public async Task RefreshSubscriptions()
{
SubItems.Clear();
@ -575,7 +565,7 @@ public class ProfilesViewModel : MyReactiveObject
await SetDefaultServer(SelectedProfile.IndexId);
}
private async Task SetDefaultServer(string? indexId)
public async Task SetDefaultServer(string? indexId)
{
if (indexId.IsNullOrEmpty())
{

View file

@ -11,9 +11,6 @@ namespace ServiceLib.ViewModels;
public class StatusBarViewModel : MyReactiveObject
{
private static readonly Lazy<StatusBarViewModel> _instance = new(() => new(null));
public static StatusBarViewModel Instance => _instance.Value;
#region ObservableCollection
public IObservableCollection<RoutingItem> RoutingItems { get; } = new ObservableCollectionExtended<RoutingItem>();
@ -212,26 +209,6 @@ public class StatusBarViewModel : MyReactiveObject
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async result => await UpdateStatistics(result));
AppEvents.RoutingsMenuRefreshRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await RefreshRoutingsMenu());
AppEvents.TestServerRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await TestServerAvailability());
AppEvents.InboundDisplayRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async _ => await InboundDisplayStatus());
AppEvents.SysProxyChangeRequested
.AsObservable()
.ObserveOn(RxApp.MainThreadScheduler)
.Subscribe(async result => await SetListenerType(result));
#endregion AppEvents
_ = Init();
@ -352,7 +329,7 @@ public class StatusBarViewModel : MyReactiveObject
{
return;
}
AppEvents.SetDefaultServerRequested.OnNext(SelectedServer.ID);
Locator.Current.GetService<ProfilesViewModel>()?.SetDefaultServer(SelectedServer.ID);
}
public async Task TestServerAvailability()
@ -387,7 +364,7 @@ public class StatusBarViewModel : MyReactiveObject
#region System proxy and Routings
private async Task SetListenerType(ESysProxyType type)
public async Task SetListenerType(ESysProxyType type)
{
if (_config.SystemProxyItem.SysProxyType == type)
{
@ -416,7 +393,7 @@ public class StatusBarViewModel : MyReactiveObject
}
}
private async Task RefreshRoutingsMenu()
public async Task RefreshRoutingsMenu()
{
RoutingItems.Clear();
@ -524,7 +501,7 @@ public class StatusBarViewModel : MyReactiveObject
#region UI
private async Task InboundDisplayStatus()
public async Task InboundDisplayStatus()
{
StringBuilder sb = new();
sb.Append($"[{EInboundProtocol.mixed}:{AppManager.Instance.GetLocalPort(EInboundProtocol.socks)}");

View file

@ -16,7 +16,9 @@ public partial class App : Application
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
DataContext = StatusBarViewModel.Instance;
var ViewModel = new StatusBarViewModel(null);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
DataContext = ViewModel;
}
public override void OnFrameworkInitializationCompleted()

View file

@ -3,6 +3,7 @@ using Avalonia.Input;
using Avalonia.ReactiveUI;
using DynamicData;
using ReactiveUI;
using Splat;
namespace v2rayN.Desktop.Views;
@ -12,6 +13,7 @@ public partial class ClashProxiesView : ReactiveUserControl<ClashProxiesViewMode
{
InitializeComponent();
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ClashProxiesViewModel));
lstProxyDetails.DoubleTapped += LstProxyDetails_DoubleTapped;
this.KeyDown += ClashProxiesView_KeyDown;

View file

@ -20,7 +20,7 @@ namespace v2rayN.Desktop.Views;
public partial class MainWindow : WindowBase<MainWindowViewModel>
{
private static Config _config;
private readonly WindowNotificationManager? _manager;
private WindowNotificationManager? _manager;
private CheckUpdateView? _checkUpdateView;
private BackupAndRestoreView? _backupAndRestoreView;
private bool _blCloseByUser = false;
@ -259,7 +259,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
case EGlobalHotkey.SystemProxySet:
case EGlobalHotkey.SystemProxyUnchanged:
case EGlobalHotkey.SystemProxyPac:
AppEvents.SysProxyChangeRequested.OnNext((ESysProxyType)((int)e - 1));
Locator.Current.GetService<StatusBarViewModel>()?.SetListenerType((ESysProxyType)((int)e - 1));
break;
}
}

View file

@ -8,6 +8,7 @@ using Avalonia.Threading;
using DialogHostAvalonia;
using MsBox.Avalonia.Enums;
using ReactiveUI;
using Splat;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views;
@ -47,6 +48,7 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
//}
ViewModel = new ProfilesViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ProfilesViewModel));
this.WhenActivated(disposables =>
{

View file

@ -6,6 +6,7 @@ using Avalonia.ReactiveUI;
using Avalonia.Threading;
using DialogHostAvalonia;
using ReactiveUI;
using Splat;
using v2rayN.Desktop.Common;
namespace v2rayN.Desktop.Views;
@ -19,8 +20,9 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
InitializeComponent();
_config = AppManager.Instance.Config;
ViewModel = StatusBarViewModel.Instance;
//ViewModel = new StatusBarViewModel(UpdateViewHandler);
//Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
ViewModel = Locator.Current.GetService<StatusBarViewModel>();
ViewModel?.InitUpdateView(UpdateViewHandler);
txtRunningServerDisplay.Tapped += TxtRunningServerDisplay_Tapped;

View file

@ -1,6 +1,7 @@
using System.Reactive.Disposables;
using System.Windows.Input;
using ReactiveUI;
using Splat;
namespace v2rayN.Views;
@ -13,6 +14,7 @@ public partial class ClashProxiesView
{
InitializeComponent();
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ClashProxiesViewModel));
lstProxyDetails.PreviewMouseDoubleClick += lstProxyDetails_PreviewMouseDoubleClick;
this.WhenActivated(disposables =>

View file

@ -249,7 +249,7 @@ public partial class MainWindow
case EGlobalHotkey.SystemProxySet:
case EGlobalHotkey.SystemProxyUnchanged:
case EGlobalHotkey.SystemProxyPac:
AppEvents.SysProxyChangeRequested.OnNext((ESysProxyType)((int)e - 1));
Locator.Current.GetService<StatusBarViewModel>()?.SetListenerType((ESysProxyType)((int)e - 1));
break;
}
}
@ -287,7 +287,11 @@ public partial class MainWindow
var clipboardData = WindowsUtils.GetClipboardData();
if (clipboardData.IsNotEmpty())
{
ViewModel?.AddServerViaClipboardAsync(clipboardData);
var service = Locator.Current.GetService<MainWindowViewModel>();
if (service != null)
{
_ = service.AddServerViaClipboardAsync(clipboardData);
}
}
break;

View file

@ -8,6 +8,7 @@ using System.Windows.Media;
using System.Windows.Threading;
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using Splat;
using v2rayN.Base;
using Point = System.Windows.Point;
@ -41,6 +42,7 @@ public partial class ProfilesView
}
ViewModel = new ProfilesViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ProfilesViewModel));
this.WhenActivated(disposables =>
{

View file

@ -3,6 +3,7 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Threading;
using ReactiveUI;
using Splat;
using v2rayN.Manager;
namespace v2rayN.Views;
@ -15,8 +16,8 @@ public partial class StatusBarView
{
InitializeComponent();
_config = AppManager.Instance.Config;
ViewModel = StatusBarViewModel.Instance;
ViewModel?.InitUpdateView(UpdateViewHandler);
ViewModel = new StatusBarViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
menuExit.Click += menuExit_Click;
txtRunningServerDisplay.PreviewMouseDown += txtRunningInfoDisplay_MouseDoubleClick;