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.Models;
using BD.SteamClient.Services; using BD.SteamClient.Services;
using BD.WTTS.UI.Views.Controls;
using WinAuth; using WinAuth;
using AppResources = BD.WTTS.Client.Resources.Strings;
#if !ANDROID #if !ANDROID
using ToastLength = BD.Common.Enums.ToastLength;
#endif #endif
namespace BD.WTTS.UI.ViewModels; namespace BD.WTTS.UI.ViewModels;
public sealed partial class SteamLoginImportPageViewModel : ViewModelBase 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; public static string Name => AppResources.Auth_SteamLoginImport;
readonly ISteamAccountService _steamAccountService = Ioc.Get<ISteamAccountService>(); readonly ISteamAccountService _steamAccountService = Ioc.Get<ISteamAccountService>();
@@ -94,7 +100,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
{ {
if (string.IsNullOrEmpty(PhoneCodeText)) if (string.IsNullOrEmpty(PhoneCodeText))
{ {
Toast.Show(ToastIcon.Error, AppResources.Error_PleaseEnterTelCode); Toast.Show(ToastIcon.Error, AppResources.Error_PleaseEnterCode);
return false; return false;
} }
else else
@@ -115,7 +121,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
Created = DateTimeOffset.Now, Created = DateTimeOffset.Now,
}; };
await AuthenticatorHelper.SaveAuthenticator(iADTO); await AuthenticatorHelper.SaveAuthenticator(iADTO);
SelectIndex = 4; SelectIndex = TAB_INDEX_DONE;
} }
/// <summary> /// <summary>
@@ -136,15 +142,23 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
if (_enrollState.NoPhoneNumber == true) if (_enrollState.NoPhoneNumber == true)
{ {
_enrollState.Error = null; _enrollState.Error = null;
SelectIndex = 2; //SelectIndex = 2;
// 正常情况下不会走到这里,因为已经不需要绑定手机的步骤了
return;
} }
//导入最后一步,需要账号绑定的手机验证码确认 // 导入最后一步,需要账号绑定的手机验证码确认
// 2024-04-23 Steam绑定令牌不强制手机绑定 可以输入 邮箱者手机验证码
if (_enrollState.RequiresActivation == true) if (_enrollState.RequiresActivation == true)
{ {
// 查询账号手机号绑定状态
// IsVerifyAccountPhone = await _steamAccountService.CheckAccountPhoneStatus(_enrollState.AccessToken!) ?? false;
await CheckAccountPhoneStatus();
_enrollState.Error = null; _enrollState.Error = null;
RevocationCodeText = _enrollState.RevocationCode; 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); //Toast.Show(ToastIcon.Error, Strings.LocalAuth_SteamUser_Requires2FA);
//Reset(); //Reset();
Requires2FA = _steamLoginState.Requires2FA; Requires2FA = _steamLoginState.Requires2FA;
SelectIndex = 1; SelectIndex = TAB_INDEX_LOGINCONFIRM;
return false; return false;
} }
//需要邮箱验证码 //需要邮箱验证码
@@ -170,7 +184,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
EmailDomainText = string.IsNullOrEmpty(_steamLoginState.EmailDomain) == false EmailDomainText = string.IsNullOrEmpty(_steamLoginState.EmailDomain) == false
? $"******@{_steamLoginState.EmailDomain}" ? $"******@{_steamLoginState.EmailDomain}"
: string.Empty; : string.Empty;
SelectIndex = 1; SelectIndex = TAB_INDEX_LOGINCONFIRM;
return false; return false;
} }
else if (!string.IsNullOrEmpty(_steamLoginState.Message)) else if (!string.IsNullOrEmpty(_steamLoginState.Message))
@@ -189,6 +203,12 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
return !string.IsNullOrEmpty(_steamLoginState.AccessToken); return !string.IsNullOrEmpty(_steamLoginState.AccessToken);
} }
async ValueTask CheckAccountPhoneStatus()
{
// 查询账号手机号绑定状态
IsVerifyAccountPhone = await _steamAccountService.CheckAccountPhoneStatus(_enrollState.AccessToken!) ?? false;
}
public async Task LoginSteamImport() public async Task LoginSteamImport()
{ {
if (IsLoading) if (IsLoading)
@@ -200,7 +220,7 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
try try
{ {
if (SelectIndex == 0) if (SelectIndex == TAB_INDEX_LOGIN)
{ {
await LoginSteamFirstAsync(); await LoginSteamFirstAsync();
} }
@@ -224,16 +244,56 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
//已有令牌情况下执行替换令牌逻辑 //已有令牌情况下执行替换令牌逻辑
if (_enrollState.ReplaceAuth) 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; return;
} }
else if (SelectIndex == 3) else if (SelectIndex == TAB_INDEX_VERIFYCODE)
{ {
if (string.IsNullOrEmpty(PhoneCodeText)) if (string.IsNullOrEmpty(PhoneCodeText))
{ {
Toast.Show(ToastIcon.Error, Strings.Error_PleaseEnterTelCode); Toast.Show(ToastIcon.Error, Strings.Error_PleaseEnterCode);
return; return;
} }
@@ -319,4 +379,4 @@ public sealed partial class SteamLoginImportPageViewModel : ViewModelBase
IsLoading = false; 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; namespace BD.WTTS.UI.ViewModels;
public sealed partial class SteamLoginImportPageViewModel public sealed partial class SteamLoginImportPageViewModel
@@ -67,4 +61,10 @@ public sealed partial class SteamLoginImportPageViewModel
[Reactive] [Reactive]
public string? PhoneNumberText { get; set; } 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:CompileBindings="True"
x:DataType="spp:SteamLoginImportPageViewModel" x:DataType="spp:SteamLoginImportPageViewModel"
mc:Ignorable="d"> mc:Ignorable="d">
<Grid RowDefinitions="Auto,*"> <Grid RowDefinitions="Auto,*">
<spp:Stepper SelectedIndex="{Binding SelectIndex}"> <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.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.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 IsVisible="false" Content="{Binding Path=Res.Steam_BindTel, 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:StepperItem Content="{Binding Path=Res.LocalAuth_VerifyCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</spp:Stepper> <spp:StepperItem Content="{Binding Path=Res.Btn_Text_Complete, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</spp:Stepper>
<spp:ContentLoader <spp:ContentLoader
Grid.Row="1" Grid.Row="1"
MinWidth="600" MinWidth="600"
MinHeight="400" MinHeight="400"
IsLoading="{Binding IsLoading}" IsLoading="{Binding IsLoading}"
IsShowNoResultText="False"> IsShowNoResultText="False">
<Carousel IsVisible="{Binding !IsLoading}" SelectedIndex="{Binding SelectIndex}"> <Carousel IsVisible="{Binding !IsLoading}" SelectedIndex="{Binding SelectIndex}">
<!-- 登录 --> <!-- 登录 -->
<StackPanel <StackPanel
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Spacing="10"> Spacing="10">
<PathIcon <PathIcon
Width="88" Width="88"
Height="88" Height="88"
Data="{StaticResource Steam}" /> Data="{StaticResource Steam}" />
<TextBox <TextBox
MaxWidth="280" MaxWidth="280"
Text="{Binding UserNameText}" Text="{Binding UserNameText}"
Watermark="{Binding Path=Res.Steam_User, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Watermark="{Binding Path=Res.Steam_User, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox <TextBox
Name="PasswordText" Name="PasswordText"
MaxWidth="280" MaxWidth="280"
Classes="revealPasswordButton" Classes="revealPasswordButton"
PasswordChar="{StaticResource PasswordChar}" PasswordChar="{StaticResource PasswordChar}"
Text="{Binding PasswordText}" Text="{Binding PasswordText}"
Watermark="{Binding Path=Res.Steam_Password, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Watermark="{Binding Path=Res.Steam_Password, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<Button <Button
MinWidth="280" MinWidth="280"
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Bottom" VerticalAlignment="Bottom"
HorizontalContentAlignment="Center" HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}" Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Login, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Content="{Binding Path=Res.Login, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel> </StackPanel>
<!-- 邮箱验证 --> <!-- 邮箱验证 -->
<Panel> <Panel>
<spp:Snackbar <spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top" VerticalAlignment="Top"
IsClosable="False" IsClosable="False"
IsOpen="True" IsOpen="True"
IsVisible="{Binding !Requires2FA}" IsVisible="{Binding !Requires2FA}"
Message="{Binding Path=Res.LocalAuth_EmailCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" Message="{Binding Path=Res.LocalAuth_EmailCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" /> Severity="Warning" />
<spp:Snackbar <spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top" VerticalAlignment="Top"
IsClosable="False" IsClosable="False"
IsOpen="True" IsOpen="True"
IsVisible="{Binding Requires2FA}" IsVisible="{Binding Requires2FA}"
Message="{Binding Path=Res.LocalAuth_Steam2FACodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" Message="{Binding Path=Res.LocalAuth_Steam2FACodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Warning" /> Severity="Warning" />
<StackPanel <StackPanel
HorizontalAlignment="Center" HorizontalAlignment="Center"
VerticalAlignment="Center" VerticalAlignment="Center"
Spacing="10"> 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.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}}" /> <TextBlock IsVisible="{Binding Requires2FA}" Text="{Binding Path=Res.Steam2FACode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox <TextBox
Name="EmailAuthText" Name="EmailAuthText"
MinWidth="300" MinWidth="300"
FontSize="24" FontSize="24"
Text="{Binding EmailAuthText}" /> Text="{Binding EmailAuthText}" />
<!--<TextBlock <!--<TextBlock
Margin="10,0" Margin="10,0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Text="{Binding EmailDomainText}" />--> Text="{Binding EmailDomainText}" />-->
<!--<TextBlock <!--<TextBlock
Margin="10,0" Margin="10,0"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Text="{Binding Path=Res.LocalAuth_EmailCodeTip, Text="{Binding Path=Res.LocalAuth_EmailCodeTip,
@@ -97,121 +98,138 @@
Source={x:Static s:ResourceService.Current}}" Source={x:Static s:ResourceService.Current}}"
TextAlignment="Center" TextAlignment="Center"
TextWrapping="WrapWithOverflow" />--> TextWrapping="WrapWithOverflow" />-->
<Button <Button
MinWidth="280" MinWidth="280"
HorizontalAlignment="Center" HorizontalAlignment="Center"
HorizontalContentAlignment="Center" HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}" Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel> </StackPanel>
</Panel> </Panel>
<!-- 绑定手机 --> <!-- 绑定手机 -->
<Panel> <!--
<spp:Snackbar <Panel>
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" <spp:Snackbar
VerticalAlignment="Top" Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
IsClosable="False" VerticalAlignment="Top"
IsOpen="True" IsClosable="False"
Message="{Binding Path=Res.Warning_SteamAuthPhoneBind, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" IsOpen="True"
Severity="Warning" /> Message="{Binding Path=Res.Warning_SteamAuthPhoneBind, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
<StackPanel Severity="Warning" />
HorizontalAlignment="Center" <StackPanel
VerticalAlignment="Center" HorizontalAlignment="Center"
Spacing="10"> VerticalAlignment="Center"
Spacing="10">
<DockPanel> <DockPanel>
<TextBlock <TextBlock
Margin="0,0,0,6" Margin="0,0,0,6"
DockPanel.Dock="Top" DockPanel.Dock="Top"
Text="{Binding Path=Res.User_Phone, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Text="{Binding Path=Res.User_Phone, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox <TextBox
Name="PhoneNumberText" Name="PhoneNumberText"
MaxWidth="300" MaxWidth="300"
Text="{Binding PhoneNumberText}" Text="{Binding PhoneNumberText}"
Watermark="+8601234567890" /> Watermark="+8601234567890" />
</DockPanel> </DockPanel>
<Button <Button
MinWidth="280" MinWidth="280"
HorizontalAlignment="Center" HorizontalAlignment="Center"
HorizontalContentAlignment="Center" HorizontalContentAlignment="Center"
Command="{Binding LoginSteamImport}" Command="{Binding LoginSteamImport}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel> </StackPanel>
</Panel> </Panel>-->
<!-- 验证手机 --> <!-- 验证手机 或 邮箱 -->
<Panel> <!-- 2024-04-23 Steam绑定令牌不强制手机绑定 可以输入 邮箱者手机验证码 -->
<spp:Snackbar <Panel>
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" <spp:Snackbar
VerticalAlignment="Top" Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
IsClosable="False" VerticalAlignment="Top"
IsOpen="True" IsClosable="False"
Message="{Binding Path=Res.LocalAuth_SMSCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" IsVisible="{Binding IsVerifyAccountPhone}"
Severity="Warning" /> IsOpen="True"
<StackPanel Message="{Binding Path=Res.LocalAuth_SMSCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
HorizontalAlignment="Center" Severity="Warning" />
VerticalAlignment="Center" <spp:Snackbar
Spacing="10"> Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
<DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}"> VerticalAlignment="Top"
<TextBlock IsClosable="False"
Margin="0,0,0,6" IsVisible="{Binding !IsVerifyAccountPhone}"
DockPanel.Dock="Top" IsOpen="True"
Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Message="{Binding Path=Res.LocalAuth_EmailCodeTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
<TextBox Severity="Warning" />
MaxWidth="300" <StackPanel
IsReadOnly="True" HorizontalAlignment="Center"
Text="{Binding RevocationCodeText, Mode=OneWay}" /> VerticalAlignment="Center"
</DockPanel> Spacing="10">
<!--<CheckBox Content="{Binding Path=Res.RecoveryCode_Remember, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />--> <DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
<DockPanel> <TextBlock
<TextBlock Margin="0,0,0,6"
Margin="0,0,0,6" DockPanel.Dock="Top"
DockPanel.Dock="Top" Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
Text="{Binding Path=Res.SMSCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> <TextBox
<TextBox MaxWidth="300"
Name="PhoneCodeText" IsReadOnly="True"
MaxWidth="300" Text="{Binding RevocationCodeText, Mode=OneWay}" />
Text="{Binding PhoneCodeText}" /> </DockPanel>
</DockPanel> <!--<CheckBox Content="{Binding Path=Res.RecoveryCode_Remember, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />-->
<Button <DockPanel>
MinWidth="280" <TextBlock
HorizontalAlignment="Center" Margin="0,0,0,6"
HorizontalContentAlignment="Center" DockPanel.Dock="Top"
Command="{Binding LoginSteamImport}" IsVisible="{Binding IsVerifyAccountPhone}"
Content="{Binding Path=Res.Continue, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Text="{Binding Path=Res.SMSCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel> <TextBlock
</Panel> 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> <Panel>
<spp:Snackbar <spp:Snackbar
Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" Title="{Binding Path=Res.Notice_Tray_Title, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
VerticalAlignment="Top" VerticalAlignment="Top"
IsClosable="False" IsClosable="False"
IsOpen="True" IsOpen="True"
Message="{Binding Path=Res.RecoveryCode_RememberTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" Message="{Binding Path=Res.RecoveryCode_RememberTip, Mode=OneWay, Source={x:Static s:ResourceService.Current}}"
Severity="Success" /> Severity="Success" />
<StackPanel VerticalAlignment="Center" Spacing="10"> <StackPanel VerticalAlignment="Center" Spacing="10">
<DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}"> <DockPanel IsVisible="{Binding RevocationCodeText, Mode=OneWay, Converter={StaticResource IsNullConverter}, ConverterParameter=invert}">
<TextBlock <TextBlock
Margin="0,0,0,6" Margin="0,0,0,6"
DockPanel.Dock="Top" DockPanel.Dock="Top"
Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Text="{Binding Path=Res.RecoveryCode, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
<TextBox <TextBox
MaxWidth="300" MaxWidth="300"
IsReadOnly="True" IsReadOnly="True"
Text="{Binding RevocationCodeText, Mode=OneWay}" /> Text="{Binding RevocationCodeText, Mode=OneWay}" />
</DockPanel> </DockPanel>
<Button <Button
MinWidth="280" MinWidth="280"
HorizontalAlignment="Center" HorizontalAlignment="Center"
Command="{Binding Reset}" Command="{Binding Reset}"
Content="{Binding Path=Res.Confirm, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" /> Content="{Binding Path=Res.Confirm, Mode=OneWay, Source={x:Static s:ResourceService.Current}}" />
</StackPanel> </StackPanel>
</Panel> </Panel>
</Carousel> </Carousel>
</spp:ContentLoader> </spp:ContentLoader>
</Grid> </Grid>
</UserControl> </UserControl>
@@ -14,7 +14,7 @@ public partial class SteamLoginImportPage : ReactiveUserControl<SteamLoginImport
DataContext ??= new SteamLoginImportPageViewModel(); DataContext ??= new SteamLoginImportPageViewModel();
PasswordText.KeyUp += PasswordTextOnKeyUp; PasswordText.KeyUp += PasswordTextOnKeyUp;
EmailAuthText.KeyUp += PasswordTextOnKeyUp; EmailAuthText.KeyUp += PasswordTextOnKeyUp;
PhoneNumberText.KeyUp += PasswordTextOnKeyUp; //PhoneNumberText.KeyUp += PasswordTextOnKeyUp;
PhoneCodeText.KeyUp += PasswordTextOnKeyUp; PhoneCodeText.KeyUp += PasswordTextOnKeyUp;
EmailAuthText.TextInput += EmailAuthText_TextInput; EmailAuthText.TextInput += EmailAuthText_TextInput;
PhoneCodeText.TextInput += EmailAuthText_TextInput; PhoneCodeText.TextInput += EmailAuthText_TextInput;
@@ -34,4 +34,4 @@ public partial class SteamLoginImportPage : ReactiveUserControl<SteamLoginImport
e.Handled = true; 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> /// <summary>
/// 查找类似 使用 Steam++ V1 版本工具箱导出的文件导入令牌 的本地化字符串。 /// 查找类似 使用 Steam++ V1 版本工具箱导出的文件导入令牌 的本地化字符串。
/// </summary> /// </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> /// <summary>
/// 查找类似 Steam 客户端登录区域: 的本地化字符串。 /// 查找类似 Steam 客户端登录区域: 的本地化字符串。
/// </summary> /// </summary>
@@ -2945,6 +2945,12 @@
</data> </data>
<data name="Idle_PIN_NotBeNull" xml:space="preserve"> <data name="Idle_PIN_NotBeNull" xml:space="preserve">
<value>PIN CODE 不能为空</value> <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>
<data name="CommunityFix_Starting" xml:space="preserve"> <data name="CommunityFix_Starting" xml:space="preserve">
<value>正在启动加速...</value> <value>正在启动加速...</value>