From 8ff04dca0d8ebe0a651433bf6accc725fbb5dbae Mon Sep 17 00:00:00 2001 From: 2dust <31833384+2dust@users.noreply.github.com> Date: Sat, 10 Aug 2024 10:02:00 +0800 Subject: [PATCH] Refactor code to decouple view and viewmodel --- v2rayN/v2rayN/App.xaml | 2 +- v2rayN/v2rayN/Base/MyReactiveObject.cs | 14 ++++++++++ v2rayN/v2rayN/Enums/EViewAction.cs | 5 +++- v2rayN/v2rayN/Global.cs | 2 +- .../v2rayN/ViewModels/AddServer2ViewModel.cs | 19 +++++-------- .../v2rayN/ViewModels/AddServerViewModel.cs | 17 ++++-------- .../ViewModels/ClashConnectionsViewModel.cs | 5 ++-- .../ViewModels/ClashProxiesViewModel.cs | 5 ++-- .../v2rayN/ViewModels/DNSSettingViewModel.cs | 18 +++++-------- .../v2rayN/ViewModels/MainWindowViewModel.cs | 16 +++++------ .../ViewModels/OptionSettingViewModel.cs | 16 ++++------- v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs | 16 +++++------ .../ViewModels/RoutingRuleDetailsViewModel.cs | 17 +++++------- .../ViewModels/RoutingRuleSettingViewModel.cs | 19 +++++-------- .../ViewModels/RoutingSettingViewModel.cs | 18 +++++-------- v2rayN/v2rayN/ViewModels/SubEditViewModel.cs | 18 +++++-------- .../v2rayN/ViewModels/SubSettingViewModel.cs | 15 +++++------ .../ViewModels/ThemeSettingViewModel.cs | 6 ++--- v2rayN/v2rayN/Views/AddServer2Window.xaml.cs | 14 +++++++++- v2rayN/v2rayN/Views/AddServerWindow.xaml.cs | 11 +++++++- v2rayN/v2rayN/Views/ClashConnectionsView.xaml | 6 ++--- v2rayN/v2rayN/Views/ClashProxiesView.xaml | 8 +++--- v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs | 12 ++++++++- v2rayN/v2rayN/Views/MainWindow.xaml.cs | 3 +-- .../v2rayN/Views/OptionSettingWindow.xaml.cs | 11 +++++++- v2rayN/v2rayN/Views/ProfilesView.xaml.cs | 12 ++++++++- .../Views/RoutingRuleDetailsWindow.xaml.cs | 12 ++++++++- .../Views/RoutingRuleSettingWindow.xaml.cs | 27 ++++++++++++++++++- .../v2rayN/Views/RoutingSettingWindow.xaml.cs | 20 +++++++++++++- v2rayN/v2rayN/Views/SubEditWindow.xaml.cs | 12 ++++++++- v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs | 20 +++++++++++++- v2rayN/v2rayN/Views/ThemeSettingView.xaml | 2 +- v2rayN/v2rayN/Views/ThemeSettingView.xaml.cs | 7 ++--- 33 files changed, 246 insertions(+), 159 deletions(-) create mode 100644 v2rayN/v2rayN/Base/MyReactiveObject.cs diff --git a/v2rayN/v2rayN/App.xaml b/v2rayN/v2rayN/App.xaml index 04a602cb6fd..3b7aefeec9d 100644 --- a/v2rayN/v2rayN/App.xaml +++ b/v2rayN/v2rayN/App.xaml @@ -1,9 +1,9 @@  diff --git a/v2rayN/v2rayN/Base/MyReactiveObject.cs b/v2rayN/v2rayN/Base/MyReactiveObject.cs new file mode 100644 index 00000000000..0cd30b1c69d --- /dev/null +++ b/v2rayN/v2rayN/Base/MyReactiveObject.cs @@ -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? _updateView; + protected NoticeHandler? _noticeHandler; + } +} \ No newline at end of file diff --git a/v2rayN/v2rayN/Enums/EViewAction.cs b/v2rayN/v2rayN/Enums/EViewAction.cs index 8a5a4641e32..d7c3935821b 100644 --- a/v2rayN/v2rayN/Enums/EViewAction.cs +++ b/v2rayN/v2rayN/Enums/EViewAction.cs @@ -3,6 +3,9 @@ public enum EViewAction { AdjustMainLvColWidth, - ProfilesFocus + ProfilesFocus, + CloseWindow, + ShowYesNo, + AddBatchRoutingRulesYesNo, } } \ No newline at end of file diff --git a/v2rayN/v2rayN/Global.cs b/v2rayN/v2rayN/Global.cs index fb89927f541..ed548b81ff3 100644 --- a/v2rayN/v2rayN/Global.cs +++ b/v2rayN/v2rayN/Global.cs @@ -179,7 +179,7 @@ internal class Global public static readonly List DomainDNSAddress = ["223.5.5.5", "223.6.6.6", "localhost"]; public static readonly List SingboxDomainDNSAddress = ["223.5.5.5", "223.6.6.6", "dhcp://auto"]; public static readonly List Languages = new() { "zh-Hans", "zh-Hant", "en", "fa-Ir", "ru" }; - public static readonly List Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" }; + public static readonly List Alpns = new() { "h3", "h2", "http/1.1", "h3,h2", "h2,http/1.1", "h3,h2,http/1.1", "" }; public static readonly List LogLevels = new() { "debug", "info", "warning", "error", "none" }; public static readonly List InboundTags = new() { "socks", "http", "socks2", "http2" }; public static readonly List RuleProtocols = new() { "http", "tls", "bittorrent" }; diff --git a/v2rayN/v2rayN/ViewModels/AddServer2ViewModel.cs b/v2rayN/v2rayN/ViewModels/AddServer2ViewModel.cs index b2272749546..9a5c1ba3a98 100644 --- a/v2rayN/v2rayN/ViewModels/AddServer2ViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/AddServer2ViewModel.cs @@ -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 @@ public class AddServer2ViewModel : ReactiveValidationObject public ReactiveCommand SaveServerCmd { get; } public bool IsModified { get; set; } - public AddServer2ViewModel(ProfileItem profileItem, Window view) + public AddServer2ViewModel(ProfileItem profileItem, Func? updateView) { _noticeHandler = Locator.Current.GetService(); _config = LazyConfig.Instance.GetConfig(); + _updateView = updateView; if (profileItem.indexId.IsNullOrEmpty()) { @@ -39,8 +36,6 @@ public AddServer2ViewModel(ProfileItem profileItem, Window view) SelectedSource = JsonUtils.DeepCopy(profileItem); } - _view = view; - BrowseServerCmd = ReactiveCommand.Create(() => { BrowseServer(); @@ -55,8 +50,6 @@ public AddServer2ViewModel(ProfileItem profileItem, Window view) { SaveServer(); }); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } private void SaveServer() @@ -91,7 +84,7 @@ private void SaveServer() if (ConfigHandler.EditCustomServer(_config, item) == 0) { _noticeHandler?.Enqueue(ResUI.OperationSuccess); - _view.DialogResult = true; + _updateView?.Invoke(EViewAction.CloseWindow); } else { diff --git a/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs b/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs index 686f46a4291..e2170b7351f 100644 --- a/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/AddServerViewModel.cs @@ -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 @@ 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 SaveCmd { get; } - public AddServerViewModel(ProfileItem profileItem, Window view) + public AddServerViewModel(ProfileItem profileItem, Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); - _view = view; + _updateView = updateView; if (profileItem.id.IsNullOrEmpty()) { @@ -44,8 +40,6 @@ public AddServerViewModel(ProfileItem profileItem, Window view) { SaveServer(); }); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } private void SaveServer() @@ -141,8 +135,7 @@ private void SaveServer() if (ret == 0) { _noticeHandler?.Enqueue(ResUI.OperationSuccess); - _view.DialogResult = true; - //_view?.Close(); + _updateView?.Invoke(EViewAction.CloseWindow); } else { diff --git a/v2rayN/v2rayN/ViewModels/ClashConnectionsViewModel.cs b/v2rayN/v2rayN/ViewModels/ClashConnectionsViewModel.cs index ae6cd39859b..b71c41bd699 100644 --- a/v2rayN/v2rayN/ViewModels/ClashConnectionsViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/ClashConnectionsViewModel.cs @@ -5,16 +5,15 @@ 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 _connectionItems = new ObservableCollectionExtended(); public IObservableCollection ConnectionItems => _connectionItems; diff --git a/v2rayN/v2rayN/ViewModels/ClashProxiesViewModel.cs b/v2rayN/v2rayN/ViewModels/ClashProxiesViewModel.cs index 42242333b90..fb6f28a1ebd 100644 --- a/v2rayN/v2rayN/ViewModels/ClashProxiesViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/ClashProxiesViewModel.cs @@ -6,6 +6,7 @@ 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 @@ namespace v2rayN.ViewModels { - public class ClashProxiesViewModel : ReactiveObject + public class ClashProxiesViewModel : MyReactiveObject { - private static Config _config; - private NoticeHandler? _noticeHandler; private Dictionary? proxies; private Dictionary? providers; private int delayTimeout = 99999999; diff --git a/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs index ac42a508c2a..4fef5f06ebf 100644 --- a/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/DNSSettingViewModel.cs @@ -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 @@ 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 @@ public class DNSSettingViewModel : ReactiveObject public ReactiveCommand ImportDefConfig4V2rayCmd { get; } public ReactiveCommand ImportDefConfig4SingboxCmd { get; } - public DNSSettingViewModel(Window view) + public DNSSettingViewModel(Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); - _view = view; + _updateView = updateView; var item = LazyConfig.Instance.GetDNSItem(ECoreType.Xray); useSystemHosts = item.useSystemHosts; @@ -63,8 +59,6 @@ public DNSSettingViewModel(Window view) 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 @@ private void SaveSetting() 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); } } } \ No newline at end of file diff --git a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs index 9a4b18e3f2e..7cf7b708f0c 100644 --- a/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/MainWindowViewModel.cs @@ -11,6 +11,7 @@ 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 @@ 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 _updateView; + private bool _showInTaskbar; #endregion private prop @@ -171,15 +170,14 @@ public class MainWindowViewModel : ReactiveObject #region Init - public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Action updateView) + public MainWindowViewModel(ISnackbarMessageQueue snackbarMessageQueue, Func? updateView) { + _config = LazyConfig.Instance.GetConfig(); + _noticeHandler = Locator.Current.GetService(); _updateView = updateView; + ThreadPool.RegisterWaitForSingleObject(App.ProgramStarted, OnProgramStarted, null, -1, false); - - _noticeHandler = new NoticeHandler(snackbarMessageQueue); Locator.CurrentMutable.RegisterLazySingleton(() => _noticeHandler, typeof(NoticeHandler)); - _config = LazyConfig.Instance.GetConfig(); - MessageBus.Current.Listen(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz()); SelectedRouting = new(); diff --git a/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs index 95a9387c623..67331a0c851 100644 --- a/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/OptionSettingViewModel.cs @@ -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 @@ 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 @@ public class OptionSettingViewModel : ReactiveObject public ReactiveCommand SaveCmd { get; } - public OptionSettingViewModel(Window view) + public OptionSettingViewModel(Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); - _view = view; + _updateView = updateView; #region Core @@ -201,8 +197,6 @@ public OptionSettingViewModel(Window view) { SaveSetting(); }); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } private void InitCoreType() @@ -365,7 +359,7 @@ private void SaveSetting() { _noticeHandler?.Enqueue(ResUI.OperationSuccess); } - _view.DialogResult = true; + _updateView?.Invoke(EViewAction.CloseWindow); } else { diff --git a/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs b/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs index bfd5365c9c9..90232e9a05d 100644 --- a/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/ProfilesViewModel.cs @@ -8,6 +8,7 @@ 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 @@ namespace v2rayN.ViewModels { - public class ProfilesViewModel : ReactiveObject + public class ProfilesViewModel : MyReactiveObject { #region private prop private List _lstProfile; private string _serverFilter = string.Empty; - private static Config _config; - private NoticeHandler? _noticeHandler; + private Dictionary _dicHeaderSort = new(); - private Action _updateView; #endregion private prop @@ -103,12 +102,12 @@ public class ProfilesViewModel : ReactiveObject #region Init - public ProfilesViewModel(Action updateView) + public ProfilesViewModel(Func? updateView) { + _config = LazyConfig.Instance.GetConfig(); + _noticeHandler = Locator.Current.GetService(); _updateView = updateView; - _noticeHandler = Locator.Current.GetService(); - _config = LazyConfig.Instance.GetConfig(); MessageBus.Current.Listen(Global.CommandRefreshProfiles).Subscribe(x => RefreshServersBiz()); SelectedProfile = new(); @@ -507,8 +506,7 @@ public void RemoveServer() { return; } - - if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No) + if (_updateView?.Invoke(EViewAction.ShowYesNo) == false) { return; } diff --git a/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs b/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs index 9bafcb6ea43..469f1837960 100644 --- a/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/RoutingRuleDetailsViewModel.cs @@ -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 ProtocolItems { get; set; } public IList InboundTagItems { get; set; } @@ -35,11 +32,11 @@ public class RoutingRuleDetailsViewModel : ReactiveObject public ReactiveCommand SaveCmd { get; } - public RoutingRuleDetailsViewModel(RulesItem rulesItem, Window view) + public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); - _view = view; + _updateView = updateView; if (rulesItem.id.IsNullOrEmpty()) { @@ -61,8 +58,6 @@ public RoutingRuleDetailsViewModel(RulesItem rulesItem, Window view) { SaveRules(); }); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } private void SaveRules() @@ -98,7 +93,7 @@ private void SaveRules() return; } //_noticeHandler?.Enqueue(ResUI.OperationSuccess); - _view.DialogResult = true; + _updateView?.Invoke(EViewAction.CloseWindow); } } } \ No newline at end of file diff --git a/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs index 569de0f44bd..17a72433030 100644 --- a/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/RoutingRuleSettingViewModel.cs @@ -3,7 +3,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; @@ -13,11 +13,8 @@ namespace v2rayN.ViewModels { - public class RoutingRuleSettingViewModel : ReactiveObject + public class RoutingRuleSettingViewModel : MyReactiveObject { - private static Config _config; - private NoticeHandler? _noticeHandler; - private Window _view; private List _rules; [Reactive] @@ -44,11 +41,11 @@ public class RoutingRuleSettingViewModel : ReactiveObject public ReactiveCommand SaveCmd { get; } - public RoutingRuleSettingViewModel(RoutingItem routingItem, Window view) + public RoutingRuleSettingViewModel(RoutingItem routingItem, Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); - _view = view; + _updateView = updateView; SelectedSource = new(); if (routingItem.id.IsNullOrEmpty()) @@ -115,8 +112,6 @@ public RoutingRuleSettingViewModel(RoutingItem routingItem, Window view) { SaveRouting(); }); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } public void RefreshRulesItems() @@ -174,7 +169,7 @@ public void RuleRemove() _noticeHandler?.Enqueue(ResUI.PleaseSelectRules); return; } - if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No) + if (_updateView?.Invoke(EViewAction.ShowYesNo) == false) { return; } @@ -254,7 +249,7 @@ private void SaveRouting() if (ConfigHandler.SaveRoutingItem(_config, item) == 0) { _noticeHandler?.Enqueue(ResUI.OperationSuccess); - _view.DialogResult = true; + _updateView?.Invoke(EViewAction.CloseWindow); } else { @@ -323,7 +318,7 @@ private async Task ImportRulesFromUrl() 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; } diff --git a/v2rayN/v2rayN/ViewModels/RoutingSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/RoutingSettingViewModel.cs index 334869be01e..8dffbda8388 100644 --- a/v2rayN/v2rayN/ViewModels/RoutingSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/RoutingSettingViewModel.cs @@ -3,7 +3,8 @@ 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 @@ 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 _lockedRules; @@ -73,11 +71,11 @@ public class RoutingSettingViewModel : ReactiveObject #endregion Reactive - public RoutingSettingViewModel(Window view) + public RoutingSettingViewModel(Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); - _view = view; + _updateView = updateView; SelectedSource = new(); ConfigHandler.InitBuiltinRouting(_config); @@ -125,8 +123,6 @@ public RoutingSettingViewModel(Window view) { SaveRouting(); }); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } #region locked @@ -211,7 +207,7 @@ private void SaveRouting() if (ConfigHandler.SaveConfig(_config) == 0) { _noticeHandler?.Enqueue(ResUI.OperationSuccess); - _view.DialogResult = true; + _updateView?.Invoke(EViewAction.CloseWindow); } else { @@ -263,7 +259,7 @@ public void RoutingAdvancedRemove() _noticeHandler?.Enqueue(ResUI.PleaseSelectRules); return; } - if (UI.ShowYesNo(ResUI.RemoveRules) == MessageBoxResult.No) + if (_updateView?.Invoke(EViewAction.ShowYesNo) == false) { return; } diff --git a/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs b/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs index 84d02cdec57..659ba07c99f 100644 --- a/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/SubEditViewModel.cs @@ -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 SaveCmd { get; } - public SubEditViewModel(SubItem subItem, Window view) + public SubEditViewModel(SubItem subItem, Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); - _view = view; + _updateView = updateView; if (subItem.id.IsNullOrEmpty()) { @@ -39,8 +36,6 @@ public SubEditViewModel(SubItem subItem, Window view) { SaveSub(); }); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } private void SaveSub() @@ -75,8 +70,7 @@ private void SaveSub() if (ConfigHandler.AddSubItem(_config, item) == 0) { _noticeHandler?.Enqueue(ResUI.OperationSuccess); - _view.DialogResult = true; - //_view?.Close(); + _updateView?.Invoke(EViewAction.CloseWindow); } else { diff --git a/v2rayN/v2rayN/ViewModels/SubSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/SubSettingViewModel.cs index ab57773fb74..1e4c2d61443 100644 --- a/v2rayN/v2rayN/ViewModels/SubSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/SubSettingViewModel.cs @@ -5,7 +5,8 @@ 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 @@ namespace v2rayN.ViewModels { - public class SubSettingViewModel : ReactiveObject + public class SubSettingViewModel : MyReactiveObject { - private static Config _config; - private NoticeHandler? _noticeHandler; - private IObservableCollection _subItems = new ObservableCollectionExtended(); public IObservableCollection SubItems => _subItems; @@ -32,10 +30,11 @@ public class SubSettingViewModel : ReactiveObject public ReactiveCommand SubShareCmd { get; } public bool IsModified { get; set; } - public SubSettingViewModel(Window view) + public SubSettingViewModel(Func? updateView) { _config = LazyConfig.Instance.GetConfig(); _noticeHandler = Locator.Current.GetService(); + _updateView = updateView; SelectedSource = new(); @@ -61,8 +60,6 @@ public SubSettingViewModel(Window view) { SubShare(); }, canEditRemove); - - Utils.SetDarkBorder(view, _config.uiItem.followSystemTheme ? !Utils.IsLightTheme() : _config.uiItem.colorModeDark); } public void RefreshSubItems() @@ -96,7 +93,7 @@ public void EditSub(bool blNew) private void DeleteSub() { - if (UI.ShowYesNo(ResUI.RemoveServer) == MessageBoxResult.No) + if (_updateView?.Invoke(EViewAction.ShowYesNo) == false) { return; } diff --git a/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs b/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs index aa4fed23c26..8070a86ae9b 100644 --- a/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs +++ b/v2rayN/v2rayN/ViewModels/ThemeSettingViewModel.cs @@ -8,16 +8,14 @@ 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] diff --git a/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs b/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs index ae03d27488f..acd0a73b0e2 100644 --- a/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs +++ b/v2rayN/v2rayN/Views/AddServer2Window.xaml.cs @@ -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 @@ public AddServer2Window(ProfileItem profileItem) 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 @@ public AddServer2Window(ProfileItem profileItem) 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) diff --git a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs index a5503e02704..54967fa2d1a 100644 --- a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs @@ -21,7 +21,7 @@ public AddServerWindow(ProfileItem profileItem) 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 @@ public AddServerWindow(ProfileItem profileItem) 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(); diff --git a/v2rayN/v2rayN/Views/ClashConnectionsView.xaml b/v2rayN/v2rayN/Views/ClashConnectionsView.xaml index 6f220850145..acf760fe070 100644 --- a/v2rayN/v2rayN/Views/ClashConnectionsView.xaml +++ b/v2rayN/v2rayN/Views/ClashConnectionsView.xaml @@ -1,11 +1,11 @@ { @@ -55,6 +56,15 @@ public DNSSettingWindow() }); } + 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"); diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayN/v2rayN/Views/MainWindow.xaml.cs index bacf22058ff..28e99ba2572 100644 --- a/v2rayN/v2rayN/Views/MainWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/MainWindow.xaml.cs @@ -1,5 +1,4 @@ -using MaterialDesignThemes.Wpf; -using ReactiveUI; +using ReactiveUI; using Splat; using System.ComponentModel; using System.Reactive.Disposables; diff --git a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs index 341dbaaba80..c66397ae66c 100644 --- a/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/OptionSettingWindow.xaml.cs @@ -23,7 +23,7 @@ public OptionSettingWindow() _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 @@ public OptionSettingWindow() }); } + private bool UpdateViewHandler(EViewAction action) + { + if (action == EViewAction.CloseWindow) + { + this.DialogResult = true; + } + return true; + } + private List GetFonts(string path) { var lstFonts = new List(); diff --git a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs index e1637e1c0ba..5e3988b6270 100644 --- a/v2rayN/v2rayN/Views/ProfilesView.xaml.cs +++ b/v2rayN/v2rayN/Views/ProfilesView.xaml.cs @@ -10,6 +10,7 @@ using v2rayN.Enums; using v2rayN.Handler; using v2rayN.Models; +using v2rayN.Resx; using v2rayN.ViewModels; using Point = System.Windows.Point; @@ -96,7 +97,7 @@ private void Current_Exit(object sender, ExitEventArgs e) StorageUI(); } - private void UpdateViewHandler(EViewAction action) + private bool UpdateViewHandler(EViewAction action) { if (action == EViewAction.AdjustMainLvColWidth) { @@ -109,6 +110,15 @@ private void UpdateViewHandler(EViewAction action) { 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) diff --git a/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml.cs b/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml.cs index afc6a55fe3b..8559b3cd923 100644 --- a/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/RoutingRuleDetailsWindow.xaml.cs @@ -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 @@ public RoutingRuleDetailsWindow(RulesItem rulesItem) 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 @@ public RoutingRuleDetailsWindow(RulesItem rulesItem) }); } + private bool UpdateViewHandler(EViewAction action) + { + if (action == EViewAction.CloseWindow) + { + this.DialogResult = true; + } + return true; + } + private void Window_Loaded(object sender, RoutedEventArgs e) { cmbOutboundTag.Focus(); diff --git a/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml.cs index a7f55e21cfe..471699fad99 100644 --- a/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/RoutingRuleSettingWindow.xaml.cs @@ -4,6 +4,7 @@ using System.Windows.Input; using v2rayN.Enums; using v2rayN.Models; +using v2rayN.Resx; using v2rayN.ViewModels; namespace v2rayN.Views @@ -20,7 +21,7 @@ public RoutingRuleSettingWindow(RoutingItem routingItem) 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 @@ public RoutingRuleSettingWindow(RoutingItem routingItem) }); } + 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(); diff --git a/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs index 829000e9c23..537e1fab42a 100644 --- a/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/RoutingSettingWindow.xaml.cs @@ -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 @@ public RoutingSettingWindow() lstRoutings.SelectionChanged += lstRoutings_SelectionChanged; lstRoutings.MouseDoubleClick += LstRoutings_MouseDoubleClick; - ViewModel = new RoutingSettingViewModel(this); + ViewModel = new RoutingSettingViewModel(UpdateViewHandler); Global.DomainStrategies.ForEach(it => { @@ -68,6 +70,22 @@ public RoutingSettingWindow() }); } + 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) diff --git a/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs b/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs index 16b9baf4594..fc570a668ea 100644 --- a/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/SubEditWindow.xaml.cs @@ -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 @@ public SubEditWindow(SubItem subItem) 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 @@ public SubEditWindow(SubItem subItem) }); } + private bool UpdateViewHandler(EViewAction action) + { + if (action == EViewAction.CloseWindow) + { + this.DialogResult = true; + } + return true; + } + private void Window_Loaded(object sender, RoutedEventArgs e) { txtRemarks.Focus(); diff --git a/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs index ee7137da789..73d26896b5c 100644 --- a/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/SubSettingWindow.xaml.cs @@ -3,7 +3,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 @@ -16,7 +18,7 @@ public SubSettingWindow() 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 @@ public SubSettingWindow() }); } + 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) diff --git a/v2rayN/v2rayN/Views/ThemeSettingView.xaml b/v2rayN/v2rayN/Views/ThemeSettingView.xaml index 21d2ebf2baf..a274268afe9 100644 --- a/v2rayN/v2rayN/Views/ThemeSettingView.xaml +++ b/v2rayN/v2rayN/Views/ThemeSettingView.xaml @@ -94,4 +94,4 @@ Style="{StaticResource DefComboBox}" /> - + \ No newline at end of file diff --git a/v2rayN/v2rayN/Views/ThemeSettingView.xaml.cs b/v2rayN/v2rayN/Views/ThemeSettingView.xaml.cs index e2c2636d4b7..02f8c009684 100644 --- a/v2rayN/v2rayN/Views/ThemeSettingView.xaml.cs +++ b/v2rayN/v2rayN/Views/ThemeSettingView.xaml.cs @@ -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 @@ public ThemeSettingView() 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); - }); + }); } } -} +} \ No newline at end of file