Compare commits

..

5 Commits

Author SHA1 Message Date
qhy040404
37767261cd impl #1100 2024-04-26 11:21:09 +08:00
DismissedLight
97c5e7d37f Merge pull request #1574 from DGP-Studio/fix/1485 2024-04-26 09:27:45 +08:00
DismissedLight
388f9d5657 Merge pull request #1575 from DGP-Studio/feat/1245 2024-04-26 09:24:50 +08:00
qhy040404
74e11f3823 impl #1245 2024-04-25 22:39:05 +08:00
qhy040404
c1305cda43 set passwordbox to a constant value 2024-04-25 22:13:48 +08:00
13 changed files with 149 additions and 76 deletions

View File

@@ -48,7 +48,6 @@ internal sealed class WindowSubclass : IDisposable
{
windowProc = OnSubclassProcedure;
bool windowHooked = SetWindowSubclass(options.Hwnd, windowProc, WindowSubclassId, 0);
bool propHooked = SetPropW(options.Hwnd, "NonRudeHWND", BOOL.TRUE);
hotKeyController.RegisterAll();
bool titleBarHooked = true;
@@ -56,7 +55,7 @@ internal sealed class WindowSubclass : IDisposable
// only hook up drag bar proc when use legacy Window.ExtendsContentIntoTitleBar
if (!options.UseLegacyDragBarImplementation)
{
return windowHooked && propHooked && titleBarHooked;
return windowHooked && titleBarHooked;
}
titleBarHooked = false;
@@ -64,13 +63,13 @@ internal sealed class WindowSubclass : IDisposable
if (hwndDragBar.IsNull)
{
return windowHooked && propHooked && titleBarHooked;
return windowHooked && titleBarHooked;
}
legacyDragBarProc = OnLegacyDragBarProcedure;
titleBarHooked = SetWindowSubclass(hwndDragBar, legacyDragBarProc, DragBarSubclassId, 0);
return windowHooked && propHooked && titleBarHooked;
return windowHooked && titleBarHooked;
}
/// <inheritdoc/>
@@ -79,7 +78,6 @@ internal sealed class WindowSubclass : IDisposable
hotKeyController.UnregisterAll();
RemoveWindowSubclass(options.Hwnd, windowProc, WindowSubclassId);
RemovePropW(options.Hwnd, "NonRudeHWND");
windowProc = default!;
if (options.UseLegacyDragBarImplementation)

View File

@@ -16,6 +16,9 @@ internal sealed partial class SettingEntry
public const string ElementTheme = "ElementTheme";
public const string BackgroundImageType = "BackgroundImageType";
public const string IsAutoUploadGachaLogEnabled = "IsAutoUploadGachaLogEnabled";
public const string IsAutoUploadSpiralAbyssRecordEnabled = "IsAutoUploadSpiralAbyssRecordEnabled";
public const string AnnouncementRegion = "AnnouncementRegion";
public const string IsEmptyHistoryWishVisible = "IsEmptyHistoryWishVisible";

View File

@@ -1733,6 +1733,12 @@
<data name="ViewModelSettingSetGamePathDatabaseFailedTitle" xml:space="preserve">
<value>保存游戏路径失败</value>
</data>
<data name="ViewModelSpiralAbyssUploadRecordHomaNotLoginContent" xml:space="preserve">
<value>当前未登录胡桃账号,上传深渊数据无法获赠胡桃云时长</value>
</data>
<data name="ViewModelSpiralAbyssUploadRecordHomaNotLoginTitle" xml:space="preserve">
<value>上传深渊数据</value>
</data>
<data name="ViewModelUserAdded" xml:space="preserve">
<value>用户 [{0}] 添加成功</value>
</data>
@@ -2582,6 +2588,24 @@
<data name="ViewpageSettingHomeHeader" xml:space="preserve">
<value>主页</value>
</data>
<data name="ViewPageSettingHutaoCloudAutoUploadDescription" xml:space="preserve">
<value>登录胡桃通行证后自动上传至胡桃云</value>
</data>
<data name="ViewPageSettingHutaoCloudAutoUploadHeader" xml:space="preserve">
<value>自动上传</value>
</data>
<data name="ViewPageSettingHutaoCloudGachaLogAutoUploadDescription" xml:space="preserve">
<value>刷新祈愿记录后自动上传至胡桃云,需要有效的胡桃云服务</value>
</data>
<data name="ViewPageSettingHutaoCloudGachaLogAutoUploadHeader" xml:space="preserve">
<value>自动上传祈愿记录</value>
</data>
<data name="ViewPageSettingHutaoCloudSpiralAbyssAutoUploadDescription" xml:space="preserve">
<value>刷新深境螺旋数据后自动上传至胡桃云</value>
</data>
<data name="ViewPageSettingHutaoCloudSpiralAbyssAutoUploadHeader" xml:space="preserve">
<value>自动上传深境螺旋数据</value>
</data>
<data name="ViewPageSettingHutaoPassportDangerZoneDescription" xml:space="preserve">
<value>三思而后行</value>
</data>

View File

@@ -15,6 +15,8 @@ namespace Snap.Hutao.Service;
[Injection(InjectAs.Singleton)]
internal sealed partial class AppOptions : DbStoreOptions
{
private bool? isAutoUploadGachaLogEnabled;
private bool? isAutoUploadSpiralAbyssRecordEnabled;
private bool? isEmptyHistoryWishVisible;
private bool? isUnobtainedWishItemVisible;
private BackdropType? backdropType;
@@ -23,6 +25,18 @@ internal sealed partial class AppOptions : DbStoreOptions
private Region? region;
private string? geetestCustomCompositeUrl;
public bool IsAutoUploadGachaLogEnabled
{
get => GetOption(ref isAutoUploadGachaLogEnabled, SettingEntry.IsAutoUploadGachaLogEnabled, false);
set => SetOption(ref isAutoUploadGachaLogEnabled, SettingEntry.IsAutoUploadGachaLogEnabled, value);
}
public bool IsAutoUploadSpiralAbyssRecordEnabled
{
get => GetOption(ref isAutoUploadSpiralAbyssRecordEnabled, SettingEntry.IsAutoUploadSpiralAbyssRecordEnabled, false);
set => SetOption(ref isAutoUploadSpiralAbyssRecordEnabled, SettingEntry.IsAutoUploadSpiralAbyssRecordEnabled, value);
}
public bool IsEmptyHistoryWishVisible
{
get => GetOption(ref isEmptyHistoryWishVisible, SettingEntry.IsEmptyHistoryWishVisible, false);

View File

@@ -19,6 +19,8 @@
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportUserNameHint}"
Text="{x:Bind UserName, Mode=TwoWay}"/>
<PasswordBox
Width="360"
MaxWidth="360"
Margin="0,16,0,0"
Password="{x:Bind Password, Mode=TwoWay}"
PlaceholderText="{shcm:ResourceString Name=ViewPageHutaoPassportPasswordHint}"/>

View File

@@ -31,6 +31,8 @@
Content="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeAction}"/>
</Grid>
<PasswordBox
Width="360"
MaxWidth="360"
Margin="0,16,0,0"
IsEnabled="{x:Bind VerifyCode, Converter={StaticResource StringBoolConverter}, Mode=OneWay}"
Password="{x:Bind Password, Mode=TwoWay}"

View File

@@ -31,6 +31,8 @@
Content="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeAction}"/>
</Grid>
<PasswordBox
Width="360"
MaxWidth="360"
Margin="0,16,0,0"
IsEnabled="{x:Bind VerifyCode, Converter={StaticResource StringBoolConverter}, Mode=OneWay}"
Password="{x:Bind Password, Mode=TwoWay}"

View File

@@ -37,6 +37,8 @@
Content="{shcm:ResourceString Name=ViewPageHutaoPassportVerifyCodeAction}"/>
</Grid>
<PasswordBox
Width="360"
MaxWidth="360"
Margin="0,16,0,0"
IsEnabled="{x:Bind VerifyCode, Converter={StaticResource StringBoolConverter}, Mode=OneWay}"
Password="{x:Bind Password, Mode=TwoWay}"

View File

@@ -265,6 +265,22 @@
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
</ScrollViewer>
<ScrollViewer>
<cwc:SettingsExpander
Description="{shcm:ResourceString Name=ViewPageSettingHutaoCloudAutoUploadDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingHutaoCloudAutoUploadHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE898;}"
IsExpanded="True">
<cwc:SettingsExpander.Items>
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageSettingHutaoCloudGachaLogAutoUploadDescription}" Header="{shcm:ResourceString Name=ViewPageSettingHutaoCloudGachaLogAutoUploadHeader}">
<ToggleSwitch IsOn="{Binding AppOptions.IsAutoUploadGachaLogEnabled, Mode=TwoWay}"/>
</cwc:SettingsCard>
<cwc:SettingsCard Description="{shcm:ResourceString Name=ViewPageSettingHutaoCloudSpiralAbyssAutoUploadDescription}" Header="{shcm:ResourceString Name=ViewPageSettingHutaoCloudSpiralAbyssAutoUploadHeader}">
<ToggleSwitch IsOn="{Binding AppOptions.IsAutoUploadSpiralAbyssRecordEnabled, Mode=TwoWay}"/>
</cwc:SettingsCard>
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
</ScrollViewer>
</StackPanel>
</Border>
</Border>

View File

@@ -11,6 +11,7 @@ using Snap.Hutao.Factory.Picker;
using Snap.Hutao.Factory.Progress;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.InterChange.GachaLog;
using Snap.Hutao.Service;
using Snap.Hutao.Service.GachaLog;
using Snap.Hutao.Service.GachaLog.QueryProvider;
using Snap.Hutao.Service.Notification;
@@ -38,6 +39,7 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel
private readonly IInfoBarService infoBarService;
private readonly JsonSerializerOptions options;
private readonly ITaskContext taskContext;
private readonly AppOptions appOptions;
private ObservableCollection<GachaArchive>? archives;
private GachaArchive? selectedArchive;
@@ -198,6 +200,11 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel
{
await SetSelectedArchiveAndUpdateStatisticsAsync(gachaLogService.CurrentArchive, true).ConfigureAwait(false);
await hideToken.DisposeAsync().ConfigureAwait(false);
if (HutaoCloudViewModel.Options.IsCloudServiceAllowed && appOptions.IsAutoUploadGachaLogEnabled)
{
await HutaoCloudViewModel.UploadAsync(gachaLogService.CurrentArchive).ConfigureAwait(false);
}
}
else
{

View File

@@ -47,6 +47,35 @@ internal sealed partial class HutaoCloudViewModel : Abstraction.ViewModel
/// </summary>
internal ICommand RetrieveCommand { get; set; }
[Command("UploadCommand")]
internal async Task UploadAsync(GachaArchive? gachaArchive)
{
if (gachaArchive is not null)
{
ContentDialog dialog = await contentDialogFactory
.CreateForIndeterminateProgressAsync(SH.ViewModelGachaLogUploadToHutaoCloudProgress)
.ConfigureAwait(false);
bool isOk;
string message;
using (await dialog.BlockAsync(taskContext).ConfigureAwait(false))
{
(isOk, message) = await hutaoCloudService.UploadGachaItemsAsync(gachaArchive).ConfigureAwait(false);
}
if (isOk)
{
infoBarService.Success(message);
await RefreshUidCollectionAsync().ConfigureAwait(false);
}
else
{
infoBarService.Warning(message);
}
}
}
/// <summary>
/// 异步获取祈愿记录
/// </summary>
@@ -77,35 +106,6 @@ internal sealed partial class HutaoCloudViewModel : Abstraction.ViewModel
await Windows.System.Launcher.LaunchUriAsync("https://afdian.net/item/80d3b9decf9011edb5f452540025c377".ToUri());
}
[Command("UploadCommand")]
private async Task UploadAsync(GachaArchive? gachaArchive)
{
if (gachaArchive is not null)
{
ContentDialog dialog = await contentDialogFactory
.CreateForIndeterminateProgressAsync(SH.ViewModelGachaLogUploadToHutaoCloudProgress)
.ConfigureAwait(false);
bool isOk;
string message;
using (await dialog.BlockAsync(taskContext).ConfigureAwait(false))
{
(isOk, message) = await hutaoCloudService.UploadGachaItemsAsync(gachaArchive).ConfigureAwait(false);
}
if (isOk)
{
infoBarService.Success(message);
await RefreshUidCollectionAsync().ConfigureAwait(false);
}
else
{
infoBarService.Warning(message);
}
}
}
[Command("DeleteCommand")]
private async Task DeleteAsync(string? uid)
{

View File

@@ -2,7 +2,11 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.Messaging;
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Factory.ContentDialog;
using Snap.Hutao.Message;
using Snap.Hutao.Service;
using Snap.Hutao.Service.Hutao;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.SpiralAbyss;
using Snap.Hutao.Service.User;
@@ -24,11 +28,14 @@ namespace Snap.Hutao.ViewModel.SpiralAbyss;
internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel, IRecipient<UserChangedMessage>
{
private readonly ISpiralAbyssRecordService spiralAbyssRecordService;
private readonly IContentDialogFactory contentDialogFactory;
private readonly HutaoSpiralAbyssClient spiralAbyssClient;
private readonly IInfoBarService infoBarService;
private readonly ITaskContext taskContext;
private readonly IUserService userService;
private readonly HutaoDatabaseViewModel hutaoDatabaseViewModel;
private readonly HutaoUserOptions hutaoUserOptions;
private readonly AppOptions appOptions;
private ObservableCollection<SpiralAbyssView>? spiralAbyssEntries;
private SpiralAbyssView? selectedView;
@@ -119,6 +126,11 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
await taskContext.SwitchToMainThreadAsync();
SelectedView = SpiralAbyssEntries.FirstOrDefault(s => s.Engaged);
if (hutaoUserOptions.IsLoggedIn && appOptions.IsAutoUploadSpiralAbyssRecordEnabled)
{
await UploadSpiralAbyssRecordCoreAsync(userAndUid).ConfigureAwait(false);
}
}
}
}
@@ -128,30 +140,47 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
{
if (UserAndUid.TryFromUser(userService.Current, out UserAndUid? userAndUid))
{
SimpleRecord? record = await spiralAbyssClient.GetPlayerRecordAsync(userAndUid).ConfigureAwait(false);
if (record is not null)
if (!hutaoUserOptions.IsLoggedIn)
{
Web.Response.Response response = await spiralAbyssClient.UploadRecordAsync(record).ConfigureAwait(false);
ContentDialogResult result = await contentDialogFactory
.CreateForConfirmCancelAsync(SH.ViewModelSpiralAbyssUploadRecordHomaNotLoginTitle, SH.ViewModelSpiralAbyssUploadRecordHomaNotLoginContent)
.ConfigureAwait(false);
if (response is { ReturnCode: 0 })
if (result is not ContentDialogResult.Primary)
{
if (response is ILocalizableResponse localizableResponse)
{
infoBarService.Success(localizableResponse.GetLocalizationMessage());
}
}
else
{
if (response is ILocalizableResponse localizableResponse)
{
infoBarService.Warning(localizableResponse.GetLocalizationMessage());
}
return;
}
}
await UploadSpiralAbyssRecordCoreAsync(userAndUid).ConfigureAwait(false);
}
else
{
infoBarService.Warning(SH.MustSelectUserAndUid);
}
}
private async ValueTask UploadSpiralAbyssRecordCoreAsync(UserAndUid userAndUid)
{
SimpleRecord? record = await spiralAbyssClient.GetPlayerRecordAsync(userAndUid).ConfigureAwait(false);
if (record is not null)
{
Web.Response.Response response = await spiralAbyssClient.UploadRecordAsync(record).ConfigureAwait(false);
if (response is { ReturnCode: 0 })
{
if (response is ILocalizableResponse localizableResponse)
{
infoBarService.Success(localizableResponse.GetLocalizationMessage());
}
}
else
{
if (response is ILocalizableResponse localizableResponse)
{
infoBarService.Warning(localizableResponse.GetLocalizationMessage());
}
}
}
}
}

View File

@@ -85,19 +85,6 @@ internal static class User32
[SupportedOSPlatform("windows5.0")]
public static extern int ReleaseDC([AllowNull] HWND hWnd, HDC hDC);
[DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true)]
[SupportedOSPlatform("windows5.0")]
public static extern HANDLE RemovePropW(HWND hWnd, PCWSTR lpString);
[DebuggerStepThrough]
public static unsafe HANDLE RemovePropW(HWND hWnd, string str)
{
fixed (char* lpString = str)
{
return RemovePropW(hWnd, lpString);
}
}
[DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, ExactSpelling = true, SetLastError = true)]
[SupportedOSPlatform("windows5.0")]
public static unsafe extern uint SendInput(uint cInputs, INPUT* pInputs, int cbSize);
@@ -115,19 +102,6 @@ internal static class User32
[SupportedOSPlatform("windows5.0")]
public static extern BOOL SetForegroundWindow(HWND hWnd);
[DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[SupportedOSPlatform("windows5.0")]
public static extern BOOL SetPropW(HWND hWnd, PCWSTR lpString, [AllowNull] nint hData);
[DebuggerStepThrough]
public static unsafe BOOL SetPropW(HWND hWnd, string str, [AllowNull] nint hData)
{
fixed (char* lpString = str)
{
return SetPropW(hWnd, lpString, hData);
}
}
[DllImport("USER32.dll", CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Unicode, ExactSpelling = true, SetLastError = true)]
[SupportedOSPlatform("windows5.0")]
public static extern nint SetWindowLongPtrW(HWND hWnd, WINDOW_LONG_PTR_INDEX nIndex, nint dwNewLong);