diff --git a/v2rayN/Directory.Packages.props b/v2rayN/Directory.Packages.props index 663b2545..992e02f6 100644 --- a/v2rayN/Directory.Packages.props +++ b/v2rayN/Directory.Packages.props @@ -11,15 +11,14 @@ - + - - - + + diff --git a/v2rayN/ServiceLib/Common/Extension.cs b/v2rayN/ServiceLib/Common/Extension.cs index f9ccdc58..bf2f3d96 100644 --- a/v2rayN/ServiceLib/Common/Extension.cs +++ b/v2rayN/ServiceLib/Common/Extension.cs @@ -143,7 +143,7 @@ public static class Extension [CallerFilePath] string filePath = "", [CallerLineNumber] int lineNumber = 0) { - return Signal.Defer(() => interaction.Handle(input)) + return Signal.Defer(() => interaction.WhenHandled(input)) .Catch>(ex => { Logging.SaveLog($"Unhandled interaction exception in {memberName} at {filePath}:{lineNumber}", ex); diff --git a/v2rayN/ServiceLib/ServiceLib.csproj b/v2rayN/ServiceLib/ServiceLib.csproj index 69729807..b66c9eec 100644 --- a/v2rayN/ServiceLib/ServiceLib.csproj +++ b/v2rayN/ServiceLib/ServiceLib.csproj @@ -10,10 +10,6 @@ true - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs b/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs index fb89f4fe..aea7ce68 100644 --- a/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/AddServerViewModel.cs @@ -103,6 +103,9 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable [Reactive] public partial string MasqueHeaders { get; set; } + [Reactive] + public partial string Network { get; set; } + [Reactive] public partial string RawHeaderType { get; set; } @@ -274,7 +277,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable this.WhenAnyValue(x => x.CertSha) .Subscribe(_ => UpdateCertTip()); - this.WhenAnyValue(x => x.SelectedSource.Network) + this.WhenAnyValue(x => x.Network) .Subscribe(_ => { this.RaisePropertyChanged(nameof(TransportHeaderType)); @@ -299,6 +302,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable CoreType = SelectedSource?.CoreType?.ToString(); AllowInsecure = SelectedSource?.GetAllowInsecure() == true; MuxEnabled = SelectedSource?.MuxEnabled == true; + Network = SelectedSource?.Network ?? Global.DefaultNetwork; Cert = SelectedSource?.Cert ?? string.Empty; CertSha = SelectedSource?.CertSha ?? string.Empty; @@ -405,10 +409,11 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable SelectedSource.MuxEnabled = MuxEnabled; SelectedSource.Cert = Cert.IsNullOrEmpty() ? string.Empty : Cert; SelectedSource.CertSha = CertSha.IsNullOrEmpty() ? string.Empty : CertSha; - if (!Global.Networks.Contains(SelectedSource.Network)) + if (!Global.Networks.Contains(Network)) { - SelectedSource.Network = Global.DefaultNetwork; + Network = Global.DefaultNetwork; } + SelectedSource.Network = Network; var transport = new TransportExtraItem { diff --git a/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs b/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs index a02bf152..c1314749 100644 --- a/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs +++ b/v2rayN/ServiceLib/ViewModels/DNSSettingViewModel.cs @@ -35,7 +35,7 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable [Reactive] public partial bool RayCustomDNSEnableCompatible { get; set; } [Reactive] public partial bool SBCustomDNSEnableCompatible { get; set; } - public bool IsSimpleDNSEnabled => !(RayCustomDNSEnableCompatible && SBCustomDNSEnableCompatible); + [ObservableAsProperty] public partial bool IsSimpleDNSEnabled { get; } public ReactiveCommand SaveCmd { get; } public ReactiveCommand ImportDefConfig4V2rayCompatibleCmd { get; } @@ -60,8 +60,11 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable await Task.CompletedTask; }); - this.WhenAnyValue(x => x.RayCustomDNSEnableCompatible, x => x.SBCustomDNSEnableCompatible) - .Subscribe(_ => this.RaisePropertyChanged(nameof(IsSimpleDNSEnabled))); + _isSimpleDNSEnabledHelper = this.WhenAnyValue( + x => x.RayCustomDNSEnableCompatible, + x => x.SBCustomDNSEnableCompatible, + (a, b) => !(a && b)) + .ToProperty(this, nameof(IsSimpleDNSEnabled)); _ = Init(); } diff --git a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs index d7805232..ae9183ab 100644 --- a/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/AddServerWindow.axaml.cs @@ -152,7 +152,7 @@ public partial class AddServerWindow : WindowBase }) .DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.Network, v => v.cmbNetwork.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RawHeaderType, v => v.cmbHeaderTypeRaw.SelectedValue).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Host, v => v.txtRequestHostRaw.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Path, v => v.txtPathRaw.Text).DisposeWith(disposables); diff --git a/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs b/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs index 2ab1a608..866ed941 100644 --- a/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs +++ b/v2rayN/v2rayN.Desktop/Views/DNSSettingWindow.axaml.cs @@ -67,14 +67,10 @@ public partial class DNSSettingWindow : WindowBase this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables); - this.WhenAnyValue(x => x.ViewModel.IsSimpleDNSEnabled) - .Select(b => !b) - .BindTo(txtBasicDNSSettingsInvalid, t => t.IsVisible); - this.WhenAnyValue(x => x.ViewModel.IsSimpleDNSEnabled) - .Select(b => !b) - .BindTo(txtAdvancedDNSSettingsInvalid, t => t.IsVisible); - this.Bind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridBasicDNSSettings.IsEnabled).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridAdvancedDNSSettings.IsEnabled).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtBasicDNSSettingsInvalid.IsVisible, isSimpleDnsEnabled => !isSimpleDnsEnabled).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtAdvancedDNSSettingsInvalid.IsVisible, isSimpleDnsEnabled => !isSimpleDnsEnabled).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridBasicDNSSettings.IsEnabled).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridAdvancedDNSSettings.IsEnabled).DisposeWith(disposables); }); } diff --git a/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj b/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj index 28630574..4b631e4f 100644 --- a/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj +++ b/v2rayN/v2rayN.Desktop/v2rayN.Desktop.csproj @@ -23,10 +23,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - diff --git a/v2rayN/v2rayN/Base/ViewHost.cs b/v2rayN/v2rayN/Base/ViewHost.cs index e6d5b068..ce563fce 100644 --- a/v2rayN/v2rayN/Base/ViewHost.cs +++ b/v2rayN/v2rayN/Base/ViewHost.cs @@ -4,9 +4,10 @@ namespace v2rayN.Base; public static class ViewHost { - public static void Show( + public static void Show( ContentControl host, - object? viewModel) + TViewModel? viewModel) + where TViewModel : class { if (viewModel == null) { diff --git a/v2rayN/v2rayN/Common/SimpleViewLocator.cs b/v2rayN/v2rayN/Common/SimpleViewLocator.cs index b3395fda..8b57bfbf 100644 --- a/v2rayN/v2rayN/Common/SimpleViewLocator.cs +++ b/v2rayN/v2rayN/Common/SimpleViewLocator.cs @@ -37,31 +37,27 @@ public class SimpleViewLocator : IViewLocator public static SimpleViewLocator Instance => _instance.Value; public IViewFor? ResolveView() where TViewModel : class - { - return ResolveView(null); - } - - public IViewFor? ResolveView(string? contract) where TViewModel : class { if (_mappings.TryGetValue(typeof(TViewModel), out var factory)) { - return factory() as IViewFor; + var view = factory() as IViewFor; + return view; } return null; } - public IViewFor? ResolveView(object? instance) + public IViewFor? ResolveView(TViewModel viewModel, string? contract) where TViewModel : class { - return ResolveView(instance, null); + return ResolveView(); } - public IViewFor? ResolveView(object? instance, string? contract) + public IViewFor? ResolveView(object? viewModel, string? contract) { - if (instance == null) + if (viewModel == null) { return null; } - var viewModelType = instance.GetType(); + var viewModelType = viewModel.GetType(); if (_mappings.TryGetValue(viewModelType, out var factory)) { return factory(); @@ -69,6 +65,16 @@ public class SimpleViewLocator : IViewLocator return null; } + public IViewFor? ResolveViewUnsafe(object? viewModel, string? contract) + { + return ResolveView(viewModel, contract); + } + + public IViewFor? ResolveView(TViewModel instance) where TViewModel : class + { + return ResolveView(instance, null); + } + public void Register(Func factory) where TViewModel : class where TView : class, IViewFor diff --git a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs index f8e1573f..7effbc40 100644 --- a/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/AddServerWindow.xaml.cs @@ -150,7 +150,7 @@ public partial class AddServerWindow }) .DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.SelectedSource.Network, v => v.cmbNetwork.Text).DisposeWith(disposables); + this.Bind(ViewModel, vm => vm.Network, v => v.cmbNetwork.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.RawHeaderType, v => v.cmbHeaderTypeRaw.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Host, v => v.txtRequestHostRaw.Text).DisposeWith(disposables); this.Bind(ViewModel, vm => vm.Path, v => v.txtPathRaw.Text).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs b/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs index dcf267fe..3260ce89 100644 --- a/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs +++ b/v2rayN/v2rayN/Views/DNSSettingWindow.xaml.cs @@ -63,16 +63,10 @@ public partial class DNSSettingWindow this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables); - this.WhenAnyValue(x => x.ViewModel.IsSimpleDNSEnabled) - .Select(b => b ? Visibility.Collapsed : Visibility.Visible) - .BindTo(this, x => x.txtBasicDNSSettingsInvalid.Visibility) - .DisposeWith(disposables); - this.WhenAnyValue(x => x.ViewModel.IsSimpleDNSEnabled) - .Select(b => b ? Visibility.Collapsed : Visibility.Visible) - .BindTo(this, x => x.txtAdvancedDNSSettingsInvalid.Visibility) - .DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridBasicDNSSettings.IsEnabled).DisposeWith(disposables); - this.Bind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridAdvancedDNSSettings.IsEnabled).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtBasicDNSSettingsInvalid.Visibility, isSimpleDnsEnabled => isSimpleDnsEnabled ? Visibility.Collapsed : Visibility.Visible).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtAdvancedDNSSettingsInvalid.Visibility, isSimpleDnsEnabled => isSimpleDnsEnabled ? Visibility.Collapsed : Visibility.Visible).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridBasicDNSSettings.IsEnabled).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridAdvancedDNSSettings.IsEnabled).DisposeWith(disposables); }); WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme); } diff --git a/v2rayN/v2rayN/Views/StatusBarView.xaml.cs b/v2rayN/v2rayN/Views/StatusBarView.xaml.cs index 4dab2d75..aeadc0c9 100644 --- a/v2rayN/v2rayN/Views/StatusBarView.xaml.cs +++ b/v2rayN/v2rayN/Views/StatusBarView.xaml.cs @@ -18,10 +18,10 @@ public partial class StatusBarView this.WhenActivated(disposables => { //system proxy - this.OneWayBind(ViewModel, vm => vm.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, viewModelToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); - this.OneWayBind(ViewModel, vm => vm.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, viewModelToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); - this.OneWayBind(ViewModel, vm => vm.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, viewModelToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); - this.OneWayBind(ViewModel, vm => vm.BlSystemProxyPac, v => v.menuSystemProxyPac2.Visibility, conversionHint: BooleanToVisibilityHint.UseHidden, viewModelToViewConverterOverride: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHints.UseHidden, converter: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHints.UseHidden, converter: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHints.UseHidden, converter: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); + this.OneWayBind(ViewModel, vm => vm.BlSystemProxyPac, v => v.menuSystemProxyPac2.Visibility, conversionHint: BooleanToVisibilityHints.UseHidden, converter: new BooleanToVisibilityTypeConverter()).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SystemProxyClearCmd, v => v.menuSystemProxyClear).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables); diff --git a/v2rayN/v2rayN/v2rayN.csproj b/v2rayN/v2rayN/v2rayN.csproj index 237a1271..880548d3 100644 --- a/v2rayN/v2rayN/v2rayN.csproj +++ b/v2rayN/v2rayN/v2rayN.csproj @@ -16,10 +16,6 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive -