This commit is contained in:
DismissedLight
2023-02-08 12:28:31 +08:00
parent aec483510f
commit e60a04a2bc
9 changed files with 149 additions and 28 deletions

View File

@@ -3,6 +3,7 @@
using Microsoft.Win32;
using Snap.Hutao.Core.Json;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Extension;
using Snap.Hutao.Web.Hoyolab.DynamicSecret;
using System.Collections.Immutable;
@@ -123,16 +124,25 @@ internal static class CoreEnvironment
private static string GetDatafolderPath()
{
string myDocument = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string preferredPath = LocalSetting.Get(SettingKeys.DataFolderPath, string.Empty);
if (string.IsNullOrEmpty(preferredPath))
{
string myDocument = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
#if RELEASE
// 将测试版与正式版的文件目录分离
string folderName = Package.Current.PublisherDisplayName == "DGP Studio CI" ? "HutaoAlpha" : "Hutao";
// 将测试版与正式版的文件目录分离
string folderName = Package.Current.PublisherDisplayName == "DGP Studio CI" ? "HutaoAlpha" : "Hutao";
#else
// 使得迁移能正常生成
string folderName = "Hutao";
// 使得迁移能正常生成
string folderName = "Hutao";
#endif
string path = Path.GetFullPath(Path.Combine(myDocument, folderName));
Directory.CreateDirectory(path);
return path;
string path = Path.GetFullPath(Path.Combine(myDocument, folderName));
Directory.CreateDirectory(path);
return path;
}
else
{
return preferredPath;
}
}
}

View File

@@ -63,6 +63,32 @@ internal static class PickerExtension
}
}
/// <inheritdoc cref="FolderPicker.PickSingleFolderAsync"/>
public static async Task<ValueResult<bool, string>> TryPickSingleFolderAsync(this FolderPicker picker)
{
StorageFolder? folder;
Exception? exception = null;
try
{
folder = await picker.PickSingleFolderAsync().AsTask().ConfigureAwait(false);
}
catch (Exception ex)
{
exception = ex;
folder = null;
}
if (folder != null)
{
return new(true, folder.Path);
}
else
{
InfoBarWaringPickerException(exception);
return new(false, null!);
}
}
private static void InfoBarWaringPickerException(Exception? exception)
{
if (exception != null)

View File

@@ -77,6 +77,12 @@ internal static class LocalSetting
return Get<char>(key, defaultValue);
}
/// <inheritdoc cref="Get{T}(string, T)"/>
public static string Get(string key, string defaultValue)
{
return Get<string>(key, defaultValue);
}
/// <inheritdoc cref="Get{T}(string, T)"/>
public static DateTimeOffset Get(string key, DateTimeOffset defaultValue)
{
@@ -173,6 +179,12 @@ internal static class LocalSetting
Set<char>(key, value);
}
/// <inheritdoc cref="Set{T}(string, T)"/>
public static void Set(string key, string value)
{
Set<string>(key, value);
}
/// <inheritdoc cref="Set{T}(string, T)"/>
public static void Set(string key, DateTimeOffset value)
{
@@ -216,8 +228,7 @@ internal static class LocalSetting
/// <param name="key">键</param>
/// <param name="defaultValue">默认值</param>
/// <returns>获取的值</returns>
private static T Get<T>(string key, T defaultValue = default)
where T : struct
private static T Get<T>(string key, T defaultValue = default!)
{
if (Container.Values.TryGetValue(key, out object? value))
{
@@ -238,7 +249,6 @@ internal static class LocalSetting
/// <param name="key">键</param>
/// <param name="value">值</param>
private static void Set<T>(string key, T value)
where T : struct
{
Container.Values[key] = value;
}

View File

@@ -23,6 +23,11 @@ internal static class SettingKeys
/// </summary>
public const string LaunchTimes = "LaunchTimes";
/// <summary>
/// 数据文件夹
/// </summary>
public const string DataFolderPath = "DataFolderPath";
/// <summary>
/// 静态资源合约
/// 新增合约时 请注意

View File

@@ -1761,6 +1761,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 设置数据目录成功,重启以应用更改 的本地化字符串。
/// </summary>
internal static string ViewModelSettingSetDataFolderSuccess {
get {
return ResourceManager.GetString("ViewModelSettingSetDataFolderSuccess", resourceCulture);
}
}
/// <summary>
/// 查找类似 用户 [{0}] 添加成功 的本地化字符串。
/// </summary>
@@ -3327,6 +3336,24 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 更改目录后需要手动移动目录内的数据,否则会重新创建用户数据 的本地化字符串。
/// </summary>
internal static string ViewPageSettingSetDataFolderDescription {
get {
return ResourceManager.GetString("ViewPageSettingSetDataFolderDescription", resourceCulture);
}
}
/// <summary>
/// 查找类似 更改数据目录 的本地化字符串。
/// </summary>
internal static string ViewPageSettingSetDataFolderHeader {
get {
return ResourceManager.GetString("ViewPageSettingSetDataFolderHeader", resourceCulture);
}
}
/// <summary>
/// 查找类似 设置路径 的本地化字符串。
/// </summary>
@@ -3372,6 +3399,15 @@ namespace Snap.Hutao.Resource.Localization {
}
}
/// <summary>
/// 查找类似 更改 的本地化字符串。
/// </summary>
internal static string ViewPageSettingStorageSetAction {
get {
return ResourceManager.GetString("ViewPageSettingStorageSetAction", resourceCulture);
}
}
/// <summary>
/// 查找类似 前往商店 的本地化字符串。
/// </summary>

View File

@@ -684,6 +684,9 @@
<data name="ViewModelSettingClearWebCacheSuccess" xml:space="preserve">
<value>清除完成</value>
</data>
<data name="ViewModelSettingSetDataFolderSuccess" xml:space="preserve">
<value>设置数据目录成功,重启以应用更改</value>
</data>
<data name="ViewModelUserAdded" xml:space="preserve">
<value>用户 [{0}] 添加成功</value>
</data>
@@ -1206,6 +1209,12 @@
<data name="ViewPageSettingGameHeader" xml:space="preserve">
<value>游戏</value>
</data>
<data name="ViewPageSettingSetDataFolderDescription" xml:space="preserve">
<value>更改目录后需要手动移动目录内的数据,否则会重新创建用户数据</value>
</data>
<data name="ViewPageSettingSetDataFolderHeader" xml:space="preserve">
<value>更改数据目录</value>
</data>
<data name="ViewPageSettingSetGamePathAction" xml:space="preserve">
<value>设置路径</value>
</data>
@@ -1221,6 +1230,9 @@
<data name="ViewPageSettingStorageOpenAction" xml:space="preserve">
<value>打开</value>
</data>
<data name="ViewPageSettingStorageSetAction" xml:space="preserve">
<value>更改</value>
</data>
<data name="ViewPageSettingUpdateCheckAction" xml:space="preserve">
<value>前往商店</value>
</data>

View File

@@ -139,8 +139,16 @@
<Button Command="{Binding Experimental.OpenDataFolderCommand}" Content="{shcm:ResourceString Name=ViewPageSettingStorageOpenAction}"/>
</wsc:Setting.ActionContent>
</wsc:Setting>
<wsc:Setting
Description="{shcm:ResourceString Name=ViewPageSettingSetDataFolderDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingSetDataFolderHeader}"
Icon="&#xE8DE;">
<wsc:Setting.ActionContent>
<Button Command="{Binding SetDataFolderCommand}" Content="{shcm:ResourceString Name=ViewPageSettingStorageSetAction}"/>
</wsc:Setting.ActionContent>
</wsc:Setting>
<wsc:Setting
Margin="0,4,0,0"
Description="{shcm:ResourceString Name=ViewPageSettingCacheFolderDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingCacheFolderHeader}"
Icon="&#xE8B7;">

View File

@@ -4,17 +4,22 @@
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using Snap.Hutao.Core.Database;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Core.Windowing;
using Snap.Hutao.Factory.Abstraction;
using Snap.Hutao.Model;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.GachaLog;
using Snap.Hutao.Service.GachaLog.QueryProvider;
using Snap.Hutao.Service.Game;
using Snap.Hutao.Service.Game.Locator;
using Snap.Hutao.View.Dialog;
using System.IO;
using System.Runtime.InteropServices;
using Windows.Storage;
using Windows.Storage.Pickers;
namespace Snap.Hutao.ViewModel;
@@ -75,6 +80,7 @@ internal class SettingViewModel : Abstraction.ViewModel
UpdateCheckCommand = new AsyncRelayCommand(CheckUpdateAsync);
DeleteGameWebCacheCommand = new RelayCommand(DeleteGameWebCache);
ShowSignInWebViewDialogCommand = new AsyncRelayCommand(ShowSignInWebViewDialogAsync);
SetDataFolderCommand = new AsyncRelayCommand(SetDataFolderAsync);
}
/// <summary>
@@ -178,6 +184,11 @@ internal class SettingViewModel : Abstraction.ViewModel
/// </summary>
public ICommand ShowSignInWebViewDialogCommand { get; }
/// <summary>
/// 设置数据目录命令
/// </summary>
public ICommand SetDataFolderCommand { get; }
private async Task SetGamePathAsync()
{
IGameLocator locator = Ioc.Default.GetRequiredService<IEnumerable<IGameLocator>>()
@@ -242,4 +253,18 @@ internal class SettingViewModel : Abstraction.ViewModel
await Windows.System.Launcher.LaunchUriAsync(new(@"ms-windows-store://pdp/?productid=9PH4NXJ2JN52"));
#endif
}
private async Task SetDataFolderAsync()
{
IPickerFactory pickerFactory = Ioc.Default.GetRequiredService<IPickerFactory>();
FolderPicker picker = pickerFactory.GetFolderPicker();
(bool isOk, string folder) = await picker.TryPickSingleFolderAsync().ConfigureAwait(false);
IInfoBarService infoBarService = Ioc.Default.GetRequiredService<IInfoBarService>();
if (isOk)
{
LocalSetting.Set(SettingKeys.DataFolderPath, folder);
infoBarService.Success(SH.ViewModelSettingSetDataFolderSuccess);
}
}
}

View File

@@ -3,6 +3,7 @@
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Web.Bridge.Model;
using System.Runtime.CompilerServices;
namespace Snap.Hutao.Web.Response;
@@ -43,24 +44,12 @@ public class Response
/// </summary>
/// <typeparam name="TData">类型</typeparam>
/// <param name="response">本体</param>
/// <param name="callerName">调用方法名称</param>
/// <returns>本体或默认值,当本体为 null 时 返回默认值</returns>
public static Response<TData> DefaultIfNull<TData>(Response<TData>? response)
public static Response<TData> DefaultIfNull<TData>(Response<TData>? response, [CallerMemberName] string callerName = default!)
{
// 0x26F19335 is a magic number that hashed from "Snap.Hutao"
return response ?? new(0x26F19335, $"[{typeof(TData).Name}] 请求异常", default);
}
/// <summary>
/// 返回本体或带有消息提示的默认值
/// </summary>
/// <typeparam name="TData">类型</typeparam>
/// <param name="response">本体</param>
/// <param name="message">消息</param>
/// <returns>本体或默认值,当本体为 null 时 返回默认值</returns>
public static Response<TData> DefaultIfNull<TData>(Response<TData>? response, string message)
{
// 0x26F19335 is a magic number that hashed from "Snap.Hutao"
return response ?? new(0x26F19335, message, default);
return response ?? new(0x26F19335, $"[{callerName}] 中的 [{typeof(TData).Name}] 请求异常", default);
}
/// <inheritdoc/>