mirror of
https://github.com/2dust/v2rayN.git
synced 2025-10-26 10:14:42 +00:00
Compare commits
10 commits
cba8a49d5c
...
84ca5808b9
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
84ca5808b9 | ||
|
|
d86003df55 | ||
|
|
faff8e4ea2 | ||
|
|
6b85aa0b03 | ||
|
|
671678724b | ||
|
|
e96a4818c4 | ||
|
|
0377e7ce19 | ||
|
|
6929886b3e | ||
|
|
721d70c8c7 | ||
|
|
27b45aee83 |
26 changed files with 240 additions and 179 deletions
|
|
@ -20,11 +20,11 @@
|
||||||
<PackageVersion Include="ReactiveUI.WPF" Version="20.4.1" />
|
<PackageVersion Include="ReactiveUI.WPF" Version="20.4.1" />
|
||||||
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.10" />
|
<PackageVersion Include="Semi.Avalonia" Version="11.2.1.10" />
|
||||||
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.10" />
|
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="11.2.1.10" />
|
||||||
<PackageVersion Include="Splat.NLog" Version="16.2.1" />
|
<PackageVersion Include="NLog" Version="6.0.4" />
|
||||||
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
<PackageVersion Include="sqlite-net-pcl" Version="1.9.172" />
|
||||||
<PackageVersion Include="TaskScheduler" Version="2.12.2" />
|
<PackageVersion Include="TaskScheduler" Version="2.12.2" />
|
||||||
<PackageVersion Include="WebDav.Client" Version="2.9.0" />
|
<PackageVersion Include="WebDav.Client" Version="2.9.0" />
|
||||||
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
<PackageVersion Include="YamlDotNet" Version="16.3.0" />
|
||||||
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
<PackageVersion Include="ZXing.Net.Bindings.SkiaSharp" Version="0.16.14" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,6 @@ public enum EViewAction
|
||||||
ProfilesFocus,
|
ProfilesFocus,
|
||||||
ShareSub,
|
ShareSub,
|
||||||
ShareServer,
|
ShareServer,
|
||||||
ShowHideWindow,
|
|
||||||
ScanScreenTask,
|
ScanScreenTask,
|
||||||
ScanImageTask,
|
ScanImageTask,
|
||||||
BrowseServer,
|
BrowseServer,
|
||||||
|
|
|
||||||
32
v2rayN/ServiceLib/Events/AppEvents.cs
Normal file
32
v2rayN/ServiceLib/Events/AppEvents.cs
Normal file
|
|
@ -0,0 +1,32 @@
|
||||||
|
using System.Reactive;
|
||||||
|
|
||||||
|
namespace ServiceLib.Events;
|
||||||
|
|
||||||
|
public static class AppEvents
|
||||||
|
{
|
||||||
|
public static readonly EventChannel<Unit> ReloadRequested = new();
|
||||||
|
public static readonly EventChannel<bool?> ShowHideWindowRequested = new();
|
||||||
|
public static readonly EventChannel<Unit> AddServerViaScanRequested = new();
|
||||||
|
public static readonly EventChannel<Unit> AddServerViaClipboardRequested = new();
|
||||||
|
public static readonly EventChannel<bool> SubscriptionsUpdateRequested = new();
|
||||||
|
|
||||||
|
public static readonly EventChannel<Unit> ProfilesRefreshRequested = new();
|
||||||
|
public static readonly EventChannel<Unit> SubscriptionsRefreshRequested = new();
|
||||||
|
public static readonly EventChannel<Unit> ProxiesReloadRequested = new();
|
||||||
|
public static readonly EventChannel<ServerSpeedItem> DispatcherStatisticsRequested = new();
|
||||||
|
|
||||||
|
public static readonly EventChannel<string> SendSnackMsgRequested = new();
|
||||||
|
public static readonly EventChannel<string> SendMsgViewRequested = new();
|
||||||
|
|
||||||
|
public static readonly EventChannel<Unit> AppExitRequested = new();
|
||||||
|
public static readonly EventChannel<bool> ShutdownRequested = new();
|
||||||
|
|
||||||
|
public static readonly EventChannel<Unit> AdjustMainLvColWidthRequested = new();
|
||||||
|
|
||||||
|
public static readonly EventChannel<string> SetDefaultServerRequested = new();
|
||||||
|
|
||||||
|
public static readonly EventChannel<Unit> RoutingsMenuRefreshRequested = new();
|
||||||
|
public static readonly EventChannel<Unit> TestServerRequested = new();
|
||||||
|
public static readonly EventChannel<Unit> InboundDisplayRequested = new();
|
||||||
|
public static readonly EventChannel<ESysProxyType> SysProxyChangeRequested = new();
|
||||||
|
}
|
||||||
29
v2rayN/ServiceLib/Events/EventChannel.cs
Normal file
29
v2rayN/ServiceLib/Events/EventChannel.cs
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
using System.Reactive;
|
||||||
|
using System.Reactive.Linq;
|
||||||
|
using System.Reactive.Subjects;
|
||||||
|
|
||||||
|
namespace ServiceLib.Events;
|
||||||
|
|
||||||
|
public sealed class EventChannel<T>
|
||||||
|
{
|
||||||
|
private readonly ISubject<T> _subject = Subject.Synchronize(new Subject<T>());
|
||||||
|
|
||||||
|
public IObservable<T> AsObservable()
|
||||||
|
{
|
||||||
|
return _subject.AsObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Publish(T value)
|
||||||
|
{
|
||||||
|
_subject.OnNext(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Publish()
|
||||||
|
{
|
||||||
|
if (typeof(T) != typeof(Unit))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("Publish() without value is only valid for EventChannel<Unit>.");
|
||||||
|
}
|
||||||
|
_subject.OnNext((T)(object)Unit.Default);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
global using ServiceLib.Base;
|
global using ServiceLib.Base;
|
||||||
global using ServiceLib.Common;
|
global using ServiceLib.Common;
|
||||||
global using ServiceLib.Enums;
|
global using ServiceLib.Enums;
|
||||||
|
global using ServiceLib.Events;
|
||||||
global using ServiceLib.Handler;
|
global using ServiceLib.Handler;
|
||||||
global using ServiceLib.Helper;
|
global using ServiceLib.Helper;
|
||||||
global using ServiceLib.Manager;
|
global using ServiceLib.Manager;
|
||||||
|
|
|
||||||
|
|
@ -1,21 +0,0 @@
|
||||||
using System.Reactive;
|
|
||||||
using System.Reactive.Subjects;
|
|
||||||
|
|
||||||
namespace ServiceLib.Handler;
|
|
||||||
|
|
||||||
public static class AppEvents
|
|
||||||
{
|
|
||||||
public static readonly Subject<Unit> ProfilesRefreshRequested = 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<ServerSpeedItem> DispatcherStatisticsRequested = new();
|
|
||||||
}
|
|
||||||
|
|
@ -97,7 +97,7 @@ public sealed class AppManager
|
||||||
Logging.SaveLog("AppExitAsync Begin");
|
Logging.SaveLog("AppExitAsync Begin");
|
||||||
|
|
||||||
await SysProxyHandler.UpdateSysProxy(_config, true);
|
await SysProxyHandler.UpdateSysProxy(_config, true);
|
||||||
AppEvents.AppExitRequested.OnNext(Unit.Default);
|
AppEvents.AppExitRequested.Publish();
|
||||||
await Task.Delay(50); //Wait for AppExitRequested to be processed
|
await Task.Delay(50); //Wait for AppExitRequested to be processed
|
||||||
|
|
||||||
await ConfigHandler.SaveConfig(_config);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
|
|
@ -121,7 +121,13 @@ public sealed class AppManager
|
||||||
|
|
||||||
public void Shutdown(bool byUser)
|
public void Shutdown(bool byUser)
|
||||||
{
|
{
|
||||||
AppEvents.ShutdownRequested.OnNext(byUser);
|
AppEvents.ShutdownRequested.Publish(byUser);
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RebootAsAdmin()
|
||||||
|
{
|
||||||
|
ProcUtils.RebootAsAdmin();
|
||||||
|
await AppManager.Instance.AppExitAsync(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion App
|
#endregion App
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ public class NoticeManager
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AppEvents.SendSnackMsgRequested.OnNext(content);
|
AppEvents.SendSnackMsgRequested.Publish(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMessage(string? content)
|
public void SendMessage(string? content)
|
||||||
|
|
@ -20,7 +20,7 @@ public class NoticeManager
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AppEvents.SendMsgViewRequested.OnNext(content);
|
AppEvents.SendMsgViewRequested.Publish(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendMessageEx(string? content)
|
public void SendMessageEx(string? content)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="ReactiveUI.Fody" />
|
<PackageReference Include="ReactiveUI.Fody" />
|
||||||
<PackageReference Include="sqlite-net-pcl" />
|
<PackageReference Include="sqlite-net-pcl" />
|
||||||
<PackageReference Include="Splat.NLog" />
|
<PackageReference Include="NLog" />
|
||||||
<PackageReference Include="WebDav.Client" />
|
<PackageReference Include="WebDav.Client" />
|
||||||
<PackageReference Include="YamlDotNet" />
|
<PackageReference Include="YamlDotNet" />
|
||||||
<PackageReference Include="QRCoder" />
|
<PackageReference Include="QRCoder" />
|
||||||
|
|
|
||||||
|
|
@ -79,6 +79,7 @@ public class CoreConfigClashService
|
||||||
|
|
||||||
//external-controller
|
//external-controller
|
||||||
fileContent["external-controller"] = $"{Global.Loopback}:{AppManager.Instance.StatePort2}";
|
fileContent["external-controller"] = $"{Global.Loopback}:{AppManager.Instance.StatePort2}";
|
||||||
|
fileContent.Remove("secret");
|
||||||
//allow-lan
|
//allow-lan
|
||||||
if (_config.Inbound.First().AllowLANConn)
|
if (_config.Inbound.First().AllowLANConn)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,9 @@ using System.Reactive;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using DynamicData;
|
|
||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
|
||||||
|
|
||||||
namespace ServiceLib.ViewModels;
|
namespace ServiceLib.ViewModels;
|
||||||
|
|
||||||
|
|
@ -225,11 +223,11 @@ public class CheckUpdateViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
if (blReload)
|
if (blReload)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
AppEvents.ReloadRequested.Publish();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.CloseCore();
|
await CoreManager.Instance.CoreStop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,8 @@ public class ClashProxiesViewModel : MyReactiveObject
|
||||||
SortingSelected = _config.ClashUIItem.ProxiesSorting;
|
SortingSelected = _config.ClashUIItem.ProxiesSorting;
|
||||||
RuleModeSelected = (int)_config.ClashUIItem.RuleMode;
|
RuleModeSelected = (int)_config.ClashUIItem.RuleMode;
|
||||||
|
|
||||||
|
#region WhenAnyValue && ReactiveCommand
|
||||||
|
|
||||||
this.WhenAnyValue(
|
this.WhenAnyValue(
|
||||||
x => x.SelectedGroup,
|
x => x.SelectedGroup,
|
||||||
y => y != null && y.Name.IsNotEmpty())
|
y => y != null && y.Name.IsNotEmpty())
|
||||||
|
|
@ -89,6 +91,17 @@ public class ClashProxiesViewModel : MyReactiveObject
|
||||||
y => y == true)
|
y => y == true)
|
||||||
.Subscribe(c => { _config.ClashUIItem.ProxiesAutoRefresh = AutoRefresh; });
|
.Subscribe(c => { _config.ClashUIItem.ProxiesAutoRefresh = AutoRefresh; });
|
||||||
|
|
||||||
|
#endregion WhenAnyValue && ReactiveCommand
|
||||||
|
|
||||||
|
#region AppEvents
|
||||||
|
|
||||||
|
AppEvents.ProxiesReloadRequested
|
||||||
|
.AsObservable()
|
||||||
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
|
.Subscribe(async _ => await ProxiesReload());
|
||||||
|
|
||||||
|
#endregion AppEvents
|
||||||
|
|
||||||
_ = Init();
|
_ = Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Concurrency;
|
using System.Reactive.Concurrency;
|
||||||
|
using System.Reactive.Linq;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
|
||||||
|
|
||||||
namespace ServiceLib.ViewModels;
|
namespace ServiceLib.ViewModels;
|
||||||
|
|
||||||
|
|
@ -194,7 +194,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
});
|
});
|
||||||
RebootAsAdminCmd = ReactiveCommand.CreateFromTask(async () =>
|
RebootAsAdminCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
await RebootAsAdmin();
|
await AppManager.Instance.RebootAsAdmin();
|
||||||
});
|
});
|
||||||
ClearServerStatisticsCmd = ReactiveCommand.CreateFromTask(async () =>
|
ClearServerStatisticsCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
|
|
@ -227,6 +227,30 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
|
|
||||||
#endregion WhenAnyValue && ReactiveCommand
|
#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();
|
_ = Init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -251,7 +275,6 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
BlReloadEnabled = true;
|
BlReloadEnabled = true;
|
||||||
await Reload();
|
await Reload();
|
||||||
await AutoHideStartup();
|
await AutoHideStartup();
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Init
|
#endregion Init
|
||||||
|
|
@ -280,7 +303,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
if (_config.UiItem.EnableAutoAdjustMainLvColWidth)
|
if (_config.UiItem.EnableAutoAdjustMainLvColWidth)
|
||||||
{
|
{
|
||||||
AppEvents.AdjustMainLvColWidthRequested.OnNext(Unit.Default);
|
AppEvents.AdjustMainLvColWidthRequested.Publish();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -291,12 +314,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
AppEvents.DispatcherStatisticsRequested.OnNext(update);
|
AppEvents.DispatcherStatisticsRequested.Publish(update);
|
||||||
}
|
|
||||||
|
|
||||||
public void ShowHideWindow(bool? blShow)
|
|
||||||
{
|
|
||||||
_updateView?.Invoke(EViewAction.ShowHideWindow, blShow);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Actions
|
#endregion Actions
|
||||||
|
|
@ -305,14 +323,14 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
|
|
||||||
private async Task RefreshServers()
|
private async Task RefreshServers()
|
||||||
{
|
{
|
||||||
AppEvents.ProfilesRefreshRequested.OnNext(Unit.Default);
|
AppEvents.ProfilesRefreshRequested.Publish();
|
||||||
|
|
||||||
await Task.Delay(200);
|
await Task.Delay(200);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void RefreshSubscriptions()
|
private void RefreshSubscriptions()
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.RefreshSubscriptions();
|
AppEvents.SubscriptionsRefreshRequested.Publish();
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion Servers && Groups
|
#endregion Servers && Groups
|
||||||
|
|
@ -448,7 +466,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
|
var ret = await _updateView?.Invoke(EViewAction.OptionSettingWindow, null);
|
||||||
if (ret == true)
|
if (ret == true)
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.InboundDisplayStatus();
|
AppEvents.InboundDisplayRequested.Publish();
|
||||||
await Reload();
|
await Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -459,7 +477,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
if (ret == true)
|
if (ret == true)
|
||||||
{
|
{
|
||||||
await ConfigHandler.InitBuiltinRouting(_config);
|
await ConfigHandler.InitBuiltinRouting(_config);
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
|
AppEvents.RoutingsMenuRefreshRequested.Publish();
|
||||||
await Reload();
|
await Reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -482,12 +500,6 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RebootAsAdmin()
|
|
||||||
{
|
|
||||||
ProcUtils.RebootAsAdmin();
|
|
||||||
await AppManager.Instance.AppExitAsync(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task ClearServerStatistics()
|
private async Task ClearServerStatistics()
|
||||||
{
|
{
|
||||||
await StatisticsManager.Instance.ClearAllServerStatistics();
|
await StatisticsManager.Instance.ClearAllServerStatistics();
|
||||||
|
|
@ -533,9 +545,15 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
await SysProxyHandler.UpdateSysProxy(_config, false);
|
await SysProxyHandler.UpdateSysProxy(_config, false);
|
||||||
await Task.Delay(1000);
|
await Task.Delay(1000);
|
||||||
});
|
});
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.TestServerAvailability();
|
AppEvents.TestServerRequested.Publish();
|
||||||
|
|
||||||
RxApp.MainThreadScheduler.Schedule(() => _ = ReloadResult());
|
var showClashUI = _config.IsRunningCore(ECoreType.sing_box);
|
||||||
|
if (showClashUI)
|
||||||
|
{
|
||||||
|
AppEvents.ProxiesReloadRequested.Publish();
|
||||||
|
}
|
||||||
|
|
||||||
|
RxApp.MainThreadScheduler.Schedule(() => ReloadResult(showClashUI));
|
||||||
|
|
||||||
BlReloadEnabled = true;
|
BlReloadEnabled = true;
|
||||||
if (_hasNextReloadJob)
|
if (_hasNextReloadJob)
|
||||||
|
|
@ -545,19 +563,11 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task ReloadResult()
|
private void ReloadResult(bool showClashUI)
|
||||||
{
|
{
|
||||||
// BlReloadEnabled = true;
|
// BlReloadEnabled = true;
|
||||||
//Locator.Current.GetService<StatusBarViewModel>()?.ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, false);
|
ShowClashUI = showClashUI;
|
||||||
ShowClashUI = _config.IsRunningCore(ECoreType.sing_box);
|
TabMainSelectedIndex = showClashUI ? TabMainSelectedIndex : 0;
|
||||||
if (ShowClashUI)
|
|
||||||
{
|
|
||||||
Locator.Current.GetService<ClashProxiesViewModel>()?.ProxiesReload();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TabMainSelectedIndex = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadCore()
|
private async Task LoadCore()
|
||||||
|
|
@ -566,17 +576,11 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
await CoreManager.Instance.LoadCore(node);
|
await CoreManager.Instance.LoadCore(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CloseCore()
|
|
||||||
{
|
|
||||||
await ConfigHandler.SaveConfig(_config);
|
|
||||||
await CoreManager.Instance.CoreStop();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async Task AutoHideStartup()
|
private async Task AutoHideStartup()
|
||||||
{
|
{
|
||||||
if (_config.UiItem.AutoHideStartup)
|
if (_config.UiItem.AutoHideStartup)
|
||||||
{
|
{
|
||||||
ShowHideWindow(false);
|
AppEvents.ShowHideWindowRequested.Publish(false);
|
||||||
}
|
}
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
@ -589,7 +593,7 @@ public class MainWindowViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
await ConfigHandler.ApplyRegionalPreset(_config, type);
|
await ConfigHandler.ApplyRegionalPreset(_config, type);
|
||||||
await ConfigHandler.InitRouting(_config);
|
await ConfigHandler.InitRouting(_config);
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.RefreshRoutingsMenu();
|
AppEvents.RoutingsMenuRefreshRequested.Publish();
|
||||||
|
|
||||||
await ConfigHandler.SaveConfig(_config);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
await new UpdateService().UpdateGeoFileAll(_config, UpdateTaskHandler);
|
await new UpdateService().UpdateGeoFileAll(_config, UpdateTaskHandler);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ using DynamicData;
|
||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
|
||||||
|
|
||||||
namespace ServiceLib.ViewModels;
|
namespace ServiceLib.ViewModels;
|
||||||
|
|
||||||
|
|
@ -250,11 +249,21 @@ public class ProfilesViewModel : MyReactiveObject
|
||||||
.ObserveOn(RxApp.MainThreadScheduler)
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
.Subscribe(async _ => await RefreshServersBiz());
|
.Subscribe(async _ => await RefreshServersBiz());
|
||||||
|
|
||||||
|
AppEvents.SubscriptionsRefreshRequested
|
||||||
|
.AsObservable()
|
||||||
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
|
.Subscribe(async _ => await RefreshSubscriptions());
|
||||||
|
|
||||||
AppEvents.DispatcherStatisticsRequested
|
AppEvents.DispatcherStatisticsRequested
|
||||||
.AsObservable()
|
.AsObservable()
|
||||||
.ObserveOn(RxApp.MainThreadScheduler)
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
.Subscribe(async result => await UpdateStatistics(result));
|
.Subscribe(async result => await UpdateStatistics(result));
|
||||||
|
|
||||||
|
AppEvents.SetDefaultServerRequested
|
||||||
|
.AsObservable()
|
||||||
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
|
.Subscribe(async indexId => await SetDefaultServer(indexId));
|
||||||
|
|
||||||
#endregion AppEvents
|
#endregion AppEvents
|
||||||
|
|
||||||
_ = Init();
|
_ = Init();
|
||||||
|
|
@ -276,7 +285,7 @@ public class ProfilesViewModel : MyReactiveObject
|
||||||
|
|
||||||
private void Reload()
|
private void Reload()
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
AppEvents.ReloadRequested.Publish();
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetSpeedTestResult(SpeedTestResult result)
|
public async Task SetSpeedTestResult(SpeedTestResult result)
|
||||||
|
|
@ -362,7 +371,7 @@ public class ProfilesViewModel : MyReactiveObject
|
||||||
|
|
||||||
public async Task RefreshServers()
|
public async Task RefreshServers()
|
||||||
{
|
{
|
||||||
AppEvents.ProfilesRefreshRequested.OnNext(Unit.Default);
|
AppEvents.ProfilesRefreshRequested.Publish();
|
||||||
|
|
||||||
await Task.Delay(200);
|
await Task.Delay(200);
|
||||||
}
|
}
|
||||||
|
|
@ -390,7 +399,7 @@ public class ProfilesViewModel : MyReactiveObject
|
||||||
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
|
await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshSubscriptions()
|
private async Task RefreshSubscriptions()
|
||||||
{
|
{
|
||||||
SubItems.Clear();
|
SubItems.Clear();
|
||||||
|
|
||||||
|
|
@ -579,7 +588,7 @@ public class ProfilesViewModel : MyReactiveObject
|
||||||
await SetDefaultServer(SelectedProfile.IndexId);
|
await SetDefaultServer(SelectedProfile.IndexId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task SetDefaultServer(string? indexId)
|
private async Task SetDefaultServer(string? indexId)
|
||||||
{
|
{
|
||||||
if (indexId.IsNullOrEmpty())
|
if (indexId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,14 @@ using System.Text;
|
||||||
using DynamicData.Binding;
|
using DynamicData.Binding;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
|
||||||
|
|
||||||
namespace ServiceLib.ViewModels;
|
namespace ServiceLib.ViewModels;
|
||||||
|
|
||||||
public class StatusBarViewModel : MyReactiveObject
|
public class StatusBarViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
|
private static readonly Lazy<StatusBarViewModel> _instance = new(() => new(null));
|
||||||
|
public static StatusBarViewModel Instance => _instance.Value;
|
||||||
|
|
||||||
#region ObservableCollection
|
#region ObservableCollection
|
||||||
|
|
||||||
public IObservableCollection<RoutingItem> RoutingItems { get; } = new ObservableCollectionExtended<RoutingItem>();
|
public IObservableCollection<RoutingItem> RoutingItems { get; } = new ObservableCollectionExtended<RoutingItem>();
|
||||||
|
|
@ -146,17 +148,17 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
|
|
||||||
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
|
NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(null);
|
AppEvents.ShowHideWindowRequested.Publish(null);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
ShowWindowCmd = ReactiveCommand.CreateFromTask(async () =>
|
ShowWindowCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(true);
|
AppEvents.ShowHideWindowRequested.Publish(true);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
HideWindowCmd = ReactiveCommand.CreateFromTask(async () =>
|
HideWindowCmd = ReactiveCommand.CreateFromTask(async () =>
|
||||||
{
|
{
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.ShowHideWindow(false);
|
AppEvents.ShowHideWindowRequested.Publish(false);
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -209,6 +211,26 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
.ObserveOn(RxApp.MainThreadScheduler)
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
.Subscribe(async result => await UpdateStatistics(result));
|
.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
|
#endregion AppEvents
|
||||||
|
|
||||||
_ = Init();
|
_ = Init();
|
||||||
|
|
@ -252,23 +274,20 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
|
|
||||||
private async Task AddServerViaClipboard()
|
private async Task AddServerViaClipboard()
|
||||||
{
|
{
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
AppEvents.AddServerViaClipboardRequested.Publish();
|
||||||
if (service != null)
|
await Task.Delay(1000);
|
||||||
await service.AddServerViaClipboardAsync(null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task AddServerViaScan()
|
private async Task AddServerViaScan()
|
||||||
{
|
{
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
AppEvents.AddServerViaScanRequested.Publish();
|
||||||
if (service != null)
|
await Task.Delay(1000);
|
||||||
await service.AddServerViaScanAsync();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task UpdateSubscriptionProcess(bool blProxy)
|
private async Task UpdateSubscriptionProcess(bool blProxy)
|
||||||
{
|
{
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
AppEvents.SubscriptionsUpdateRequested.Publish(blProxy);
|
||||||
if (service != null)
|
await Task.Delay(1000);
|
||||||
await service.UpdateSubscriptionProcess("", blProxy);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task RefreshServersBiz()
|
private async Task RefreshServersBiz()
|
||||||
|
|
@ -329,7 +348,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Locator.Current.GetService<ProfilesViewModel>()?.SetDefaultServer(SelectedServer.ID);
|
AppEvents.SetDefaultServerRequested.Publish(SelectedServer.ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task TestServerAvailability()
|
public async Task TestServerAvailability()
|
||||||
|
|
@ -364,7 +383,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
|
|
||||||
#region System proxy and Routings
|
#region System proxy and Routings
|
||||||
|
|
||||||
public async Task SetListenerType(ESysProxyType type)
|
private async Task SetListenerType(ESysProxyType type)
|
||||||
{
|
{
|
||||||
if (_config.SystemProxyItem.SysProxyType == type)
|
if (_config.SystemProxyItem.SysProxyType == type)
|
||||||
{
|
{
|
||||||
|
|
@ -393,7 +412,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task RefreshRoutingsMenu()
|
private async Task RefreshRoutingsMenu()
|
||||||
{
|
{
|
||||||
RoutingItems.Clear();
|
RoutingItems.Clear();
|
||||||
|
|
||||||
|
|
@ -430,7 +449,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
if (await ConfigHandler.SetDefaultRouting(_config, item) == 0)
|
if (await ConfigHandler.SetDefaultRouting(_config, item) == 0)
|
||||||
{
|
{
|
||||||
NoticeManager.Instance.SendMessageEx(ResUI.TipChangeRouting);
|
NoticeManager.Instance.SendMessageEx(ResUI.TipChangeRouting);
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
AppEvents.ReloadRequested.Publish();
|
||||||
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
_updateView?.Invoke(EViewAction.DispatcherRefreshIcon, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -463,7 +482,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
if (Utils.IsWindows())
|
if (Utils.IsWindows())
|
||||||
{
|
{
|
||||||
_config.TunModeItem.EnableTun = false;
|
_config.TunModeItem.EnableTun = false;
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.RebootAsAdmin();
|
await AppManager.Instance.RebootAsAdmin();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -477,7 +496,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
await ConfigHandler.SaveConfig(_config);
|
await ConfigHandler.SaveConfig(_config);
|
||||||
Locator.Current.GetService<MainWindowViewModel>()?.Reload();
|
AppEvents.ReloadRequested.Publish();
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool AllowEnableTun()
|
private bool AllowEnableTun()
|
||||||
|
|
@ -501,7 +520,7 @@ public class StatusBarViewModel : MyReactiveObject
|
||||||
|
|
||||||
#region UI
|
#region UI
|
||||||
|
|
||||||
public async Task InboundDisplayStatus()
|
private async Task InboundDisplayStatus()
|
||||||
{
|
{
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
sb.Append($"[{EInboundProtocol.mixed}:{AppManager.Instance.GetLocalPort(EInboundProtocol.socks)}");
|
sb.Append($"[{EInboundProtocol.mixed}:{AppManager.Instance.GetLocalPort(EInboundProtocol.socks)}");
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
|
using System.Reactive;
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
using Splat;
|
|
||||||
using v2rayN.Desktop.Common;
|
|
||||||
using v2rayN.Desktop.Views;
|
using v2rayN.Desktop.Views;
|
||||||
|
|
||||||
namespace v2rayN.Desktop;
|
namespace v2rayN.Desktop;
|
||||||
|
|
@ -16,9 +15,7 @@ public partial class App : Application
|
||||||
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
|
||||||
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
TaskScheduler.UnobservedTaskException += TaskScheduler_UnobservedTaskException;
|
||||||
|
|
||||||
var ViewModel = new StatusBarViewModel(null);
|
DataContext = StatusBarViewModel.Instance;
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
|
|
||||||
DataContext = ViewModel;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void OnFrameworkInitializationCompleted()
|
public override void OnFrameworkInitializationCompleted()
|
||||||
|
|
@ -57,16 +54,8 @@ public partial class App : Application
|
||||||
{
|
{
|
||||||
if (desktop.MainWindow != null)
|
if (desktop.MainWindow != null)
|
||||||
{
|
{
|
||||||
var clipboardData = await AvaUtils.GetClipboardData(desktop.MainWindow);
|
AppEvents.AddServerViaClipboardRequested.Publish();
|
||||||
if (clipboardData.IsNullOrEmpty())
|
await Task.Delay(1000);
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
|
||||||
if (service != null)
|
|
||||||
{
|
|
||||||
_ = service.AddServerViaClipboardAsync(clipboardData);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ global using ServiceLib;
|
||||||
global using ServiceLib.Base;
|
global using ServiceLib.Base;
|
||||||
global using ServiceLib.Common;
|
global using ServiceLib.Common;
|
||||||
global using ServiceLib.Enums;
|
global using ServiceLib.Enums;
|
||||||
|
global using ServiceLib.Events;
|
||||||
global using ServiceLib.Handler;
|
global using ServiceLib.Handler;
|
||||||
global using ServiceLib.Manager;
|
global using ServiceLib.Manager;
|
||||||
global using ServiceLib.Models;
|
global using ServiceLib.Models;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ using Avalonia.Input;
|
||||||
using Avalonia.ReactiveUI;
|
using Avalonia.ReactiveUI;
|
||||||
using DynamicData;
|
using DynamicData;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views;
|
namespace v2rayN.Desktop.Views;
|
||||||
|
|
||||||
|
|
@ -13,7 +12,6 @@ public partial class ClashProxiesView : ReactiveUserControl<ClashProxiesViewMode
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
|
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ClashProxiesViewModel));
|
|
||||||
lstProxyDetails.DoubleTapped += LstProxyDetails_DoubleTapped;
|
lstProxyDetails.DoubleTapped += LstProxyDetails_DoubleTapped;
|
||||||
this.KeyDown += ClashProxiesView_KeyDown;
|
this.KeyDown += ClashProxiesView_KeyDown;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,6 @@ using Avalonia.Threading;
|
||||||
using DialogHostAvalonia;
|
using DialogHostAvalonia;
|
||||||
using MsBox.Avalonia.Enums;
|
using MsBox.Avalonia.Enums;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
using v2rayN.Desktop.Base;
|
using v2rayN.Desktop.Base;
|
||||||
using v2rayN.Desktop.Common;
|
using v2rayN.Desktop.Common;
|
||||||
using v2rayN.Desktop.Manager;
|
using v2rayN.Desktop.Manager;
|
||||||
|
|
@ -20,7 +19,7 @@ namespace v2rayN.Desktop.Views;
|
||||||
public partial class MainWindow : WindowBase<MainWindowViewModel>
|
public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
{
|
{
|
||||||
private static Config _config;
|
private static Config _config;
|
||||||
private WindowNotificationManager? _manager;
|
private readonly WindowNotificationManager? _manager;
|
||||||
private CheckUpdateView? _checkUpdateView;
|
private CheckUpdateView? _checkUpdateView;
|
||||||
private BackupAndRestoreView? _backupAndRestoreView;
|
private BackupAndRestoreView? _backupAndRestoreView;
|
||||||
private bool _blCloseByUser = false;
|
private bool _blCloseByUser = false;
|
||||||
|
|
@ -40,7 +39,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
menuClose.Click += MenuClose_Click;
|
menuClose.Click += MenuClose_Click;
|
||||||
|
|
||||||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
|
||||||
|
|
||||||
switch (_config.UiItem.MainGirdOrientation)
|
switch (_config.UiItem.MainGirdOrientation)
|
||||||
{
|
{
|
||||||
|
|
@ -155,6 +153,12 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
.ObserveOn(RxApp.MainThreadScheduler)
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
.Subscribe(content => Shutdown(content))
|
.Subscribe(content => Shutdown(content))
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
|
|
||||||
|
AppEvents.ShowHideWindowRequested
|
||||||
|
.AsObservable()
|
||||||
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
|
.Subscribe(blShow => ShowHideWindow(blShow))
|
||||||
|
.DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (Utils.IsWindows())
|
if (Utils.IsWindows())
|
||||||
|
|
@ -228,12 +232,6 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
case EViewAction.SubSettingWindow:
|
case EViewAction.SubSettingWindow:
|
||||||
return await new SubSettingWindow().ShowDialog<bool>(this);
|
return await new SubSettingWindow().ShowDialog<bool>(this);
|
||||||
|
|
||||||
case EViewAction.ShowHideWindow:
|
|
||||||
Dispatcher.UIThread.Post(() =>
|
|
||||||
ShowHideWindow((bool?)obj),
|
|
||||||
DispatcherPriority.Default);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.ScanScreenTask:
|
case EViewAction.ScanScreenTask:
|
||||||
await ScanScreenTaskAsync();
|
await ScanScreenTaskAsync();
|
||||||
break;
|
break;
|
||||||
|
|
@ -243,11 +241,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.AddServerViaClipboard:
|
case EViewAction.AddServerViaClipboard:
|
||||||
var clipboardData = await AvaUtils.GetClipboardData(this);
|
await AddServerViaClipboardAsync();
|
||||||
if (clipboardData.IsNotEmpty() && ViewModel != null)
|
|
||||||
{
|
|
||||||
await ViewModel.AddServerViaClipboardAsync(clipboardData);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -266,7 +260,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
case EGlobalHotkey.SystemProxySet:
|
case EGlobalHotkey.SystemProxySet:
|
||||||
case EGlobalHotkey.SystemProxyUnchanged:
|
case EGlobalHotkey.SystemProxyUnchanged:
|
||||||
case EGlobalHotkey.SystemProxyPac:
|
case EGlobalHotkey.SystemProxyPac:
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.SetListenerType((ESysProxyType)((int)e - 1));
|
AppEvents.SysProxyChangeRequested.Publish((ESysProxyType)((int)e - 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -302,11 +296,7 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
switch (e.Key)
|
switch (e.Key)
|
||||||
{
|
{
|
||||||
case Key.V:
|
case Key.V:
|
||||||
var clipboardData = await AvaUtils.GetClipboardData(this);
|
await AddServerViaClipboardAsync();
|
||||||
if (clipboardData.IsNotEmpty() && ViewModel != null)
|
|
||||||
{
|
|
||||||
await ViewModel.AddServerViaClipboardAsync(clipboardData);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Key.S:
|
case Key.S:
|
||||||
|
|
@ -333,6 +323,15 @@ public partial class MainWindow : WindowBase<MainWindowViewModel>
|
||||||
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
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()
|
public async Task ScanScreenTaskAsync()
|
||||||
{
|
{
|
||||||
//ShowHideWindow(false);
|
//ShowHideWindow(false);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ using Avalonia.Threading;
|
||||||
using DialogHostAvalonia;
|
using DialogHostAvalonia;
|
||||||
using MsBox.Avalonia.Enums;
|
using MsBox.Avalonia.Enums;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
using v2rayN.Desktop.Common;
|
using v2rayN.Desktop.Common;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views;
|
namespace v2rayN.Desktop.Views;
|
||||||
|
|
@ -48,7 +47,6 @@ public partial class ProfilesView : ReactiveUserControl<ProfilesViewModel>
|
||||||
//}
|
//}
|
||||||
|
|
||||||
ViewModel = new ProfilesViewModel(UpdateViewHandler);
|
ViewModel = new ProfilesViewModel(UpdateViewHandler);
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ProfilesViewModel));
|
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ using Avalonia.ReactiveUI;
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
using DialogHostAvalonia;
|
using DialogHostAvalonia;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
using v2rayN.Desktop.Common;
|
using v2rayN.Desktop.Common;
|
||||||
|
|
||||||
namespace v2rayN.Desktop.Views;
|
namespace v2rayN.Desktop.Views;
|
||||||
|
|
@ -20,9 +19,8 @@ public partial class StatusBarView : ReactiveUserControl<StatusBarViewModel>
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
_config = AppManager.Instance.Config;
|
_config = AppManager.Instance.Config;
|
||||||
//ViewModel = new StatusBarViewModel(UpdateViewHandler);
|
|
||||||
//Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
|
ViewModel = StatusBarViewModel.Instance;
|
||||||
ViewModel = Locator.Current.GetService<StatusBarViewModel>();
|
|
||||||
ViewModel?.InitUpdateView(UpdateViewHandler);
|
ViewModel?.InitUpdateView(UpdateViewHandler);
|
||||||
|
|
||||||
txtRunningServerDisplay.Tapped += TxtRunningServerDisplay_Tapped;
|
txtRunningServerDisplay.Tapped += TxtRunningServerDisplay_Tapped;
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ global using ServiceLib;
|
||||||
global using ServiceLib.Base;
|
global using ServiceLib.Base;
|
||||||
global using ServiceLib.Common;
|
global using ServiceLib.Common;
|
||||||
global using ServiceLib.Enums;
|
global using ServiceLib.Enums;
|
||||||
|
global using ServiceLib.Events;
|
||||||
global using ServiceLib.Handler;
|
global using ServiceLib.Handler;
|
||||||
global using ServiceLib.Manager;
|
global using ServiceLib.Manager;
|
||||||
global using ServiceLib.Models;
|
global using ServiceLib.Models;
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
|
|
||||||
namespace v2rayN.Views;
|
namespace v2rayN.Views;
|
||||||
|
|
||||||
|
|
@ -14,7 +13,6 @@ public partial class ClashProxiesView
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
|
ViewModel = new ClashProxiesViewModel(UpdateViewHandler);
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ClashProxiesViewModel));
|
|
||||||
lstProxyDetails.PreviewMouseDoubleClick += lstProxyDetails_PreviewMouseDoubleClick;
|
lstProxyDetails.PreviewMouseDoubleClick += lstProxyDetails_PreviewMouseDoubleClick;
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
|
|
|
||||||
|
|
@ -6,10 +6,8 @@ using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Interop;
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
using v2rayN.Manager;
|
using v2rayN.Manager;
|
||||||
|
|
||||||
namespace v2rayN.Views;
|
namespace v2rayN.Views;
|
||||||
|
|
@ -37,7 +35,6 @@ public partial class MainWindow
|
||||||
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
menuBackupAndRestore.Click += MenuBackupAndRestore_Click;
|
||||||
|
|
||||||
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
ViewModel = new MainWindowViewModel(UpdateViewHandler);
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
|
|
||||||
|
|
||||||
switch (_config.UiItem.MainGirdOrientation)
|
switch (_config.UiItem.MainGirdOrientation)
|
||||||
{
|
{
|
||||||
|
|
@ -148,10 +145,16 @@ public partial class MainWindow
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
|
|
||||||
AppEvents.ShutdownRequested
|
AppEvents.ShutdownRequested
|
||||||
.AsObservable()
|
.AsObservable()
|
||||||
.ObserveOn(RxApp.MainThreadScheduler)
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
.Subscribe(content => Shutdown(content))
|
.Subscribe(content => Shutdown(content))
|
||||||
.DisposeWith(disposables);
|
.DisposeWith(disposables);
|
||||||
|
|
||||||
|
AppEvents.ShowHideWindowRequested
|
||||||
|
.AsObservable()
|
||||||
|
.ObserveOn(RxApp.MainThreadScheduler)
|
||||||
|
.Subscribe(blShow => ShowHideWindow(blShow))
|
||||||
|
.DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
this.Title = $"{Utils.GetVersion()} - {(Utils.IsAdministrator() ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
|
||||||
|
|
@ -217,13 +220,6 @@ public partial class MainWindow
|
||||||
case EViewAction.SubSettingWindow:
|
case EViewAction.SubSettingWindow:
|
||||||
return (new SubSettingWindow().ShowDialog() ?? false);
|
return (new SubSettingWindow().ShowDialog() ?? false);
|
||||||
|
|
||||||
case EViewAction.ShowHideWindow:
|
|
||||||
Application.Current?.Dispatcher.Invoke((() =>
|
|
||||||
{
|
|
||||||
ShowHideWindow((bool?)obj);
|
|
||||||
}), DispatcherPriority.Normal);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case EViewAction.ScanScreenTask:
|
case EViewAction.ScanScreenTask:
|
||||||
await ScanScreenTaskAsync();
|
await ScanScreenTaskAsync();
|
||||||
break;
|
break;
|
||||||
|
|
@ -233,11 +229,7 @@ public partial class MainWindow
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EViewAction.AddServerViaClipboard:
|
case EViewAction.AddServerViaClipboard:
|
||||||
var clipboardData = WindowsUtils.GetClipboardData();
|
await AddServerViaClipboardAsync();
|
||||||
if (clipboardData.IsNotEmpty())
|
|
||||||
{
|
|
||||||
ViewModel?.AddServerViaClipboardAsync(clipboardData);
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -256,7 +248,7 @@ public partial class MainWindow
|
||||||
case EGlobalHotkey.SystemProxySet:
|
case EGlobalHotkey.SystemProxySet:
|
||||||
case EGlobalHotkey.SystemProxyUnchanged:
|
case EGlobalHotkey.SystemProxyUnchanged:
|
||||||
case EGlobalHotkey.SystemProxyPac:
|
case EGlobalHotkey.SystemProxyPac:
|
||||||
Locator.Current.GetService<StatusBarViewModel>()?.SetListenerType((ESysProxyType)((int)e - 1));
|
AppEvents.SysProxyChangeRequested.Publish((ESysProxyType)((int)e - 1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -290,16 +282,7 @@ public partial class MainWindow
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
AddServerViaClipboardAsync().ContinueWith(_ => { });
|
||||||
var clipboardData = WindowsUtils.GetClipboardData();
|
|
||||||
if (clipboardData.IsNotEmpty())
|
|
||||||
{
|
|
||||||
var service = Locator.Current.GetService<MainWindowViewModel>();
|
|
||||||
if (service != null)
|
|
||||||
{
|
|
||||||
_ = service.AddServerViaClipboardAsync(clipboardData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
@ -333,6 +316,15 @@ public partial class MainWindow
|
||||||
ProcUtils.ProcessStart(Utils.GetBinPath("EnableLoopback.exe"));
|
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()
|
private async Task ScanScreenTaskAsync()
|
||||||
{
|
{
|
||||||
ShowHideWindow(false);
|
ShowHideWindow(false);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ using System.Windows.Media;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using MaterialDesignThemes.Wpf;
|
using MaterialDesignThemes.Wpf;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
using v2rayN.Base;
|
using v2rayN.Base;
|
||||||
using Point = System.Windows.Point;
|
using Point = System.Windows.Point;
|
||||||
|
|
||||||
|
|
@ -42,7 +41,6 @@ public partial class ProfilesView
|
||||||
}
|
}
|
||||||
|
|
||||||
ViewModel = new ProfilesViewModel(UpdateViewHandler);
|
ViewModel = new ProfilesViewModel(UpdateViewHandler);
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(ProfilesViewModel));
|
|
||||||
|
|
||||||
this.WhenActivated(disposables =>
|
this.WhenActivated(disposables =>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
using v2rayN.Manager;
|
using v2rayN.Manager;
|
||||||
|
|
||||||
namespace v2rayN.Views;
|
namespace v2rayN.Views;
|
||||||
|
|
@ -16,8 +15,8 @@ public partial class StatusBarView
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_config = AppManager.Instance.Config;
|
_config = AppManager.Instance.Config;
|
||||||
ViewModel = new StatusBarViewModel(UpdateViewHandler);
|
ViewModel = StatusBarViewModel.Instance;
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel));
|
ViewModel?.InitUpdateView(UpdateViewHandler);
|
||||||
|
|
||||||
menuExit.Click += menuExit_Click;
|
menuExit.Click += menuExit_Click;
|
||||||
txtRunningServerDisplay.PreviewMouseDown += txtRunningInfoDisplay_MouseDoubleClick;
|
txtRunningServerDisplay.PreviewMouseDown += txtRunningInfoDisplay_MouseDoubleClick;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue