diff --git a/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs b/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs index 25240f0e21e..63ac0ce8bc7 100644 --- a/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/AddServer2ViewModel.cs @@ -22,30 +22,21 @@ public AddServer2ViewModel(ProfileItem profileItem, Func { _updateView?.Invoke(EViewAction.BrowseServer, null); }); - EditServerCmd = ReactiveCommand.CreateFromTask(async () => { await EditServer(); }); - SaveServerCmd = ReactiveCommand.CreateFromTask(async () => { await SaveServerAsync(); }); + + SelectedSource = profileItem.indexId.IsNullOrEmpty() ? profileItem : JsonUtils.DeepCopy(profileItem); + CoreType = SelectedSource?.coreType?.ToString(); } private async Task SaveServerAsync() diff --git a/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs b/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs index 5bff42feeb1..8ac3ebb6005 100644 --- a/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs @@ -17,9 +17,13 @@ public class AddServerViewModel : MyReactiveObject public AddServerViewModel(ProfileItem profileItem, Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; + SaveCmd = ReactiveCommand.CreateFromTask(async () => + { + await SaveServerAsync(); + }); + if (profileItem.indexId.IsNullOrEmpty()) { profileItem.network = Global.DefaultNetwork; @@ -33,11 +37,6 @@ public AddServerViewModel(ProfileItem profileItem, Func - { - await SaveServerAsync(); - }); } private async Task SaveServerAsync() diff --git a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs index 2712cb3dbe4..ddb808c650b 100644 --- a/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/BackupAndRestoreViewModel.cs @@ -29,7 +29,6 @@ public BackupAndRestoreViewModel(Func>? updateV { await WebDavCheck(); }); - RemoteBackupCmd = ReactiveCommand.CreateFromTask(async () => { await RemoteBackup(); diff --git a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs index b314c79bea6..13249f85dcf 100644 --- a/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/CheckUpdateViewModel.cs @@ -17,31 +17,25 @@ public class CheckUpdateViewModel : MyReactiveObject public IObservableCollection CheckUpdateItems => _checkUpdateItem; public ReactiveCommand CheckUpdateCmd { get; } [Reactive] public bool EnableCheckPreReleaseUpdate { get; set; } - [Reactive] public bool IsCheckUpdate { get; set; } - [Reactive] public bool AutoRun { get; set; } public CheckUpdateViewModel(Func>? updateView) { _config = AppHandler.Instance.Config; _updateView = updateView; - RefreshSubItems(); - CheckUpdateCmd = ReactiveCommand.CreateFromTask(async () => { - await CheckUpdate() - .ContinueWith(t => - { - _ = UpdateFinished(); - }); + await CheckUpdate(); }); + EnableCheckPreReleaseUpdate = _config.guiItem.checkPreReleaseUpdate; - IsCheckUpdate = true; this.WhenAnyValue( x => x.EnableCheckPreReleaseUpdate, y => y == true) .Subscribe(c => { _config.guiItem.checkPreReleaseUpdate = EnableCheckPreReleaseUpdate; }); + + RefreshSubItems(); } private void RefreshSubItems() @@ -86,31 +80,31 @@ private async Task CheckUpdate() _lstUpdated = _checkUpdateItem.Where(x => x.IsSelected == true) .Select(x => new CheckUpdateItem() { CoreType = x.CoreType }).ToList(); - for (int k = _checkUpdateItem.Count - 1; k >= 0; k--) + for (var k = _checkUpdateItem.Count - 1; k >= 0; k--) { var item = _checkUpdateItem[k]; - if (item.IsSelected == true) + if (item.IsSelected != true) continue; + + UpdateView(item.CoreType, "..."); + if (item.CoreType == _geo) { - IsCheckUpdate = false; - UpdateView(item.CoreType, "..."); - if (item.CoreType == _geo) - { - await CheckUpdateGeo(); - } - else if (item.CoreType == _v2rayN) - { - await CheckUpdateN(EnableCheckPreReleaseUpdate); - } - else if (item.CoreType == ECoreType.mihomo.ToString()) - { - await CheckUpdateCore(item, false); - } - else - { - await CheckUpdateCore(item, EnableCheckPreReleaseUpdate); - } + await CheckUpdateGeo(); + } + else if (item.CoreType == _v2rayN) + { + await CheckUpdateN(EnableCheckPreReleaseUpdate); + } + else if (item.CoreType == ECoreType.mihomo.ToString()) + { + await CheckUpdateCore(item, false); + } + else + { + await CheckUpdateCore(item, EnableCheckPreReleaseUpdate); } } + + await UpdateFinished(); } private void UpdatedPlusPlus(string coreType, string fileName) @@ -204,7 +198,6 @@ public void UpdateFinishedResult(bool blReload) { if (blReload) { - IsCheckUpdate = true; Locator.Current.GetService()?.Reload(); } else diff --git a/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs b/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs index 325871f5b68..14f91385d06 100644 --- a/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ClashConnectionsViewModel.cs @@ -10,7 +10,6 @@ namespace ServiceLib.ViewModels public class ClashConnectionsViewModel : MyReactiveObject { private IObservableCollection _connectionItems = new ObservableCollectionExtended(); - public IObservableCollection ConnectionItems => _connectionItems; [Reactive] @@ -42,13 +41,12 @@ public ClashConnectionsViewModel(Func>? updateV this.WhenAnyValue( x => x.SortingSelected, y => y >= 0) - .Subscribe(c => DoSortingSelected(c)); + .Subscribe(async c => await DoSortingSelected(c)); this.WhenAnyValue( x => x.AutoRefresh, y => y == true) .Subscribe(c => { _config.clashUIItem.connectionsAutoRefresh = AutoRefresh; }); - ConnectionCloseCmd = ReactiveCommand.CreateFromTask(async () => { await ClashConnectionClose(false); @@ -62,26 +60,12 @@ public ClashConnectionsViewModel(Func>? updateV Init(); } - private void DoSortingSelected(bool c) - { - if (!c) - { - return; - } - if (SortingSelected != _config.clashUIItem.connectionsSorting) - { - _config.clashUIItem.connectionsSorting = SortingSelected; - } - - GetClashConnections(); - } - - private void Init() + private async Task Init() { var lastTime = DateTime.Now; Observable.Interval(TimeSpan.FromSeconds(5)) - .Subscribe(x => + .Subscribe(async x => { if (!(AutoRefresh && _config.uiItem.showInTaskbar && _config.IsRunningCore(ECoreType.sing_box))) { @@ -92,7 +76,7 @@ private void Init() { if ((dtNow - lastTime).Minutes % _config.clashUIItem.connectionsRefreshInterval == 0) { - GetClashConnections(); + await GetClashConnections(); lastTime = dtNow; } Task.Delay(1000).Wait(); @@ -100,6 +84,20 @@ private void Init() }); } + private async Task DoSortingSelected(bool c) + { + if (!c) + { + return; + } + if (SortingSelected != _config.clashUIItem.connectionsSorting) + { + _config.clashUIItem.connectionsSorting = SortingSelected; + } + + await GetClashConnections(); + } + private async Task GetClashConnections() { var ret = await ClashApiHandler.Instance.GetClashConnectionsAsync(_config); diff --git a/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs index 74e512577d8..5fea4792c54 100644 --- a/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ClashProxiesViewModel.cs @@ -46,9 +46,26 @@ public ClashProxiesViewModel(Func>? updateView) _config = AppHandler.Instance.Config; _updateView = updateView; + ProxiesReloadCmd = ReactiveCommand.CreateFromTask(async () => + { + await ProxiesReload(); + }); + ProxiesDelaytestCmd = ReactiveCommand.CreateFromTask(async () => + { + await ProxiesDelayTest(true); + }); + + ProxiesDelaytestPartCmd = ReactiveCommand.CreateFromTask(async () => + { + await ProxiesDelayTest(false); + }); + ProxiesSelectActivityCmd = ReactiveCommand.CreateFromTask(async () => + { + await SetActiveProxy(); + }); + SelectedGroup = new(); SelectedDetail = new(); - AutoRefresh = _config.clashUIItem.proxiesAutoRefresh; SortingSelected = _config.clashUIItem.proxiesSorting; RuleModeSelected = (int)_config.clashUIItem.ruleMode; @@ -61,7 +78,7 @@ public ClashProxiesViewModel(Func>? updateView) this.WhenAnyValue( x => x.RuleModeSelected, y => y >= 0) - .Subscribe(c => DoRulemodeSelected(c)); + .Subscribe(async c => await DoRulemodeSelected(c)); this.WhenAnyValue( x => x.SortingSelected, @@ -73,29 +90,16 @@ public ClashProxiesViewModel(Func>? updateView) y => y == true) .Subscribe(c => { _config.clashUIItem.proxiesAutoRefresh = AutoRefresh; }); - ProxiesReloadCmd = ReactiveCommand.CreateFromTask(async () => - { - await ProxiesReload(); - }); - ProxiesDelaytestCmd = ReactiveCommand.CreateFromTask(async () => - { - await ProxiesDelayTest(true); - }); - - ProxiesDelaytestPartCmd = ReactiveCommand.CreateFromTask(async () => - { - await ProxiesDelayTest(false); - }); - ProxiesSelectActivityCmd = ReactiveCommand.CreateFromTask(async () => - { - await SetActiveProxy(); - }); + Init(); + } - ProxiesReload(); - DelayTestTask(); + private async Task Init() + { + await ProxiesReload(); + await DelayTestTask(); } - private void DoRulemodeSelected(bool c) + private async Task DoRulemodeSelected(bool c) { if (!c) { @@ -105,16 +109,16 @@ private void DoRulemodeSelected(bool c) { return; } - SetRuleModeCheck((ERuleMode)RuleModeSelected); + await SetRuleModeCheck((ERuleMode)RuleModeSelected); } - public void SetRuleModeCheck(ERuleMode mode) + public async Task SetRuleModeCheck(ERuleMode mode) { if (_config.clashUIItem.ruleMode == mode) { return; } - SetRuleMode(mode); + await SetRuleMode(mode); } private void DoSortingSelected(bool c) @@ -385,7 +389,7 @@ private async Task ProxiesDelayTest(bool blAll) { if (item == null) { - GetClashProxies(true); + await GetClashProxies(true); return; } if (Utils.IsNullOrEmpty(result)) @@ -427,7 +431,7 @@ public void ProxiesDelayTestResult(SpeedTestResult result) #region task - public void DelayTestTask() + public async Task DelayTestTask() { var lastTime = DateTime.Now; diff --git a/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs index 7806f6a3048..f7fcf848b77 100644 --- a/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs @@ -23,21 +23,7 @@ public class DNSSettingViewModel : MyReactiveObject public DNSSettingViewModel(Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; - - var item = AppHandler.Instance.GetDNSItem(ECoreType.Xray).Result; - useSystemHosts = item.useSystemHosts; - domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty; - domainDNSAddress = item?.domainDNSAddress ?? string.Empty; - normalDNS = item?.normalDNS ?? string.Empty; - - var item2 = AppHandler.Instance.GetDNSItem(ECoreType.sing_box).Result; - domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty; - domainDNSAddress2 = item2?.domainDNSAddress ?? string.Empty; - normalDNS2 = item2?.normalDNS ?? string.Empty; - tunDNS2 = item2?.tunDNS ?? string.Empty; - SaveCmd = ReactiveCommand.CreateFromTask(async () => { await SaveSettingAsync(); @@ -53,6 +39,23 @@ public DNSSettingViewModel(Func>? updateView) normalDNS2 = Utils.GetEmbedText(Global.DNSSingboxNormalFileName); tunDNS2 = Utils.GetEmbedText(Global.TunSingboxDNSFileName); }); + + Init(); + } + + private async Task Init() + { + var item = await AppHandler.Instance.GetDNSItem(ECoreType.Xray); + useSystemHosts = item.useSystemHosts; + domainStrategy4Freedom = item?.domainStrategy4Freedom ?? string.Empty; + domainDNSAddress = item?.domainDNSAddress ?? string.Empty; + normalDNS = item?.normalDNS ?? string.Empty; + + var item2 = await AppHandler.Instance.GetDNSItem(ECoreType.sing_box); + domainStrategy4Freedom2 = item2?.domainStrategy4Freedom ?? string.Empty; + domainDNSAddress2 = item2?.domainDNSAddress ?? string.Empty; + normalDNS2 = item2?.normalDNS ?? string.Empty; + tunDNS2 = item2?.tunDNS ?? string.Empty; } private async Task SaveSettingAsync() diff --git a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs index 428ecf1e94e..4110070e110 100644 --- a/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/MainWindowViewModel.cs @@ -70,10 +70,6 @@ public MainWindowViewModel(Func>? updateView) _config = AppHandler.Instance.Config; _updateView = updateView; - Init(); - - _config.uiItem.showInTaskbar = true; - #region WhenAnyValue && ReactiveCommand //servers @@ -203,11 +199,13 @@ public MainWindowViewModel(Func>? updateView) #endregion WhenAnyValue && ReactiveCommand - AutoHideStartup(); + Init(); } private async Task Init() { + _config.uiItem.showInTaskbar = true; + await ConfigHandler.InitBuiltinRouting(_config); await ConfigHandler.InitBuiltinDNS(_config); CoreHandler.Instance.Init(_config, UpdateHandler); @@ -219,6 +217,7 @@ private async Task Init() } await Reload(); + await AutoHideStartup(); } #endregion Init @@ -571,16 +570,11 @@ public async Task CloseCore() CoreHandler.Instance.CoreStop(); } - private void AutoHideStartup() + private async Task AutoHideStartup() { if (_config.uiItem.autoHideStartup) { - Observable.Range(1, 1) - .Delay(TimeSpan.FromSeconds(1)) - .Subscribe(async x => - { - ShowHideWindow(false); - }); + ShowHideWindow(false); } } diff --git a/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs b/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs index 1c9b5ce597d..5ddec596cfd 100644 --- a/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/MsgViewModel.cs @@ -23,9 +23,6 @@ public MsgViewModel(Func>? updateView) { _config = AppHandler.Instance.Config; _updateView = updateView; - - MessageBus.Current.Listen(EMsgCommand.SendMsgView.ToString()).Subscribe(async x => await AppendQueueMsg(x)); - MsgFilter = _config.msgUIItem.mainMsgFilter ?? string.Empty; AutoRefresh = _config.msgUIItem.autoRefresh ?? true; @@ -37,6 +34,13 @@ public MsgViewModel(Func>? updateView) x => x.AutoRefresh, y => y == true) .Subscribe(c => { _config.msgUIItem.autoRefresh = AutoRefresh; }); + + MessageBus.Current.Listen(EMsgCommand.SendMsgView.ToString()).Subscribe(OnNext); + } + + private async void OnNext(string x) + { + await AppendQueueMsg(x); } private async Task AppendQueueMsg(string msg) diff --git a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs index d00d797d0ae..012caa06403 100644 --- a/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/OptionSettingViewModel.cs @@ -105,9 +105,18 @@ public class OptionSettingViewModel : MyReactiveObject public OptionSettingViewModel(Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; + SaveCmd = ReactiveCommand.CreateFromTask(async () => + { + await SaveSettingAsync(); + }); + + Init(); + } + + private async Task Init() + { #region Core var inbound = _config.inbound[0]; @@ -191,15 +200,10 @@ public OptionSettingViewModel(Func>? updateView #endregion Tun mode - InitCoreType(); - - SaveCmd = ReactiveCommand.CreateFromTask(async () => - { - await SaveSettingAsync(); - }); + await InitCoreType(); } - private void InitCoreType() + private async Task InitCoreType() { if (_config.coreTypeItem == null) { @@ -339,7 +343,7 @@ private async Task SaveSettingAsync() _config.tunModeItem.enableIPv6Address = TunEnableIPv6Address; //coreType - SaveCoreType(); + await SaveCoreType(); if (await ConfigHandler.SaveConfig(_config) == 0) { @@ -359,7 +363,7 @@ private async Task SaveSettingAsync() } } - private int SaveCoreType() + private async Task SaveCoreType() { for (int k = 1; k <= _config.coreTypeItem.Count; k++) { @@ -396,7 +400,6 @@ private int SaveCoreType() } item.coreType = (ECoreType)Enum.Parse(typeof(ECoreType), type); } - return 0; } } } \ No newline at end of file diff --git a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs index d25ff4f6f72..065da8d0558 100644 --- a/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/ProfilesViewModel.cs @@ -99,20 +99,6 @@ public ProfilesViewModel(Func>? updateView) _config = AppHandler.Instance.Config; _updateView = updateView; - if (_updateView != null) - { - MessageBus.Current.Listen(EMsgCommand.RefreshProfiles.ToString()) - .Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null)); - } - - SelectedProfile = new(); - SelectedSub = new(); - SelectedMoveToGroup = new(); - SelectedServer = new(); - - RefreshSubscriptions(); - RefreshServers(); - #region WhenAnyValue && ReactiveCommand var canEditRemove = this.WhenAnyValue( @@ -122,16 +108,16 @@ public ProfilesViewModel(Func>? updateView) this.WhenAnyValue( x => x.SelectedSub, y => y != null && !y.remarks.IsNullOrEmpty() && _config.subIndexId != y.id) - .Subscribe(c => SubSelectedChangedAsync(c)); + .Subscribe(async c => await SubSelectedChangedAsync(c)); this.WhenAnyValue( x => x.SelectedMoveToGroup, y => y != null && !y.remarks.IsNullOrEmpty()) - .Subscribe(c => MoveToGroup(c)); + .Subscribe(async c => await MoveToGroup(c)); this.WhenAnyValue( x => x.SelectedServer, y => y != null && !y.Text.IsNullOrEmpty()) - .Subscribe(c => ServerSelectedChanged(c)); + .Subscribe(async c => await ServerSelectedChanged(c)); this.WhenAnyValue( x => x.ServerFilter, @@ -240,12 +226,35 @@ public ProfilesViewModel(Func>? updateView) }); #endregion WhenAnyValue && ReactiveCommand + + if (_updateView != null) + { + MessageBus.Current.Listen(EMsgCommand.RefreshProfiles.ToString()).Subscribe(OnNext); + } + + Init(); + } + + private async Task Init() + { + SelectedProfile = new(); + SelectedSub = new(); + SelectedMoveToGroup = new(); + SelectedServer = new(); + + await RefreshSubscriptions(); + RefreshServers(); } #endregion Init #region Actions + private async void OnNext(string x) + { + await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null); + } + private void Reload() { Locator.Current.GetService()?.Reload(); @@ -534,7 +543,7 @@ public async Task SetDefaultServer(string indexId) } } - private void ServerSelectedChanged(bool c) + private async Task ServerSelectedChanged(bool c) { if (!c) { @@ -548,7 +557,7 @@ private void ServerSelectedChanged(bool c) { return; } - SetDefaultServer(SelectedServer.ID); + await SetDefaultServer(SelectedServer.ID); } public async Task ShareServerAsync() diff --git a/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs b/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs index 1a2419dfea3..91fdbdc5abd 100644 --- a/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/RoutingRuleDetailsViewModel.cs @@ -29,9 +29,13 @@ public class RoutingRuleDetailsViewModel : MyReactiveObject public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; + SaveCmd = ReactiveCommand.CreateFromTask(async () => + { + await SaveRulesAsync(); + }); + if (rulesItem.id.IsNullOrEmpty()) { rulesItem.id = Utils.GetGuid(false); @@ -47,11 +51,6 @@ public RoutingRuleDetailsViewModel(RulesItem rulesItem, Func - { - await SaveRulesAsync(); - }); } private async Task SaveRulesAsync() diff --git a/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs index 5e22091cb66..91f90ec2428 100644 --- a/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/RoutingRuleSettingViewModel.cs @@ -36,26 +36,11 @@ public class RoutingRuleSettingViewModel : MyReactiveObject public RoutingRuleSettingViewModel(RoutingItem routingItem, Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; - SelectedSource = new(); - - if (routingItem.id.IsNullOrEmpty()) - { - SelectedRouting = routingItem; - _rules = new(); - } - else - { - SelectedRouting = routingItem; - _rules = JsonUtils.Deserialize>(SelectedRouting.ruleSet); - } - - RefreshRulesItems(); var canEditRemove = this.WhenAnyValue( - x => x.SelectedSource, - selectedSource => selectedSource != null && !selectedSource.outboundTag.IsNullOrEmpty()); + x => x.SelectedSource, + selectedSource => selectedSource != null && !selectedSource.outboundTag.IsNullOrEmpty()); RuleAddCmd = ReactiveCommand.CreateFromTask(async () => { @@ -104,6 +89,12 @@ public RoutingRuleSettingViewModel(RoutingItem routingItem, Func>(SelectedRouting.ruleSet); + + RefreshRulesItems(); } public void RefreshRulesItems() diff --git a/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs index 46b58feeeed..89e223961d5 100644 --- a/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/RoutingSettingViewModel.cs @@ -67,27 +67,14 @@ public class RoutingSettingViewModel : MyReactiveObject public RoutingSettingViewModel(Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; - SelectedSource = new(); - - ConfigHandler.InitBuiltinRouting(_config); - - enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced; - domainStrategy = _config.routingBasicItem.domainStrategy; - domainMatcher = _config.routingBasicItem.domainMatcher; - domainStrategy4Singbox = _config.routingBasicItem.domainStrategy4Singbox; - - RefreshRoutingItems(); - - BindingLockedData(); var canEditRemove = this.WhenAnyValue( - x => x.SelectedSource, - selectedSource => selectedSource != null && !selectedSource.remarks.IsNullOrEmpty()); + x => x.SelectedSource, + selectedSource => selectedSource != null && !selectedSource.remarks.IsNullOrEmpty()); this.WhenAnyValue( - x => x.enableRoutingAdvanced) + x => x.enableRoutingAdvanced) .Subscribe(c => enableRoutingBasic = !enableRoutingAdvanced); RoutingBasicImportRulesCmd = ReactiveCommand.CreateFromTask(async () => @@ -116,6 +103,22 @@ public RoutingSettingViewModel(Func>? updateVie { await SaveRoutingAsync(); }); + + Init(); + } + + private async Task Init() + { + SelectedSource = new(); + + enableRoutingAdvanced = _config.routingBasicItem.enableRoutingAdvanced; + domainStrategy = _config.routingBasicItem.domainStrategy; + domainMatcher = _config.routingBasicItem.domainMatcher; + domainStrategy4Singbox = _config.routingBasicItem.domainStrategy4Singbox; + + await ConfigHandler.InitBuiltinRouting(_config); + await RefreshRoutingItems(); + await BindingLockedData(); } #region locked @@ -148,7 +151,7 @@ private async Task BindingLockedData() } } - private void EndBindingLockedData() + private async Task EndBindingLockedData() { if (_lockedItem != null) { @@ -163,7 +166,7 @@ private void EndBindingLockedData() _lockedItem.ruleSet = JsonUtils.Serialize(_lockedRules, false); - ConfigHandler.SaveRoutingItem(_config, _lockedItem); + await ConfigHandler.SaveRoutingItem(_config, _lockedItem); } } @@ -206,7 +209,7 @@ private async Task SaveRoutingAsync() _config.routingBasicItem.domainMatcher = domainMatcher; _config.routingBasicItem.domainStrategy4Singbox = domainStrategy4Singbox; - EndBindingLockedData(); + await EndBindingLockedData(); if (await ConfigHandler.SaveConfig(_config) == 0) { @@ -250,7 +253,7 @@ public async Task RoutingAdvancedEditAsync(bool blNew) } if (await _updateView?.Invoke(EViewAction.RoutingRuleSettingWindow, item) == true) { - RefreshRoutingItems(); + await RefreshRoutingItems(); IsModified = true; } } @@ -271,11 +274,11 @@ public async Task RoutingAdvancedRemoveAsync() var item = await AppHandler.Instance.GetRoutingItem(it?.id); if (item != null) { - ConfigHandler.RemoveRoutingItem(item); + await ConfigHandler.RemoveRoutingItem(item); } } - RefreshRoutingItems(); + await RefreshRoutingItems(); IsModified = true; } @@ -290,7 +293,7 @@ public async Task RoutingAdvancedSetDefault() if (await ConfigHandler.SetDefaultRouting(_config, item) == 0) { - RefreshRoutingItems(); + await RefreshRoutingItems(); IsModified = true; } } @@ -299,7 +302,7 @@ private async Task RoutingAdvancedImportRules() { if (await ConfigHandler.InitRouting(_config, true) == 0) { - RefreshRoutingItems(); + await RefreshRoutingItems(); IsModified = true; } } diff --git a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs index f1c25567364..80c5366e48f 100644 --- a/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/StatusBarViewModel.cs @@ -105,33 +105,12 @@ public StatusBarViewModel(Func>? updateView) { _config = AppHandler.Instance.Config; - if (updateView != null) - { - Init(updateView); - } - - SelectedRouting = new(); - SelectedServer = new(); - - if (_config.tunModeItem.enableTun && AppHandler.Instance.IsAdministrator) - { - EnableTun = true; - } - else - { - _config.tunModeItem.enableTun = EnableTun = false; - } - - RefreshRoutingsMenu(); - InboundDisplayStatus(); - ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, true); - #region WhenAnyValue && ReactiveCommand this.WhenAnyValue( x => x.SelectedRouting, y => y != null && !y.remarks.IsNullOrEmpty()) - .Subscribe(c => RoutingSelectedChangedAsync(c)); + .Subscribe(async c => await RoutingSelectedChangedAsync(c)); this.WhenAnyValue( x => x.SelectedServer, @@ -142,12 +121,12 @@ public StatusBarViewModel(Func>? updateView) this.WhenAnyValue( x => x.SystemProxySelected, y => y >= 0) - .Subscribe(c => DoSystemProxySelected(c)); + .Subscribe(async c => await DoSystemProxySelected(c)); this.WhenAnyValue( x => x.EnableTun, y => y == true) - .Subscribe(c => DoEnableTun(c)); + .Subscribe(async c => await DoEnableTun(c)); NotifyLeftClickCmd = ReactiveCommand.CreateFromTask(async () => { @@ -190,18 +169,47 @@ public StatusBarViewModel(Func>? updateView) }); #endregion WhenAnyValue && ReactiveCommand + + if (updateView != null) + { + InitUpdateView(updateView); + } + Init(); } - public void Init(Func>? updateView) + private async Task Init() + { + SelectedRouting = new(); + SelectedServer = new(); + + if (_config.tunModeItem.enableTun && AppHandler.Instance.IsAdministrator) + { + EnableTun = true; + } + else + { + _config.tunModeItem.enableTun = EnableTun = false; + } + + await RefreshRoutingsMenu(); + await InboundDisplayStatus(); + await ChangeSystemProxyAsync(_config.systemProxyItem.sysProxyType, true); + } + + public void InitUpdateView(Func>? updateView) { _updateView = updateView; if (_updateView != null) { - MessageBus.Current.Listen(EMsgCommand.RefreshProfiles.ToString()) - .Subscribe(async x => await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null)); + MessageBus.Current.Listen(EMsgCommand.RefreshProfiles.ToString()).Subscribe(OnNext); } } + private async void OnNext(string x) + { + await _updateView?.Invoke(EViewAction.DispatcherRefreshServersBiz, null); + } + private async Task AddServerViaClipboard() { var service = Locator.Current.GetService(); @@ -387,7 +395,7 @@ private async Task RoutingSelectedChangedAsync(bool c) } } - private void DoSystemProxySelected(bool c) + private async Task DoSystemProxySelected(bool c) { if (!c) { @@ -397,10 +405,10 @@ private void DoSystemProxySelected(bool c) { return; } - SetListenerType((ESysProxyType)SystemProxySelected); + await SetListenerType((ESysProxyType)SystemProxySelected); } - private void DoEnableTun(bool c) + private async Task DoEnableTun(bool c) { if (_config.tunModeItem.enableTun != EnableTun) { @@ -412,7 +420,7 @@ private void DoEnableTun(bool c) Locator.Current.GetService()?.RebootAsAdmin(); return; } - ConfigHandler.SaveConfig(_config); + await ConfigHandler.SaveConfig(_config); Locator.Current.GetService()?.Reload(); } } @@ -421,7 +429,7 @@ private void DoEnableTun(bool c) #region UI - public void InboundDisplayStatus() + public async Task InboundDisplayStatus() { StringBuilder sb = new(); sb.Append($"[{EInboundProtocol.socks}:{AppHandler.Instance.GetLocalPort(EInboundProtocol.socks)}]"); diff --git a/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs b/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs index d58dd257b61..3f38ab9a74a 100644 --- a/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/SubEditViewModel.cs @@ -14,27 +14,19 @@ public class SubEditViewModel : MyReactiveObject public SubEditViewModel(SubItem subItem, Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; - if (subItem.id.IsNullOrEmpty()) - { - SelectedSource = subItem; - } - else - { - SelectedSource = JsonUtils.DeepCopy(subItem); - } - SaveCmd = ReactiveCommand.CreateFromTask(async () => { await SaveSubAsync(); }); + + SelectedSource = subItem.id.IsNullOrEmpty() ? subItem : JsonUtils.DeepCopy(subItem); } private async Task SaveSubAsync() { - string remarks = SelectedSource.remarks; + var remarks = SelectedSource.remarks; if (Utils.IsNullOrEmpty(remarks)) { NoticeHandler.Instance.Enqueue(ResUI.PleaseFillRemarks); diff --git a/v2rayN/ServiceLib/ViewModels/SubSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/SubSettingViewModel.cs index 72d17b7628d..840c1c7e09a 100644 --- a/v2rayN/ServiceLib/ViewModels/SubSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/SubSettingViewModel.cs @@ -25,13 +25,8 @@ public class SubSettingViewModel : MyReactiveObject public SubSettingViewModel(Func>? updateView) { _config = AppHandler.Instance.Config; - _updateView = updateView; - SelectedSource = new(); - - RefreshSubItems(); - var canEditRemove = this.WhenAnyValue( x => x.SelectedSource, selectedSource => selectedSource != null && !selectedSource.id.IsNullOrEmpty()); @@ -52,6 +47,15 @@ public SubSettingViewModel(Func>? updateView) { await _updateView?.Invoke(EViewAction.ShareSub, SelectedSource?.url); }, canEditRemove); + + Init(); + } + + private async Task Init() + { + SelectedSource = new(); + + await RefreshSubItems(); } public async Task RefreshSubItems() diff --git a/v2rayN/v2rayN.Desktop/Views/CheckUpdateView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/CheckUpdateView.axaml.cs index a11a72fadbd..6859b5776e1 100644 --- a/v2rayN/v2rayN.Desktop/Views/CheckUpdateView.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/CheckUpdateView.axaml.cs @@ -19,7 +19,6 @@ public CheckUpdateView() this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables); - this.OneWayBind(ViewModel, vm => vm.IsCheckUpdate, v => v.btnCheckUpdate.IsEnabled).DisposeWith(disposables); }); } diff --git a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs index f4d6d8ea2d6..2c07ac3c8ff 100644 --- a/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/MainWindow.axaml.cs @@ -4,7 +4,6 @@ using Avalonia.Controls.Notifications; using Avalonia.Input; using Avalonia.Interactivity; -using Avalonia.Platform.Storage; using Avalonia.ReactiveUI; using Avalonia.Threading; using DialogHostAvalonia; @@ -40,7 +39,7 @@ public MainWindow() menuCheckUpdate.Click += MenuCheckUpdate_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click; - MessageBus.Current.Listen(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x)); + MessageBus.Current.Listen(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg); ViewModel = new MainWindowViewModel(UpdateViewHandler); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel)); @@ -123,6 +122,7 @@ public MainWindow() menuSettingsSetUWP.IsVisible = false; menuGlobalHotkeySetting.IsVisible = false; } + menuAddServerViaScan.IsVisible = false; switch (_config.uiItem.mainGirdOrientation) { @@ -289,7 +289,7 @@ private async void MainWindow_KeyDown(object? sender, KeyEventArgs e) break; case Key.S: - ScanScreenTaskAsync().ContinueWith(_ => { }); + await ScanScreenTaskAsync(); break; } } diff --git a/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs b/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs index d0dbda616fa..89563971415 100644 --- a/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/StatusBarView.axaml.cs @@ -21,7 +21,7 @@ public StatusBarView() //ViewModel = new StatusBarViewModel(UpdateViewHandler); //Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(StatusBarViewModel)); ViewModel = Locator.Current.GetService(); - ViewModel?.Init(UpdateViewHandler); + ViewModel?.InitUpdateView(UpdateViewHandler); txtRunningServerDisplay.Tapped += TxtRunningServerDisplay_Tapped; txtRunningInfoDisplay.Tapped += TxtRunningServerDisplay_Tapped; diff --git a/v2rayN/v2rayN/Views/CheckUpdateView.xaml.cs b/v2rayN/v2rayN/Views/CheckUpdateView.xaml.cs index def6e53ff82..ad676092f5f 100644 --- a/v2rayN/v2rayN/Views/CheckUpdateView.xaml.cs +++ b/v2rayN/v2rayN/Views/CheckUpdateView.xaml.cs @@ -19,7 +19,6 @@ public CheckUpdateView() this.Bind(ViewModel, vm => vm.EnableCheckPreReleaseUpdate, v => v.togEnableCheckPreReleaseUpdate.IsChecked).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.CheckUpdateCmd, v => v.btnCheckUpdate).DisposeWith(disposables); - this.OneWayBind(ViewModel, vm => vm.IsCheckUpdate, v => v.btnCheckUpdate.IsEnabled).DisposeWith(disposables); }); } diff --git a/v2rayN/v2rayN/Views/MainWindow.xaml.cs b/v2rayN/v2rayN/Views/MainWindow.xaml.cs index 5c233c7ee0f..d5b61a5cfe6 100644 --- a/v2rayN/v2rayN/Views/MainWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/MainWindow.xaml.cs @@ -36,7 +36,7 @@ public MainWindow() menuCheckUpdate.Click += MenuCheckUpdate_Click; menuBackupAndRestore.Click += MenuBackupAndRestore_Click; - MessageBus.Current.Listen(EMsgCommand.SendSnackMsg.ToString()).Subscribe(x => DelegateSnackMsg(x)); + MessageBus.Current.Listen(EMsgCommand.SendSnackMsg.ToString()).Subscribe(DelegateSnackMsg); ViewModel = new MainWindowViewModel(UpdateViewHandler); Locator.CurrentMutable.RegisterLazySingleton(() => ViewModel, typeof(MainWindowViewModel));