From 66546700b01d0bd47799e0dbc0b57a39934fa562 Mon Sep 17 00:00:00 2001 From: DHR60 <192860629+DHR60@users.noreply.github.com> Date: Thu, 5 Nov 2026 02:08:04 +0000 Subject: [PATCH] Fix UI (#10527) * Revert "Cache selected views in SimpleViewLocator" This reverts commit 8ebbd7f4f85860f626f6fa614ed7bb03ea3c0e1b. * Fix UI * Optimize Styles * Code clean --- v2rayN/ServiceLib/Resx/ResUI.Designer.cs | 56 ++--- v2rayN/ServiceLib/Resx/ResUI.az.resx | 20 +- v2rayN/v2rayN.Desktop/App.axaml | 10 +- .../v2rayN.Desktop/Assets/GlobalStyles.axaml | 24 +- .../Common/SimpleViewLocator.cs | 28 +-- .../ViewModels/ThemeSettingViewModel.cs | 70 +----- v2rayN/v2rayN.Desktop/Views/JsonEditor.axaml | 1 - v2rayN/v2rayN.Desktop/Views/MainWindow.axaml | 70 ++---- .../v2rayN.Desktop/Views/MainWindow.axaml.cs | 223 +++++++++++++----- .../Views/MessageBoxDialog.axaml | 1 - 10 files changed, 252 insertions(+), 251 deletions(-) diff --git a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs index 9f79f3cb..373fef1a 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.Designer.cs +++ b/v2rayN/ServiceLib/Resx/ResUI.Designer.cs @@ -1,4 +1,4 @@ -//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ // // 此代码由工具生成。 // 运行时版本:4.0.30319.42000 @@ -222,6 +222,15 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 Enter a valid IPv6 CIDR range with at least two addresses, for example fc00::/18. 的本地化字符串。 + /// + public static string FillCorrectFakeIPv6Range { + get { + return ResourceManager.GetString("FillCorrectFakeIPv6Range", resourceCulture); + } + } + /// /// 查找类似 Please enter the correct port format. 的本地化字符串。 /// @@ -3240,6 +3249,24 @@ namespace ServiceLib.Resx { } } + /// + /// 查找类似 IPv6 FakeIP 的本地化字符串。 + /// + public static string TbFakeIPv6 { + get { + return ResourceManager.GetString("TbFakeIPv6", resourceCulture); + } + } + + /// + /// 查找类似 Return fake IPv6 addresses as well. Requires FakeIP to be enabled and AAAA queries to be allowed. 的本地化字符串。 + /// + public static string TbFakeIPv6Tips { + get { + return ResourceManager.GetString("TbFakeIPv6Tips", resourceCulture); + } + } + /// /// 查找类似 Fallback 的本地化字符串。 /// @@ -5444,32 +5471,5 @@ namespace ServiceLib.Resx { return ResourceManager.GetString("UpgradeAppNotExistTip", resourceCulture); } } - /// - /// IPv6 FakeIP - /// - public static string TbFakeIPv6 { - get { - return ResourceManager.GetString("TbFakeIPv6", resourceCulture); - } - } - - /// - /// Return fake IPv6 addresses as well. Requires FakeIP to be enabled and AAAA queries to be allowed. - /// - public static string TbFakeIPv6Tips { - get { - return ResourceManager.GetString("TbFakeIPv6Tips", resourceCulture); - } - } - - /// - /// Enter a valid IPv6 CIDR range with at least two addresses, for example fc00::/18. - /// - public static string FillCorrectFakeIPv6Range { - get { - return ResourceManager.GetString("FillCorrectFakeIPv6Range", resourceCulture); - } - } - } } diff --git a/v2rayN/ServiceLib/Resx/ResUI.az.resx b/v2rayN/ServiceLib/Resx/ResUI.az.resx index af512b03..f6f50f26 100644 --- a/v2rayN/ServiceLib/Resx/ResUI.az.resx +++ b/v2rayN/ServiceLib/Resx/ResUI.az.resx @@ -1153,7 +1153,7 @@ ACK aşkarlaması mümkün olmadıqda ehtiyat gecikmə (məsələn, 500ms). Yalnız sing-box. Boş = standart. - Aralıq formatı yanlışdır. 'başlanğıc-son' formatından istifadə edin (məsələn, 50-100). + Aralıq formatı yanlışdır. 'başlanğıc-son' formatından istifadə edin (məsələn, 50-100). sing-box üçün keş faylını aktiv et (qayda dəsti faylları) @@ -1453,7 +1453,7 @@ SVCB və HTTPS sorğularını blokla - DNS hostları: (hər sətirdə "domain1 ip1 ip2") + DNS hostları: (hər sətirdə "domain1 ip1 ip2") Əsas DNS parametrləri @@ -1558,25 +1558,25 @@ Ehtiyat seçim - '{0}' nüvəsi '{1}' şəbəkə növünü dəstəkləmir + '{0}' nüvəsi '{1}' şəbəkə növünü dəstəkləmir '{0}' nüvəsi '{1}' protokolunu '{2}' ötürmə protokolu ilə dəstəkləmir - '{0}' nüvəsi '{1}' protokolunu dəstəkləmir + '{0}' nüvəsi '{1}' protokolunu dəstəkləmir {0} xassəsi yanlışdır, yoxlayın - '{0}' protokolu dəstəklənmir + '{0}' protokolu dəstəklənmir Sistemdə sistem paneli funksiyası yoxdursa, bunu aktiv etməyin - Marşrutlaşdırma və DNS üçün ayrı qaydalar təyin edə və ya hər ikisinə tətbiq etmək üçün "ALL" seçə bilərsiniz + Marşrutlaşdırma və DNS üçün ayrı qaydalar təyin edə və ya hər ikisinə tətbiq etmək üçün "ALL" seçə bilərsiniz Qayda növü @@ -1654,10 +1654,10 @@ Təyin edildikdə sertifikat sabitlənəcək və "Təhlükəsiz olmayan əlaqəy Standart olaraq yalnız marşrutlaşdırma zamanı həll üçün çağırılır; uzaq serverin bu DNS-ə çata bildiyinə əmin olun - Təyin edilməyibsə və ya "AsIs" seçilibsə, DNS həlli sistem DNS-indən istifadə edir; əks halda daxili DNS modulu istifadə olunur. + Təyin edilməyibsə və ya "AsIs" seçilibsə, DNS həlli sistem DNS-indən istifadə edir; əks halda daxili DNS modulu istifadə olunur. - Təyin edilməyibsə və ya "AsIs" seçilibsə, DNS həlli uzaq serverin DNS-i tərəfindən aparılır; əks halda daxili DNS modulu istifadə olunur. + Təyin edilməyibsə və ya "AsIs" seçilibsə, DNS həlli uzaq serverin DNS-i tərəfindən aparılır; əks halda daxili DNS modulu istifadə olunur. Port dəyişmə intervalı @@ -1891,7 +1891,7 @@ Təyin edildikdə sertifikat sabitlənəcək və "Təhlükəsiz olmayan əlaqəy HTTP başlıqları (JSON) - İstəyə bağlıdır. Nümunə: {"X-hwid": "my_device"}. Dəyərlər abunəlik çevirmə xidməti də daxil olmaqla, bu qrupdakı bütün URL-lər üçün standart başlıqları əvəz edir. + İstəyə bağlıdır. Nümunə: {"X-hwid": "my_device"}. Dəyərlər abunəlik çevirmə xidməti də daxil olmaqla, bu qrupdakı bütün URL-lər üçün standart başlıqları əvəz edir. HTTP başlıqları yanlışdır. Unikal başlıq adları və sətir dəyərləri olan JSON obyektindən istifadə edin. Başlıq adlarında və dəyərlərində sətirsonu simvolları olmamalıdır. @@ -1899,4 +1899,4 @@ Təyin edildikdə sertifikat sabitlənəcək və "Təhlükəsiz olmayan əlaqəy Proses - + \ No newline at end of file diff --git a/v2rayN/v2rayN.Desktop/App.axaml b/v2rayN/v2rayN.Desktop/App.axaml index e64e1613..4ecb6337 100644 --- a/v2rayN/v2rayN.Desktop/App.axaml +++ b/v2rayN/v2rayN.Desktop/App.axaml @@ -20,17 +20,9 @@ - - - + diff --git a/v2rayN/v2rayN.Desktop/Assets/GlobalStyles.axaml b/v2rayN/v2rayN.Desktop/Assets/GlobalStyles.axaml index eccdeb91..a809e297 100644 --- a/v2rayN/v2rayN.Desktop/Assets/GlobalStyles.axaml +++ b/v2rayN/v2rayN.Desktop/Assets/GlobalStyles.axaml @@ -1,4 +1,8 @@ - + @@ -6,7 +10,7 @@ @@ -28,6 +32,10 @@ + + + + + diff --git a/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs b/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs index e4b883ae..8b4328f5 100644 --- a/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs +++ b/v2rayN/v2rayN.Desktop/Common/SimpleViewLocator.cs @@ -1,4 +1,3 @@ -using System.Runtime.CompilerServices; using Avalonia.Controls.Templates; using v2rayN.Desktop.ViewModels; using v2rayN.Desktop.Views; @@ -10,7 +9,6 @@ public class SimpleViewLocator : IDataTemplate private static readonly Lazy _instance = new(() => new SimpleViewLocator()); private readonly Dictionary> _locator = new(); - private readonly ConditionalWeakTable _cachedViews = new(); private SimpleViewLocator() { @@ -47,18 +45,9 @@ public class SimpleViewLocator : IDataTemplate return new TextBlock { Text = "No VM provided" }; } - var vmType = data.GetType(); - if (!_locator.TryGetValue(vmType, out var factory)) - { - return new TextBlock { Text = $"VM Not Registered: {vmType}" }; - } + _locator.TryGetValue(data.GetType(), out var factory); - if (ShouldCache(vmType)) - { - return _cachedViews.GetValue(data, _ => CreateView(factory, vmType)); - } - - return CreateView(factory, vmType); + return factory?.Invoke() ?? new TextBlock { Text = $"VM Not Registered: {data.GetType()}" }; } public bool Match(object? data) @@ -66,19 +55,6 @@ public class SimpleViewLocator : IDataTemplate return data is MyReactiveObject; } - private static bool ShouldCache(Type vmType) - { - return vmType == typeof(MsgViewModel) - || vmType == typeof(ClashProxiesViewModel) - || vmType == typeof(ClashConnectionsViewModel) - || vmType == typeof(ProfilesViewModel); - } - - private static Control CreateView(Func factory, Type vmType) - { - return factory.Invoke() ?? new TextBlock { Text = $"View Factory Returned Null: {vmType}" }; - } - public void RegisterViewFactory(Func factory) where TViewModel : class { _locator.Add(typeof(TViewModel), factory); diff --git a/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs b/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs index 4f542ca4..49155b6d 100644 --- a/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs +++ b/v2rayN/v2rayN.Desktop/ViewModels/ThemeSettingViewModel.cs @@ -1,16 +1,9 @@ -using Avalonia.Controls.Notifications; -using Avalonia.Controls.Primitives; -using AvaloniaEdit; using Semi.Avalonia; namespace v2rayN.Desktop.ViewModels; public partial class ThemeSettingViewModel : MyReactiveObject { - private Style? _fontSizeStyle; - private Style? _fontSizeExStyle; - private Style? _fontFamilyStyle; - [Reactive] public partial string CurrentTheme { get; set; } [Reactive] public partial int CurrentFontSize { get; set; } @@ -102,26 +95,7 @@ public partial class ThemeSettingViewModel : MyReactiveObject { return; } - - var style = new Style(x => Selectors.Or( - x.OfType