mirror of https://github.com/2dust/v2rayN
Refactor code to decouple view and viewmodel
parent
d893ee4829
commit
8ff04dca0d
|
@ -1,9 +1,9 @@
|
||||||
<Application
|
<Application
|
||||||
x:Class="v2rayN.App"
|
x:Class="v2rayN.App"
|
||||||
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:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:conv="clr-namespace:v2rayN.Converters"
|
xmlns:conv="clr-namespace:v2rayN.Converters"
|
||||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
|
||||||
ShutdownMode="OnExplicitShutdown"
|
ShutdownMode="OnExplicitShutdown"
|
||||||
StartupUri="Views/MainWindow.xaml">
|
StartupUri="Views/MainWindow.xaml">
|
||||||
<Application.Resources>
|
<Application.Resources>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
using ReactiveUI;
|
||||||
|
using v2rayN.Enums;
|
||||||
|
using v2rayN.Handler;
|
||||||
|
using v2rayN.Models;
|
||||||
|
|
||||||
|
namespace v2rayN.Base
|
||||||
|
{
|
||||||
|
public class MyReactiveObject : ReactiveObject
|
||||||
|
{
|
||||||
|
protected static Config? _config;
|
||||||
|
protected Func<EViewAction, bool>? _updateView;
|
||||||
|
protected NoticeHandler? _noticeHandler;
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,9 @@
|
||||||
public enum EViewAction
|
public enum EViewAction
|
||||||
{
|
{
|
||||||
AdjustMainLvColWidth,
|
AdjustMainLvColWidth,
|
||||||
ProfilesFocus
|
ProfilesFocus,
|
||||||
|
CloseWindow,
|
||||||
|
ShowYesNo,
|
||||||
|
AddBatchRoutingRulesYesNo,
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,22 +1,18 @@
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using ReactiveUI.Validation.Helpers;
|
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.Resx;
|
using v2rayN.Resx;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class AddServer2ViewModel : ReactiveValidationObject
|
public class AddServer2ViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public ProfileItem SelectedSource { get; set; }
|
public ProfileItem SelectedSource { get; set; }
|
||||||
|
|
||||||
|
@ -25,10 +21,11 @@ namespace v2rayN.ViewModels
|
||||||
public ReactiveCommand<Unit, Unit> SaveServerCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveServerCmd { get; }
|
||||||
public bool IsModified { get; set; }
|
public bool IsModified { get; set; }
|
||||||
|
|
||||||
public AddServer2ViewModel(ProfileItem profileItem, Window view)
|
public AddServer2ViewModel(ProfileItem profileItem, Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
|
_updateView = updateView;
|
||||||
|
|
||||||
if (profileItem.indexId.IsNullOrEmpty())
|
if (profileItem.indexId.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
@ -39,8 +36,6 @@ namespace v2rayN.ViewModels
|
||||||
SelectedSource = JsonUtils.DeepCopy(profileItem);
|
SelectedSource = JsonUtils.DeepCopy(profileItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
_view = view;
|
|
||||||
|
|
||||||
BrowseServerCmd = ReactiveCommand.Create(() =>
|
BrowseServerCmd = ReactiveCommand.Create(() =>
|
||||||
{
|
{
|
||||||
BrowseServer();
|
BrowseServer();
|
||||||
|
@ -55,8 +50,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SaveServer();
|
SaveServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveServer()
|
private void SaveServer()
|
||||||
|
@ -91,7 +84,7 @@ namespace v2rayN.ViewModels
|
||||||
if (ConfigHandler.EditCustomServer(_config, item) == 0)
|
if (ConfigHandler.EditCustomServer(_config, item) == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
@ -10,22 +10,18 @@ using v2rayN.Resx;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class AddServerViewModel : ReactiveObject
|
public class AddServerViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public ProfileItem SelectedSource { get; set; }
|
public ProfileItem SelectedSource { get; set; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
|
|
||||||
public AddServerViewModel(ProfileItem profileItem, Window view)
|
public AddServerViewModel(ProfileItem profileItem, Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_view = view;
|
_updateView = updateView;
|
||||||
|
|
||||||
if (profileItem.id.IsNullOrEmpty())
|
if (profileItem.id.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
@ -44,8 +40,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SaveServer();
|
SaveServer();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveServer()
|
private void SaveServer()
|
||||||
|
@ -141,8 +135,7 @@ namespace v2rayN.ViewModels
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
//_view?.Close();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,16 +5,15 @@ using ReactiveUI.Fody.Helpers;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class ClashConnectionsViewModel : ReactiveObject
|
public class ClashConnectionsViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
|
|
||||||
private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>();
|
private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>();
|
||||||
|
|
||||||
public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems;
|
public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems;
|
||||||
|
|
|
@ -6,6 +6,7 @@ using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
@ -15,10 +16,8 @@ using static v2rayN.Models.ClashProxies;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class ClashProxiesViewModel : ReactiveObject
|
public class ClashProxiesViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Dictionary<String, ProxiesItem>? proxies;
|
private Dictionary<String, ProxiesItem>? proxies;
|
||||||
private Dictionary<String, ProvidersItem>? providers;
|
private Dictionary<String, ProvidersItem>? providers;
|
||||||
private int delayTimeout = 99999999;
|
private int delayTimeout = 99999999;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
@ -10,12 +10,8 @@ using v2rayN.Resx;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class DNSSettingViewModel : ReactiveObject
|
public class DNSSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
|
|
||||||
[Reactive] public bool useSystemHosts { get; set; }
|
[Reactive] public bool useSystemHosts { get; set; }
|
||||||
[Reactive] public string domainStrategy4Freedom { get; set; }
|
[Reactive] public string domainStrategy4Freedom { get; set; }
|
||||||
[Reactive] public string domainDNSAddress { get; set; }
|
[Reactive] public string domainDNSAddress { get; set; }
|
||||||
|
@ -30,11 +26,11 @@ namespace v2rayN.ViewModels
|
||||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
|
public ReactiveCommand<Unit, Unit> ImportDefConfig4V2rayCmd { get; }
|
||||||
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; }
|
public ReactiveCommand<Unit, Unit> ImportDefConfig4SingboxCmd { get; }
|
||||||
|
|
||||||
public DNSSettingViewModel(Window view)
|
public DNSSettingViewModel(Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_view = view;
|
_updateView = updateView;
|
||||||
|
|
||||||
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
|
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
|
||||||
useSystemHosts = item.useSystemHosts;
|
useSystemHosts = item.useSystemHosts;
|
||||||
|
@ -63,8 +59,6 @@ namespace v2rayN.ViewModels
|
||||||
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
|
||||||
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
|
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveSetting()
|
private void SaveSetting()
|
||||||
|
@ -114,11 +108,11 @@ namespace v2rayN.ViewModels
|
||||||
item2.domainStrategy4Freedom = domainStrategy4Freedom2;
|
item2.domainStrategy4Freedom = domainStrategy4Freedom2;
|
||||||
item2.domainDNSAddress = domainDNSAddress2;
|
item2.domainDNSAddress = domainDNSAddress2;
|
||||||
item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
|
item2.normalDNS = JsonUtils.Serialize(JsonUtils.ParseJson(normalDNS2));
|
||||||
item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2));;
|
item2.tunDNS = JsonUtils.Serialize(JsonUtils.ParseJson(tunDNS2)); ;
|
||||||
ConfigHandler.SaveDNSItems(_config, item2);
|
ConfigHandler.SaveDNSItems(_config, item2);
|
||||||
|
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@ using System.Reactive.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Handler.Statistics;
|
using v2rayN.Handler.Statistics;
|
||||||
|
@ -20,14 +21,12 @@ using v2rayN.Views;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class MainWindowViewModel : ReactiveObject
|
public class MainWindowViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
#region private prop
|
#region private prop
|
||||||
|
|
||||||
private CoreHandler _coreHandler;
|
private CoreHandler _coreHandler;
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Action<EViewAction> _updateView;
|
|
||||||
private bool _showInTaskbar;
|
private bool _showInTaskbar;
|
||||||
|
|
||||||
#endregion private prop
|
#endregion private prop
|
||||||
|
@ -171,15 +170,14 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
|
|
||||||
public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Action<EViewAction> updateView)
|
public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_updateView = updateView;
|
|
||||||
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
|
||||||
|
|
||||||
_noticeHandler = new NoticeHandler(snackbarMessageQueue);
|
|
||||||
Locator.CurrentMutable.RegisterLazySingleton(() => _noticeHandler, typeof(NoticeHandler));
|
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
|
_updateView = updateView;
|
||||||
|
|
||||||
|
ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false);
|
||||||
|
Locator.CurrentMutable.RegisterLazySingleton(() => _noticeHandler, typeof(NoticeHandler));
|
||||||
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
|
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
|
||||||
|
|
||||||
SelectedRouting = new();
|
SelectedRouting = new();
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
@ -10,12 +10,8 @@ using v2rayN.Resx;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class OptionSettingViewModel : ReactiveObject
|
public class OptionSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
|
|
||||||
#region Core
|
#region Core
|
||||||
|
|
||||||
[Reactive] public int localPort { get; set; }
|
[Reactive] public int localPort { get; set; }
|
||||||
|
@ -109,11 +105,11 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
|
|
||||||
public OptionSettingViewModel(Window view)
|
public OptionSettingViewModel(Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_view = view;
|
_updateView = updateView;
|
||||||
|
|
||||||
#region Core
|
#region Core
|
||||||
|
|
||||||
|
@ -201,8 +197,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SaveSetting();
|
SaveSetting();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitCoreType()
|
private void InitCoreType()
|
||||||
|
@ -365,7 +359,7 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
}
|
}
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,7 @@ using System.Reactive;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Handler.Fmt;
|
using v2rayN.Handler.Fmt;
|
||||||
|
@ -18,16 +19,14 @@ using v2rayN.Views;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class ProfilesViewModel : ReactiveObject
|
public class ProfilesViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
#region private prop
|
#region private prop
|
||||||
|
|
||||||
private List<ProfileItem> _lstProfile;
|
private List<ProfileItem> _lstProfile;
|
||||||
private string _serverFilter = string.Empty;
|
private string _serverFilter = string.Empty;
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Dictionary<string, bool> _dicHeaderSort = new();
|
private Dictionary<string, bool> _dicHeaderSort = new();
|
||||||
private Action<EViewAction> _updateView;
|
|
||||||
|
|
||||||
#endregion private prop
|
#endregion private prop
|
||||||
|
|
||||||
|
@ -103,12 +102,12 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
#region Init
|
#region Init
|
||||||
|
|
||||||
public ProfilesViewModel(Action<EViewAction> updateView)
|
public ProfilesViewModel(Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_updateView = updateView;
|
_updateView = updateView;
|
||||||
|
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
|
||||||
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
|
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
|
||||||
|
|
||||||
SelectedProfile = new();
|
SelectedProfile = new();
|
||||||
|
@ -507,8 +506,7 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
|
||||||
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
|
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,19 +2,16 @@
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.Resx;
|
using v2rayN.Resx;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class RoutingRuleDetailsViewModel : ReactiveObject
|
public class RoutingRuleDetailsViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
|
|
||||||
public IList<string> ProtocolItems { get; set; }
|
public IList<string> ProtocolItems { get; set; }
|
||||||
public IList<string> InboundTagItems { get; set; }
|
public IList<string> InboundTagItems { get; set; }
|
||||||
|
|
||||||
|
@ -35,11 +32,11 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
|
|
||||||
public RoutingRuleDetailsViewModel(RulesItem rulesItem, Window view)
|
public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_view = view;
|
_updateView = updateView;
|
||||||
|
|
||||||
if (rulesItem.id.IsNullOrEmpty())
|
if (rulesItem.id.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
@ -61,8 +58,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SaveRules();
|
SaveRules();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveRules()
|
private void SaveRules()
|
||||||
|
@ -98,7 +93,7 @@ namespace v2rayN.ViewModels
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
//_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -3,7 +3,7 @@ using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
@ -13,11 +13,8 @@ using Application = System.Windows.Application;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class RoutingRuleSettingViewModel : ReactiveObject
|
public class RoutingRuleSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
private List<RulesItem> _rules;
|
private List<RulesItem> _rules;
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
|
@ -44,11 +41,11 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
|
|
||||||
public RoutingRuleSettingViewModel(RoutingItem routingItem, Window view)
|
public RoutingRuleSettingViewModel(RoutingItem routingItem, Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_view = view;
|
_updateView = updateView;
|
||||||
SelectedSource = new();
|
SelectedSource = new();
|
||||||
|
|
||||||
if (routingItem.id.IsNullOrEmpty())
|
if (routingItem.id.IsNullOrEmpty())
|
||||||
|
@ -115,8 +112,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SaveRouting();
|
SaveRouting();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshRulesItems()
|
public void RefreshRulesItems()
|
||||||
|
@ -174,7 +169,7 @@ namespace v2rayN.ViewModels
|
||||||
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
|
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
|
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +249,7 @@ namespace v2rayN.ViewModels
|
||||||
if (ConfigHandler.SaveRoutingItem(_config, item) == 0)
|
if (ConfigHandler.SaveRoutingItem(_config, item) == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -323,7 +318,7 @@ namespace v2rayN.ViewModels
|
||||||
private int AddBatchRoutingRules(RoutingItem routingItem, string? clipboardData)
|
private int AddBatchRoutingRules(RoutingItem routingItem, string? clipboardData)
|
||||||
{
|
{
|
||||||
bool blReplace = false;
|
bool blReplace = false;
|
||||||
if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No)
|
if (_updateView?.Invoke(EViewAction.AddBatchRoutingRulesYesNo) == false)
|
||||||
{
|
{
|
||||||
blReplace = true;
|
blReplace = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,8 @@ using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.Resx;
|
using v2rayN.Resx;
|
||||||
|
@ -11,11 +12,8 @@ using v2rayN.Views;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class RoutingSettingViewModel : ReactiveObject
|
public class RoutingSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
private RoutingItem _lockedItem;
|
private RoutingItem _lockedItem;
|
||||||
private List<RulesItem> _lockedRules;
|
private List<RulesItem> _lockedRules;
|
||||||
|
|
||||||
|
@ -73,11 +71,11 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
#endregion Reactive
|
#endregion Reactive
|
||||||
|
|
||||||
public RoutingSettingViewModel(Window view)
|
public RoutingSettingViewModel(Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_view = view;
|
_updateView = updateView;
|
||||||
SelectedSource = new();
|
SelectedSource = new();
|
||||||
|
|
||||||
ConfigHandler.InitBuiltinRouting(_config);
|
ConfigHandler.InitBuiltinRouting(_config);
|
||||||
|
@ -125,8 +123,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SaveRouting();
|
SaveRouting();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#region locked
|
#region locked
|
||||||
|
@ -211,7 +207,7 @@ namespace v2rayN.ViewModels
|
||||||
if (ConfigHandler.SaveConfig(_config) == 0)
|
if (ConfigHandler.SaveConfig(_config) == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -263,7 +259,7 @@ namespace v2rayN.ViewModels
|
||||||
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
|
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
|
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,29 +2,26 @@
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.Resx;
|
using v2rayN.Resx;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class SubEditViewModel : ReactiveObject
|
public class SubEditViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private Window _view;
|
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
public SubItem SelectedSource { get; set; }
|
public SubItem SelectedSource { get; set; }
|
||||||
|
|
||||||
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
|
||||||
|
|
||||||
public SubEditViewModel(SubItem subItem, Window view)
|
public SubEditViewModel(SubItem subItem, Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
_view = view;
|
_updateView = updateView;
|
||||||
|
|
||||||
if (subItem.id.IsNullOrEmpty())
|
if (subItem.id.IsNullOrEmpty())
|
||||||
{
|
{
|
||||||
|
@ -39,8 +36,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SaveSub();
|
SaveSub();
|
||||||
});
|
});
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SaveSub()
|
private void SaveSub()
|
||||||
|
@ -75,8 +70,7 @@ namespace v2rayN.ViewModels
|
||||||
if (ConfigHandler.AddSubItem(_config, item) == 0)
|
if (ConfigHandler.AddSubItem(_config, item) == 0)
|
||||||
{
|
{
|
||||||
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
|
||||||
_view.DialogResult = true;
|
_updateView?.Invoke(EViewAction.CloseWindow);
|
||||||
//_view?.Close();
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -5,7 +5,8 @@ using ReactiveUI;
|
||||||
using ReactiveUI.Fody.Helpers;
|
using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive;
|
using System.Reactive;
|
||||||
using System.Windows;
|
using v2rayN.Base;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.Resx;
|
using v2rayN.Resx;
|
||||||
|
@ -13,11 +14,8 @@ using v2rayN.Views;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class SubSettingViewModel : ReactiveObject
|
public class SubSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
|
|
||||||
private IObservableCollection<SubItem> _subItems = new ObservableCollectionExtended<SubItem>();
|
private IObservableCollection<SubItem> _subItems = new ObservableCollectionExtended<SubItem>();
|
||||||
public IObservableCollection<SubItem> SubItems => _subItems;
|
public IObservableCollection<SubItem> SubItems => _subItems;
|
||||||
|
|
||||||
|
@ -32,10 +30,11 @@ namespace v2rayN.ViewModels
|
||||||
public ReactiveCommand<Unit, Unit> SubShareCmd { get; }
|
public ReactiveCommand<Unit, Unit> SubShareCmd { get; }
|
||||||
public bool IsModified { get; set; }
|
public bool IsModified { get; set; }
|
||||||
|
|
||||||
public SubSettingViewModel(Window view)
|
public SubSettingViewModel(Func<EViewAction, bool>? updateView)
|
||||||
{
|
{
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
|
||||||
|
_updateView = updateView;
|
||||||
|
|
||||||
SelectedSource = new();
|
SelectedSource = new();
|
||||||
|
|
||||||
|
@ -61,8 +60,6 @@ namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
SubShare();
|
SubShare();
|
||||||
}, canEditRemove);
|
}, canEditRemove);
|
||||||
|
|
||||||
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshSubItems()
|
public void RefreshSubItems()
|
||||||
|
@ -96,7 +93,7 @@ namespace v2rayN.ViewModels
|
||||||
|
|
||||||
private void DeleteSub()
|
private void DeleteSub()
|
||||||
{
|
{
|
||||||
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
|
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,14 @@ using ReactiveUI.Fody.Helpers;
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.Reactive.Linq;
|
using System.Reactive.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using v2rayN.Base;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
|
||||||
using v2rayN.Resx;
|
using v2rayN.Resx;
|
||||||
|
|
||||||
namespace v2rayN.ViewModels
|
namespace v2rayN.ViewModels
|
||||||
{
|
{
|
||||||
public class ThemeSettingViewModel : ReactiveObject
|
public class ThemeSettingViewModel : MyReactiveObject
|
||||||
{
|
{
|
||||||
private static Config _config;
|
|
||||||
private NoticeHandler? _noticeHandler;
|
|
||||||
private readonly PaletteHelper _paletteHelper = new();
|
private readonly PaletteHelper _paletteHelper = new();
|
||||||
|
|
||||||
[Reactive]
|
[Reactive]
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
this.Owner = Application.Current.MainWindow;
|
this.Owner = Application.Current.MainWindow;
|
||||||
this.Loaded += Window_Loaded;
|
this.Loaded += Window_Loaded;
|
||||||
ViewModel = new AddServer2ViewModel(profileItem, this);
|
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
|
||||||
|
|
||||||
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))
|
foreach (ECoreType it in Enum.GetValues(typeof(ECoreType)))
|
||||||
{
|
{
|
||||||
|
@ -37,6 +38,17 @@ namespace v2rayN.Views
|
||||||
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.EditServerCmd, v => v.btnEdit).DisposeWith(disposables);
|
||||||
this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables);
|
this.BindCommand(ViewModel, vm => vm.SaveServerCmd, v => v.btnSave).DisposeWith(disposables);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Utils.SetDarkBorder(this, LazyConfig.Instance.GetConfig().uiItem.followSystemTheme ? !Utils.IsLightTheme() : LazyConfig.Instance.GetConfig().uiItem.colorModeDark);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
|
|
@ -21,7 +21,7 @@ namespace v2rayN.Views
|
||||||
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
|
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
|
||||||
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
|
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
|
||||||
|
|
||||||
ViewModel = new AddServerViewModel(profileItem, this);
|
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
|
||||||
|
|
||||||
if (profileItem.configType == EConfigType.VLESS)
|
if (profileItem.configType == EConfigType.VLESS)
|
||||||
{
|
{
|
||||||
|
@ -224,6 +224,15 @@ namespace v2rayN.Views
|
||||||
this.Title = $"{profileItem.configType}";
|
this.Title = $"{profileItem.configType}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
txtRemarks.Focus();
|
txtRemarks.Focus();
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.ClashConnectionsView"
|
x:Class="v2rayN.Views.ClashConnectionsView"
|
||||||
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: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: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:resx="clr-namespace:v2rayN.Resx"
|
xmlns:resx="clr-namespace:v2rayN.Resx"
|
||||||
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<reactiveui:ReactiveUserControl
|
<reactiveui:ReactiveUserControl
|
||||||
x:Class="v2rayN.Views.ClashProxiesView"
|
x:Class="v2rayN.Views.ClashProxiesView"
|
||||||
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:converters="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: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:converters="clr-namespace:v2rayN.Converters"
|
||||||
xmlns:resx="clr-namespace:v2rayN.Resx"
|
xmlns:resx="clr-namespace:v2rayN.Resx"
|
||||||
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
xmlns:vms="clr-namespace:v2rayN.ViewModels"
|
||||||
d:DesignHeight="450"
|
d:DesignHeight="450"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
@ -18,7 +19,7 @@ namespace v2rayN.Views
|
||||||
this.Owner = Application.Current.MainWindow;
|
this.Owner = Application.Current.MainWindow;
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
|
|
||||||
ViewModel = new DNSSettingViewModel(this);
|
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
Global.DomainStrategy4Freedoms.ForEach(it =>
|
Global.DomainStrategy4Freedoms.ForEach(it =>
|
||||||
{
|
{
|
||||||
|
@ -55,6 +56,15 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e)
|
private void linkDnsObjectDoc_Click(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
|
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using MaterialDesignThemes.Wpf;
|
using ReactiveUI;
|
||||||
using ReactiveUI;
|
|
||||||
using Splat;
|
using Splat;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
|
|
|
@ -23,7 +23,7 @@ namespace v2rayN.Views
|
||||||
_config = LazyConfig.Instance.GetConfig();
|
_config = LazyConfig.Instance.GetConfig();
|
||||||
var lstFonts = GetFonts(Utils.GetFontsPath());
|
var lstFonts = GetFonts(Utils.GetFontsPath());
|
||||||
|
|
||||||
ViewModel = new OptionSettingViewModel(this);
|
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
|
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
|
||||||
Global.destOverrideProtocols.ForEach(it =>
|
Global.destOverrideProtocols.ForEach(it =>
|
||||||
|
@ -171,6 +171,15 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private List<string> GetFonts(string path)
|
private List<string> GetFonts(string path)
|
||||||
{
|
{
|
||||||
var lstFonts = new List<string>();
|
var lstFonts = new List<string>();
|
||||||
|
|
|
@ -10,6 +10,7 @@ using v2rayN.Base;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Handler;
|
using v2rayN.Handler;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
using v2rayN.Resx;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
using Point = System.Windows.Point;
|
using Point = System.Windows.Point;
|
||||||
|
|
||||||
|
@ -96,7 +97,7 @@ namespace v2rayN.Views
|
||||||
StorageUI();
|
StorageUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateViewHandler(EViewAction action)
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
{
|
{
|
||||||
if (action == EViewAction.AdjustMainLvColWidth)
|
if (action == EViewAction.AdjustMainLvColWidth)
|
||||||
{
|
{
|
||||||
|
@ -109,6 +110,15 @@ namespace v2rayN.Views
|
||||||
{
|
{
|
||||||
lstProfiles.Focus();
|
lstProfiles.Focus();
|
||||||
}
|
}
|
||||||
|
else if (action == EViewAction.ShowYesNo)
|
||||||
|
{
|
||||||
|
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void lstProfiles_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
private void lstProfiles_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
|
||||||
|
@ -17,7 +18,7 @@ namespace v2rayN.Views
|
||||||
clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged;
|
clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged;
|
||||||
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
|
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
|
||||||
|
|
||||||
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, this);
|
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
|
||||||
cmbOutboundTag.Items.Add(Global.ProxyTag);
|
cmbOutboundTag.Items.Add(Global.ProxyTag);
|
||||||
cmbOutboundTag.Items.Add(Global.DirectTag);
|
cmbOutboundTag.Items.Add(Global.DirectTag);
|
||||||
cmbOutboundTag.Items.Add(Global.BlockTag);
|
cmbOutboundTag.Items.Add(Global.BlockTag);
|
||||||
|
@ -61,6 +62,15 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
cmbOutboundTag.Focus();
|
cmbOutboundTag.Focus();
|
||||||
|
|
|
@ -4,6 +4,7 @@ using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using v2rayN.Enums;
|
using v2rayN.Enums;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
using v2rayN.Resx;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
|
||||||
namespace v2rayN.Views
|
namespace v2rayN.Views
|
||||||
|
@ -20,7 +21,7 @@ namespace v2rayN.Views
|
||||||
lstRules.SelectionChanged += lstRules_SelectionChanged;
|
lstRules.SelectionChanged += lstRules_SelectionChanged;
|
||||||
lstRules.MouseDoubleClick += LstRules_MouseDoubleClick;
|
lstRules.MouseDoubleClick += LstRules_MouseDoubleClick;
|
||||||
|
|
||||||
ViewModel = new RoutingRuleSettingViewModel(routingItem, this);
|
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
|
||||||
Global.DomainStrategies.ForEach(it =>
|
Global.DomainStrategies.ForEach(it =>
|
||||||
{
|
{
|
||||||
cmbdomainStrategy.Items.Add(it);
|
cmbdomainStrategy.Items.Add(it);
|
||||||
|
@ -62,6 +63,30 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
else if (action == EViewAction.ShowYesNo)
|
||||||
|
{
|
||||||
|
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (action == EViewAction.AddBatchRoutingRulesYesNo)
|
||||||
|
{
|
||||||
|
if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
txtRemarks.Focus();
|
txtRemarks.Focus();
|
||||||
|
|
|
@ -2,7 +2,9 @@
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
using v2rayN.Resx;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
|
||||||
namespace v2rayN.Views
|
namespace v2rayN.Views
|
||||||
|
@ -19,7 +21,7 @@ namespace v2rayN.Views
|
||||||
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
|
||||||
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
|
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
|
||||||
|
|
||||||
ViewModel = new RoutingSettingViewModel(this);
|
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
|
||||||
|
|
||||||
Global.DomainStrategies.ForEach(it =>
|
Global.DomainStrategies.ForEach(it =>
|
||||||
{
|
{
|
||||||
|
@ -68,6 +70,22 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
else if (action == EViewAction.ShowYesNo)
|
||||||
|
{
|
||||||
|
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
|
private void RoutingSettingWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
|
||||||
{
|
{
|
||||||
if (ViewModel?.IsModified == true)
|
if (ViewModel?.IsModified == true)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using v2rayN.Enums;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
|
||||||
|
@ -15,7 +16,7 @@ namespace v2rayN.Views
|
||||||
this.Owner = Application.Current.MainWindow;
|
this.Owner = Application.Current.MainWindow;
|
||||||
this.Loaded += Window_Loaded;
|
this.Loaded += Window_Loaded;
|
||||||
|
|
||||||
ViewModel = new SubEditViewModel(subItem, this);
|
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
|
||||||
|
|
||||||
Global.SubConvertTargets.ForEach(it =>
|
Global.SubConvertTargets.ForEach(it =>
|
||||||
{
|
{
|
||||||
|
@ -40,6 +41,15 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void Window_Loaded(object sender, RoutedEventArgs e)
|
private void Window_Loaded(object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
txtRemarks.Focus();
|
txtRemarks.Focus();
|
||||||
|
|
|
@ -3,7 +3,9 @@ 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.Enums;
|
||||||
using v2rayN.Models;
|
using v2rayN.Models;
|
||||||
|
using v2rayN.Resx;
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
|
||||||
namespace v2rayN.Views
|
namespace v2rayN.Views
|
||||||
|
@ -16,7 +18,7 @@ namespace v2rayN.Views
|
||||||
|
|
||||||
this.Owner = Application.Current.MainWindow;
|
this.Owner = Application.Current.MainWindow;
|
||||||
|
|
||||||
ViewModel = new SubSettingViewModel(this);
|
ViewModel = new SubSettingViewModel(UpdateViewHandler);
|
||||||
this.Closing += SubSettingWindow_Closing;
|
this.Closing += SubSettingWindow_Closing;
|
||||||
lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick;
|
lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick;
|
||||||
lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;
|
lstSubscription.SelectionChanged += LstSubscription_SelectionChanged;
|
||||||
|
@ -33,6 +35,22 @@ namespace v2rayN.Views
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private bool UpdateViewHandler(EViewAction action)
|
||||||
|
{
|
||||||
|
if (action == EViewAction.CloseWindow)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
else if (action == EViewAction.ShowYesNo)
|
||||||
|
{
|
||||||
|
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void SubSettingWindow_Closing(object? sender, CancelEventArgs e)
|
private void SubSettingWindow_Closing(object? sender, CancelEventArgs e)
|
||||||
{
|
{
|
||||||
if (ViewModel?.IsModified == true)
|
if (ViewModel?.IsModified == true)
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
using ReactiveUI;
|
using ReactiveUI;
|
||||||
using Splat;
|
|
||||||
using System.Reactive.Disposables;
|
using System.Reactive.Disposables;
|
||||||
using System.Windows.Input;
|
|
||||||
using v2rayN.Handler;
|
|
||||||
using v2rayN.ViewModels;
|
using v2rayN.ViewModels;
|
||||||
|
|
||||||
namespace v2rayN.Views
|
namespace v2rayN.Views
|
||||||
|
|
Loading…
Reference in New Issue