diff --git a/src/AboutAppInfoPopup.cs b/src/AboutAppInfoPopup.cs index e86786570ca8420e826d352942e873563658c63c..6d9bb7bcd3708fdc1134e3208a06948eac8e4d21 100644 --- a/src/AboutAppInfoPopup.cs +++ b/src/AboutAppInfoPopup.cs @@ -414,18 +414,18 @@ namespace System.Application.UI // b.Append(DeviceSecurityCheckUtil.IsEmulator.ToLowerString()); // b.AppendLine(); //} - b.Append("[device.gl.renderer] "); - b.Append(GLES20.GlGetString(GLES20.GlRenderer) ?? ""); - b.AppendLine(); - b.Append("[device.gl.vendor] "); - b.Append(GLES20.GlGetString(GLES20.GlVendor) ?? ""); - b.AppendLine(); - b.Append("[device.gl.version] "); - b.Append(GLES20.GlGetString(GLES20.GlVersion) ?? ""); - b.AppendLine(); - b.Append("[device.gl.extensions] "); - b.Append(GLES20.GlGetString(GLES20.GlExtensions) ?? ""); - b.AppendLine(); + //b.Append("[device.gl.renderer] "); + //b.Append(GLES20.GlGetString(GLES20.GlRenderer) ?? ""); + //b.AppendLine(); + //b.Append("[device.gl.vendor] "); + //b.Append(GLES20.GlGetString(GLES20.GlVendor) ?? ""); + //b.AppendLine(); + //b.Append("[device.gl.version] "); + //b.Append(GLES20.GlGetString(GLES20.GlVersion) ?? ""); + //b.AppendLine(); + //b.Append("[device.gl.extensions] "); + //b.Append(GLES20.GlGetString(GLES20.GlExtensions) ?? ""); + //b.AppendLine(); b.Append("[device.biometric] "); b.Append(IBiometricService.Instance.IsSupportedAsync().Result.ToLowerString()); b.AppendLine(); diff --git a/src/Common.ClientLib.Droid/Application/Security/DeviceSecurityCheckUtil.cs b/src/Common.ClientLib.Droid/Application/Security/DeviceSecurityCheckUtil.cs index 90ed0e88a7438fde58055173484aab6f67d6b9dc..7c27f58cafa4fdfedea8d6c5d12be801c9b805b5 100644 --- a/src/Common.ClientLib.Droid/Application/Security/DeviceSecurityCheckUtil.cs +++ b/src/Common.ClientLib.Droid/Application/Security/DeviceSecurityCheckUtil.cs @@ -267,23 +267,28 @@ // newRating++; // } -// try -// { -// var opengl = Android.Opengl.GLES20.GlGetString(Android.Opengl.GLES20.GlRenderer); -// if (!string.IsNullOrWhiteSpace(opengl)) -// { -//#pragma warning disable CS8604 // 可能的 null 引用参数。 -// if (contains(opengl, "Bluestacks") || -// contains(opengl, "Translator") || -// contains(opengl, "youwave") -// ) -//#pragma warning restore CS8604 // 可能的 null 引用参数。 -// newRating += 10; -// } -// } -// catch -// { -// } +/* signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdd0 + * Cause: null pointer dereference + * backtrace: + * #00 pc 0000000000005ff4 /system/lib64/libGLESv1_CM.so (glGetString+52) + */ +//// try +//// { +//// var opengl = Android.Opengl.GLES20.GlGetString(Android.Opengl.GLES20.GlRenderer); +//// if (!string.IsNullOrWhiteSpace(opengl)) +//// { +////#pragma warning disable CS8604 // 可能的 null 引用参数。 +//// if (contains(opengl, "Bluestacks") || +//// contains(opengl, "Translator") || +//// contains(opengl, "youwave") +//// ) +////#pragma warning restore CS8604 // 可能的 null 引用参数。 +//// newRating += 10; +//// } +//// } +//// catch +//// { +//// } // try // { diff --git a/src/Common.ClientLib/Application/Services/Implementation/PreferencesPlatformServiceImpl.cs b/src/Common.ClientLib/Application/Services/Implementation/PreferencesPlatformServiceImpl.cs index 51d302a55c0eb71b3e64d1d7f674d171e306485e..c89b5b7b84fc7859cbcca839561f7dcc4df8728e 100644 --- a/src/Common.ClientLib/Application/Services/Implementation/PreferencesPlatformServiceImpl.cs +++ b/src/Common.ClientLib/Application/Services/Implementation/PreferencesPlatformServiceImpl.cs @@ -2,9 +2,7 @@ using SQLite; using System.Application.Entities; using System.Application.Repositories; using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Globalization; -using NotNull = System.Diagnostics.CodeAnalysis.NotNullAttribute; using SQLiteNotNull = SQLite.NotNullAttribute; using SQLiteTable = SQLite.TableAttribute; @@ -26,93 +24,33 @@ namespace System.Application.Services.Implementation if (sharedName == null) return GetId(key); return $"{key}_{sharedName}_S"; } - public void PlatformClear(string? sharedName) { - if (sharedName == null) - { - conn.Execute(Sql_Delete_All); - } - else - { - conn.Execute(Sql_Delete_Where_SharedName_Equals, sharedName); - } + conn.Execute(Sql_Delete_Where_SharedName_Equals, sharedName ?? string.Empty); } - //public void PlatformClear(string? sharedName) - //{ - // if (sharedName == null) - // { - // conn.DeleteAll(); - // } - // else - // { - // var items = conn.Table().Where(x => x.SharedName == sharedName).ToArray(); - // foreach (var item in items) - // { - // conn.Delete(item); - // } - // } - //} - - //public bool PlatformContainsKey(string key, string? sharedName) - //{ - // int r; - // if (sharedName == null) - // { - // r = conn.Execute(Sql_Select_SharedName_Where_Key_Equals_And_SharedName_IsNull, GetId(key)); - // } - // else - // { - // r = conn.Execute(Sql_Select_SharedName_Where_Key_Equals_And_SharedName_Equals, GetId(key, sharedName), sharedName); - // } - // return r > 0; - //} - public bool PlatformContainsKey(string key, string? sharedName) { var id = GetId(key, sharedName); - var item = conn.Table().Where(x => x.Id == id && x.SharedName == sharedName).FirstOrDefault(); + sharedName ??= string.Empty; + var item = conn.Table() + .Where(x => x.Id == id && x.SharedName == sharedName) + .FirstOrDefault(); return item != null; } - //public T? PlatformGet(string key, T? defaultValue, string? sharedName) where T : notnull, IConvertible - //{ - // string? r; - // if (sharedName == null) - // { - // r = conn.ExecuteScalar(Sql_Select_Value_Where_Key_Equals_And_SharedName_IsNull, GetId(key)); - // } - // else - // { - // r = conn.ExecuteScalar(Sql_Select_Value_Where_Key_Equals_And_SharedName_Equals, GetId(key, sharedName), sharedName); - // } - // if (r == null) return defaultValue; - // var r2 = ConvertibleHelper.Convert(r); - // return r2; - //} - public T? PlatformGet(string key, T? defaultValue, string? sharedName) where T : notnull, IConvertible { var id = GetId(key, sharedName); - var item = conn.Table().Where(x => x.Id == id && x.SharedName == sharedName).FirstOrDefault(); + sharedName ??= string.Empty; + var item = conn.Table() + .Where(x => x.Id == id && x.SharedName == sharedName) + .FirstOrDefault(); if (item == null) return defaultValue; var value = ConvertibleHelper.Convert(item.Value); return value; } - //public void PlatformRemove(string key, string? sharedName) - //{ - // if (sharedName == null) - // { - // conn.Execute(Sql_Delete_Where_Id_Equals_And_SharedName_IsNull, GetId(key)); - // } - // else - // { - // conn.Execute(Sql_Delete_Where_Id_Equals_And_SharedName_Equals, GetId(key, sharedName), sharedName); - // } - //} - public void PlatformRemove(string key, string? sharedName) { var id = GetId(key, sharedName); @@ -132,19 +70,16 @@ namespace System.Application.Services.Implementation { Id = id, Value = value.ToString(CultureInfo.InvariantCulture), - SharedName = sharedName, + SharedName = sharedName ?? string.Empty, }); } } - const string TableName = "0984415E"; + const string TableName = "1984415E"; const string ColumnName_Id = "0F5E4BAA"; const string ColumnName_Value = "4FC331D7"; const string ColumnName_SharedName = "F6A739AA"; - const string Sql_Delete_All = - $"DELETE FROM \"{TableName}\""; - const string Sql_Delete_Where_SharedName_Equals = $"DELETE FROM \"{TableName}\" WHERE \"{ColumnName_SharedName}\" = ?"; @@ -174,19 +109,18 @@ namespace System.Application.Services.Implementation [Column(ColumnName_Id)] [PrimaryKey] [SQLiteNotNull] - [NotNull, DisallowNull] // C# 8 not null - public string? Id { get; set; } + public string Id { get; set; } = string.Empty; [Column(ColumnName_Value)] [SQLiteNotNull] - [NotNull, DisallowNull] // C# 8 not null - public string? Value { get; set; } + public string Value { get; set; } = string.Empty; #pragma warning restore CS8618 // 在退出构造函数时,不可为 null 的字段必须包含非 null 值。请考虑声明为可以为 null。 [Column(ColumnName_SharedName)] - public string? SharedName { get; set; } + [SQLiteNotNull] + public string SharedName { get; set; } = string.Empty; - string DebuggerDisplay() => SharedName == null ? $"{Id}, {Value}" : $"{Id}, {Value}, {SharedName}"; + string DebuggerDisplay() => SharedName == string.Empty ? $"{Id}, {Value}" : $"{Id}, {Value}, {SharedName}"; } } } diff --git a/src/ST.Client.Android/Services/Implementation/AndroidDeviceInfoPlatformServiceImpl.cs b/src/ST.Client.Android/Services/Implementation/AndroidDeviceInfoPlatformServiceImpl.cs index 2301a861ff649e0750c5c581db234f33300d005c..bfbe02a5e76d53f72046f77b50d2c22d9851c0bb 100644 --- a/src/ST.Client.Android/Services/Implementation/AndroidDeviceInfoPlatformServiceImpl.cs +++ b/src/ST.Client.Android/Services/Implementation/AndroidDeviceInfoPlatformServiceImpl.cs @@ -114,23 +114,28 @@ namespace System.Application.Services.Implementation newRating++; } - try - { - var opengl = Android.Opengl.GLES20.GlGetString(Android.Opengl.GLES20.GlRenderer); - if (!string.IsNullOrWhiteSpace(opengl)) - { -#pragma warning disable CS8604 // 可能的 null 引用参数。 - if (contains(opengl, "Bluestacks") || - contains(opengl, "Translator") || - contains(opengl, "youwave") - ) -#pragma warning restore CS8604 // 可能的 null 引用参数。 - newRating += 10; - } - } - catch - { - } + /* signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0xdd0 + * Cause: null pointer dereference + * backtrace: + * #00 pc 0000000000005ff4 /system/lib64/libGLESv1_CM.so (glGetString+52) + */ +// try +// { +// var opengl = Android.Opengl.GLES20.GlGetString(Android.Opengl.GLES20.GlRenderer); +// if (!string.IsNullOrWhiteSpace(opengl)) +// { +//#pragma warning disable CS8604 // 可能的 null 引用参数。 +// if (contains(opengl, "Bluestacks") || +// contains(opengl, "Translator") || +// contains(opengl, "youwave") +// ) +//#pragma warning restore CS8604 // 可能的 null 引用参数。 +// newRating += 10; +// } +// } +// catch +// { +// } try { diff --git a/src/ST.Client/UI/ViewModels/MainWindowViewModel.TabItems.cs b/src/ST.Client/UI/ViewModels/MainWindowViewModel.TabItems.cs index a744ef7a86b7dee9c5c01beffbcc623c65e44e53..39f8be13597467d1798236d672e406143e518f65 100644 --- a/src/ST.Client/UI/ViewModels/MainWindowViewModel.TabItems.cs +++ b/src/ST.Client/UI/ViewModels/MainWindowViewModel.TabItems.cs @@ -9,7 +9,24 @@ namespace System.Application.UI.ViewModels readonly Dictionary> mTabItems = new(); public IEnumerable TabItems => mTabItems.Values.Select(x => x.Value); - public IReadOnlyList? FooterTabItems { get; private set; } + IReadOnlyList? _FooterTabItems; + public IReadOnlyList? FooterTabItems + { + get + { + if (_FooterTabItems == null) + { + var settingsPageVM = SettingsPageViewModel.Instance; + var aboutPageVM = AboutPageViewModel.Instance; + _FooterTabItems = new List + { + settingsPageVM, + aboutPageVM, + }; + } + return _FooterTabItems; + } + } public IEnumerable AllTabItems { @@ -20,6 +37,18 @@ namespace System.Application.UI.ViewModels } } + /// + /// 当前 ,延时加载 + /// + public IEnumerable CurrentAllTabItems + { + get + { + if (_FooterTabItems == null) return TabItems; + else return TabItems.Concat(_FooterTabItems); + } + } + void AddTabItem() where TabItemVM : TabItemViewModel, new() { Lazy value = new(() => new TabItemVM() diff --git a/src/ST.Client/UI/ViewModels/MainWindowViewModel.cs b/src/ST.Client/UI/ViewModels/MainWindowViewModel.cs index 0ed2a3849ba46b1ce9948574302330bae12c87b1..f7eba2abc98ca5e511786325d062fc83ac0ccf32 100644 --- a/src/ST.Client/UI/ViewModels/MainWindowViewModel.cs +++ b/src/ST.Client/UI/ViewModels/MainWindowViewModel.cs @@ -88,20 +88,14 @@ namespace System.Application.UI.ViewModels }); } - FooterTabItems = new List - { - SettingsPageViewModel.Instance, - AboutPageViewModel.Instance, - }; - #region InitTabItems //AddTabItem(); AddTabItem(); - AddTabItem(); if (IApplication.IsDesktopPlatform) { + AddTabItem(); AddTabItem(); AddTabItem(); } @@ -134,7 +128,7 @@ namespace System.Application.UI.ViewModels R.Subscribe(() => { - foreach (var item in AllTabItems) + foreach (var item in CurrentAllTabItems) { item.RaisePropertyChanged(nameof(TabItemViewModelBase.Name)); } diff --git a/src/ST.Client/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs index 9054999cee262f27920f3d360b87175473c4ad68..9079ad1c8a5a83410252ef8d2131efbf399a5132 100644 --- a/src/ST.Client/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/CommunityProxyPageViewModel.cs @@ -19,7 +19,7 @@ namespace System.Application.UI.ViewModels { public partial class CommunityProxyPageViewModel { - readonly IHostsFileService hostsFileService = IHostsFileService.Instance; + readonly IHostsFileService? hostsFileService; readonly IPlatformService platformService = IPlatformService.Instance; public ReactiveCommand? SetupCertificateCommand { get; } @@ -58,6 +58,7 @@ namespace System.Application.UI.ViewModels if (IApplication.IsDesktopPlatform) { + hostsFileService = IHostsFileService.Instance; SetupCertificateCommand = ReactiveCommand.Create(SetupCertificate_OnClick); DeleteCertificateCommand = ReactiveCommand.Create(DeleteCertificate_OnClick); EditHostsFileCommand = ReactiveCommand.Create(hostsFileService.OpenFile); diff --git a/src/ST.Client/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs b/src/ST.Client/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs index 2c46dbf6466672a53cafd24087466cbaabbe298d..d97d07ced6a0629f7b16a6b48c53f680bc93893f 100644 --- a/src/ST.Client/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs +++ b/src/ST.Client/UI/ViewModels/Pages/Settings/SettingsPageViewModel.cs @@ -28,12 +28,12 @@ namespace System.Application.UI.ViewModels UpdateChannels = Enum2.GetAll(); - SelectFont = R.Fonts.FirstOrDefault(x => x.Value == UISettings.FontName.Value); - this.WhenValueChanged(x => x.SelectFont, false) - .Subscribe(x => UISettings.FontName.Value = x.Value); - if (IApplication.IsDesktopPlatform) { + SelectFont = R.Fonts.FirstOrDefault(x => x.Value == UISettings.FontName.Value); + this.WhenValueChanged(x => x.SelectFont, false) + .Subscribe(x => UISettings.FontName.Value = x.Value); + SelectImage_Click = ReactiveCommand.CreateFromTask(async () => { FilePickerFileType fileTypes = new ValueTuple[] {