XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEToolBox

【WPF】XFE工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using XFEToolBox.Client.Model;
using XFEToolBox.Client.Profiles.CrossVersionProfiles;
using XFEToolBox.Client.Utilities.Server;
using XFEToolBox.WpfCore.Controls;
using XFEToolBox.Client.Views.Windows;

namespace XFEToolBox.Client.Views.Pages.Popups;

public partial class LoginPopupPage : Page, IPopupPage
{
    private bool isRegistrationMode;

    public PopupWindow? PopupWindow { get; set; }

    public LoginPopupPage() : this(false)
    {
    }

    public LoginPopupPage(bool showRegistration)
    {
        InitializeComponent();
        LoginAccountTextBox.Text = SystemProfile.LastLoginAccount;
        SetRegistrationMode(showRegistration);
    }

    private void Page_Loaded(object sender, RoutedEventArgs e) => FocusFirstField();

    private void ModeButton_Click(object sender, RoutedEventArgs e) =>
        SetRegistrationMode(RegisterModeButton.IsChecked == true);

    private async void SubmitButton_Click(object sender, RoutedEventArgs e) => await SubmitAsync();

    private async void PasswordBox_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Enter)
        {
            e.Handled = true;
            await SubmitAsync();
        }
    }

    private void SetRegistrationMode(bool showRegistration)
    {
        isRegistrationMode = showRegistration;
        LoginModeButton.IsChecked = !showRegistration;
        RegisterModeButton.IsChecked = showRegistration;
        LoginPanel.Visibility = showRegistration ? Visibility.Collapsed : Visibility.Visible;
        RegisterPanel.Visibility = showRegistration ? Visibility.Visible : Visibility.Collapsed;
        FormTitleText.Text = showRegistration ? "创建新账户" : "欢迎回来";
        FormSubtitleText.Text = showRegistration ? "注册后将自动登录" : "登录 XFE 工具箱账户";
        SubmitButton.Content = showRegistration ? "注册并登录" : "登录";
        SubmitButton.IsEnabled = true;
        StatusText.Text = string.Empty;

        if (IsLoaded)
            FocusFirstField();
    }

    private void FocusFirstField() => Dispatcher.BeginInvoke(() =>
    {
        if (isRegistrationMode)
            RegisterAccountTextBox.Focus();
        else if (string.IsNullOrWhiteSpace(LoginAccountTextBox.Text))
            LoginAccountTextBox.Focus();
        else
            LoginPasswordBox.Focus();
    });

    private async Task SubmitAsync()
    {
        if (!SubmitButton.IsEnabled)
            return;

        if (isRegistrationMode)
            await RegisterAsync();
        else
            await LoginAsync();
    }

    private async Task LoginAsync()
    {
        if (string.IsNullOrWhiteSpace(LoginAccountTextBox.Text) || string.IsNullOrEmpty(LoginPasswordBox.Password))
        {
            ShowError("请输入账号和密码。");
            return;
        }

        BeginRequest("正在登录…", "正在连接工具服务器");
        var result = await ClientSession.LoginAsync(LoginAccountTextBox.Text.Trim(), LoginPasswordBox.Password);
        await HandleResultAsync(result, LoginPasswordBox);
    }

    private async Task RegisterAsync()
    {
        var account = RegisterAccountTextBox.Text.Trim();
        var nickName = RegisterNickNameTextBox.Text.Trim();
        if (account.Length < 3 || string.IsNullOrWhiteSpace(nickName) || string.IsNullOrEmpty(RegisterPasswordBox.Password))
        {
            ShowError("请完整填写注册信息,账号至少 3 位。");
            return;
        }

        if (RegisterPasswordBox.Password.Length < 8)
        {
            ShowError("密码至少需要 8 位。");
            return;
        }

        if (RegisterPasswordBox.Password != RegisterConfirmPasswordBox.Password)
        {
            ShowError("两次输入的密码不一致。");
            return;
        }

        BeginRequest("正在注册…", "正在创建 XFE 工具箱账户");
        var result = await ClientSession.RegisterAsync(account, RegisterPasswordBox.Password, nickName);
        await HandleResultAsync(result, RegisterPasswordBox, RegisterConfirmPasswordBox);
    }

    private void BeginRequest(string buttonText, string statusText)
    {
        SubmitButton.IsEnabled = false;
        SubmitButton.Content = buttonText;
        StatusText.Foreground = new SolidColorBrush(Color.FromRgb(104, 104, 126));
        StatusText.Text = statusText;
    }

    private async Task HandleResultAsync(
        (bool Success, string Message) result,
        params PasswordEditor[] passwordEditors)
    {
        StatusText.Text = result.Message;
        StatusText.Foreground = new SolidColorBrush(result.Success
            ? Color.FromRgb(63, 145, 96)
            : Color.FromRgb(198, 83, 83));

        if (result.Success)
        {
            foreach (var passwordEditor in passwordEditors)
                passwordEditor.Clear();
            await Task.Delay(180);
            if (PopupWindow is not null)
                await PopupWindow.CloseWithResultAsync(MessageBoxResult.OK);
            return;
        }

        SubmitButton.IsEnabled = true;
        SubmitButton.Content = isRegistrationMode ? "注册并登录" : "登录";
        ShakeSurface();
    }

    private void ShowError(string message)
    {
        StatusText.Foreground = new SolidColorBrush(Color.FromRgb(198, 83, 83));
        StatusText.Text = message;
        ShakeSurface();
    }

    private void ShakeSurface()
    {
        if (AccountSurface.RenderTransform is not TranslateTransform translation)
            return;

        var animation = new DoubleAnimationUsingKeyFrames { Duration = TimeSpan.FromMilliseconds(280) };
        animation.KeyFrames.Add(new EasingDoubleKeyFrame(0, KeyTime.FromPercent(0)));
        animation.KeyFrames.Add(new EasingDoubleKeyFrame(-7, KeyTime.FromPercent(0.2)));
        animation.KeyFrames.Add(new EasingDoubleKeyFrame(6, KeyTime.FromPercent(0.4)));
        animation.KeyFrames.Add(new EasingDoubleKeyFrame(-4, KeyTime.FromPercent(0.6)));
        animation.KeyFrames.Add(new EasingDoubleKeyFrame(2, KeyTime.FromPercent(0.8)));
        animation.KeyFrames.Add(new EasingDoubleKeyFrame(0, KeyTime.FromPercent(1)));
        translation.BeginAnimation(TranslateTransform.XProperty, animation);
    }
}