Refactor code to decouple view and viewmodel

pull/5550/head
2dust 2024-08-10 10:02:00 +08:00
parent d893ee4829
commit 8ff04dca0d
33 changed files with 248 additions and 161 deletions

View File

@ -1,9 +1,9 @@
<Application
x:Class="v2rayN.App"
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:conv="clr-namespace:v2rayN.Converters"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
ShutdownMode="OnExplicitShutdown"
StartupUri="Views/MainWindow.xaml">
<Application.Resources>

View File

@ -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;
}
}

View File

@ -3,6 +3,9 @@
public enum EViewAction
{
AdjustMainLvColWidth,
ProfilesFocus
ProfilesFocus,
CloseWindow,
ShowYesNo,
AddBatchRoutingRulesYesNo,
}
}

View File

@ -179,7 +179,7 @@ namespace v2rayN
public static readonly List<string> DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"];
public static readonly List<string> SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"];
public static readonly List<string> Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" };
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
public static readonly List<string> Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" };
public static readonly List<string> LogLevels = new() { "debug", "info", "warning", "error", "none" };
public static readonly List<string> InboundTags = new() { "socks", "http", "socks2", "http2" };
public static readonly List<string> RuleProtocols = new() { "http", "tls", "bittorrent" };

View File

@ -1,22 +1,18 @@
using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using ReactiveUI.Validation.Helpers;
using Splat;
using System.IO;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.ViewModels
{
public class AddServer2ViewModel : ReactiveValidationObject
public class AddServer2ViewModel : MyReactiveObject
{
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
[Reactive]
public ProfileItem SelectedSource { get; set; }
@ -25,10 +21,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveServerCmd { get; }
public bool IsModified { get; set; }
public AddServer2ViewModel(ProfileItem profileItem, Window view)
public AddServer2ViewModel(ProfileItem profileItem, Func<EViewAction, bool>? updateView)
{
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig();
_updateView = updateView;
if (profileItem.indexId.IsNullOrEmpty())
{
@ -39,8 +36,6 @@ namespace v2rayN.ViewModels
SelectedSource = JsonUtils.DeepCopy(profileItem);
}
_view = view;
BrowseServerCmd = ReactiveCommand.Create(() =>
{
BrowseServer();
@ -55,8 +50,6 @@ namespace v2rayN.ViewModels
{
SaveServer();
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
private void SaveServer()
@ -91,7 +84,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.EditCustomServer(_config, item) == 0)
{
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true;
_updateView?.Invoke(EViewAction.CloseWindow);
}
else
{

View File

@ -2,7 +2,7 @@
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
@ -10,22 +10,18 @@ using v2rayN.Resx;
namespace v2rayN.ViewModels
{
public class AddServerViewModel : ReactiveObject
public class AddServerViewModel : MyReactiveObject
{
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
[Reactive]
public ProfileItem SelectedSource { get; set; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public AddServerViewModel(ProfileItem profileItem, Window view)
public AddServerViewModel(ProfileItem profileItem, Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view;
_updateView = updateView;
if (profileItem.id.IsNullOrEmpty())
{
@ -44,8 +40,6 @@ namespace v2rayN.ViewModels
{
SaveServer();
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
private void SaveServer()
@ -141,8 +135,7 @@ namespace v2rayN.ViewModels
if (ret == 0)
{
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true;
//_view?.Close();
_updateView?.Invoke(EViewAction.CloseWindow);
}
else
{

View File

@ -5,16 +5,15 @@ using ReactiveUI.Fody.Helpers;
using System.Reactive;
using System.Reactive.Linq;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
namespace v2rayN.ViewModels
{
public class ClashConnectionsViewModel : ReactiveObject
public class ClashConnectionsViewModel : MyReactiveObject
{
private static Config _config;
private IObservableCollection<ClashConnectionModel> _connectionItems = new ObservableCollectionExtended<ClashConnectionModel>();
public IObservableCollection<ClashConnectionModel> ConnectionItems => _connectionItems;

View File

@ -6,6 +6,7 @@ using Splat;
using System.Reactive;
using System.Reactive.Linq;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
@ -15,10 +16,8 @@ using static v2rayN.Models.ClashProxies;
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, ProvidersItem>? providers;
private int delayTimeout = 99999999;

View File

@ -2,7 +2,7 @@
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
@ -10,12 +10,8 @@ using v2rayN.Resx;
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 string domainStrategy4Freedom { 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> ImportDefConfig4SingboxCmd { get; }
public DNSSettingViewModel(Window view)
public DNSSettingViewModel(Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view;
_updateView = updateView;
var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray);
useSystemHosts = item.useSystemHosts;
@ -63,8 +59,6 @@ namespace v2rayN.ViewModels
normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName);
tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName);
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
private void SaveSetting()
@ -114,11 +108,11 @@ namespace v2rayN.ViewModels
item2.domainStrategy4Freedom = domainStrategy4Freedom2;
item2.domainDNSAddress = domainDNSAddress2;
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);
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true;
_updateView?.Invoke(EViewAction.CloseWindow);
}
}
}

View File

@ -11,6 +11,7 @@ using System.Reactive.Linq;
using System.Text;
using System.Windows;
using System.Windows.Media;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Handler.Statistics;
@ -20,14 +21,12 @@ using v2rayN.Views;
namespace v2rayN.ViewModels
{
public class MainWindowViewModel : ReactiveObject
public class MainWindowViewModel : MyReactiveObject
{
#region private prop
private CoreHandler _coreHandler;
private static Config _config;
private NoticeHandler? _noticeHandler;
private Action<EViewAction> _updateView;
private bool _showInTaskbar;
#endregion private prop
@ -171,15 +170,14 @@ namespace v2rayN.ViewModels
#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();
_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());
SelectedRouting = new();

View File

@ -2,7 +2,7 @@
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
@ -10,12 +10,8 @@ using v2rayN.Resx;
namespace v2rayN.ViewModels
{
public class OptionSettingViewModel : ReactiveObject
public class OptionSettingViewModel : MyReactiveObject
{
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
#region Core
[Reactive] public int localPort { get; set; }
@ -109,11 +105,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public OptionSettingViewModel(Window view)
public OptionSettingViewModel(Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view;
_updateView = updateView;
#region Core
@ -201,8 +197,6 @@ namespace v2rayN.ViewModels
{
SaveSetting();
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
private void InitCoreType()
@ -365,7 +359,7 @@ namespace v2rayN.ViewModels
{
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
}
_view.DialogResult = true;
_updateView?.Invoke(EViewAction.CloseWindow);
}
else
{

View File

@ -8,6 +8,7 @@ using System.Reactive;
using System.Reactive.Linq;
using System.Text;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Handler.Fmt;
@ -18,16 +19,14 @@ using v2rayN.Views;
namespace v2rayN.ViewModels
{
public class ProfilesViewModel : ReactiveObject
public class ProfilesViewModel : MyReactiveObject
{
#region private prop
private List<ProfileItem> _lstProfile;
private string _serverFilter = string.Empty;
private static Config _config;
private NoticeHandler? _noticeHandler;
private Dictionary<string, bool> _dicHeaderSort = new();
private Action<EViewAction> _updateView;
#endregion private prop
@ -103,12 +102,12 @@ namespace v2rayN.ViewModels
#region Init
public ProfilesViewModel(Action<EViewAction> updateView)
public ProfilesViewModel(Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_updateView = updateView;
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_config = LazyConfig.Instance.GetConfig();
MessageBus.Current.Listen<string>(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz());
SelectedProfile = new();
@ -507,8 +506,7 @@ namespace v2rayN.ViewModels
{
return;
}
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
{
return;
}

View File

@ -2,19 +2,16 @@
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx;
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> InboundTagItems { get; set; }
@ -35,11 +32,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public RoutingRuleDetailsViewModel(RulesItem rulesItem, Window view)
public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view;
_updateView = updateView;
if (rulesItem.id.IsNullOrEmpty())
{
@ -61,8 +58,6 @@ namespace v2rayN.ViewModels
{
SaveRules();
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
private void SaveRules()
@ -98,7 +93,7 @@ namespace v2rayN.ViewModels
return;
}
//_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true;
_updateView?.Invoke(EViewAction.CloseWindow);
}
}
}

View File

@ -3,7 +3,7 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
@ -13,11 +13,8 @@ using Application = System.Windows.Application;
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;
[Reactive]
@ -44,11 +41,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public RoutingRuleSettingViewModel(RoutingItem routingItem, Window view)
public RoutingRuleSettingViewModel(RoutingItem routingItem, Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view;
_updateView = updateView;
SelectedSource = new();
if (routingItem.id.IsNullOrEmpty())
@ -115,8 +112,6 @@ namespace v2rayN.ViewModels
{
SaveRouting();
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
public void RefreshRulesItems()
@ -174,7 +169,7 @@ namespace v2rayN.ViewModels
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
return;
}
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
{
return;
}
@ -254,7 +249,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.SaveRoutingItem(_config, item) == 0)
{
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true;
_updateView?.Invoke(EViewAction.CloseWindow);
}
else
{
@ -323,7 +318,7 @@ namespace v2rayN.ViewModels
private int AddBatchRoutingRules(RoutingItem routingItem, string? clipboardData)
{
bool blReplace = false;
if (UI.ShowYesNo(ResUI.AddBatchRoutingRulesYesNo) == MessageBoxResult.No)
if (_updateView?.Invoke(EViewAction.AddBatchRoutingRulesYesNo) == false)
{
blReplace = true;
}

View File

@ -3,7 +3,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx;
@ -11,11 +12,8 @@ using v2rayN.Views;
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 List<RulesItem> _lockedRules;
@ -73,11 +71,11 @@ namespace v2rayN.ViewModels
#endregion Reactive
public RoutingSettingViewModel(Window view)
public RoutingSettingViewModel(Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view;
_updateView = updateView;
SelectedSource = new();
ConfigHandler.InitBuiltinRouting(_config);
@ -125,8 +123,6 @@ namespace v2rayN.ViewModels
{
SaveRouting();
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
#region locked
@ -211,7 +207,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.SaveConfig(_config) == 0)
{
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true;
_updateView?.Invoke(EViewAction.CloseWindow);
}
else
{
@ -263,7 +259,7 @@ namespace v2rayN.ViewModels
_noticeHandler?.Enqueue(ResUI.PleaseSelectRules);
return;
}
if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No)
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
{
return;
}

View File

@ -2,29 +2,26 @@
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.ViewModels
{
public class SubEditViewModel : ReactiveObject
public class SubEditViewModel : MyReactiveObject
{
private static Config _config;
private NoticeHandler? _noticeHandler;
private Window _view;
[Reactive]
public SubItem SelectedSource { get; set; }
public ReactiveCommand<Unit, Unit> SaveCmd { get; }
public SubEditViewModel(SubItem subItem, Window view)
public SubEditViewModel(SubItem subItem, Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_view = view;
_updateView = updateView;
if (subItem.id.IsNullOrEmpty())
{
@ -39,8 +36,6 @@ namespace v2rayN.ViewModels
{
SaveSub();
});
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
private void SaveSub()
@ -75,8 +70,7 @@ namespace v2rayN.ViewModels
if (ConfigHandler.AddSubItem(_config, item) == 0)
{
_noticeHandler?.Enqueue(ResUI.OperationSuccess);
_view.DialogResult = true;
//_view?.Close();
_updateView?.Invoke(EViewAction.CloseWindow);
}
else
{

View File

@ -5,7 +5,8 @@ using ReactiveUI;
using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive;
using System.Windows;
using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx;
@ -13,11 +14,8 @@ using v2rayN.Views;
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>();
public IObservableCollection<SubItem> SubItems => _subItems;
@ -32,10 +30,11 @@ namespace v2rayN.ViewModels
public ReactiveCommand<Unit, Unit> SubShareCmd { get; }
public bool IsModified { get; set; }
public SubSettingViewModel(Window view)
public SubSettingViewModel(Func<EViewAction, bool>? updateView)
{
_config = LazyConfig.Instance.GetConfig();
_noticeHandler = Locator.Current.GetService<NoticeHandler>();
_updateView = updateView;
SelectedSource = new();
@ -61,8 +60,6 @@ namespace v2rayN.ViewModels
{
SubShare();
}, canEditRemove);
Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark);
}
public void RefreshSubItems()
@ -96,7 +93,7 @@ namespace v2rayN.ViewModels
private void DeleteSub()
{
if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No)
if (_updateView?.Invoke(EViewAction.ShowYesNo) == false)
{
return;
}

View File

@ -8,16 +8,14 @@ using ReactiveUI.Fody.Helpers;
using Splat;
using System.Reactive.Linq;
using System.Windows;
using v2rayN.Base;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx;
namespace v2rayN.ViewModels
{
public class ThemeSettingViewModel : ReactiveObject
public class ThemeSettingViewModel : MyReactiveObject
{
private static Config _config;
private NoticeHandler? _noticeHandler;
private readonly PaletteHelper _paletteHelper = new();
[Reactive]

View File

@ -2,6 +2,7 @@
using System.Reactive.Disposables;
using System.Windows;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.ViewModels;
@ -15,7 +16,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow;
this.Loaded += Window_Loaded;
ViewModel = new AddServer2ViewModel(profileItem, this);
ViewModel = new AddServer2ViewModel(profileItem, UpdateViewHandler);
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.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)

View File

@ -21,7 +21,7 @@ namespace v2rayN.Views
cmbNetwork.SelectionChanged += CmbNetwork_SelectionChanged;
cmbStreamSecurity.SelectionChanged += CmbStreamSecurity_SelectionChanged;
ViewModel = new AddServerViewModel(profileItem, this);
ViewModel = new AddServerViewModel(profileItem, UpdateViewHandler);
if (profileItem.configType == EConfigType.VLESS)
{
@ -224,6 +224,15 @@ namespace v2rayN.Views
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)
{
txtRemarks.Focus();

View File

@ -1,11 +1,11 @@
<reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashConnectionsView"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
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:vms="clr-namespace:v2rayN.ViewModels"
d:DesignHeight="450"

View File

@ -1,12 +1,12 @@
<reactiveui:ReactiveUserControl
x:Class="v2rayN.Views.ClashProxiesView"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
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:vms="clr-namespace:v2rayN.ViewModels"
d:DesignHeight="450"

View File

@ -1,6 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables;
using System.Windows;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.ViewModels;
@ -18,7 +19,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow;
_config = LazyConfig.Instance.GetConfig();
ViewModel = new DNSSettingViewModel(this);
ViewModel = new DNSSettingViewModel(UpdateViewHandler);
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)
{
Utils.ProcessStart("https://xtls.github.io/config/dns.html#dnsobject");

View File

@ -1,5 +1,4 @@
using MaterialDesignThemes.Wpf;
using ReactiveUI;
using ReactiveUI;
using Splat;
using System.ComponentModel;
using System.Reactive.Disposables;

View File

@ -23,7 +23,7 @@ namespace v2rayN.Views
_config = LazyConfig.Instance.GetConfig();
var lstFonts = GetFonts(Utils.GetFontsPath());
ViewModel = new OptionSettingViewModel(this);
ViewModel = new OptionSettingViewModel(UpdateViewHandler);
clbdestOverride.SelectionChanged += ClbdestOverride_SelectionChanged;
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)
{
var lstFonts = new List<string>();

View File

@ -10,6 +10,7 @@ using v2rayN.Base;
using v2rayN.Enums;
using v2rayN.Handler;
using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels;
using Point = System.Windows.Point;
@ -96,7 +97,7 @@ namespace v2rayN.Views
StorageUI();
}
private void UpdateViewHandler(EViewAction action)
private bool UpdateViewHandler(EViewAction action)
{
if (action == EViewAction.AdjustMainLvColWidth)
{
@ -109,6 +110,15 @@ namespace v2rayN.Views
{
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)

View File

@ -1,6 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables;
using System.Windows;
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.ViewModels;
@ -17,7 +18,7 @@ namespace v2rayN.Views
clbProtocol.SelectionChanged += ClbProtocol_SelectionChanged;
clbInboundTag.SelectionChanged += ClbInboundTag_SelectionChanged;
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, this);
ViewModel = new RoutingRuleDetailsViewModel(rulesItem, UpdateViewHandler);
cmbOutboundTag.Items.Add(Global.ProxyTag);
cmbOutboundTag.Items.Add(Global.DirectTag);
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)
{
cmbOutboundTag.Focus();

View File

@ -4,6 +4,7 @@ using System.Windows;
using System.Windows.Input;
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels;
namespace v2rayN.Views
@ -20,7 +21,7 @@ namespace v2rayN.Views
lstRules.SelectionChanged += lstRules_SelectionChanged;
lstRules.MouseDoubleClick += LstRules_MouseDoubleClick;
ViewModel = new RoutingRuleSettingViewModel(routingItem, this);
ViewModel = new RoutingRuleSettingViewModel(routingItem, UpdateViewHandler);
Global.DomainStrategies.ForEach(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)
{
txtRemarks.Focus();

View File

@ -2,7 +2,9 @@
using System.Reactive.Disposables;
using System.Windows;
using System.Windows.Input;
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels;
namespace v2rayN.Views
@ -19,7 +21,7 @@ namespace v2rayN.Views
lstRoutings.SelectionChanged += lstRoutings_SelectionChanged;
lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick;
ViewModel = new RoutingSettingViewModel(this);
ViewModel = new RoutingSettingViewModel(UpdateViewHandler);
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)
{
if (ViewModel?.IsModified == true)

View File

@ -1,6 +1,7 @@
using ReactiveUI;
using System.Reactive.Disposables;
using System.Windows;
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.ViewModels;
@ -15,7 +16,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow;
this.Loaded += Window_Loaded;
ViewModel = new SubEditViewModel(subItem, this);
ViewModel = new SubEditViewModel(subItem, UpdateViewHandler);
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)
{
txtRemarks.Focus();

View File

@ -3,7 +3,9 @@ using System.ComponentModel;
using System.Reactive.Disposables;
using System.Windows;
using System.Windows.Input;
using v2rayN.Enums;
using v2rayN.Models;
using v2rayN.Resx;
using v2rayN.ViewModels;
namespace v2rayN.Views
@ -16,7 +18,7 @@ namespace v2rayN.Views
this.Owner = Application.Current.MainWindow;
ViewModel = new SubSettingViewModel(this);
ViewModel = new SubSettingViewModel(UpdateViewHandler);
this.Closing += SubSettingWindow_Closing;
lstSubscription.MouseDoubleClick += LstSubscription_MouseDoubleClick;
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)
{
if (ViewModel?.IsModified == true)

View File

@ -94,4 +94,4 @@
Style="{StaticResource DefComboBox}" />
</Grid>
</StackPanel>
</reactiveui:ReactiveUserControl>
</reactiveui:ReactiveUserControl>

View File

@ -1,8 +1,5 @@
using ReactiveUI;
using Splat;
using System.Reactive.Disposables;
using System.Windows.Input;
using v2rayN.Handler;
using v2rayN.ViewModels;
namespace v2rayN.Views
@ -35,7 +32,7 @@ namespace v2rayN.Views
this.Bind(ViewModel, vm => vm.SelectedSwatch, v => v.cmbSwatches.SelectedItem).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentFontSize, v => v.cmbCurrentFontSize.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.CurrentLanguage, v => v.cmbCurrentLanguage.Text).DisposeWith(disposables);
});
});
}
}
}
}