ReactiveUI 26 (#10249)

* ReactiveUI 25

* Fix

* Up

* ReactiveUI 26
This commit is contained in:
DHR60
2026-11-01 12:00:02 +00:00
committed by GitHub
parent 57f17d5939
commit e2f4292321
14 changed files with 52 additions and 60 deletions
+3 -4
View File
@@ -11,15 +11,14 @@
<PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" /> <PackageVersion Include="AvaloniaUI.DiagnosticsSupport" Version="2.2.3" />
<PackageVersion Include="DialogHost.Avalonia" Version="0.12.3" /> <PackageVersion Include="DialogHost.Avalonia" Version="0.12.3" />
<PackageVersion Include="IPNetwork2" Version="4.3.0" /> <PackageVersion Include="IPNetwork2" Version="4.3.0" />
<PackageVersion Include="ReactiveUI.Avalonia" Version="12.1.2" /> <PackageVersion Include="ReactiveUI.Avalonia" Version="12.1.6" />
<PackageVersion Include="CliWrap" Version="3.10.5" /> <PackageVersion Include="CliWrap" Version="3.10.5" />
<PackageVersion Include="Downloader" Version="5.10.1" /> <PackageVersion Include="Downloader" Version="5.10.1" />
<PackageVersion Include="H.NotifyIcon.Wpf" Version="2.4.1" /> <PackageVersion Include="H.NotifyIcon.Wpf" Version="2.4.1" />
<PackageVersion Include="MaterialDesignThemes" Version="5.3.2" /> <PackageVersion Include="MaterialDesignThemes" Version="5.3.2" />
<PackageVersion Include="QRCoder" Version="1.8.0" /> <PackageVersion Include="QRCoder" Version="1.8.0" />
<PackageVersion Include="ReactiveUI" Version="24.3.0" /> <PackageVersion Include="ReactiveUI" Version="26.0.1" />
<PackageVersion Include="ReactiveUI.SourceGenerators" Version="3.2.0" /> <PackageVersion Include="ReactiveUI.WPF" Version="26.0.1" />
<PackageVersion Include="ReactiveUI.WPF" Version="24.2.0" />
<PackageVersion Include="Semi.Avalonia" Version="12.1.0.1" /> <PackageVersion Include="Semi.Avalonia" Version="12.1.0.1" />
<PackageVersion Include="Semi.Avalonia.AvaloniaEdit" Version="12.0.0" /> <PackageVersion Include="Semi.Avalonia.AvaloniaEdit" Version="12.0.0" />
<PackageVersion Include="Semi.Avalonia.DataGrid" Version="12.1.0.1" /> <PackageVersion Include="Semi.Avalonia.DataGrid" Version="12.1.0.1" />
+1 -1
View File
@@ -143,7 +143,7 @@ public static class Extension
[CallerFilePath] string filePath = "", [CallerFilePath] string filePath = "",
[CallerLineNumber] int lineNumber = 0) [CallerLineNumber] int lineNumber = 0)
{ {
return Signal.Defer(() => interaction.Handle(input)) return Signal.Defer(() => interaction.WhenHandled(input))
.Catch<TOutput, UnhandledInteractionException<TInput, TOutput>>(ex => .Catch<TOutput, UnhandledInteractionException<TInput, TOutput>>(ex =>
{ {
Logging.SaveLog($"Unhandled interaction exception in {memberName} at {filePath}:{lineNumber}", ex); Logging.SaveLog($"Unhandled interaction exception in {memberName} at {filePath}:{lineNumber}", ex);
-4
View File
@@ -10,10 +10,6 @@
<PackageReference Include="ReactiveUI"> <PackageReference Include="ReactiveUI">
<TreatAsUsed>true</TreatAsUsed> <TreatAsUsed>true</TreatAsUsed>
</PackageReference> </PackageReference>
<PackageReference Include="ReactiveUI.SourceGenerators">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="sqlite-net-e" /> <PackageReference Include="sqlite-net-e" />
<PackageReference Include="Repobot.SQLite.Unofficial" /> <PackageReference Include="Repobot.SQLite.Unofficial" />
<PackageReference Include="NLog" /> <PackageReference Include="NLog" />
@@ -103,6 +103,9 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
[Reactive] [Reactive]
public partial string MasqueHeaders { get; set; } public partial string MasqueHeaders { get; set; }
[Reactive]
public partial string Network { get; set; }
[Reactive] [Reactive]
public partial string RawHeaderType { get; set; } public partial string RawHeaderType { get; set; }
@@ -274,7 +277,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
this.WhenAnyValue(x => x.CertSha) this.WhenAnyValue(x => x.CertSha)
.Subscribe(_ => UpdateCertTip()); .Subscribe(_ => UpdateCertTip());
this.WhenAnyValue(x => x.SelectedSource.Network) this.WhenAnyValue(x => x.Network)
.Subscribe(_ => .Subscribe(_ =>
{ {
this.RaisePropertyChanged(nameof(TransportHeaderType)); this.RaisePropertyChanged(nameof(TransportHeaderType));
@@ -299,6 +302,7 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
CoreType = SelectedSource?.CoreType?.ToString(); CoreType = SelectedSource?.CoreType?.ToString();
AllowInsecure = SelectedSource?.GetAllowInsecure() == true; AllowInsecure = SelectedSource?.GetAllowInsecure() == true;
MuxEnabled = SelectedSource?.MuxEnabled == true; MuxEnabled = SelectedSource?.MuxEnabled == true;
Network = SelectedSource?.Network ?? Global.DefaultNetwork;
Cert = SelectedSource?.Cert ?? string.Empty; Cert = SelectedSource?.Cert ?? string.Empty;
CertSha = SelectedSource?.CertSha ?? string.Empty; CertSha = SelectedSource?.CertSha ?? string.Empty;
@@ -405,10 +409,11 @@ public partial class AddServerViewModel : MyReactiveObject, ICloseable
SelectedSource.MuxEnabled = MuxEnabled; SelectedSource.MuxEnabled = MuxEnabled;
SelectedSource.Cert = Cert.IsNullOrEmpty() ? string.Empty : Cert; SelectedSource.Cert = Cert.IsNullOrEmpty() ? string.Empty : Cert;
SelectedSource.CertSha = CertSha.IsNullOrEmpty() ? string.Empty : CertSha; 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 var transport = new TransportExtraItem
{ {
@@ -35,7 +35,7 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable
[Reactive] public partial bool RayCustomDNSEnableCompatible { get; set; } [Reactive] public partial bool RayCustomDNSEnableCompatible { get; set; }
[Reactive] public partial bool SBCustomDNSEnableCompatible { get; set; } [Reactive] public partial bool SBCustomDNSEnableCompatible { get; set; }
public bool IsSimpleDNSEnabled => !(RayCustomDNSEnableCompatible && SBCustomDNSEnableCompatible); [ObservableAsProperty] public partial bool IsSimpleDNSEnabled { get; }
public ReactiveCommand<RxVoid, RxVoid> SaveCmd { get; } public ReactiveCommand<RxVoid, RxVoid> SaveCmd { get; }
public ReactiveCommand<RxVoid, RxVoid> ImportDefConfig4V2rayCompatibleCmd { get; } public ReactiveCommand<RxVoid, RxVoid> ImportDefConfig4V2rayCompatibleCmd { get; }
@@ -60,8 +60,11 @@ public partial class DNSSettingViewModel : MyReactiveObject, ICloseable
await Task.CompletedTask; await Task.CompletedTask;
}); });
this.WhenAnyValue(x => x.RayCustomDNSEnableCompatible, x => x.SBCustomDNSEnableCompatible) _isSimpleDNSEnabledHelper = this.WhenAnyValue(
.Subscribe(_ => this.RaisePropertyChanged(nameof(IsSimpleDNSEnabled))); x => x.RayCustomDNSEnableCompatible,
x => x.SBCustomDNSEnableCompatible,
(a, b) => !(a && b))
.ToProperty(this, nameof(IsSimpleDNSEnabled));
_ = Init(); _ = Init();
} }
@@ -152,7 +152,7 @@ public partial class AddServerWindow : WindowBase<AddServerViewModel>
}) })
.DisposeWith(disposables); .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.RawHeaderType, v => v.cmbHeaderTypeRaw.SelectedValue).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Host, v => v.txtRequestHostRaw.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); this.Bind(ViewModel, vm => vm.Path, v => v.txtPathRaw.Text).DisposeWith(disposables);
@@ -67,14 +67,10 @@ public partial class DNSSettingWindow : WindowBase<DNSSettingViewModel>
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables);
this.WhenAnyValue(x => x.ViewModel.IsSimpleDNSEnabled) this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtBasicDNSSettingsInvalid.IsVisible, isSimpleDnsEnabled => !isSimpleDnsEnabled).DisposeWith(disposables);
.Select(b => !b) this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtAdvancedDNSSettingsInvalid.IsVisible, isSimpleDnsEnabled => !isSimpleDnsEnabled).DisposeWith(disposables);
.BindTo(txtBasicDNSSettingsInvalid, t => t.IsVisible); this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridBasicDNSSettings.IsEnabled).DisposeWith(disposables);
this.WhenAnyValue(x => x.ViewModel.IsSimpleDNSEnabled) this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridAdvancedDNSSettings.IsEnabled).DisposeWith(disposables);
.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);
}); });
} }
@@ -23,10 +23,6 @@
<PackageReference Condition="'$(Configuration)' == 'Debug'" Include="AvaloniaUI.DiagnosticsSupport" /> <PackageReference Condition="'$(Configuration)' == 'Debug'" Include="AvaloniaUI.DiagnosticsSupport" />
<PackageReference Include="DialogHost.Avalonia" /> <PackageReference Include="DialogHost.Avalonia" />
<PackageReference Include="ReactiveUI.Avalonia" /> <PackageReference Include="ReactiveUI.Avalonia" />
<PackageReference Include="ReactiveUI.SourceGenerators">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Semi.Avalonia" /> <PackageReference Include="Semi.Avalonia" />
<PackageReference Include="Semi.Avalonia.AvaloniaEdit" /> <PackageReference Include="Semi.Avalonia.AvaloniaEdit" />
<PackageReference Include="Semi.Avalonia.DataGrid"> <PackageReference Include="Semi.Avalonia.DataGrid">
+3 -2
View File
@@ -4,9 +4,10 @@ namespace v2rayN.Base;
public static class ViewHost public static class ViewHost
{ {
public static void Show( public static void Show<TViewModel>(
ContentControl host, ContentControl host,
object? viewModel) TViewModel? viewModel)
where TViewModel : class
{ {
if (viewModel == null) if (viewModel == null)
{ {
+17 -11
View File
@@ -37,31 +37,27 @@ public class SimpleViewLocator : IViewLocator
public static SimpleViewLocator Instance => _instance.Value; public static SimpleViewLocator Instance => _instance.Value;
public IViewFor<TViewModel>? ResolveView<TViewModel>() where TViewModel : class public IViewFor<TViewModel>? ResolveView<TViewModel>() where TViewModel : class
{
return ResolveView<TViewModel>(null);
}
public IViewFor<TViewModel>? ResolveView<TViewModel>(string? contract) where TViewModel : class
{ {
if (_mappings.TryGetValue(typeof(TViewModel), out var factory)) if (_mappings.TryGetValue(typeof(TViewModel), out var factory))
{ {
return factory() as IViewFor<TViewModel>; var view = factory() as IViewFor<TViewModel>;
return view;
} }
return null; return null;
} }
public IViewFor? ResolveView(object? instance) public IViewFor? ResolveView<TViewModel>(TViewModel viewModel, string? contract) where TViewModel : class
{ {
return ResolveView(instance, null); return ResolveView<TViewModel>();
} }
public IViewFor? ResolveView(object? instance, string? contract) public IViewFor? ResolveView(object? viewModel, string? contract)
{ {
if (instance == null) if (viewModel == null)
{ {
return null; return null;
} }
var viewModelType = instance.GetType(); var viewModelType = viewModel.GetType();
if (_mappings.TryGetValue(viewModelType, out var factory)) if (_mappings.TryGetValue(viewModelType, out var factory))
{ {
return factory(); return factory();
@@ -69,6 +65,16 @@ public class SimpleViewLocator : IViewLocator
return null; return null;
} }
public IViewFor? ResolveViewUnsafe(object? viewModel, string? contract)
{
return ResolveView(viewModel, contract);
}
public IViewFor? ResolveView<TViewModel>(TViewModel instance) where TViewModel : class
{
return ResolveView(instance, null);
}
public void Register<TViewModel, TView>(Func<TView> factory) public void Register<TViewModel, TView>(Func<TView> factory)
where TViewModel : class where TViewModel : class
where TView : class, IViewFor<TViewModel> where TView : class, IViewFor<TViewModel>
+1 -1
View File
@@ -150,7 +150,7 @@ public partial class AddServerWindow
}) })
.DisposeWith(disposables); .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.RawHeaderType, v => v.cmbHeaderTypeRaw.Text).DisposeWith(disposables);
this.Bind(ViewModel, vm => vm.Host, v => v.txtRequestHostRaw.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); this.Bind(ViewModel, vm => vm.Path, v => v.txtPathRaw.Text).DisposeWith(disposables);
+4 -10
View File
@@ -63,16 +63,10 @@ public partial class DNSSettingWindow
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4V2rayCompatibleCmd, v => v.btnImportDefConfig4V2rayCompatible).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.ImportDefConfig4SingboxCompatibleCmd, v => v.btnImportDefConfig4SingboxCompatible).DisposeWith(disposables);
this.WhenAnyValue(x => x.ViewModel.IsSimpleDNSEnabled) this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtBasicDNSSettingsInvalid.Visibility, isSimpleDnsEnabled => isSimpleDnsEnabled ? Visibility.Collapsed : Visibility.Visible).DisposeWith(disposables);
.Select(b => b ? Visibility.Collapsed : Visibility.Visible) this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.txtAdvancedDNSSettingsInvalid.Visibility, isSimpleDnsEnabled => isSimpleDnsEnabled ? Visibility.Collapsed : Visibility.Visible).DisposeWith(disposables);
.BindTo(this, x => x.txtBasicDNSSettingsInvalid.Visibility) this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridBasicDNSSettings.IsEnabled).DisposeWith(disposables);
.DisposeWith(disposables); this.OneWayBind(ViewModel, vm => vm.IsSimpleDNSEnabled, v => v.gridAdvancedDNSSettings.IsEnabled).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);
}); });
WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme); WindowsUtils.SetDarkBorder(this, AppManager.Instance.Config.UiItem.CurrentTheme);
} }
+4 -4
View File
@@ -18,10 +18,10 @@ public partial class StatusBarView
this.WhenActivated(disposables => this.WhenActivated(disposables =>
{ {
//system proxy //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.BlSystemProxyClear, v => v.menuSystemProxyClear2.Visibility, conversionHint: BooleanToVisibilityHints.UseHidden, converter: 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.BlSystemProxySet, v => v.menuSystemProxySet2.Visibility, conversionHint: BooleanToVisibilityHints.UseHidden, converter: 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.BlSystemProxyNothing, v => v.menuSystemProxyNothing2.Visibility, conversionHint: BooleanToVisibilityHints.UseHidden, converter: 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.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.SystemProxyClearCmd, v => v.menuSystemProxyClear).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SystemProxySetCmd, v => v.menuSystemProxySet).DisposeWith(disposables);
this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables); this.BindCommand(ViewModel, vm => vm.SystemProxyNothingCmd, v => v.menuSystemProxyNothing).DisposeWith(disposables);
-4
View File
@@ -16,10 +16,6 @@
<ItemGroup> <ItemGroup>
<PackageReference Include="MaterialDesignThemes" /> <PackageReference Include="MaterialDesignThemes" />
<PackageReference Include="H.NotifyIcon.Wpf" /> <PackageReference Include="H.NotifyIcon.Wpf" />
<PackageReference Include="ReactiveUI.SourceGenerators">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="ReactiveUI.WPF" /> <PackageReference Include="ReactiveUI.WPF" />
</ItemGroup> </ItemGroup>