Compare commits

...

7 Commits

Author SHA1 Message Date
wangyingpan 7a4964efac 🚑 解决冲突 2024-04-29 13:29:44 +08:00
wangyingpan f646ab1c6f ✨ 替换令牌中添加绑定手机号窜哦做 2024-04-28 16:36:57 +08:00
wangyingpan b4e0b6d773 Merge branch 'fix/authenticator-verifycode-ui' of https://github.com/BeyondDimension/SteamTools into fix/authenticator-verifycode-ui 2024-04-23 14:55:55 +08:00
wangyingpan 5e5b397251 🎨 删除绑定手机号步骤
🐛 修复替换令牌逻辑验证码信息展示错误的问题
2024-04-23 14:54:30 +08:00
wangyingpan 18c742a9ef 🐛 修复添加令牌邮箱/短信验证ui显示 2024-04-23 14:54:30 +08:00
wangyingpan d634204bd4 🎨 删除绑定手机号步骤
🐛 修复替换令牌逻辑验证码信息展示错误的问题
2024-04-23 14:43:44 +08:00
wangyingpan c20b20407e 🐛 修复添加令牌邮箱/短信验证ui显示 2024-04-23 13:55:25 +08:00
10 changed files with 581 additions and 213 deletions
@@ -0,0 +1,162 @@
using WinAuth;
using AppResources = BD.WTTS.Client.Resources.Strings;
namespace BD.WTTS.UI.ViewModels;
/// <summary>
/// 添加 Steam 账号手机号页面 VM
/// </summary>
public class AddSteamAccountPhoneNumberPageViewModel : WindowViewModel
{
#region 步骤 Index 定义
const int TAB_INDEX_BINDING = 0;
const int TAB_INDEX_CONFIRMATION_Email = 1;
const int TAB_INDEX_CONFIRMATION_SMS = 2;
#endregion 步骤 Index 定义
/// <summary>
/// 手机号文本
/// </summary>
[Reactive]
public string? PhoneNumberText { get; set; }
/// <summary>
/// 验证码文本
/// </summary>
[Reactive]
public string? CodeText { get; set; }
/// <summary>
/// 步骤 Index
/// </summary>
[Reactive]
public int SelectIndex { get; set; }
/// <summary>
/// 是否显示加载中
/// </summary>
[Reactive]
public bool IsLoading { get; set; }
private readonly SteamAuthenticator.EnrollState _enrollState;
private readonly SteamAuthenticator _steamAuthenticator;
public AddSteamAccountPhoneNumberPageViewModel(
SteamAuthenticator.EnrollState enrollState,
SteamAuthenticator steamAuthenticator
)
{
SelectIndex = TAB_INDEX_BINDING;
_steamAuthenticator = steamAuthenticator;
_enrollState = enrollState;
}
/// <summary>
/// 开始绑定手机号
/// </summary>
/// <returns></returns>
public async Task StartBindingAsync()
{
if (IsLoading)
{
Toast.Show(ToastIcon.Warning, AppResources.Warning_DoNotOperateFrequently);
return;
}
if (string.IsNullOrEmpty(PhoneNumberText))
{
Toast.Show(ToastIcon.Warning, AppResources.Warning_PleaseEnterTel);
return;
}
IsLoading = true;
try
{
string? msg = await _steamAuthenticator.AddPhoneNumberAsync(_enrollState, PhoneNumberText);
Toast.Show(ToastIcon.Info, msg ?? string.Empty);
if (_enrollState.RequiresEmailConfirmPhone)
{
SelectIndex = TAB_INDEX_CONFIRMATION_Email;
}
else
{
SelectIndex = TAB_INDEX_CONFIRMATION_SMS;
}
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 确认邮箱链接
/// </summary>
/// <returns></returns>
public async Task ConfirmBindingEmailAsync()
{
if (IsLoading)
{
Toast.Show(ToastIcon.Warning, AppResources.Warning_DoNotOperateFrequently);
return;
}
if (string.IsNullOrEmpty(PhoneNumberText))
{
Toast.Show(ToastIcon.Warning, AppResources.Warning_PleaseEnterTel);
return;
}
IsLoading = true;
try
{
var reslut = await _steamAuthenticator.AddPhoneNumberAsync(_enrollState, PhoneNumberText!);
if (_enrollState.RequiresEmailConfirmPhone == false && reslut == null)
{
SelectIndex = TAB_INDEX_CONFIRMATION_SMS;
}
}
finally
{
IsLoading = false;
}
}
/// <summary>
/// 验收短信验证码
/// </summary>
/// <returns></returns>
public async Task VerifyAccountPhoneWithCodeAsync()
{
if (string.IsNullOrEmpty(PhoneNumberText))
{
Toast.Show(ToastIcon.Warning, AppResources.Warning_PleaseEnterTel);
return;
}
if (string.IsNullOrEmpty(CodeText))
{
Toast.Show(ToastIcon.Warning, AppResources.Error_PleaseEnterTelCode);
return;
}
var verified = await _steamAuthenticator
.VerifyPhoneNumberAsync(PhoneNumberText!, CodeText!, _enrollState.AccessToken!);
if (verified)
{
Close?.Invoke(verified);
}
}
}
@@ -1,16 +1,22 @@
using AppResources = BD.WTTS.Client.Resources.Strings;
using BD.SteamClient.Models;
using BD.SteamClient.Services;
using BD.WTTS.UI.Views.Controls;
using WinAuth;
using AppResources = BD.WTTS.Client.Resources.Strings;
#if !ANDROID
using ToastLength = BD.Common.Enums.ToastLength;
#endif
namespace BD.WTTS.UI.ViewModels;
public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
{
const int TAB_INDEX_LOGIN = 0;
const int TAB_INDEX_LOGINCONFIRM = 1;
const int TAB_INDEX_VERIFYCODE = 2;
const int TAB_INDEX_DONE = 3;
public static string Name => AppResources.Auth_SteamLoginImport;
readonly ISteamAccountService _steamAccountService = Ioc.Get<ISteamAccountService>();
@@ -94,7 +100,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
{
if (string.IsNullOrEmpty(PhoneCodeText))
{
Toast.Show(ToastIcon.Error, AppResources.Error_PleaseEnterTelCode);
Toast.Show(ToastIcon.Error, AppResources.Error_PleaseEnterCode);
return false;
}
else
@@ -115,7 +121,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
Created = DateTimeOffset.Now,
};
await AuthenticatorHelper.SaveAuthenticator(iADTO);
SelectIndex = 4;
SelectIndex = TAB_INDEX_DONE;
}
/// <summary>
@@ -136,15 +142,23 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
if (_enrollState.NoPhoneNumber == true)
{
_enrollState.Error = null;
SelectIndex = 2;
//SelectIndex = 2;
// 正常情况下不会走到这里,因为已经不需要绑定手机的步骤了
return;
}
//导入最后一步,需要账号绑定的手机验证码确认
// 导入最后一步,需要账号绑定的手机验证码确认
// 2024-04-23 Steam绑定令牌不强制手机绑定 可以输入 邮箱者手机验证码
if (_enrollState.RequiresActivation == true)
{
// 查询账号手机号绑定状态
// IsVerifyAccountPhone = await _steamAccountService.CheckAccountPhoneStatus(_enrollState.AccessToken!) ?? false;
await CheckAccountPhoneStatus();
_enrollState.Error = null;
RevocationCodeText = _enrollState.RevocationCode;
SelectIndex = 3;
SelectIndex = TAB_INDEX_VERIFYCODE;
}
}
@@ -161,7 +175,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
//Toast.Show(ToastIcon.Error, Strings.LocalAuth_SteamUser_Requires2FA);
//Reset();
Requires2FA = _steamLoginState.Requires2FA;
SelectIndex = 1;
SelectIndex = TAB_INDEX_LOGINCONFIRM;
return false;
}
//需要邮箱验证码
@@ -170,7 +184,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
EmailDomainText = string.IsNullOrEmpty(_steamLoginState.EmailDomain) == false
? $"******@{_steamLoginState.EmailDomain}"
: string.Empty;
SelectIndex = 1;
SelectIndex = TAB_INDEX_LOGINCONFIRM;
return false;
}
else if (!string.IsNullOrEmpty(_steamLoginState.Message))
@@ -189,6 +203,12 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
return !string.IsNullOrEmpty(_steamLoginState.AccessToken);
}
async ValueTask CheckAccountPhoneStatus()
{
// 查询账号手机号绑定状态
IsVerifyAccountPhone = await _steamAccountService.CheckAccountPhoneStatus(_enrollState.AccessToken!) ?? false;
}
public async Task LoginSteamImport()
{
if (IsLoading)
@@ -200,7 +220,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
try
{
if (SelectIndex == 0)
if (SelectIndex == TAB_INDEX_LOGIN)
{
await LoginSteamFirstAsync();
}
@@ -224,16 +244,56 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
//已有令牌情况下执行替换令牌逻辑
if (_enrollState.ReplaceAuth)
{
if (SelectIndex == 1 && await steamAuthenticator.RemoveAuthenticatorViaChallengeStartSync(_enrollState.AccessToken!))
if (SelectIndex == TAB_INDEX_LOGINCONFIRM && await steamAuthenticator.RemoveAuthenticatorViaChallengeStartSync(_enrollState.AccessToken!))
{
SelectIndex = 3;
await CheckAccountPhoneStatus();
SelectIndex = TAB_INDEX_VERIFYCODE;
if (!IsVerifyAccountPhone)
{
Toast.Show(ToastIcon.Warning, "只绑定邮箱的情况下无法直接替换令牌");
// 弹出绑定手机号流程
var added = await IWindowManager.Instance.ShowTaskDialogAsync(
viewModel: new AddSteamAccountPhoneNumberPageViewModel(_enrollState, steamAuthenticator),
pageContent: new AddSteamAccountPhoneNumberPage(),
isCancelButton: false,
isOkButton: false,
isRetryButton: false
);
// 查询账号手机号绑定状态
await CheckAccountPhoneStatus();
// 如果通过弹出的绑定手机号绑定成功 开始执行替换令牌
if (added && IsVerifyAccountPhone)
{
/*
* 绑定手机号会发送验证码
* 执行开始替换令牌操作也会发送验证码
* 如果两个操作间隔太短会导致 Steam 不发送验证码
*/
await Task.Delay(TimeSpan.FromSeconds(30));
await steamAuthenticator.RemoveAuthenticatorViaChallengeStartSync(_enrollState.AccessToken!);
}
// 取消了绑定手机号流程 无法执行替换令牌操作
else
{
SelectIndex = TAB_INDEX_LOGIN;
}
return;
}
return;
}
else if (SelectIndex == 3)
else if (SelectIndex == TAB_INDEX_VERIFYCODE)
{
if (string.IsNullOrEmpty(PhoneCodeText))
{
Toast.Show(ToastIcon.Error, Strings.Error_PleaseEnterTelCode);
Toast.Show(ToastIcon.Error, Strings.Error_PleaseEnterCode);
return;
}
@@ -319,4 +379,4 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
IsLoading = false;
}
}
}
}
@@ -1,9 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BD.WTTS.UI.ViewModels;
public sealed partial class SteamLoginImportPageViewModel
@@ -67,4 +61,10 @@ public sealed partial class SteamLoginImportPageViewModel
[Reactive]
public string? PhoneNumberText { get; set; }
}
/// <summary>
/// 是否已验证账号的手机号
/// </summary>
[Reactive]
public bool IsVerifyAccountPhone { get; set; }
}
@@ -0,0 +1,93 @@
<UserControl
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:spp="https://steampp.net/ui"
xmlns:s="https://steampp.net/services"
d:DesignWidth="400"
d:DesignHeight="250"
x:DataType="spp:AddSteamAccountPhoneNumberPageViewModel"
x:CompileBindings="True"
x:Class="BD.WTTS.UI.Views.Controls.AddSteamAccountPhoneNumberPage"
mc:Ignorable="d">
<Grid RowDefinitions="Auto,*">
<spp:Stepper SelectedIndex="{Binding SelectIndex}">
<spp:StepperItem Content="{Binding Path=Res.Steam_BindTel, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.Steam_ConfirmEmailLink, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.TelCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</spp:Stepper>
<spp:ContentLoader
Grid.Row="1"
MinWidth="400"
MinHeight="250"
IsLoading="{Binding IsLoading}"
IsShowNoResultText="False">
<Carousel IsVisible="{Binding !IsLoading}" SelectedIndex="{Binding SelectIndex}">
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<DockPanel>
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.User_Phone, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="PhoneNumberText"
MaxWidth="300"
Text="{Binding PhoneNumberText}"
Watermark="+8601234567890" />
</DockPanel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding StartBindingAsync}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding ConfirmBindingEmailAsync}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<DockPanel>
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.Error_PleaseEnterTelCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="CodeText"
MaxWidth="300"
Text="{Binding CodeText}" />
</DockPanel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding VerifyAccountPhoneWithCodeAsync}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Carousel>
</spp:ContentLoader>
</Grid>
</UserControl>
@@ -0,0 +1,11 @@
using Avalonia.Controls;
namespace BD.WTTS.UI.Views.Controls;
public partial class AddSteamAccountPhoneNumberPage : UserControl
{
public AddSteamAccountPhoneNumberPage()
{
InitializeComponent();
}
}
@@ -11,85 +11,86 @@
x:CompileBindings="True"
x:DataType="spp:SteamLoginImportPageViewModel"
mc:Ignorable="d">
<Grid RowDefinitions="Auto,*">
<spp:Stepper SelectedIndex="{Binding SelectIndex}">
<spp:StepperItem Content="{Binding Path=Res.Steam_Login, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.LoginVerify, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.Steam_BindTel, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.TelCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.Btn_Text_Complete, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</spp:Stepper>
<Grid RowDefinitions="Auto,*">
<spp:Stepper SelectedIndex="{Binding SelectIndex}">
<spp:StepperItem Content="{Binding Path=Res.Steam_Login, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.LoginVerify, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<!--隐藏绑定手机号步骤-->
<!--<spp:StepperItem IsVisible="false" Content="{Binding Path=Res.Steam_BindTel, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />-->
<spp:StepperItem Content="{Binding Path=Res.LocalAuth_VerifyCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<spp:StepperItem Content="{Binding Path=Res.Btn_Text_Complete, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</spp:Stepper>
<spp:ContentLoader
Grid.Row="1"
MinWidth="600"
MinHeight="400"
IsLoading="{Binding IsLoading}"
IsShowNoResultText="False">
<Carousel IsVisible="{Binding !IsLoading}" SelectedIndex="{Binding SelectIndex}">
<!-- 登录 -->
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<PathIcon
Width="88"
Height="88"
Data="{StaticResource Steam}" />
<TextBox
MaxWidth="280"
Text="{Binding UserNameText}"
Watermark="{Binding Path=Res.Steam_User, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="PasswordText"
MaxWidth="280"
Classes="revealPasswordButton"
PasswordChar="{StaticResource PasswordChar}"
Text="{Binding PasswordText}"
Watermark="{Binding Path=Res.Steam_Password, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<Button
MinWidth="280"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Login, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
<spp:ContentLoader
Grid.Row="1"
MinWidth="600"
MinHeight="400"
IsLoading="{Binding IsLoading}"
IsShowNoResultText="False">
<Carousel IsVisible="{Binding !IsLoading}" SelectedIndex="{Binding SelectIndex}">
<!-- 登录 -->
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<PathIcon
Width="88"
Height="88"
Data="{StaticResource Steam}" />
<TextBox
MaxWidth="280"
Text="{Binding UserNameText}"
Watermark="{Binding Path=Res.Steam_User, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="PasswordText"
MaxWidth="280"
Classes="revealPasswordButton"
PasswordChar="{StaticResource PasswordChar}"
Text="{Binding PasswordText}"
Watermark="{Binding Path=Res.Steam_Password, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<Button
MinWidth="280"
HorizontalAlignment="Center"
VerticalAlignment="Bottom"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Login, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
<!-- 邮箱验证 -->
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
IsVisible="{Binding !Requires2FA}"
Message="{Binding Path=Res.LocalAuth_EmailCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
IsVisible="{Binding Requires2FA}"
Message="{Binding Path=Res.LocalAuth_Steam2FACodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<TextBlock IsVisible="{Binding !Requires2FA}" Text="{Binding Path=Res.EmailCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBlock IsVisible="{Binding Requires2FA}" Text="{Binding Path=Res.Steam2FACode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="EmailAuthText"
MinWidth="300"
FontSize="24"
Text="{Binding EmailAuthText}" />
<!--<TextBlock
<!-- 邮箱验证 -->
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
IsVisible="{Binding !Requires2FA}"
Message="{Binding Path=Res.LocalAuth_EmailCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
IsVisible="{Binding Requires2FA}"
Message="{Binding Path=Res.LocalAuth_Steam2FACodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<TextBlock IsVisible="{Binding !Requires2FA}" Text="{Binding Path=Res.EmailCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBlock IsVisible="{Binding Requires2FA}" Text="{Binding Path=Res.Steam2FACode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="EmailAuthText"
MinWidth="300"
FontSize="24"
Text="{Binding EmailAuthText}" />
<!--<TextBlock
Margin="10,0"
HorizontalAlignment="Center"
Text="{Binding EmailDomainText}" />-->
<!--<TextBlock
<!--<TextBlock
Margin="10,0"
HorizontalAlignment="Center"
Text="{Binding Path=Res.LocalAuth_EmailCodeTip,
@@ -97,121 +98,138 @@
Source={x:Static s:ResourceService.Current}}"
TextAlignment="Center"
TextWrapping="WrapWithOverflow" />-->
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>
<!-- 绑定手机 -->
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
Message="{Binding Path=Res.Warning_SteamAuthPhoneBind, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<!-- 绑定手机 -->
<!--
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
Message="{Binding Path=Res.Warning_SteamAuthPhoneBind, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<DockPanel>
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.User_Phone, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="PhoneNumberText"
MaxWidth="300"
Text="{Binding PhoneNumberText}"
Watermark="+8601234567890" />
</DockPanel>
<DockPanel>
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.User_Phone, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="PhoneNumberText"
MaxWidth="300"
Text="{Binding PhoneNumberText}"
Watermark="+8601234567890" />
</DockPanel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>-->
<!-- 验证手机 -->
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
Message="{Binding Path=Res.LocalAuth_SMSCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
MaxWidth="300"
IsReadOnly="True"
Text="{Binding RevocationCodeText, Mode=OneWay}" />
</DockPanel>
<!--<CheckBox Content="{Binding Path=Res.RecoveryCode_Remember, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />-->
<DockPanel>
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.SMSCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="PhoneCodeText"
MaxWidth="300"
Text="{Binding PhoneCodeText}" />
</DockPanel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>
<!-- 验证手机 或 邮箱 -->
<!-- 2024-04-23 Steam绑定令牌不强制手机绑定 可以输入 邮箱者手机验证码 -->
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsVisible="{Binding IsVerifyAccountPhone}"
IsOpen="True"
Message="{Binding Path=Res.LocalAuth_SMSCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsVisible="{Binding !IsVerifyAccountPhone}"
IsOpen="True"
Message="{Binding Path=Res.LocalAuth_EmailCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" />
<StackPanel
HorizontalAlignment="Center"
VerticalAlignment="Center"
Spacing="10">
<DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
MaxWidth="300"
IsReadOnly="True"
Text="{Binding RevocationCodeText, Mode=OneWay}" />
</DockPanel>
<!--<CheckBox Content="{Binding Path=Res.RecoveryCode_Remember, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />-->
<DockPanel>
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
IsVisible="{Binding IsVerifyAccountPhone}"
Text="{Binding Path=Res.SMSCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
IsVisible="{Binding !IsVerifyAccountPhone}"
Text="{Binding Path=Res.EmailCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
Name="PhoneCodeText"
MaxWidth="300"
Text="{Binding PhoneCodeText}" />
</DockPanel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>
<!-- 完成 -->
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
Message="{Binding Path=Res.RecoveryCode_RememberTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Success" />
<StackPanel VerticalAlignment="Center" Spacing="10">
<DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
MaxWidth="300"
IsReadOnly="True"
Text="{Binding RevocationCodeText, Mode=OneWay}" />
</DockPanel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
Command="{Binding Reset}"
Content="{Binding Path=Res.Confirm, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>
</Carousel>
</spp:ContentLoader>
</Grid>
</UserControl>
<!-- 完成 -->
<Panel>
<spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top"
IsClosable="False"
IsOpen="True"
Message="{Binding Path=Res.RecoveryCode_RememberTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Success" />
<StackPanel VerticalAlignment="Center" Spacing="10">
<DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
<TextBlock
Margin="0,0,0,6"
DockPanel.Dock="Top"
Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox
MaxWidth="300"
IsReadOnly="True"
Text="{Binding RevocationCodeText, Mode=OneWay}" />
</DockPanel>
<Button
MinWidth="280"
HorizontalAlignment="Center"
Command="{Binding Reset}"
Content="{Binding Path=Res.Confirm, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel>
</Panel>
</Carousel>
</spp:ContentLoader>
</Grid>
</UserControl>
@@ -14,7 +14,7 @@ public partial class SteamLoginImportPage : ReactiveUserControl<SteamLoginImport
DataContext ??= new SteamLoginImportPageViewModel();
PasswordText.KeyUp += PasswordTextOnKeyUp;
EmailAuthText.KeyUp += PasswordTextOnKeyUp;
PhoneNumberText.KeyUp += PasswordTextOnKeyUp;
//PhoneNumberText.KeyUp += PasswordTextOnKeyUp;
PhoneCodeText.KeyUp += PasswordTextOnKeyUp;
EmailAuthText.TextInput += EmailAuthText_TextInput;
PhoneCodeText.TextInput += EmailAuthText_TextInput;
@@ -34,4 +34,4 @@ public partial class SteamLoginImportPage : ReactiveUserControl<SteamLoginImport
e.Handled = true;
}
}
}
}
+18
View File
@@ -4484,6 +4484,15 @@ namespace BD.WTTS.Client.Resources {
}
}
/// <summary>
/// 查找类似 验证码 的本地化字符串。
/// </summary>
public static string LocalAuth_VerifyCode {
get {
return ResourceManager.GetString("LocalAuth_VerifyCode", resourceCulture);
}
}
/// <summary>
/// 查找类似 使用 Steam++ V1 版本工具箱导出的文件导入令牌 的本地化字符串。
/// </summary>
@@ -6702,6 +6711,15 @@ namespace BD.WTTS.Client.Resources {
}
}
/// <summary>
/// 查找类似 确认邮箱链接 的本地化字符串。
/// </summary>
public static string Steam_ConfirmEmailLink {
get {
return ResourceManager.GetString("Steam_ConfirmEmailLink", resourceCulture);
}
}
/// <summary>
/// 查找类似 Steam 客户端登录区域: 的本地化字符串。
/// </summary>
@@ -2945,6 +2945,12 @@
</data>
<data name="Idle_PIN_NotBeNull" xml:space="preserve">
<value>PIN CODE 不能为空</value>
</data>
<data name="LocalAuth_VerifyCode" xml:space="preserve">
<value>验证码</value>
</data>
<data name="Steam_ConfirmEmailLink" xml:space="preserve">
<value>确认邮箱链接</value>
</data>
<data name="CommunityFix_Starting" xml:space="preserve">
<value>正在启动加速...</value>