Refactoring Project

pull/5566/head
2dust 2024-08-20 14:15:29 +08:00
parent 61bea05f63
commit 8d1d10b783
53 changed files with 278 additions and 249 deletions

View File

@ -1,7 +1,6 @@
using ReactiveUI; using ReactiveUI;
using v2rayN.Handler;
namespace v2rayN.Base namespace ServiceLib.Base
{ {
public class MyReactiveObject : ReactiveObject public class MyReactiveObject : ReactiveObject
{ {

View File

@ -366,6 +366,7 @@ namespace ServiceLib.Common
public static bool IsBase64String(string plainText) public static bool IsBase64String(string plainText)
{ {
if(plainText.IsNullOrEmpty()) return false;
var buffer = new Span<byte>(new byte[plainText.Length]); var buffer = new Span<byte>(new byte[plainText.Length]);
return Convert.TryFromBase64String(plainText, buffer, out int _); return Convert.TryFromBase64String(plainText, buffer, out int _);
} }

View File

@ -7,6 +7,10 @@
SaveFileDialog, SaveFileDialog,
AddBatchRoutingRulesYesNo, AddBatchRoutingRulesYesNo,
AdjustMainLvColWidth, AdjustMainLvColWidth,
UpdateSysProxy,
SetClipboardData,
AddServerViaClipboard,
ImportRulesFromClipboard,
ProfilesFocus, ProfilesFocus,
ShareSub, ShareSub,
ShareServer, ShareServer,

View File

@ -0,0 +1,3 @@
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<ReactiveUI />
</Weavers>

View File

@ -71,6 +71,7 @@
public const int MaxPort = 65536; public const int MaxPort = 65536;
public const string CommandClearMsg = "CommandClearMsg"; public const string CommandClearMsg = "CommandClearMsg";
public const string CommandSendMsgView = "CommandSendMsgView"; public const string CommandSendMsgView = "CommandSendMsgView";
public const string CommandSendSnackMsg = "CommandSendSnackMsg";
public const string CommandStopSpeedTest = "CommandStopSpeedTest"; public const string CommandStopSpeedTest = "CommandStopSpeedTest";
public const string CommandRefreshProfiles = "CommandRefreshProfiles"; public const string CommandRefreshProfiles = "CommandRefreshProfiles";
public const string DelayUnit = ""; public const string DelayUnit = "";

View File

@ -1,7 +1,11 @@
global using ServiceLib.Common; global using ServiceLib;
global using ServiceLib.Enums; global using ServiceLib.Base;
global using ServiceLib.Common;
global using ServiceLib.Handler;
global using ServiceLib.Handler.CoreConfig; global using ServiceLib.Handler.CoreConfig;
global using ServiceLib.Handler.Fmt; global using ServiceLib.Handler.Fmt;
global using ServiceLib.Handler.Statistics; global using ServiceLib.Handler.Statistics;
global using ServiceLib.Enums;
global using ServiceLib.Models; global using ServiceLib.Models;
global using ServiceLib.ViewModels;
global using ServiceLib.Resx; global using ServiceLib.Resx;

View File

@ -1406,6 +1406,10 @@ namespace ServiceLib.Handler
public static int AddBatchServers(Config config, string strData, string subid, bool isSub) public static int AddBatchServers(Config config, string strData, string subid, bool isSub)
{ {
if (Utils.IsNullOrEmpty(strData))
{
return -1;
}
List<ProfileItem>? lstOriSub = null; List<ProfileItem>? lstOriSub = null;
if (isSub && !Utils.IsNullOrEmpty(subid)) if (isSub && !Utils.IsNullOrEmpty(subid))
{ {

View File

@ -1,4 +1,6 @@
namespace ServiceLib.Handler using System.Runtime.InteropServices;
namespace ServiceLib.Handler
{ {
public sealed class LazyConfig public sealed class LazyConfig
{ {
@ -28,7 +30,7 @@
} }
} }
private Job _processJob = new(); private Job? _processJob;
public LazyConfig() public LazyConfig()
{ {
@ -52,7 +54,11 @@
public void AddProcess(IntPtr processHandle) public void AddProcess(IntPtr processHandle)
{ {
_processJob.AddProcess(processHandle); if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
_processJob ??= new();
_processJob?.AddProcess(processHandle);
}
} }
#endregion Config #endregion Config

View File

@ -1,24 +1,16 @@
using MaterialDesignThemes.Wpf; using ReactiveUI;
using ReactiveUI;
namespace v2rayN.Handler namespace ServiceLib.Handler
{ {
public class NoticeHandler public class NoticeHandler
{ {
private readonly ISnackbarMessageQueue? _snackbarMessageQueue;
public NoticeHandler(ISnackbarMessageQueue? snackbarMessageQueue)
{
_snackbarMessageQueue = snackbarMessageQueue ?? throw new ArgumentNullException(nameof(snackbarMessageQueue));
}
public void Enqueue(string? content) public void Enqueue(string? content)
{ {
if (content.IsNullOrEmpty()) if (content.IsNullOrEmpty())
{ {
return; return;
} }
_snackbarMessageQueue?.Enqueue(content); MessageBus.Current.SendMessage(content, Global.CommandSendSnackMsg);
} }
public void SendMessage(string? content) public void SendMessage(string? content)

View File

@ -8,6 +8,8 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="Downloader" Version="3.1.2" /> <PackageReference Include="Downloader" Version="3.1.2" />
<PackageReference Include="ReactiveUI" Version="20.1.1" />
<PackageReference Include="ReactiveUI.Fody" Version="19.5.41" />
<PackageReference Include="sqlite-net-pcl" Version="1.9.172" /> <PackageReference Include="sqlite-net-pcl" Version="1.9.172" />
<PackageReference Include="Splat.NLog" Version="15.1.1" /> <PackageReference Include="Splat.NLog" Version="15.1.1" />
<PackageReference Include="YamlDotNet" Version="16.0.0" /> <PackageReference Include="YamlDotNet" Version="16.0.0" />

View File

@ -1,12 +1,9 @@
using ReactiveUI; using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.IO;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class AddServer2ViewModel : MyReactiveObject public class AddServer2ViewModel : MyReactiveObject
{ {

View File

@ -2,10 +2,8 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class AddServerViewModel : MyReactiveObject public class AddServerViewModel : MyReactiveObject
{ {

View File

@ -4,9 +4,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using v2rayN.Base;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class ClashConnectionsViewModel : MyReactiveObject public class ClashConnectionsViewModel : MyReactiveObject
{ {

View File

@ -5,12 +5,10 @@ using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using v2rayN.Base;
using v2rayN.Handler;
using static ServiceLib.Models.ClashProviders; using static ServiceLib.Models.ClashProviders;
using static ServiceLib.Models.ClashProxies; using static ServiceLib.Models.ClashProxies;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class ClashProxiesViewModel : MyReactiveObject public class ClashProxiesViewModel : MyReactiveObject
{ {

View File

@ -2,10 +2,8 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class DNSSettingViewModel : MyReactiveObject public class DNSSettingViewModel : MyReactiveObject
{ {

View File

@ -3,14 +3,11 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Diagnostics; using System.Diagnostics;
using System.IO;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Text; using System.Text;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class MainWindowViewModel : MyReactiveObject public class MainWindowViewModel : MyReactiveObject
{ {
@ -149,6 +146,8 @@ namespace v2rayN.ViewModels
[Reactive] [Reactive]
public int TabMainSelectedIndex { get; set; } public int TabMainSelectedIndex { get; set; }
public bool IsAdministrator { get; set; }
#endregion UI #endregion UI
#region Init #region Init
@ -159,22 +158,10 @@ namespace v2rayN.ViewModels
_noticeHandler = Locator.Current.GetService<NoticeHandler>(); _noticeHandler = Locator.Current.GetService<NoticeHandler>();
_updateView = updateView; _updateView = updateView;
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null)); MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null));
SelectedRouting = new(); SelectedRouting = new();
SelectedServer = new(); SelectedServer = new();
if (_config.tunModeItem.enableTun)
{
if (WindowsUtils.IsAdministrator())
{
EnableTun = true;
}
else
{
_config.tunModeItem.enableTun = EnableTun = false;
}
}
Init(); Init();
@ -244,7 +231,7 @@ namespace v2rayN.ViewModels
}); });
AddServerViaClipboardCmd = ReactiveCommand.Create(() => AddServerViaClipboardCmd = ReactiveCommand.Create(() =>
{ {
AddServerViaClipboard(); AddServerViaClipboard(null);
}); });
AddServerViaScanCmd = ReactiveCommand.Create(() => AddServerViaScanCmd = ReactiveCommand.Create(() =>
{ {
@ -385,11 +372,6 @@ namespace v2rayN.ViewModels
ChangeSystemProxyStatus(_config.systemProxyItem.sysProxyType, true); ChangeSystemProxyStatus(_config.systemProxyItem.sysProxyType, true);
} }
private void OnProgramStarted(object state, bool timeout)
{
_updateView?.Invoke(EViewAction.ShowHideWindow, true);
}
#endregion Init #endregion Init
#region Actions #region Actions
@ -457,24 +439,15 @@ namespace v2rayN.ViewModels
try try
{ {
Logging.SaveLog("MyAppExit Begin"); Logging.SaveLog("MyAppExit Begin");
//if (blWindowsShutDown)
_updateView?.Invoke(EViewAction.UpdateSysProxy, true);
ConfigHandler.SaveConfig(_config); ConfigHandler.SaveConfig(_config);
if (blWindowsShutDown)
{
SysProxyHandler.ResetIEProxy4WindowsShutDown();
}
else
{
SysProxyHandler.UpdateSysProxy(_config, true);
}
ProfileExHandler.Instance.SaveTo(); ProfileExHandler.Instance.SaveTo();
StatisticsHandler.Instance.SaveTo(); StatisticsHandler.Instance.SaveTo();
StatisticsHandler.Instance.Close(); StatisticsHandler.Instance.Close();
_coreHandler.CoreStop(); _coreHandler.CoreStop();
Logging.SaveLog("MyAppExit End"); Logging.SaveLog("MyAppExit End");
} }
catch { } catch { }
@ -574,10 +547,14 @@ namespace v2rayN.ViewModels
} }
} }
public void AddServerViaClipboard() public void AddServerViaClipboard(string? clipboardData)
{ {
var clipboardData = WindowsUtils.GetClipboardData(); if (clipboardData == null)
int ret = ConfigHandler.AddBatchServers(_config, clipboardData!, _config.subIndexId, false); {
_updateView?.Invoke(EViewAction.AddServerViaClipboard, null);
return;
}
int ret = ConfigHandler.AddBatchServers(_config, clipboardData, _config.subIndexId, false);
if (ret > 0) if (ret > 0)
{ {
RefreshSubscriptions(); RefreshSubscriptions();
@ -843,11 +820,11 @@ namespace v2rayN.ViewModels
{ {
await Task.Run(() => await Task.Run(() =>
{ {
if (_config.tunModeItem.enableTun) //if (_config.tunModeItem.enableTun)
{ //{
Task.Delay(1000).Wait(); // Task.Delay(1000).Wait();
WindowsUtils.RemoveTunDevice(); // WindowsUtils.RemoveTunDevice();
} //}
var node = ConfigHandler.GetDefaultServer(_config); var node = ConfigHandler.GetDefaultServer(_config);
_coreHandler.LoadCore(node); _coreHandler.LoadCore(node);
@ -882,7 +859,7 @@ namespace v2rayN.ViewModels
private void ChangeSystemProxyStatus(ESysProxyType type, bool blChange) private void ChangeSystemProxyStatus(ESysProxyType type, bool blChange)
{ {
SysProxyHandler.UpdateSysProxy(_config, _config.tunModeItem.enableTun ? true : false); _updateView?.Invoke(EViewAction.UpdateSysProxy, _config.tunModeItem.enableTun ? true : false);
_noticeHandler?.SendMessage($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}", true); _noticeHandler?.SendMessage($"{ResUI.TipChangeSystemProxy} - {_config.systemProxyItem.sysProxyType.ToString()}", true);
BlSystemProxyClear = (type == ESysProxyType.ForcedClear); BlSystemProxyClear = (type == ESysProxyType.ForcedClear);
@ -968,7 +945,7 @@ namespace v2rayN.ViewModels
{ {
_config.tunModeItem.enableTun = EnableTun; _config.tunModeItem.enableTun = EnableTun;
// When running as a non-administrator, reboot to administrator mode // When running as a non-administrator, reboot to administrator mode
if (EnableTun && !WindowsUtils.IsAdministrator()) if (EnableTun && !IsAdministrator)
{ {
_config.tunModeItem.enableTun = false; _config.tunModeItem.enableTun = false;
RebootAsAdmin(); RebootAsAdmin();

View File

@ -2,10 +2,8 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class OptionSettingViewModel : MyReactiveObject public class OptionSettingViewModel : MyReactiveObject
{ {

View File

@ -6,10 +6,8 @@ using Splat;
using System.Reactive; using System.Reactive;
using System.Reactive.Linq; using System.Reactive.Linq;
using System.Text; using System.Text;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class ProfilesViewModel : MyReactiveObject public class ProfilesViewModel : MyReactiveObject
{ {
@ -697,7 +695,7 @@ namespace v2rayN.ViewModels
} }
else else
{ {
WindowsUtils.SetClipboardData(content); _updateView?.Invoke(EViewAction.SetClipboardData, content);
_noticeHandler?.SendMessage(ResUI.OperationSuccess); _noticeHandler?.SendMessage(ResUI.OperationSuccess);
} }
} }
@ -746,11 +744,11 @@ namespace v2rayN.ViewModels
{ {
if (blEncode) if (blEncode)
{ {
WindowsUtils.SetClipboardData(Utils.Base64Encode(sb.ToString())); _updateView?.Invoke(EViewAction.SetClipboardData, Utils.Base64Encode(sb.ToString()));
} }
else else
{ {
WindowsUtils.SetClipboardData(sb.ToString()); _updateView?.Invoke(EViewAction.SetClipboardData, sb.ToString());
} }
_noticeHandler?.SendMessage(ResUI.BatchExportURLSuccessfully); _noticeHandler?.SendMessage(ResUI.BatchExportURLSuccessfully);
} }

View File

@ -2,10 +2,8 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class RoutingRuleDetailsViewModel : MyReactiveObject public class RoutingRuleDetailsViewModel : MyReactiveObject
{ {

View File

@ -3,10 +3,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class RoutingRuleSettingViewModel : MyReactiveObject public class RoutingRuleSettingViewModel : MyReactiveObject
{ {
@ -70,7 +68,7 @@ namespace v2rayN.ViewModels
}); });
ImportRulesFromClipboardCmd = ReactiveCommand.Create(() => ImportRulesFromClipboardCmd = ReactiveCommand.Create(() =>
{ {
ImportRulesFromClipboard(); ImportRulesFromClipboard(null);
}); });
ImportRulesFromUrlCmd = ReactiveCommand.Create(() => ImportRulesFromUrlCmd = ReactiveCommand.Create(() =>
{ {
@ -199,8 +197,7 @@ namespace v2rayN.ViewModels
} }
if (lst.Count > 0) if (lst.Count > 0)
{ {
WindowsUtils.SetClipboardData(JsonUtils.Serialize(lst)); _updateView?.Invoke(EViewAction.SetClipboardData, JsonUtils.Serialize(lst));
//_noticeHandler?.Enqueue(ResUI.OperationSuccess"));
} }
} }
@ -273,9 +270,13 @@ namespace v2rayN.ViewModels
} }
} }
private void ImportRulesFromClipboard() public void ImportRulesFromClipboard(string? clipboardData)
{ {
var clipboardData = WindowsUtils.GetClipboardData(); if (clipboardData == null)
{
_updateView?.Invoke(EViewAction.ImportRulesFromClipboard, null);
return;
}
if (AddBatchRoutingRules(SelectedRouting, clipboardData) == 0) if (AddBatchRoutingRules(SelectedRouting, clipboardData) == 0)
{ {
RefreshRulesItems(); RefreshRulesItems();

View File

@ -3,10 +3,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class RoutingSettingViewModel : MyReactiveObject public class RoutingSettingViewModel : MyReactiveObject
{ {

View File

@ -2,10 +2,8 @@
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class SubEditViewModel : MyReactiveObject public class SubEditViewModel : MyReactiveObject
{ {

View File

@ -4,10 +4,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers; using ReactiveUI.Fody.Helpers;
using Splat; using Splat;
using System.Reactive; using System.Reactive;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace ServiceLib.ViewModels
{ {
public class SubSettingViewModel : MyReactiveObject public class SubSettingViewModel : MyReactiveObject
{ {

View File

@ -1,4 +1,5 @@
using System.Diagnostics; using Splat;
using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Threading; using System.Windows.Threading;
@ -58,6 +59,7 @@ namespace v2rayN
return; return;
} }
LazyConfig.Instance.SetConfig(_config); LazyConfig.Instance.SetConfig(_config);
Locator.CurrentMutable.RegisterLazySingleton(() => new NoticeHandler(), typeof(NoticeHandler));
//Under Win10 //Under Win10
if (Environment.OSVersion.Version.Major < 10) if (Environment.OSVersion.Version.Major < 10)

View File

@ -1,9 +1,8 @@
global using ServiceLib; global using ServiceLib;
global using ServiceLib.Base;
global using ServiceLib.Common; global using ServiceLib.Common;
global using ServiceLib.Handler;
global using ServiceLib.Handler.CoreConfig;
global using ServiceLib.Handler.Fmt;
global using ServiceLib.Handler.Statistics;
global using ServiceLib.Enums; global using ServiceLib.Enums;
global using ServiceLib.Handler;
global using ServiceLib.Models; global using ServiceLib.Models;
global using ServiceLib.Resx; global using ServiceLib.Resx;
global using ServiceLib.ViewModels;

View File

@ -10,8 +10,6 @@ using System.Reactive.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Windows; using System.Windows;
using System.Windows.Interop; using System.Windows.Interop;
using v2rayN.Base;
using v2rayN.Handler;
namespace v2rayN.ViewModels namespace v2rayN.ViewModels
{ {

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="v2rayN" Title="v2rayN"
Width="700" Width="700"
Height="500" Height="500"

View File

@ -1,7 +1,6 @@
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -40,17 +39,19 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
} this.DialogResult = true;
else if (action == EViewAction.BrowseServer) break;
{
if (UI.OpenFileDialog(out string fileName, "Config|*.json|YAML|*.yaml;*.yml|All|*.*") != true) case EViewAction.BrowseServer:
{ if (UI.OpenFileDialog(out string fileName, "Config|*.json|YAML|*.yaml;*.yml|All|*.*") != true)
return false; {
} return false;
ViewModel?.BrowseServer(fileName); }
ViewModel?.BrowseServer(fileName);
break;
} }
return true; return true;

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuServers}" Title="{x:Static resx:ResUI.menuServers}"
Width="900" Width="900"
Height="700" Height="700"

View File

@ -2,7 +2,6 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Controls; using System.Windows.Controls;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -223,9 +222,11 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
this.DialogResult = true;
break;
} }
return true; return true;
} }

View File

@ -7,7 +7,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
x:TypeArguments="vms:ClashConnectionsViewModel" x:TypeArguments="vms:ClashConnectionsViewModel"

View File

@ -2,7 +2,6 @@ using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Threading; using System.Windows.Threading;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
x:TypeArguments="vms:ClashProxiesViewModel" x:TypeArguments="vms:ClashProxiesViewModel"

View File

@ -4,7 +4,6 @@ using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using System.Windows.Threading; using System.Windows.Threading;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuDNSSetting}" Title="{x:Static resx:ResUI.menuDNSSetting}"
Width="1000" Width="1000"
Height="700" Height="700"

View File

@ -1,7 +1,6 @@
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -56,9 +55,11 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
this.DialogResult = true;
break;
} }
return true; return true;
} }

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSetting}" Title="{x:Static resx:ResUI.menuSetting}"
Width="700" Width="700"
Height="500" Height="500"

View File

@ -1,15 +1,15 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.MainWindow" x:Class="v2rayN.Views.MainWindow"
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:conv="clr-namespace:v2rayN.Converters"
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:reactiveui="http://reactiveui.net" xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf" xmlns:tb="clr-namespace:H.NotifyIcon;assembly=H.NotifyIcon.Wpf"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
xmlns:conv="clr-namespace:v2rayN.Converters"
Title="v2rayN" Title="v2rayN"
Width="900" Width="900"
Height="700" Height="700"

View File

@ -9,28 +9,25 @@ using System.Windows.Interop;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using v2rayN.Handler; using v2rayN.Handler;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
public partial class MainWindow public partial class MainWindow
{ {
private static Config _config; private static Config _config;
private NoticeHandler _noticeHandler;
public MainWindow() public MainWindow()
{ {
InitializeComponent(); InitializeComponent();
_config = LazyConfig.Instance.Config; _config = LazyConfig.Instance.Config;
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
App.Current.SessionEnding += Current_SessionEnding; App.Current.SessionEnding += Current_SessionEnding;
this.Closing += MainWindow_Closing; this.Closing += MainWindow_Closing;
this.PreviewKeyDown += MainWindow_PreviewKeyDown; this.PreviewKeyDown += MainWindow_PreviewKeyDown;
_noticeHandler = new NoticeHandler(MainSnackbar.MessageQueue); MessageBus.Current.Listen<string>(Global.CommandSendSnackMsg).Subscribe(x => DelegateSnackMsg(x));
Locator.CurrentMutable.RegisterLazySingleton(() => _noticeHandler, typeof(NoticeHandler));
ViewModel = new MainWindowViewModel(UpdateViewHandler); ViewModel = new MainWindowViewModel(UpdateViewHandler);
Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel)); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));
@ -146,7 +143,19 @@ namespace v2rayN.Views
}); });
var IsAdministrator = WindowsUtils.IsAdministrator(); var IsAdministrator = WindowsUtils.IsAdministrator();
ViewModel.IsAdministrator = IsAdministrator;
this.Title = $"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}"; this.Title = $"{Utils.GetVersion()} - {(IsAdministrator ? ResUI.RunAsAdmin : ResUI.NotRunAsAdmin)}";
if (_config.tunModeItem.enableTun)
{
if (IsAdministrator)
{
ViewModel.EnableTun = true;
}
else
{
_config.tunModeItem.enableTun = ViewModel.EnableTun = false;
}
}
if (!_config.guiItem.enableHWA) if (!_config.guiItem.enableHWA)
{ {
@ -182,6 +191,19 @@ namespace v2rayN.Views
#region Event #region Event
private void OnProgramStarted(object state, bool timeout)
{
ShowHideWindow(true);
}
private void DelegateSnackMsg(string content)
{
Application.Current?.Dispatcher.Invoke((() =>
{
MainSnackbar.MessageQueue?.Enqueue(content);
}), DispatcherPriority.Normal);
}
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
switch (action) switch (action)
@ -258,9 +280,19 @@ namespace v2rayN.Views
Application.Current.Shutdown(); Application.Current.Shutdown();
break; break;
case EViewAction ScanScreenTask: case EViewAction.ScanScreenTask:
ScanScreenTaskAsync().ContinueWith(_ => { }); ScanScreenTaskAsync().ContinueWith(_ => { });
break; break;
case EViewAction.UpdateSysProxy:
if (obj is null) return false;
SysProxyHandler.UpdateSysProxy(_config, (bool)obj);
break;
case EViewAction.AddServerViaClipboard:
var clipboardData = WindowsUtils.GetClipboardData();
ViewModel?.AddServerViaClipboard(clipboardData);
break;
} }
return true; return true;
@ -321,7 +353,8 @@ namespace v2rayN.Views
switch (e.Key) switch (e.Key)
{ {
case Key.V: case Key.V:
ViewModel?.AddServerViaClipboard(); var clipboardData = WindowsUtils.GetClipboardData();
ViewModel?.AddServerViaClipboard(clipboardData);
break; break;
case Key.S: case Key.S:

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSetting}" Title="{x:Static resx:ResUI.menuSetting}"
Width="1000" Width="1000"
Height="700" Height="700"

View File

@ -4,7 +4,6 @@ using System.IO;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Media; using System.Windows.Media;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -171,10 +170,12 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false); case EViewAction.CloseWindow:
this.DialogResult = true; WindowsUtils.SetAutoRun(Global.AutoRunRegPath, Global.AutoRunName, togAutoRun.IsChecked ?? false);
this.DialogResult = true;
break;
} }
return true; return true;
} }

View File

@ -9,7 +9,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
d:DesignHeight="450" d:DesignHeight="450"
d:DesignWidth="800" d:DesignWidth="800"
x:TypeArguments="vms:ProfilesViewModel" x:TypeArguments="vms:ProfilesViewModel"

View File

@ -10,7 +10,6 @@ using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Threading; using System.Windows.Threading;
using v2rayN.Base; using v2rayN.Base;
using v2rayN.ViewModels;
using Point = System.Windows.Point; using Point = System.Windows.Point;
namespace v2rayN.Views namespace v2rayN.Views
@ -103,6 +102,11 @@ namespace v2rayN.Views
{ {
switch (action) switch (action)
{ {
case EViewAction.SetClipboardData:
if (obj is null) return false;
WindowsUtils.SetClipboardData((string)obj);
break;
case EViewAction.AdjustMainLvColWidth: case EViewAction.AdjustMainLvColWidth:
Application.Current?.Dispatcher.Invoke((() => Application.Current?.Dispatcher.Invoke((() =>
{ {

View File

@ -1,14 +1,14 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleDetailsWindow" x:Class="v2rayN.Views.RoutingRuleDetailsWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:conv="clr-namespace:v2rayN.Converters" xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}" Title="{x:Static resx:ResUI.menuRoutingRuleDetailsSetting}"
Width="900" Width="900"
Height="700" Height="700"

View File

@ -1,7 +1,6 @@
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -63,9 +62,11 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
this.DialogResult = true;
break;
} }
return true; return true;
} }

View File

@ -1,14 +1,14 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.RoutingRuleSettingWindow" x:Class="v2rayN.Views.RoutingRuleSettingWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:conv="clr-namespace:v2rayN.Converters" xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:vms="clr-namespace:v2rayN.ViewModels" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net"
xmlns:resx="clr-namespace:ServiceLib.Resx;assembly=ServiceLib"
xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuRoutingRuleSetting}" Title="{x:Static resx:ResUI.menuRoutingRuleSetting}"
Width="960" Width="960"
Height="700" Height="700"

View File

@ -2,7 +2,6 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -63,37 +62,53 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
} this.DialogResult = true;
else if (action == EViewAction.ShowYesNo) break;
{
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No) case EViewAction.ShowYesNo:
{
return false; if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
} {
} return false;
else if (action == EViewAction.AddBatchRoutingRulesYesNo) }
{ break;
if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No)
{ case EViewAction.AddBatchRoutingRulesYesNo:
return false;
} if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No)
} {
else if (action == EViewAction.RoutingRuleDetailsWindow) return false;
{ }
if (obj is null) return false; break;
return (new RoutingRuleDetailsWindow((RulesItem)obj)).ShowDialog() ?? false;
} case EViewAction.RoutingRuleDetailsWindow:
else if (action == EViewAction.ImportRulesFromFile)
{ if (obj is null) return false;
if (UI.OpenFileDialog(out string fileName, "Rules|*.json|All|*.*") != true) return (new RoutingRuleDetailsWindow((RulesItem)obj)).ShowDialog() ?? false;
{
return false; case EViewAction.ImportRulesFromFile:
}
ViewModel?.ImportRulesFromFile(fileName); if (UI.OpenFileDialog(out string fileName, "Rules|*.json|All|*.*") != true)
{
return false;
}
ViewModel?.ImportRulesFromFile(fileName);
break;
case EViewAction.SetClipboardData:
if (obj is null) return false;
WindowsUtils.SetClipboardData((string)obj);
break;
case EViewAction.ImportRulesFromClipboard:
var clipboardData = WindowsUtils.GetClipboardData();
ViewModel?.ImportRulesFromClipboard(clipboardData);
break;
} }
return true; return true;
} }

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuRoutingSetting}" Title="{x:Static resx:ResUI.menuRoutingSetting}"
Width="990" Width="990"
Height="700" Height="700"

View File

@ -2,7 +2,6 @@
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -70,21 +69,23 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
} this.DialogResult = true;
else if (action == EViewAction.ShowYesNo) break;
{
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No) case EViewAction.ShowYesNo:
{ if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
return false; {
} return false;
} }
else if (action == EViewAction.RoutingRuleSettingWindow) break;
{
if (obj is null) return false; case EViewAction.RoutingRuleSettingWindow:
return (new RoutingRuleSettingWindow((RoutingItem)obj)).ShowDialog() ?? false;
if (obj is null) return false;
return (new RoutingRuleSettingWindow((RoutingItem)obj)).ShowDialog() ?? false;
} }
return true; return true;
} }

View File

@ -1,14 +1,14 @@
<reactiveui:ReactiveWindow <reactiveui:ReactiveWindow
x:Class="v2rayN.Views.SubEditWindow" x:Class="v2rayN.Views.SubEditWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:reactiveui="http://reactiveui.net"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:conv="clr-namespace:v2rayN.Converters" xmlns:conv="clr-namespace:v2rayN.Converters"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSubSetting}" Title="{x:Static resx:ResUI.menuSubSetting}"
Width="700" Width="700"
Height="600" Height="600"

View File

@ -1,7 +1,6 @@
using ReactiveUI; using ReactiveUI;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -42,9 +41,12 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
this.DialogResult = true;
break;
} }
return true; return true;
} }

View File

@ -8,7 +8,7 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:reactiveui="http://reactiveui.net" 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:v2rayN.ViewModels" xmlns:vms="clr-namespace:ServiceLib.ViewModels;assembly=ServiceLib"
Title="{x:Static resx:ResUI.menuSubSetting}" Title="{x:Static resx:ResUI.menuSubSetting}"
Width="800" Width="800"
Height="600" Height="600"

View File

@ -4,7 +4,6 @@ using System.ComponentModel;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using v2rayN.ViewModels;
namespace v2rayN.Views namespace v2rayN.Views
{ {
@ -36,26 +35,27 @@ namespace v2rayN.Views
private bool UpdateViewHandler(EViewAction action, object? obj) private bool UpdateViewHandler(EViewAction action, object? obj)
{ {
if (action == EViewAction.CloseWindow) switch (action)
{ {
this.DialogResult = true; case EViewAction.CloseWindow:
} this.DialogResult = true;
else if (action == EViewAction.ShowYesNo) break;
{
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No) case EViewAction.ShowYesNo:
{ if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
return false; {
} return false;
} }
else if (action == EViewAction.SubEditWindow) break;
{
if (obj is null) return false; case EViewAction.SubEditWindow:
return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false; if (obj is null) return false;
} return (new SubEditWindow((SubItem)obj)).ShowDialog() ?? false;
else if (action == EViewAction.ShareSub)
{ case EViewAction.ShareSub:
if (obj is null) return false; if (obj is null) return false;
ShareSub((string)obj); ShareSub((string)obj);
break;
} }
return true; return true;
} }