diff --git a/src/ST.Client.Desktop.Avalonia/ServiceCollectionExtensions.AddShowWindowService.cs b/src/ST.Client.Desktop.Avalonia/ServiceCollectionExtensions.AddShowWindowService.cs
new file mode 100644
index 000000000..c690e43a3
--- /dev/null
+++ b/src/ST.Client.Desktop.Avalonia/ServiceCollectionExtensions.AddShowWindowService.cs
@@ -0,0 +1,20 @@
+using System.Application.Services;
+using System.Application.Services.Implementation;
+
+// ReSharper disable once CheckNamespace
+namespace Microsoft.Extensions.DependencyInjection
+{
+ public static partial class ServiceCollectionExtensions
+ {
+ ///
+ /// 添加显示窗口服务
+ ///
+ ///
+ ///
+ public static IServiceCollection AddShowWindowService(this IServiceCollection services)
+ {
+ services.AddSingleton();
+ return services;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Desktop.Avalonia/ServiceCollectionExtensions.cs b/src/ST.Client.Desktop.Avalonia/ServiceCollectionExtensions.cs
index 7edf49c52..702509002 100644
--- a/src/ST.Client.Desktop.Avalonia/ServiceCollectionExtensions.cs
+++ b/src/ST.Client.Desktop.Avalonia/ServiceCollectionExtensions.cs
@@ -1,5 +1,4 @@
using Avalonia.Controls;
-using System;
using System.Application.Services;
using System.Application.Services.Implementation;
using System.Application.UI;
@@ -7,7 +6,7 @@ using System.Application.UI;
// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection
{
- public static class ServiceCollectionExtensions
+ public static partial class ServiceCollectionExtensions
{
///
/// 添加主线程助手类(MainThreadDesktop)服务
@@ -20,17 +19,6 @@ namespace Microsoft.Extensions.DependencyInjection
return services;
}
- ///
- /// 添加显示窗口服务
- ///
- ///
- ///
- public static IServiceCollection AddShowWindowService(this IServiceCollection services)
- {
- services.AddSingleton();
- return services;
- }
-
///
/// 添加应用程序更新服务
///
diff --git a/src/ST.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs b/src/ST.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs
index 56632b5b4..60967575a 100644
--- a/src/ST.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs
+++ b/src/ST.Client.Desktop.Avalonia/Windows/WpfCompatExtensions.cs
@@ -31,7 +31,7 @@ namespace System.Windows
window.CanResize = true;
break;
}
- p.SetResizeMode(window.PlatformImpl.Handle.Handle, (int)value);
+ p.SetResizeMode(window.PlatformImpl.Handle.Handle, value);
}
static readonly bool IsWin32NT = Environment.OSVersion.Platform == PlatformID.Win32NT;
diff --git a/src/ST.Client.Desktop.Linux/Services/Implementation/LinuxDesktopPlatformServiceImpl.cs b/src/ST.Client.Desktop.Linux/Services/Implementation/LinuxDesktopPlatformServiceImpl.cs
index 4321b7aab..a313e8900 100644
--- a/src/ST.Client.Desktop.Linux/Services/Implementation/LinuxDesktopPlatformServiceImpl.cs
+++ b/src/ST.Client.Desktop.Linux/Services/Implementation/LinuxDesktopPlatformServiceImpl.cs
@@ -1,12 +1,13 @@
using System.Application.Models;
using System.Diagnostics;
using System.IO;
+using System.Windows;
namespace System.Application.Services.Implementation
{
internal sealed partial class LinuxDesktopPlatformServiceImpl : IDesktopPlatformService
{
- public void SetResizeMode(IntPtr hWnd, int value)
+ public void SetResizeMode(IntPtr hWnd, ResizeModeCompat value)
{
}
diff --git a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.cs b/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.cs
index b50b6d16d..b5801a410 100644
--- a/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.cs
+++ b/src/ST.Client.Desktop.Mac/Services/Implementation/MacDesktopPlatformServiceImpl.cs
@@ -7,12 +7,13 @@ using System.Application.Models;
using System.Diagnostics;
using System.IO;
using System.Runtime.InteropServices;
+using System.Windows;
namespace System.Application.Services.Implementation
{
internal sealed partial class MacDesktopPlatformServiceImpl : IDesktopPlatformService
{
- public void SetResizeMode(IntPtr hWnd, int value)
+ public void SetResizeMode(IntPtr hWnd, ResizeModeCompat value)
{
}
@@ -29,7 +30,7 @@ namespace System.Application.Services.Implementation
Arguments = $"-a \"{name}\" \"{filePath}\"",
};
pInfo.UseShellExecute = true;
- var p = Process.Start(pInfo);
+ var p = Process.Start(pInfo);
if (p == null) throw new FileNotFoundException(name);
p.Close();
}
diff --git a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.WindowTopRightButtons.cs b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.WindowTopRightButtons.cs
index 1c288c3cd..472f97c1f 100644
--- a/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.WindowTopRightButtons.cs
+++ b/src/ST.Client.Desktop.Windows/Services/Implementation/WindowsDesktopPlatformServiceImpl.WindowTopRightButtons.cs
@@ -1,4 +1,5 @@
using System.Runtime.InteropServices;
+using System.Windows;
namespace System.Application.Services.Implementation
{
@@ -85,16 +86,16 @@ namespace System.Application.Services.Implementation
_ = SetWindowLong(hWnd, GWL_STYLE, GetWindowLong(hWnd, GWL_STYLE) & ~WS_MAXIMIZEBOX);
}
- public void SetResizeMode(IntPtr hWnd, int value)
+ public void SetResizeMode(IntPtr hWnd, ResizeModeCompat value)
{
switch (value)
{
- case IDesktopPlatformService.ResizeMode_NoResize:
+ case ResizeModeCompat.NoResize:
_ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MAXIMIZE, MF_BYCOMMAND);
_ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MINIMIZE, MF_BYCOMMAND);
HideMinimizeAndMaximizeButtons(hWnd);
break;
- case IDesktopPlatformService.ResizeMode_CanMinimize:
+ case ResizeModeCompat.CanMinimize:
_ = DeleteMenu(GetSystemMenu(hWnd, false), SC_MAXIMIZE, MF_BYCOMMAND);
DisableMaximizeButton(hWnd);
break;
diff --git a/src/ST.Client.Desktop/CustomWindow.cs b/src/ST.Client.Desktop/CustomWindow.cs
index 8bc1b1541..deac5e106 100644
--- a/src/ST.Client.Desktop/CustomWindow.cs
+++ b/src/ST.Client.Desktop/CustomWindow.cs
@@ -5,13 +5,18 @@ namespace System.Application
///
public enum CustomWindow
{
+#if !__MOBILE__
LoginOrRegister,
+#endif
MessageBox,
+#if !__MOBILE__
AddAuth,
ShowAuth,
AuthTrade,
EncryptionAuth,
+#endif
Password,
+#if !__MOBILE__
TaskBar,
ExportAuth,
ScriptStore,
@@ -23,5 +28,6 @@ namespace System.Application
NewVersion,
WebView3,
BindPhoneNumber,
+#endif
}
}
\ No newline at end of file
diff --git a/src/ST.Client.Desktop/MessageBox/MessageBoxCompat.cs b/src/ST.Client.Desktop/MessageBox/MessageBoxCompat.cs
index 238ee9c56..cf7595554 100644
--- a/src/ST.Client.Desktop/MessageBox/MessageBoxCompat.cs
+++ b/src/ST.Client.Desktop/MessageBox/MessageBoxCompat.cs
@@ -1,4 +1,4 @@
-using System.Application;
+using System.Application;
using System.Application.Services;
using System.Application.UI.ViewModels;
using System.Properties;
@@ -10,20 +10,20 @@ namespace System.Windows
///
/// 显示消息框。
///
- public static class MessageBoxCompat
+ public static partial class MessageBoxCompat
{
const string default_caption = ThisAssembly.AssemblyTrademark;
const MessageBoxButtonCompat default_button = MessageBoxButtonCompat.OK;
+ static readonly Lazy mbcs =
+ new(DI.Get_Nullable);
///
public static async Task ShowAsync(
string messageBoxText, string caption, MessageBoxButtonCompat button, MessageBoxImageCompat? icon = null)
{
- var f = DI.Get_Nullable();
-
- if (f != null)
+ if (mbcs.Value != null)
{
- return await f.ShowAsync(messageBoxText, caption, button, icon);
+ return await mbcs.Value.ShowAsync(messageBoxText, caption, button, icon);
}
var viewModel = new MessageBoxWindowViewModel
diff --git a/src/ST.Client.Desktop/MessageBox/ResizeModeCompat.cs b/src/ST.Client.Desktop/MessageBox/ResizeModeCompat.cs
index 53f3efd68..3cc5cddab 100644
--- a/src/ST.Client.Desktop/MessageBox/ResizeModeCompat.cs
+++ b/src/ST.Client.Desktop/MessageBox/ResizeModeCompat.cs
@@ -1,5 +1,3 @@
-using System.Application.Services;
-
// ReSharper disable once CheckNamespace
namespace System.Windows
{
@@ -11,22 +9,22 @@ namespace System.Windows
///
/// 用户无法调整窗口的大小。 不显示 "最大化" 和 "最小化" 框。
///
- NoResize = IDesktopPlatformService.ResizeMode_NoResize,
+ NoResize,
///
/// 用户只能最小化窗口并从任务栏还原。 同时显示 "最小化" 和 "最大化" 框,但只启用 "最小化" 框。
///
- CanMinimize = IDesktopPlatformService.ResizeMode_CanMinimize,
+ CanMinimize,
///
/// 用户可以通过使用 "最小化" 和 "最大化" 框以及围绕窗口的可拖动轮廓来完全调整窗口的大小。 显示和启用 "最小化" 和 "最大化" 框。 (默认) 。
///
- CanResize = IDesktopPlatformService.ResizeMode_CanResize,
+ CanResize,
///
/// 此选项具有与相同的功能 ,但会将 "调整手柄" 添加到窗口的右下角。
///
[Obsolete("not implemented")]
- CanResizeWithGrip = IDesktopPlatformService.ResizeMode_CanResizeWithGrip,
+ CanResizeWithGrip,
}
}
\ No newline at end of file
diff --git a/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs b/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs
index 3c7573694..73c2de457 100644
--- a/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs
+++ b/src/ST.Client.Desktop/Services/IDesktopPlatformService.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Versioning;
using System.Security.Cryptography;
-using ResizeMode = System.Int32;
+using System.Windows;
namespace System.Application.Services
{
@@ -14,7 +14,7 @@ namespace System.Application.Services
public static IDesktopPlatformService Instance => DI.Get();
- void SetResizeMode(IntPtr hWnd, ResizeMode value);
+ void SetResizeMode(IntPtr hWnd, ResizeModeCompat value);
///
/// 获取一个正在运行的进程的命令行参数。
@@ -153,11 +153,6 @@ namespace System.Application.Services
#endregion
- public const ResizeMode ResizeMode_NoResize = 0;
- public const ResizeMode ResizeMode_CanMinimize = 1;
- public const ResizeMode ResizeMode_CanResize = 2;
- public const ResizeMode ResizeMode_CanResizeWithGrip = 3;
-
#region MachineUniqueIdentifier
private static (byte[] key, byte[] iv) GetMachineSecretKey(string? value)
diff --git a/src/ST.Client.Desktop/Services/IShowWindowService.cs b/src/ST.Client.Desktop/Services/IShowWindowService.cs
index 7edc2050f..77275dbba 100644
--- a/src/ST.Client.Desktop/Services/IShowWindowService.cs
+++ b/src/ST.Client.Desktop/Services/IShowWindowService.cs
@@ -1,6 +1,9 @@
using System.Application.UI.ViewModels;
using System.Threading.Tasks;
using System.Windows;
+#if __MOBILE__
+using WindowViewModel = System.Application.UI.ViewModels.PageViewModel;
+#endif
namespace System.Application.Services
{
@@ -67,8 +70,10 @@ namespace System.Application.Services
bool isDialog = true);
+#if !__MOBILE__
void CloseWindow(WindowViewModel vm);
void HideWindow(WindowViewModel vm);
void ShowWindow(WindowViewModel vm);
+#endif
}
}
\ No newline at end of file
diff --git a/src/ST.Client.Desktop/UI/ViewModels/Base/DialogWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Base/DialogWindowViewModel.cs
index db448d59c..8c914890a 100644
--- a/src/ST.Client.Desktop/UI/ViewModels/Base/DialogWindowViewModel.cs
+++ b/src/ST.Client.Desktop/UI/ViewModels/Base/DialogWindowViewModel.cs
@@ -1,4 +1,7 @@
-using System.Windows.Input;
+using System.Windows.Input;
+#if __MOBILE__
+using WindowViewModel = System.Application.UI.ViewModels.PageViewModel;
+#endif
namespace System.Application.UI.ViewModels
{
diff --git a/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.shared.cs b/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.shared.cs
index 63081a4e7..780fc2b8a 100644
--- a/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.shared.cs
+++ b/src/ST.Client.Desktop/UI/ViewModels/Pages/About/AboutPageViewModel.shared.cs
@@ -42,15 +42,11 @@ namespace System.Application.UI.ViewModels
DelAccountCommand = ReactiveCommand.CreateFromTask(async () =>
{
if (!UserService.Current.IsAuthenticated) return;
-#if !__MOBILE__
var r = await MessageBoxCompat.ShowAsync(AppResources.DelAccountTips, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OKCancel);
if (r == MessageBoxResultCompat.OK)
{
await UserService.Current.DelAccountAsync();
}
-#else
- throw new NotImplementedException();
-#endif
});
#if __MOBILE__
diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/PasswordWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/PasswordWindowViewModel.cs
index 5f565d19d..a0028a606 100644
--- a/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/PasswordWindowViewModel.cs
+++ b/src/ST.Client.Desktop/UI/ViewModels/Windows/LocalAuthPage/PasswordWindowViewModel.cs
@@ -1,11 +1,11 @@
-using Newtonsoft.Json.Linq;
using ReactiveUI;
-using System.Application.Models;
using System.Application.Services;
using System.Application.UI.Resx;
-using System.Properties;
using System.Threading.Tasks;
using System.Windows;
+#if __MOBILE__
+using WindowViewModel = System.Application.UI.ViewModels.PageViewModel;
+#endif
namespace System.Application.UI.ViewModels
{
@@ -23,7 +23,6 @@ namespace System.Application.UI.ViewModels
set => this.RaiseAndSetIfChanged(ref _Password, value);
}
-
public static async Task ShowPasswordDialog()
{
var vm = new PasswordWindowViewModel();
@@ -31,12 +30,25 @@ namespace System.Application.UI.ViewModels
return vm.Password;
}
-
- public void Ok()
+ ///
+ /// 输入内容验证
+ ///
+ ///
+ public bool InputValidator()
{
if (string.IsNullOrWhiteSpace(Password))
{
Toast.Show(AppResources.LocalAuth_ProtectionAuth_PasswordErrorTip);
+ return false;
+ }
+ return true;
+ }
+
+#if !__MOBILE__
+ public void Ok()
+ {
+ if (!InputValidator())
+ {
return;
}
this.Close();
@@ -47,5 +59,6 @@ namespace System.Application.UI.ViewModels
Password = string.Empty;
this.Close();
}
+#endif
}
}
\ No newline at end of file
diff --git a/src/ST.Client.Desktop/UI/ViewModels/Windows/MessageBoxWindowViewModel.cs b/src/ST.Client.Desktop/UI/ViewModels/Windows/MessageBoxWindowViewModel.cs
index ebb69b326..774e24023 100644
--- a/src/ST.Client.Desktop/UI/ViewModels/Windows/MessageBoxWindowViewModel.cs
+++ b/src/ST.Client.Desktop/UI/ViewModels/Windows/MessageBoxWindowViewModel.cs
@@ -1,4 +1,4 @@
-using ReactiveUI;
+using ReactiveUI;
namespace System.Application.UI.ViewModels
{
diff --git a/src/ST.Client.Mobile.Droid.Design/ui/src/main/res/layout/activity_textblock.xml b/src/ST.Client.Mobile.Droid.Design/ui/src/main/res/layout/activity_textblock.xml
new file mode 100644
index 000000000..a04f09da6
--- /dev/null
+++ b/src/ST.Client.Mobile.Droid.Design/ui/src/main/res/layout/activity_textblock.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ST.Client.Mobile.Droid.Design/ui/src/main/res/layout/textbox_password.xml b/src/ST.Client.Mobile.Droid.Design/ui/src/main/res/layout/textbox_password.xml
new file mode 100644
index 000000000..9a22d0451
--- /dev/null
+++ b/src/ST.Client.Mobile.Droid.Design/ui/src/main/res/layout/textbox_password.xml
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+
+
diff --git a/src/ST.Client.Mobile.Droid/GoToPlatformPages.cs b/src/ST.Client.Mobile.Droid/GoToPlatformPages.cs
index e66c415c3..5097abda4 100644
--- a/src/ST.Client.Mobile.Droid/GoToPlatformPages.cs
+++ b/src/ST.Client.Mobile.Droid/GoToPlatformPages.cs
@@ -45,5 +45,86 @@ namespace System.Application
public static void StartActivity(this Fragment fragment) where TActivity : Activity
=> StartActivity(fragment, typeof(TActivity));
+
+ const string KEY_ViewModel = "ByteArrayViewModel";
+ static void StartActivity(this Activity activity, Type activityType, byte[] viewModel)
+ {
+ var intent = new Intent(activity, activityType);
+ intent.PutExtra(KEY_ViewModel, viewModel);
+ activity.StartActivity(intent);
+ }
+
+ public static TViewModel? GetViewModel(this Activity activity)
+ {
+ var intent = activity.Intent;
+ if (intent != null)
+ {
+ var byteArray = intent.GetByteArrayExtra(KEY_ViewModel);
+ if (byteArray != null)
+ {
+ try
+ {
+ var value = Serializable.DMP(byteArray);
+ return value;
+ }
+ catch
+ {
+
+ }
+ }
+ }
+ return default;
+ }
+
+ public static void StartActivity(Activity activity, Type activityType, object viewModel, Type? viewModelType = null)
+ {
+ viewModelType ??= viewModel.GetType();
+ var viewModel_ = Serializable.SMP(viewModelType, viewModel);
+ StartActivity(activity, activityType, viewModel_);
+ }
+
+ public static void StartActivity(Fragment fragment, Type activityType, object viewModel, Type? viewModelType = null)
+ {
+ var activity = fragment.Activity;
+ if (activity == null) return;
+ StartActivity(activity, activityType, viewModel, viewModelType);
+ }
+
+ public static void StartActivity(Activity activity, object viewModel, Type? viewModelType = null)
+ {
+ StartActivity(activity, typeof(TActivity), viewModel, viewModelType);
+ }
+
+ public static void StartActivity(Fragment fragment, object viewModel, Type? viewModelType = null)
+ {
+ var activity = fragment.Activity;
+ if (activity == null) return;
+ StartActivity(activity, viewModel, viewModelType);
+ }
+
+ public static void StartActivity(Activity activity, Type activityType, TViewModel viewModel)
+ {
+ var viewModel_ = Serializable.SMP(viewModel);
+ StartActivity(activity, activityType, viewModel_);
+ }
+
+ public static void StartActivity(Fragment fragment, Type activityType, TViewModel viewModel)
+ {
+ var activity = fragment.Activity;
+ if (activity == null) return;
+ StartActivity(activity, activityType, viewModel);
+ }
+
+ public static void StartActivity(Activity activity, TViewModel viewModel)
+ {
+ StartActivity(activity, typeof(TActivity), viewModel);
+ }
+
+ public static void StartActivity(Fragment fragment, TViewModel viewModel)
+ {
+ var activity = fragment.Activity;
+ if (activity == null) return;
+ StartActivity(activity, viewModel);
+ }
}
}
\ No newline at end of file
diff --git a/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj b/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj
index d65514d9f..931ac551a 100644
--- a/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj
+++ b/src/ST.Client.Mobile.Droid/ST.Client.Mobile.Droid.csproj
@@ -83,6 +83,7 @@
+
@@ -347,6 +348,9 @@
Resources\layout\activity_main.xml
+
+ Resources\layout\activity_textblock.xml
+
Resources\layout\fragment_community_fix.xml
@@ -386,6 +390,9 @@
Resources\layout\shared_toolbar.xml
+
+ Resources\layout\textbox_password.xml
+
Resources\menu\bottom_nav_menu.xml
@@ -482,3 +489,5 @@
+
+
diff --git a/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs b/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs
index 1ad73706d..6d4ec9927 100644
--- a/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs
+++ b/src/ST.Client.Mobile.Droid/ServiceCollectionExtensions.cs
@@ -1,4 +1,4 @@
-using Microsoft.Extensions.Http;
+using Microsoft.Extensions.Http;
using System.Application.Services;
using System.Application.Services.Implementation;
using System.Net.Http;
diff --git a/src/ST.Client.Mobile.Droid/Services/Implementation/ShowWindowServiceImpl.cs b/src/ST.Client.Mobile.Droid/Services/Implementation/ShowWindowServiceImpl.cs
new file mode 100644
index 000000000..cabec51a4
--- /dev/null
+++ b/src/ST.Client.Mobile.Droid/Services/Implementation/ShowWindowServiceImpl.cs
@@ -0,0 +1,136 @@
+using Android.Content;
+using Android.Views;
+using Binding;
+using Google.Android.Material.Dialog;
+using System.Application.UI.Resx;
+using System.Application.UI.ViewModels;
+using System.Threading.Tasks;
+using System.Windows;
+using AlertDialog = AndroidX.AppCompat.App.AlertDialog;
+using XEPlatform = Xamarin.Essentials.Platform;
+
+namespace System.Application.Services.Implementation
+{
+ internal sealed class ShowWindowServiceImpl : IShowWindowService
+ {
+ static string PositiveButtonText => AppResources.Confirm;
+ static string NegativeButtonText => AppResources.Cancel;
+
+ Task PlatformShowWindow(CustomWindow customWindow, PageViewModel? viewModel = null, string title = "")
+ {
+ TaskCompletionSource tcs = new();
+ try
+ {
+ AlertDialog? dialog = null;
+
+ void SetConfirmButton(MaterialAlertDialogBuilder b)
+ {
+ b.SetPositiveButton(PositiveButtonText, (_, e) =>
+ {
+ tcs.TrySetResult(true);
+ });
+ }
+ void SetCancelButton(MaterialAlertDialogBuilder b)
+ {
+ b.SetNegativeButton(NegativeButtonText, (_, e) =>
+ {
+ tcs.TrySetResult(false);
+ });
+ }
+
+ Action? CreateMessageBoxDialogWindow(MaterialAlertDialogBuilder b)
+ {
+ SetConfirmButton(b);
+ SetCancelButton(b);
+ if (viewModel is MessageBoxWindowViewModel viewModel_mb)
+ {
+ b.SetMessage(viewModel_mb.Content);
+ }
+ return null;
+ }
+ Action? CreatePasswordDialogWindow(MaterialAlertDialogBuilder b)
+ {
+ // https://material.io/components/text-fields/android
+ // https://material.io/components/dialogs#specs
+ IDialogInterfaceOnClickListener? listener = null;
+ b.SetPositiveButton(PositiveButtonText, listener);
+ SetCancelButton(b);
+ var view = LayoutInflater.From(b.Context)!.Inflate(Resource.Layout.textbox_password, null, false)!;
+ var binding = new textbox_password(view);
+ binding.layoutPassword.Hint = AppResources.LocalAuth_PasswordRequired1;
+ b.SetView(view);
+ return d =>
+ {
+ d.GetButton((int)DialogButtonType.Positive).Click += (_, _) =>
+ {
+ if (viewModel is PasswordWindowViewModel viewModel_p)
+ {
+ viewModel_p.Password = binding.tbPassword.Text;
+ if (viewModel_p.InputValidator())
+ {
+ d.Dismiss();
+ tcs.TrySetResult(true);
+ }
+ }
+ };
+ };
+ }
+
+ Func?> @delegate = customWindow switch
+ {
+ CustomWindow.MessageBox => CreateMessageBoxDialogWindow,
+ CustomWindow.Password => CreatePasswordDialogWindow,
+ _ => throw new NotImplementedException(),
+ };
+ if (!string.IsNullOrEmpty(title) && viewModel != null)
+ {
+ viewModel.Title = title;
+ }
+ var builder = new MaterialAlertDialogBuilder(XEPlatform.CurrentActivity);
+ if (!string.IsNullOrWhiteSpace(viewModel?.Title))
+ {
+ builder.SetTitle(viewModel!.Title);
+ }
+ var dialog_delegate = @delegate(builder);
+ dialog = builder.Create();
+ dialog.CancelEvent += (_, _) =>
+ {
+ tcs.TrySetResult(false);
+ };
+ if (dialog_delegate != null)
+ {
+ dialog.ShowEvent += (_, _) =>
+ {
+ dialog_delegate?.Invoke(dialog);
+ };
+ }
+ dialog.Show();
+ }
+ catch (Exception e)
+ {
+ tcs.TrySetException(e);
+ }
+ return tcs.Task;
+ }
+
+ public async Task Show(CustomWindow customWindow, TWindowViewModel? viewModel = null, string title = "", ResizeModeCompat resizeMode = default, bool isDialog = false, bool isParent = true) where TWindowViewModel : PageViewModel, new()
+ {
+ await PlatformShowWindow(customWindow, viewModel, title);
+ }
+
+ public async Task Show(Type typeWindowViewModel, CustomWindow customWindow, PageViewModel? viewModel = null, string title = "", ResizeModeCompat resizeMode = default, bool isDialog = false, bool isParent = true)
+ {
+ await PlatformShowWindow(customWindow, viewModel, title);
+ }
+
+ public async Task ShowDialog(CustomWindow customWindow, TWindowViewModel? viewModel = null, string title = "", ResizeModeCompat resizeMode = default, bool isDialog = true) where TWindowViewModel : PageViewModel, new()
+ {
+ return await PlatformShowWindow(customWindow, viewModel, title);
+ }
+
+ public async Task ShowDialog(Type typeWindowViewModel, CustomWindow customWindow, PageViewModel? viewModel = null, string title = "", ResizeModeCompat resizeMode = default, bool isDialog = true)
+ {
+ await PlatformShowWindow(customWindow, viewModel, title);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Mobile.Droid/UI/Activities/AboutActivity.cs b/src/ST.Client.Mobile.Droid/UI/Activities/AboutActivity.cs
index 57134495b..dda278ae9 100644
--- a/src/ST.Client.Mobile.Droid/UI/Activities/AboutActivity.cs
+++ b/src/ST.Client.Mobile.Droid/UI/Activities/AboutActivity.cs
@@ -86,7 +86,11 @@ namespace System.Application.UI.Activities
R.Language));
break;
case PreferenceButton.开放源代码许可:
- throw new NotImplementedException();
+ TextBlockActivity.StartActivity(this, new TextBlockViewModel
+ {
+ Title = AppResources.About_OpenSource,
+ ContentSource = TextBlockViewModel.ContentSourceEnum.OpenSourceLibrary,
+ });
break;
case PreferenceButton.源码仓库:
new MaterialAlertDialogBuilder(this).SetItems(SourceRepositories, (_, e) => BrowserOpenByDialogClick(e, value => value switch
diff --git a/src/ST.Client.Mobile.Droid/UI/Activities/TextBlockActivity.cs b/src/ST.Client.Mobile.Droid/UI/Activities/TextBlockActivity.cs
new file mode 100644
index 000000000..eb15fbec2
--- /dev/null
+++ b/src/ST.Client.Mobile.Droid/UI/Activities/TextBlockActivity.cs
@@ -0,0 +1,47 @@
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Android.Runtime;
+using Binding;
+using System.Application.Models;
+using System.Application.UI.ViewModels;
+
+namespace System.Application.UI.Activities
+{
+ [Register(JavaPackageConstants.Activities + nameof(TextBlockActivity))]
+ [Activity(Theme = ManifestConstants.MainTheme_NoActionBar,
+ LaunchMode = LaunchMode.SingleTask,
+ ConfigurationChanges = ManifestConstants.ConfigurationChanges)]
+ internal sealed class TextBlockActivity : BaseActivity
+ {
+ protected override int? LayoutResource => Resource.Layout.activity_textblock;
+
+ protected override void OnCreate(Bundle? savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ var vm = this.GetViewModel();
+ if (vm == null)
+ {
+ Finish();
+ return;
+ }
+
+ this.SetSupportActionBarWithNavigationClick(binding!.toolbar);
+ SupportActionBar.SetDisplayHomeAsUpEnabled(true);
+ if (!string.IsNullOrWhiteSpace(vm.Title)) Title = vm.Title;
+
+ if (!string.IsNullOrWhiteSpace(vm.Content)) binding!.tvContent.Text = vm.Content;
+ else if (vm.ContentSource != default) binding!.tvContent.Text = vm.ContentSource switch
+ {
+ TextBlockViewModel.ContentSourceEnum.OpenSourceLibrary => OpenSourceLibrary.StringValues,
+ _ => string.Empty,
+ };
+ }
+
+ public static void StartActivity(Activity activity, TextBlockViewModel viewModel)
+ {
+ GoToPlatformPages.StartActivity(activity, viewModel);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Mobile.Droid/UI/Fragments/CommunityFixFragment.cs b/src/ST.Client.Mobile.Droid/UI/Fragments/CommunityFixFragment.cs
index 2d416fe9f..491f888d4 100644
--- a/src/ST.Client.Mobile.Droid/UI/Fragments/CommunityFixFragment.cs
+++ b/src/ST.Client.Mobile.Droid/UI/Fragments/CommunityFixFragment.cs
@@ -2,6 +2,8 @@ using Android.Runtime;
using Android.Views;
using Binding;
using System.Application.UI.Resx;
+using System.Properties;
+using System.Windows;
namespace System.Application.UI.Fragments
{
@@ -10,11 +12,14 @@ namespace System.Application.UI.Fragments
{
protected override int? LayoutResource => Resource.Layout.fragment_community_fix;
- public override void OnCreateView(View view)
+ public override async void OnCreateView(View view)
{
base.OnCreateView(view);
binding!.textView.Text = GetType().Name.TrimEnd("Fragment") + Environment.NewLine + AppResources.UnderConstruction;
binding!.textView.Gravity = GravityFlags.Center;
+
+ var r = await MessageBoxCompat.ShowAsync(AppResources.DelAccountTips, ThisAssembly.AssemblyTrademark, MessageBoxButtonCompat.OKCancel);
+ Toast.Show(r.ToString());
}
}
}
\ No newline at end of file
diff --git a/src/ST.Client.Mobile.Droid/UI/Fragments/GameListFragment.cs b/src/ST.Client.Mobile.Droid/UI/Fragments/GameListFragment.cs
index e2a05c595..df17f252f 100644
--- a/src/ST.Client.Mobile.Droid/UI/Fragments/GameListFragment.cs
+++ b/src/ST.Client.Mobile.Droid/UI/Fragments/GameListFragment.cs
@@ -2,6 +2,7 @@ using Android.Runtime;
using Android.Views;
using Binding;
using System.Application.UI.Resx;
+using System.Application.UI.ViewModels;
namespace System.Application.UI.Fragments
{
@@ -10,11 +11,14 @@ namespace System.Application.UI.Fragments
{
protected override int? LayoutResource => Resource.Layout.fragment_game_list;
- public override void OnCreateView(View view)
+ public override async void OnCreateView(View view)
{
base.OnCreateView(view);
binding!.textView.Text = GetType().Name.TrimEnd("Fragment") + Environment.NewLine + AppResources.UnderConstruction;
binding!.textView.Gravity = GravityFlags.Center;
+
+ var text = await PasswordWindowViewModel.ShowPasswordDialog();
+ Toast.Show(string.IsNullOrWhiteSpace(text) ? "IsNullOrWhiteSpace" : text!);
}
}
}
diff --git a/src/ST.Client.Mobile.Droid/UI/ViewModels/TextBlockViewModel.cs b/src/ST.Client.Mobile.Droid/UI/ViewModels/TextBlockViewModel.cs
new file mode 100644
index 000000000..1d321e583
--- /dev/null
+++ b/src/ST.Client.Mobile.Droid/UI/ViewModels/TextBlockViewModel.cs
@@ -0,0 +1,24 @@
+using MPKey = MessagePack.KeyAttribute;
+using MPObj = MessagePack.MessagePackObjectAttribute;
+
+namespace System.Application.UI.ViewModels
+{
+ [MPObj]
+ public class TextBlockViewModel
+ {
+ [MPKey(0)]
+ public string? Title { get; set; }
+
+ [MPKey(1)]
+ public string? Content { get; set; }
+
+ [MPKey(2)]
+ public ContentSourceEnum ContentSource { get; set; }
+
+ public enum ContentSourceEnum
+ {
+ None,
+ OpenSourceLibrary,
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/ST.Client.Mobile/ST.Client.Mobile.csproj b/src/ST.Client.Mobile/ST.Client.Mobile.csproj
index 74e511d9e..1554e8c9d 100644
--- a/src/ST.Client.Mobile/ST.Client.Mobile.csproj
+++ b/src/ST.Client.Mobile/ST.Client.Mobile.csproj
@@ -1,4 +1,4 @@
-
+
netstandard2.1
@@ -35,7 +35,7 @@
Mvvm
-
+
UI\ViewModels
@@ -63,22 +63,41 @@
Services\Implementation
-
+
UI\ViewModels\AboutPageViewModel.shared.cs
Models\Enum
+
+ MessageBox
+
+
+ Services
+
+
+ Services
+
+
+
+ UI\ViewModels
+
+
+ UI\ViewModels\Base
+
+
+ UI\ViewModels
+
-
+
-
-
+
+
\ No newline at end of file
diff --git a/src/Startup2.cs b/src/Startup2.cs
index 3c508b3c4..f9a98a62f 100644
--- a/src/Startup2.cs
+++ b/src/Startup2.cs
@@ -175,7 +175,7 @@ namespace System.Application
// 添加主线程助手(MainThreadDesktop)
services.AddMainThreadPlatformService();
-
+#endif
#region MessageBox
/* System.Windows.MessageBox 在 WPF 库中,仅支持 Win 平台
@@ -203,7 +203,6 @@ namespace System.Application
#endif
#endregion
-#endif
#if StartupTrace
StartupTrace.Restart("DI.ConfigureDemandServices.GUI");
#endif