Compare commits

..

1 Commits

Author SHA1 Message Date
qhy040404
4ded6dc9bf Update build.cake 2024-02-20 10:38:18 +08:00
33 changed files with 191 additions and 611 deletions

View File

@@ -13,18 +13,6 @@ on:
- '**.md'
- 'LICENSE'
- '**.yml'
pull_request:
branches:
- develop
paths-ignore:
- '.gitattributes'
- '.github/**'
- '.gitignore'
- '.gitmodules'
- '**.md'
- 'LICENSE'
- '**.yml'
- '**.resx'
jobs:
build:
@@ -46,21 +34,20 @@ jobs:
VERSION_API_TOKEN: ${{ secrets.VERSION_API_TOKEN }}
- name: Sign Msix
if: success() && github.event_name != 'pull_request'
shell: pwsh
run: |
[System.Convert]::FromBase64String("${{ secrets.CERTIFICATE }}") | Set-Content -AsByteStream temp.pfx
signtool.exe sign /debug /v /a /fd SHA256 /f temp.pfx /p ${{ secrets.PW }} ${{ github.workspace }}\src\output\Snap.Hutao.Alpha-${{ steps.cake.outputs.version }}.msix
- name: Upload signed msix
if: success() && github.event_name != 'pull_request'
uses: actions/upload-artifact@v4
if: success()
uses: actions/upload-artifact@v3
with:
name: Snap.Hutao.Alpha-${{ steps.cake.outputs.version }}
path: ${{ github.workspace }}/src/output/Snap.Hutao.Alpha-${{ steps.cake.outputs.version }}.msix
- name: Add summary
if: success() && github.event_name != 'pull_request'
if: success()
shell: pwsh
run: |
$summary = "

View File

@@ -33,28 +33,18 @@ if (GitHubActions.IsRunningOnGitHubActions)
repoDir = GitHubActions.Environment.Workflow.Workspace.FullPath;
outputPath = System.IO.Path.Combine(repoDir, "src", "output");
if (GitHubActions.Environment.PullRequest.IsPullRequest)
{
version = System.DateTime.Now.ToString("yyyy.M.d.0");
Information("Is Pull Request. Skip version.");
}
else
{
var versionAuth = HasEnvironmentVariable("VERSION_API_TOKEN") ? EnvironmentVariable("VERSION_API_TOKEN") : throw new Exception("Cannot find VERSION_API_TOKEN");
version = HttpGet(
"https://internal.snapgenshin.cn/BuildIntergration/RequestNewVersion",
new HttpSettings
{
Headers = new Dictionary<string, string>
{
var versionAuth = HasEnvironmentVariable("VERSION_API_TOKEN") ? EnvironmentVariable("VERSION_API_TOKEN") : throw new Exception("Cannot find VERSION_API_TOKEN");
version = HttpGet(
"https://internal.snapgenshin.cn/BuildIntergration/RequestNewVersion",
new HttpSettings
{
Headers = new Dictionary<string, string>
{
{ "Authorization", versionAuth }
}
}
);
Information($"Version: {version}");
}
}
}
);
Information($"Version: {version}");
GitHubActions.Commands.SetOutputParameter("version", version);
}

View File

@@ -23,12 +23,10 @@ internal static class ControlAnimationConstants
/// <summary>
/// 图像淡入
/// </summary>
public static readonly TimeSpan ImageScaleFadeIn = TimeSpan.FromSeconds(0.3);
public static readonly TimeSpan ImageFadeIn = TimeSpan.FromSeconds(0.3);
/// <summary>
/// 图像淡出
/// </summary>
public static readonly TimeSpan ImageScaleFadeOut = TimeSpan.FromSeconds(0.2);
public static readonly TimeSpan ImageOpacityFadeInOut = TimeSpan.FromSeconds(1);
public static readonly TimeSpan ImageFadeOut = TimeSpan.FromSeconds(0.2);
}

View File

@@ -1,89 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using CommunityToolkit.WinUI.Behaviors;
using Microsoft.UI.Xaml;
namespace Snap.Hutao.Control.Behavior;
[DependencyProperty("Period", typeof(TimeSpan))]
[DependencyProperty("Command", typeof(ICommand))]
[DependencyProperty("CommandParameter", typeof(object))]
internal sealed partial class PeriodicInvokeCommandOrOnActualThemeChangedBehavior : BehaviorBase<FrameworkElement>, IDisposable
{
private TaskCompletionSource acutalThemeChangedTaskCompletionSource = new();
private CancellationTokenSource periodicTimerCancellationTokenSource = new();
public void Dispose()
{
periodicTimerCancellationTokenSource.Dispose();
}
protected override bool Initialize()
{
AssociatedObject.ActualThemeChanged += OnActualThemeChanged;
return true;
}
protected override void OnAssociatedObjectLoaded()
{
RunCoreAsync().SafeForget();
}
protected override bool Uninitialize()
{
AssociatedObject.ActualThemeChanged -= OnActualThemeChanged;
return true;
}
private void OnActualThemeChanged(FrameworkElement sender, object args)
{
acutalThemeChangedTaskCompletionSource.TrySetResult();
periodicTimerCancellationTokenSource.Cancel();
}
private void TryExecuteCommand()
{
if (AssociatedObject is null)
{
return;
}
if (Command is not null && Command.CanExecute(CommandParameter))
{
Command.Execute(CommandParameter);
}
}
private async ValueTask RunCoreAsync()
{
using (PeriodicTimer timer = new(Period))
{
do
{
if (!IsAttached)
{
break;
}
ITaskContext taskContext = Ioc.Default.GetRequiredService<ITaskContext>();
await taskContext.SwitchToMainThreadAsync();
TryExecuteCommand();
await taskContext.SwitchToBackgroundAsync();
try
{
Task nextTickTask = timer.WaitForNextTickAsync(periodicTimerCancellationTokenSource.Token).AsTask();
await Task.WhenAny(nextTickTask, acutalThemeChangedTaskCompletionSource.Task).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
}
acutalThemeChangedTaskCompletionSource = new();
periodicTimerCancellationTokenSource = new();
}
while (true);
}
}
}

View File

@@ -192,7 +192,7 @@ internal abstract partial class CompositionImage : Microsoft.UI.Xaml.Controls.Co
{
await AnimationBuilder
.Create()
.Opacity(from: 0D, to: 1D, duration: ControlAnimationConstants.ImageScaleFadeIn)
.Opacity(from: 0D, to: 1D, duration: ControlAnimationConstants.ImageFadeIn)
.StartAsync(this, token)
.ConfigureAwait(true);
}
@@ -213,7 +213,7 @@ internal abstract partial class CompositionImage : Microsoft.UI.Xaml.Controls.Co
{
await AnimationBuilder
.Create()
.Opacity(from: 1D, to: 0D, duration: ControlAnimationConstants.ImageScaleFadeOut)
.Opacity(from: 1D, to: 0D, duration: ControlAnimationConstants.ImageFadeOut)
.StartAsync(this, token)
.ConfigureAwait(true);
}

View File

@@ -18,12 +18,6 @@ internal sealed class HutaoException : Exception
public HutaoExceptionKind Kind { get; private set; }
[DoesNotReturn]
public static HutaoException Throw(HutaoExceptionKind kind, string message, Exception? innerException = default)
{
throw new HutaoException(kind, message, innerException);
}
public static void ThrowIf(bool condition, HutaoExceptionKind kind, string message, Exception? innerException = default)
{
if (condition)
@@ -31,10 +25,4 @@ internal sealed class HutaoException : Exception
throw new HutaoException(kind, message, innerException);
}
}
public static HutaoException ServiceTypeCastFailed<TFrom, TTo>(string name, Exception? innerException = default)
{
string message = $"This instance of '{typeof(TFrom).FullName}' '{name}' doesn't implement '{typeof(TTo).FullName}'";
throw new HutaoException(HutaoExceptionKind.ServiceTypeCastFailed, message, innerException);
}
}

View File

@@ -6,5 +6,4 @@ namespace Snap.Hutao.Core.ExceptionService;
internal enum HutaoExceptionKind
{
None,
ServiceTypeCastFailed,
}

View File

@@ -5,7 +5,6 @@ using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Core.LifeCycle;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Model;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Win32.Foundation;
using Snap.Hutao.Win32.UI.Input.KeyboardAndMouse;
using System.Text;
@@ -18,7 +17,6 @@ namespace Snap.Hutao.Core.Windowing.HotKey;
internal sealed class HotKeyCombination : ObservableObject
{
private readonly ICurrentWindowReference currentWindowReference;
private readonly IInfoBarService infoBarService;
private readonly RuntimeOptions runtimeOptions;
private readonly string settingKey;
@@ -39,7 +37,6 @@ internal sealed class HotKeyCombination : ObservableObject
public HotKeyCombination(IServiceProvider serviceProvider, string settingKey, int hotKeyId, HOT_KEY_MODIFIERS defaultModifiers, VirtualKey defaultKey)
{
currentWindowReference = serviceProvider.GetRequiredService<ICurrentWindowReference>();
infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
runtimeOptions = serviceProvider.GetRequiredService<RuntimeOptions>();
this.settingKey = settingKey;
@@ -189,12 +186,6 @@ internal sealed class HotKeyCombination : ObservableObject
HWND hwnd = currentWindowReference.GetWindowHandle();
BOOL result = RegisterHotKey(hwnd, hotKeyId, Modifiers, (uint)Key);
registered = result;
if (!result)
{
infoBarService.Warning(SH.FormatCoreWindowHotkeyCombinationRegisterFailed(SH.ViewPageSettingKeyShortcutAutoClickingHeader, DisplayName));
}
return result;
}

View File

@@ -11,16 +11,10 @@ internal static class CollectionsNameValue
return [.. Enum.GetValues<TEnum>().Select(x => new NameValue<TEnum>(x.ToString(), x))];
}
public static List<NameValue<TEnum>> FromEnum<TEnum>(Func<TEnum, bool> condition)
public static List<NameValue<TEnum>> FromEnum<TEnum>(Func<TEnum, bool> codiction)
where TEnum : struct, Enum
{
return [.. Enum.GetValues<TEnum>().Where(condition).Select(x => new NameValue<TEnum>(x.ToString(), x))];
}
public static List<NameValue<TEnum>> FromEnum<TEnum>(Func<TEnum, string> nameSelector)
where TEnum : struct, Enum
{
return [.. Enum.GetValues<TEnum>().Select(x => new NameValue<TEnum>(nameSelector(x), x))];
return [.. Enum.GetValues<TEnum>().Where(codiction).Select(x => new NameValue<TEnum>(x.ToString(), x))];
}
public static List<NameValue<TSource>> From<TSource>(IEnumerable<TSource> sources, Func<TSource, string> nameSelector)

View File

@@ -13,7 +13,6 @@ internal sealed partial class SettingEntry
public const string Culture = "Culture";
public const string SystemBackdropType = "SystemBackdropType";
public const string BackgroundImageType = "BackgroundImageType";
public const string AnnouncementRegion = "AnnouncementRegion";

View File

@@ -186,9 +186,6 @@
<data name="CoreWebView2HelperVersionUndetected" xml:space="preserve">
<value>未检测到 WebView2 运行时</value>
</data>
<data name="CoreWindowHotkeyCombinationRegisterFailed" xml:space="preserve">
<value>[{0}] 热键 [{1}] 注册失败</value>
</data>
<data name="FilePickerExportCommit" xml:space="preserve">
<value>导出</value>
</data>
@@ -770,21 +767,6 @@
<data name="ServiceAvatarInfoSummaryShowcaseRefreshTimeFormat" xml:space="preserve">
<value>角色橱窗:{0:MM-dd HH:mm}</value>
</data>
<data name="ServiceBackgroundImageTypeBing" xml:space="preserve">
<value>必应每日一图</value>
</data>
<data name="ServiceBackgroundImageTypeDaily" xml:space="preserve">
<value>胡桃每日一图</value>
</data>
<data name="ServiceBackgroundImageTypeLauncher" xml:space="preserve">
<value>官方启动器壁纸</value>
</data>
<data name="ServiceBackgroundImageTypeLocalFolder" xml:space="preserve">
<value>本地随机图片</value>
</data>
<data name="ServiceBackgroundImageTypeNone" xml:space="preserve">
<value>无背景图片</value>
</data>
<data name="ServiceCultivationProjectCurrentUserdataCourrpted" xml:space="preserve">
<value>保存养成计划状态失败</value>
</data>
@@ -1694,9 +1676,6 @@
<data name="ViewModelWelcomeDownloadSummaryComplete" xml:space="preserve">
<value>完成</value>
</data>
<data name="ViewModelWelcomeDownloadSummaryContentTypeNotMatch" xml:space="preserve">
<value>响应内容不是有效的文件字节流</value>
</data>
<data name="ViewModelWelcomeDownloadSummaryDefault" xml:space="preserve">
<value>等待中</value>
</data>
@@ -2360,15 +2339,6 @@
<data name="ViewPageSettingBackdropMaterialHeader" xml:space="preserve">
<value>背景材质</value>
</data>
<data name="ViewPageSettingBackgroundImageCopyrightHeader" xml:space="preserve">
<value>图片版权信息</value>
</data>
<data name="ViewPageSettingBackgroundImageDescription" xml:space="preserve">
<value>更改窗体的背景图片来源,重启胡桃以尽快生效</value>
</data>
<data name="ViewPageSettingBackgroundImageHeader" xml:space="preserve">
<value>背景图片</value>
</data>
<data name="ViewPageSettingCacheFolderDescription" xml:space="preserve">
<value>图片缓存 在此处存放</value>
</data>

View File

@@ -5,7 +5,6 @@ using Snap.Hutao.Core.Windowing;
using Snap.Hutao.Model;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Service.Abstraction;
using Snap.Hutao.Service.BackgroundImage;
using Snap.Hutao.Web.Hoyolab;
namespace Snap.Hutao.Service;
@@ -16,7 +15,6 @@ internal sealed partial class AppOptions : DbStoreOptions
{
private bool? isEmptyHistoryWishVisible;
private BackdropType? backdropType;
private BackgroundImageType? backgroundImageType;
private Region? region;
private string? geetestCustomCompositeUrl;
@@ -30,16 +28,8 @@ internal sealed partial class AppOptions : DbStoreOptions
public BackdropType BackdropType
{
get => GetOption(ref backdropType, SettingEntry.SystemBackdropType, EnumParse<BackdropType>, BackdropType.Mica).Value;
set => SetOption(ref backdropType, SettingEntry.SystemBackdropType, value, EnumToStringOrEmpty);
}
public List<NameValue<BackgroundImageType>> BackgroundImageTypes { get; } = CollectionsNameValue.FromEnum<BackgroundImageType>(type => type.GetLocalizedDescription());
public BackgroundImageType BackgroundImageType
{
get => GetOption(ref backgroundImageType, SettingEntry.BackgroundImageType, EnumParse<BackgroundImageType>, BackgroundImageType.None).Value;
set => SetOption(ref backgroundImageType, SettingEntry.BackgroundImageType, value, EnumToStringOrEmpty);
get => GetOption(ref backdropType, SettingEntry.SystemBackdropType, v => Enum.Parse<BackdropType>(v), BackdropType.Mica).Value;
set => SetOption(ref backdropType, SettingEntry.SystemBackdropType, value, value => value.ToStringOrEmpty());
}
public Lazy<List<NameValue<Region>>> LazyRegions { get; } = new(KnownRegions.Get);
@@ -55,16 +45,4 @@ internal sealed partial class AppOptions : DbStoreOptions
get => GetOption(ref geetestCustomCompositeUrl, SettingEntry.GeetestCustomCompositeUrl);
set => SetOption(ref geetestCustomCompositeUrl, SettingEntry.GeetestCustomCompositeUrl, value);
}
private static T? EnumParse<T>(string input)
where T : struct, Enum
{
return Enum.Parse<T>(input);
}
private static string EnumToStringOrEmpty<T>(T? input)
where T : struct, Enum
{
return input.ToStringOrEmpty();
}
}

View File

@@ -2,14 +2,17 @@
// Licensed under the MIT license.
using Microsoft.UI.Xaml.Media.Imaging;
using Snap.Hutao.Control.Media;
using Snap.Hutao.Core;
using System.IO;
using System.Runtime.InteropServices;
using Windows.Graphics.Imaging;
using Windows.UI;
namespace Snap.Hutao.Service.BackgroundImage;
internal sealed class BackgroundImage
{
public string Path { get; set; } = default!;
public BitmapImage ImageSource { get; set; } = default!;
public Color AccentColor { get; set; }

View File

@@ -1,15 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Web.Hutao.Wallpaper;
namespace Snap.Hutao.Service.BackgroundImage;
[Injection(InjectAs.Singleton)]
internal sealed partial class BackgroundImageOptions : ObservableObject
{
private Wallpaper? wallpaper;
public Wallpaper? Wallpaper { get => wallpaper; set => SetProperty(ref wallpaper, value); }
}

View File

@@ -5,11 +5,11 @@ using Snap.Hutao.Control.Media;
using Snap.Hutao.Core;
using Snap.Hutao.Core.Caching;
using Snap.Hutao.Core.IO;
using Snap.Hutao.Web.Hutao.Wallpaper;
using Snap.Hutao.Service.Game.Scheme;
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher;
using Snap.Hutao.Web.Hoyolab.SdkStatic.Hk4e.Launcher.Content;
using Snap.Hutao.Web.Response;
using Snap.Hutao.Win32.Foundation;
using System.IO;
using System.Runtime.InteropServices;
using Windows.Graphics.Imaging;
namespace Snap.Hutao.Service.BackgroundImage;
@@ -20,13 +20,11 @@ internal sealed partial class BackgroundImageService : IBackgroundImageService
{
private static readonly HashSet<string> AllowedFormats = [".bmp", ".gif", ".ico", ".jpg", ".jpeg", ".png", ".tiff", ".webp"];
private readonly BackgroundImageOptions backgroundImageOptions;
private readonly IServiceProvider serviceProvider;
private readonly RuntimeOptions runtimeOptions;
private readonly ITaskContext taskContext;
private readonly AppOptions appOptions;
private HashSet<string> currentBackgroundPathSet;
private HashSet<string> backgroundPathSet;
public async ValueTask<ValueResult<bool, BackgroundImage>> GetNextBackgroundImageAsync(BackgroundImage? previous)
{
@@ -37,31 +35,18 @@ internal sealed partial class BackgroundImageService : IBackgroundImageService
return new(false, default!);
}
string path = System.Random.Shared.GetItems([..backgroundSet], 1)[0];
string path = System.Random.Shared.GetItems(backgroundSet.ToArray(), 1)[0];
backgroundSet.Remove(path);
if (string.Equals(path, previous?.Path, StringComparison.OrdinalIgnoreCase))
await taskContext.SwitchToMainThreadAsync();
if (string.Equals(path, previous?.ImageSource.UriSource.ToString(), StringComparison.OrdinalIgnoreCase))
{
return new(false, default!);
}
using (FileStream fileStream = File.OpenRead(path))
{
BitmapDecoder decoder;
try
{
decoder = await BitmapDecoder.CreateAsync(fileStream.AsRandomAccessStream());
}
catch (COMException comException)
{
if (comException.HResult != HRESULT.E_FAIL)
{
throw;
}
return new(false, default!);
}
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(fileStream.AsRandomAccessStream());
SoftwareBitmap softwareBitmap = await decoder.GetSoftwareBitmapAsync(BitmapPixelFormat.Bgra8, BitmapAlphaMode.Straight);
Bgra32 accentColor = softwareBitmap.GetAccentColor();
@@ -69,7 +54,6 @@ internal sealed partial class BackgroundImageService : IBackgroundImageService
BackgroundImage background = new()
{
Path = path,
ImageSource = new(path.ToUri()),
AccentColor = accentColor,
Luminance = accentColor.Luminance,
@@ -81,55 +65,32 @@ internal sealed partial class BackgroundImageService : IBackgroundImageService
private async ValueTask<HashSet<string>> SkipOrInitBackgroundAsync()
{
switch (appOptions.BackgroundImageType)
if (backgroundPathSet is null || backgroundPathSet.Count <= 0)
{
case BackgroundImageType.LocalFolder:
{
if (currentBackgroundPathSet is not { Count: > 0 })
{
string backgroundFolder = runtimeOptions.GetDataFolderBackgroundFolder();
Directory.CreateDirectory(backgroundFolder);
string backgroundFolder = runtimeOptions.GetDataFolderBackgroundFolder();
Directory.CreateDirectory(backgroundFolder);
backgroundPathSet = Directory
.GetFiles(backgroundFolder, "*.*", SearchOption.AllDirectories)
.Where(path => AllowedFormats.Contains(Path.GetExtension(path)))
.ToHashSet();
currentBackgroundPathSet = Directory
.GetFiles(backgroundFolder, "*.*", SearchOption.AllDirectories)
.Where(path => AllowedFormats.Contains(Path.GetExtension(path)))
.ToHashSet();
}
backgroundImageOptions.Wallpaper = default;
break;
}
case BackgroundImageType.HutaoBing:
await SetCurrentBackgroundPathSetAsync(client => client.GetBingWallpaperAsync()).ConfigureAwait(false);
break;
case BackgroundImageType.HutaoDaily:
await SetCurrentBackgroundPathSetAsync(client => client.GetTodayWallpaperAsync()).ConfigureAwait(false);
break;
case BackgroundImageType.HutaoOfficialLauncher:
await SetCurrentBackgroundPathSetAsync(client => client.GetLauncherWallpaperAsync()).ConfigureAwait(false);
break;
}
currentBackgroundPathSet ??= [];
return currentBackgroundPathSet;
async Task SetCurrentBackgroundPathSetAsync(Func<HutaoWallpaperClient, ValueTask<Response<Wallpaper>>> responseFactory)
{
HutaoWallpaperClient wallpaperClient = serviceProvider.GetRequiredService<HutaoWallpaperClient>();
Response<Wallpaper> response = await responseFactory(wallpaperClient).ConfigureAwait(false);
if (response is { Data: Wallpaper wallpaper })
// No image found
if (backgroundPathSet.Count <= 0)
{
await taskContext.SwitchToMainThreadAsync();
backgroundImageOptions.Wallpaper = wallpaper;
await taskContext.SwitchToBackgroundAsync();
if (wallpaper.Url is { } url)
ResourceClient resourceClient = serviceProvider.GetRequiredService<ResourceClient>();
string launguageCode = serviceProvider.GetRequiredService<CultureOptions>().LanguageCode;
LaunchScheme scheme = launguageCode is "zh-cn"
? KnownLaunchSchemes.Get().First(scheme => !scheme.IsOversea && scheme.IsNotCompatOnly)
: KnownLaunchSchemes.Get().First(scheme => scheme.IsOversea && scheme.IsNotCompatOnly);
Response<GameContent> response = await resourceClient.GetContentAsync(scheme, launguageCode).ConfigureAwait(false);
if (response is { Data.Advertisement.Background: string url })
{
ValueFile file = await serviceProvider.GetRequiredService<IImageCache>().GetFileFromCacheAsync(url).ConfigureAwait(false);
currentBackgroundPathSet = [file];
ValueFile file = await serviceProvider.GetRequiredService<IImageCache>().GetFileFromCacheAsync(url.ToUri()).ConfigureAwait(false);
backgroundPathSet = [file];
}
}
}
return backgroundPathSet;
}
}

View File

@@ -1,23 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Service.BackgroundImage;
[Localization]
internal enum BackgroundImageType
{
[LocalizationKey(nameof(SH.ServiceBackgroundImageTypeNone))]
None,
[LocalizationKey(nameof(SH.ServiceBackgroundImageTypeLocalFolder))]
LocalFolder,
[LocalizationKey(nameof(SH.ServiceBackgroundImageTypeBing))]
HutaoBing,
[LocalizationKey(nameof(SH.ServiceBackgroundImageTypeDaily))]
HutaoDaily,
[LocalizationKey(nameof(SH.ServiceBackgroundImageTypeLauncher))]
HutaoOfficialLauncher,
}

View File

@@ -7,7 +7,7 @@ using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Service.Inventory;
using Snap.Hutao.Service.Inventroy;
using Snap.Hutao.Service.Metadata.ContextAbstraction;
using Snap.Hutao.ViewModel.Cultivation;
using System.Collections.ObjectModel;

View File

@@ -23,9 +23,6 @@ internal sealed class LaunchExecutionBetterGenshinImpactAutomationHandlder : ILa
Uri betterGenshinImpactUri = "bettergi://start".ToUri();
if (await Launcher.QueryUriSupportAsync(betterGenshinImpactUri, LaunchQuerySupportType.Uri) is LaunchQuerySupportStatus.Available)
{
context.Logger.LogInformation("Waiting game window to be ready");
context.Process.WaitForInputIdle();
context.Logger.LogInformation("Launching BetterGI");
await Launcher.LaunchUriAsync(betterGenshinImpactUri);
}

View File

@@ -24,9 +24,9 @@ internal sealed class LaunchExecutionInvoker
handlers.Enqueue(new LaunchExecutionGameProcessInitializationHandler());
handlers.Enqueue(new LaunchExecutionSetDiscordActivityHandler());
handlers.Enqueue(new LaunchExecutionGameProcessStartHandler());
handlers.Enqueue(new LaunchExecutionUnlockFpsHandler());
handlers.Enqueue(new LaunchExecutionStarwardPlayTimeStatisticsHandler());
handlers.Enqueue(new LaunchExecutionBetterGenshinImpactAutomationHandlder());
handlers.Enqueue(new LaunchExecutionUnlockFpsHandler());
handlers.Enqueue(new LaunchExecutionGameProcessExitHandler());
}

View File

@@ -3,7 +3,7 @@
using Snap.Hutao.Model.Entity;
namespace Snap.Hutao.Service.Inventory;
namespace Snap.Hutao.Service.Inventroy;
internal interface IInventoryDbService
{

View File

@@ -1,7 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Service.Inventory;
namespace Snap.Hutao.Service.Inventroy;
internal interface IInventoryService
{

View File

@@ -6,7 +6,7 @@ using Snap.Hutao.Core.Database;
using Snap.Hutao.Model.Entity;
using Snap.Hutao.Model.Entity.Database;
namespace Snap.Hutao.Service.Inventory;
namespace Snap.Hutao.Service.Inventroy;
[ConstructorGenerated]
[Injection(InjectAs.Singleton, typeof(IInventoryDbService))]

View File

@@ -1,7 +1,7 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Service.Inventory;
namespace Snap.Hutao.Service.Inventroy;
[Injection(InjectAs.Transient)]
internal sealed class InventoryService : IInventoryService

View File

@@ -12,19 +12,12 @@ internal static class SupportedCultures
[
ToNameValue(CultureInfo.GetCultureInfo("zh-Hans")),
ToNameValue(CultureInfo.GetCultureInfo("zh-Hant")),
/*ToNameValue(CultureInfo.GetCultureInfo("de")),*/
ToNameValue(CultureInfo.GetCultureInfo("en")),
/*ToNameValue(CultureInfo.GetCultureInfo("es")),*/
/*ToNameValue(CultureInfo.GetCultureInfo("fr")),*/
ToNameValue(CultureInfo.GetCultureInfo("id")),
/*ToNameValue(CultureInfo.GetCultureInfo("it")),*/
ToNameValue(CultureInfo.GetCultureInfo("ja")),
ToNameValue(CultureInfo.GetCultureInfo("ko")),
ToNameValue(CultureInfo.GetCultureInfo("pt")),
ToNameValue(CultureInfo.GetCultureInfo("ko")),
ToNameValue(CultureInfo.GetCultureInfo("ru")),
/*ToNameValue(CultureInfo.GetCultureInfo("th")),*/
/*ToNameValue(CultureInfo.GetCultureInfo("tr")),*/
/*ToNameValue(CultureInfo.GetCultureInfo("vi")),*/
];
public static List<NameValue<CultureInfo>> Get()

View File

@@ -4,24 +4,12 @@
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:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shch="using:Snap.Hutao.Control.Helper"
xmlns:shcm="using:Snap.Hutao.Control.Markup"
xmlns:shv="using:Snap.Hutao.View"
xmlns:shvh="using:Snap.Hutao.View.Helper"
xmlns:shvm="using:Snap.Hutao.ViewModel"
xmlns:shvp="using:Snap.Hutao.View.Page"
d:DataContext="{d:DesignInstance Type=shvm:MainViewModel}"
mc:Ignorable="d">
<mxi:Interaction.Behaviors>
<shcb:PeriodicInvokeCommandOrOnActualThemeChangedBehavior
Command="{Binding UpdateBackgroundCommand}"
CommandParameter="{x:Bind BackdroundImagePresenter}"
Period="0:5:0"/>
</mxi:Interaction.Behaviors>
<UserControl.Resources>
<Thickness x:Key="NavigationViewContentMargin">0,44,0,0</Thickness>
<Thickness x:Key="NavigationViewContentGridBorderThickness">0,1,0,0</Thickness>
@@ -31,8 +19,8 @@
<Grid Background="{ThemeResource SolidBackgroundFillColorBaseBrush}" Transitions="{ThemeResource EntranceThemeTransitions}">
<Image
x:Name="BackdroundImagePresenter"
HorizontalAlignment="Center"
VerticalAlignment="Center"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Opacity="0"
Stretch="UniformToFill"/>

View File

@@ -5,12 +5,10 @@ using CommunityToolkit.WinUI.Animations;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
using Snap.Hutao.Control.Animation;
using Snap.Hutao.Control.Theme;
using Snap.Hutao.Service.BackgroundImage;
using Snap.Hutao.Service.Navigation;
using Snap.Hutao.View.Page;
using Snap.Hutao.ViewModel;
namespace Snap.Hutao.View;
@@ -21,23 +19,80 @@ namespace Snap.Hutao.View;
internal sealed partial class MainView : UserControl
{
private readonly INavigationService navigationService;
private readonly IBackgroundImageService backgroundImageService;
private TaskCompletionSource acutalThemeChangedTaskCompletionSource = new();
private CancellationTokenSource periodicTimerCancellationTokenSource = new();
private BackgroundImage? previousBackgroundImage;
/// <summary>
/// 构造一个新的主视图
/// </summary>
public MainView()
{
DataContext = Ioc.Default.GetRequiredService<MainViewModel>();
InitializeComponent();
ActualThemeChanged += OnActualThemeChanged;
IServiceProvider serviceProvider = Ioc.Default;
backgroundImageService = serviceProvider.GetRequiredService<IBackgroundImageService>();
RunBackgroundImageLoopAsync(serviceProvider.GetRequiredService<ITaskContext>()).SafeForget();
navigationService = serviceProvider.GetRequiredService<INavigationService>();
if (navigationService is INavigationInitialization navigationInitialization)
{
navigationInitialization.Initialize(NavView, ContentFrame);
}
navigationService
.As<INavigationInitialization>()?
.Initialize(NavView, ContentFrame);
navigationService.Navigate<AnnouncementPage>(INavigationAwaiter.Default, true);
}
private async ValueTask RunBackgroundImageLoopAsync(ITaskContext taskContext)
{
using (PeriodicTimer timer = new(TimeSpan.FromMinutes(5)))
{
do
{
(bool isOk, BackgroundImage backgroundImage) = await backgroundImageService.GetNextBackgroundImageAsync(previousBackgroundImage).ConfigureAwait(false);
if (isOk)
{
previousBackgroundImage = backgroundImage;
await taskContext.SwitchToMainThreadAsync();
await AnimationBuilder
.Create()
.Opacity(to: 0D, duration: TimeSpan.FromMilliseconds(1000), easingType: EasingType.Sine, easingMode: EasingMode.EaseIn)
.StartAsync(BackdroundImagePresenter)
.ConfigureAwait(true);
BackdroundImagePresenter.Source = backgroundImage.ImageSource;
double targetOpacity = ThemeHelper.IsDarkMode(ActualTheme) ? 1 - backgroundImage.Luminance : backgroundImage.Luminance;
await AnimationBuilder
.Create()
.Opacity(to: targetOpacity, duration: TimeSpan.FromMilliseconds(1000), easingType: EasingType.Sine, easingMode: EasingMode.EaseOut)
.StartAsync(BackdroundImagePresenter)
.ConfigureAwait(true);
}
try
{
await Task.WhenAny(timer.WaitForNextTickAsync(periodicTimerCancellationTokenSource.Token).AsTask(), acutalThemeChangedTaskCompletionSource.Task).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
}
acutalThemeChangedTaskCompletionSource = new();
periodicTimerCancellationTokenSource = new();
}
while (true);
}
}
private void OnActualThemeChanged(FrameworkElement frameworkElement, object args)
{
acutalThemeChangedTaskCompletionSource.TrySetResult();
periodicTimerCancellationTokenSource.Cancel();
}
}

View File

@@ -3,12 +3,10 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cw="using:CommunityToolkit.WinUI"
xmlns:cwb="using:CommunityToolkit.WinUI.Behaviors"
xmlns:cwc="using:CommunityToolkit.WinUI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
xmlns:shc="using:Snap.Hutao.Control"
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shch="using:Snap.Hutao.Control.Helper"
@@ -314,92 +312,6 @@
SelectedItem="{Binding SelectedBackdropType, Mode=TwoWay}"/>
</shc:SizeRestrictedContentControl>
</cwc:SettingsCard>
<cwc:SettingsExpander
Description="{shcm:ResourceString Name=ViewPageSettingBackgroundImageDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingBackgroundImageHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE8B9;}"
IsExpanded="{Binding BackgroundImageOptions.Wallpaper, Converter={StaticResource EmptyObjectToBoolConverter}}">
<shc:SizeRestrictedContentControl VerticalAlignment="Center">
<ComboBox
DisplayMemberPath="Name"
ItemsSource="{Binding AppOptions.BackgroundImageTypes}"
SelectedItem="{Binding SelectedBackgroundImageType, Mode=TwoWay}"/>
</shc:SizeRestrictedContentControl>
<cwc:SettingsExpander.Items>
<cwc:SettingsCard
Description="{Binding BackgroundImageOptions.Wallpaper.Author}"
Header="{shcm:ResourceString Name=ViewPageSettingBackgroundImageCopyrightHeader}"
IsClickEnabled="True"
Visibility="{Binding BackgroundImageOptions.Wallpaper, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
<mxi:Interaction.Behaviors>
<mxic:EventTriggerBehavior EventName="Click">
<cwb:NavigateToUriAction NavigateUri="{Binding BackgroundImageOptions.Wallpaper.SourceUrl}"/>
</mxic:EventTriggerBehavior>
</mxi:Interaction.Behaviors>
</cwc:SettingsCard>
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
</StackPanel>
</Border>
</Border>
<Border cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Padding="16" Style="{ThemeResource AcrylicBorderCardStyle}">
<StackPanel Spacing="{ThemeResource SettingsCardSpacing}">
<TextBlock Style="{StaticResource SettingsCardHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingStorageHeader}"/>
<cwc:SettingsExpander
Description="{Binding DataFolderView.Size}"
Header="{shcm:ResourceString Name=ViewPageSettingDataFolderHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xEC25;}"
IsExpanded="True">
<cwc:SettingsExpander.Content>
<Button
Command="{Binding DataFolderView.OpenFolderCommand}"
Content="{shcm:ResourceString Name=ViewSettingFolderViewOpenFolderAction}"
Style="{ThemeResource SettingButtonStyle}"/>
</cwc:SettingsExpander.Content>
<cwc:SettingsExpander.Items>
<cwc:SettingsCard
Command="{Binding OpenBackgroundImageFolderCommand}"
Description="{shcm:ResourceString Name=ViewPageSettingOpenBackgroundImageFolderDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingOpenBackgroundImageFolderHeader}"
IsClickEnabled="True"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingStorageSetAction}"
Command="{Binding SetDataFolderCommand}"
Description="{shcm:ResourceString Name=ViewPageSettingSetDataFolderDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingSetDataFolderHeader}"
IsClickEnabled="True"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
Command="{Binding DeleteServerCacheFolderCommand}"
Description="{shcm:ResourceString Name=ViewSettingDeleteServerCacheFolderDescription}"
Header="{shcm:ResourceString Name=ViewSettingDeleteServerCacheFolderHeader}"
IsClickEnabled="True"/>
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
<cwc:SettingsExpander
Description="{Binding CacheFolderView.Size}"
Header="{shcm:ResourceString Name=ViewPageSettingCacheFolderHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE8B7;}"
IsExpanded="True">
<cwc:SettingsExpander.Content>
<Button
Command="{Binding CacheFolderView.OpenFolderCommand}"
Content="{shcm:ResourceString Name=ViewSettingFolderViewOpenFolderAction}"
Style="{ThemeResource SettingButtonStyle}"/>
</cwc:SettingsExpander.Content>
<cwc:SettingsExpander.Items>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingResetAction}"
Command="{Binding ResetStaticResourceCommand}"
Description="{shcm:ResourceString Name=ViewPageSettingResetStaticResourceDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingResetStaticResourceHeader}"
IsClickEnabled="True"/>
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
</StackPanel>
</Border>
</Border>
@@ -554,6 +466,67 @@
</Border>
</Border>
<Border cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Padding="16" Style="{ThemeResource AcrylicBorderCardStyle}">
<StackPanel Spacing="{ThemeResource SettingsCardSpacing}">
<TextBlock Style="{StaticResource SettingsCardHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageSettingStorageHeader}"/>
<cwc:SettingsExpander
Description="{Binding DataFolderView.Size}"
Header="{shcm:ResourceString Name=ViewPageSettingDataFolderHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xEC25;}"
IsExpanded="True">
<cwc:SettingsExpander.Content>
<Button
Command="{Binding DataFolderView.OpenFolderCommand}"
Content="{shcm:ResourceString Name=ViewSettingFolderViewOpenFolderAction}"
Style="{ThemeResource SettingButtonStyle}"/>
</cwc:SettingsExpander.Content>
<cwc:SettingsExpander.Items>
<cwc:SettingsCard
Command="{Binding OpenBackgroundImageFolderCommand}"
Description="{shcm:ResourceString Name=ViewPageSettingOpenBackgroundImageFolderDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingOpenBackgroundImageFolderHeader}"
IsClickEnabled="True"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingStorageSetAction}"
Command="{Binding SetDataFolderCommand}"
Description="{shcm:ResourceString Name=ViewPageSettingSetDataFolderDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingSetDataFolderHeader}"
IsClickEnabled="True"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
Command="{Binding DeleteServerCacheFolderCommand}"
Description="{shcm:ResourceString Name=ViewSettingDeleteServerCacheFolderDescription}"
Header="{shcm:ResourceString Name=ViewSettingDeleteServerCacheFolderHeader}"
IsClickEnabled="True"/>
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
<cwc:SettingsExpander
Description="{Binding CacheFolderView.Size}"
Header="{shcm:ResourceString Name=ViewPageSettingCacheFolderHeader}"
HeaderIcon="{shcm:FontIcon Glyph=&#xE8B7;}"
IsExpanded="True">
<cwc:SettingsExpander.Content>
<Button
Command="{Binding CacheFolderView.OpenFolderCommand}"
Content="{shcm:ResourceString Name=ViewSettingFolderViewOpenFolderAction}"
Style="{ThemeResource SettingButtonStyle}"/>
</cwc:SettingsExpander.Content>
<cwc:SettingsExpander.Items>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="{shcm:ResourceString Name=ViewPageSettingResetAction}"
Command="{Binding ResetStaticResourceCommand}"
Description="{shcm:ResourceString Name=ViewPageSettingResetStaticResourceDescription}"
Header="{shcm:ResourceString Name=ViewPageSettingResetStaticResourceHeader}"
IsClickEnabled="True"/>
</cwc:SettingsExpander.Items>
</cwc:SettingsExpander>
</StackPanel>
</Border>
</Border>
<Border cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Padding="16" Style="{ThemeResource AcrylicBorderCardStyle}">
<StackPanel Spacing="{ThemeResource SettingsCardSpacing}">

View File

@@ -5,7 +5,6 @@ using CommunityToolkit.Common;
using CommunityToolkit.Mvvm.ComponentModel;
using Snap.Hutao.Core;
using Snap.Hutao.Core.Caching;
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Core.IO;
using System.IO;
using System.IO.Compression;
@@ -75,14 +74,6 @@ internal sealed class DownloadSummary : ObservableObject
try
{
HttpResponseMessage response = await httpClient.GetAsync(fileUrl, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);
if (response.Content.Headers.ContentType?.MediaType is not "application/octet-stream")
{
logger.LogWarning("Download Static Zip failed, Content-Type is {Type}", response.Content.Headers.ContentType);
Description = SH.ViewModelWelcomeDownloadSummaryContentTypeNotMatch;
return false;
}
long contentLength = response.Content.Headers.ContentLength ?? 0;
logger.LogInformation("Begin download, length: {length}", contentLength);
using (Stream content = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
@@ -104,7 +95,7 @@ internal sealed class DownloadSummary : ObservableObject
logger.LogError(ex, "Download Static Zip failed");
await taskContext.SwitchToMainThreadAsync();
Description = ex is HttpRequestException httpRequestException
? $"{SH.ViewModelWelcomeDownloadSummaryException} - [HTTP '{httpRequestException.StatusCode:D}'] [Error '{httpRequestException.HttpRequestError}']"
? $"{SH.ViewModelWelcomeDownloadSummaryException} - HTTP {httpRequestException.HttpRequestError} {httpRequestException.StatusCode:D}"
: ex.Message;
return false;
}
@@ -118,10 +109,8 @@ internal sealed class DownloadSummary : ObservableObject
private void ExtractFiles(Stream stream)
{
if (imageCache is not IImageCacheFilePathOperation imageCacheFilePathOperation)
{
throw HutaoException.ServiceTypeCastFailed<IImageCache, IImageCacheFilePathOperation>(nameof(imageCache));
}
IImageCacheFilePathOperation? imageCacheFilePathOperation = imageCache.As<IImageCacheFilePathOperation>();
ArgumentNullException.ThrowIfNull(imageCacheFilePathOperation);
using (ZipArchive archive = new(stream))
{

View File

@@ -1,56 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using CommunityToolkit.WinUI.Animations;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Media.Animation;
using Snap.Hutao.Control.Animation;
using Snap.Hutao.Control.Theme;
using Snap.Hutao.Service.BackgroundImage;
namespace Snap.Hutao.ViewModel;
[ConstructorGenerated]
[Injection(InjectAs.Singleton)]
internal sealed partial class MainViewModel : Abstraction.ViewModel
{
private readonly IBackgroundImageService backgroundImageService;
private readonly ITaskContext taskContext;
private BackgroundImage? previousBackgroundImage;
[Command("UpdateBackgroundCommand")]
private async Task UpdateBackgroundAsync(Image presenter)
{
(bool isOk, BackgroundImage backgroundImage) = await backgroundImageService.GetNextBackgroundImageAsync(previousBackgroundImage).ConfigureAwait(false);
if (isOk)
{
previousBackgroundImage = backgroundImage;
await taskContext.SwitchToMainThreadAsync();
await AnimationBuilder
.Create()
.Opacity(
to: 0D,
duration: ControlAnimationConstants.ImageOpacityFadeInOut,
easingType: EasingType.Quartic,
easingMode: EasingMode.EaseInOut)
.StartAsync(presenter)
.ConfigureAwait(true);
presenter.Source = backgroundImage.ImageSource;
double targetOpacity = ThemeHelper.IsDarkMode(presenter.ActualTheme) ? 1 - backgroundImage.Luminance : backgroundImage.Luminance;
await AnimationBuilder
.Create()
.Opacity(
to: targetOpacity,
duration: ControlAnimationConstants.ImageOpacityFadeInOut,
easingType: EasingType.Quartic,
easingMode: EasingMode.EaseInOut)
.StartAsync(presenter)
.ConfigureAwait(true);
}
}
}

View File

@@ -12,7 +12,6 @@ using Snap.Hutao.Factory.ContentDialog;
using Snap.Hutao.Factory.Picker;
using Snap.Hutao.Model;
using Snap.Hutao.Service;
using Snap.Hutao.Service.BackgroundImage;
using Snap.Hutao.Service.GachaLog.QueryProvider;
using Snap.Hutao.Service.Game;
using Snap.Hutao.Service.Hutao;
@@ -41,7 +40,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
private readonly IFileSystemPickerInteraction fileSystemPickerInteraction;
private readonly HutaoPassportViewModel hutaoPassportViewModel;
private readonly BackgroundImageOptions backgroundImageOptions;
private readonly IContentDialogFactory contentDialogFactory;
private readonly INavigationService navigationService;
private readonly IShellLinkInterop shellLinkInterop;
@@ -56,7 +54,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
private readonly AppOptions appOptions;
private NameValue<BackdropType>? selectedBackdropType;
private NameValue<BackgroundImageType>? selectedBackgroundImageType;
private NameValue<CultureInfo>? selectedCulture;
private NameValue<Region>? selectedRegion;
private FolderViewModel? cacheFolderView;
@@ -76,8 +73,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
public LaunchOptions LaunchOptions { get => launchOptions; }
public BackgroundImageOptions BackgroundImageOptions { get => backgroundImageOptions; }
public HutaoPassportViewModel Passport { get => hutaoPassportViewModel; }
public NameValue<BackdropType>? SelectedBackdropType
@@ -92,18 +87,6 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel
}
}
public NameValue<BackgroundImageType>? SelectedBackgroundImageType
{
get => selectedBackgroundImageType ??= AppOptions.BackgroundImageTypes.Single(t => t.Value == AppOptions.BackgroundImageType);
set
{
if (SetProperty(ref selectedBackgroundImageType, value) && value is not null)
{
AppOptions.BackgroundImageType = value.Value;
}
}
}
public NameValue<CultureInfo>? SelectedCulture
{
get => selectedCulture ??= CultureOptions.GetCurrentCultureForSelectionOrDefault();

View File

@@ -1,44 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.Web.Request.Builder;
using Snap.Hutao.Web.Request.Builder.Abstraction;
using Snap.Hutao.Web.Response;
using System.Net.Http;
namespace Snap.Hutao.Web.Hutao.Wallpaper;
[HttpClient(HttpClientConfiguration.Default)]
[ConstructorGenerated(ResolveHttpClient = true)]
internal sealed partial class HutaoWallpaperClient
{
private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory;
private readonly ILogger<HutaoWallpaperClient> logger;
private readonly HttpClient httpClient;
public ValueTask<Response<Wallpaper>> GetBingWallpaperAsync(CancellationToken token = default)
{
return GetWallpaperAsync(HutaoEndpoints.WallpaperBing, token);
}
public ValueTask<Response<Wallpaper>> GetLauncherWallpaperAsync(CancellationToken token = default)
{
return GetWallpaperAsync(HutaoEndpoints.WallpaperGenshinLauncher, token);
}
public ValueTask<Response<Wallpaper>> GetTodayWallpaperAsync(CancellationToken token = default)
{
return GetWallpaperAsync(HutaoEndpoints.WallpaperToday, token);
}
private async ValueTask<Response<Wallpaper>> GetWallpaperAsync(string url, CancellationToken token = default)
{
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
.SetRequestUri(url)
.Get();
Response<Wallpaper>? resp = await builder.TryCatchSendAsync<Response<Wallpaper>>(httpClient, logger, token).ConfigureAwait(false);
return Web.Response.Response.DefaultIfNull(resp);
}
}

View File

@@ -1,19 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
namespace Snap.Hutao.Web.Hutao.Wallpaper;
internal sealed class Wallpaper
{
[JsonPropertyName("url")]
public Uri Url { get; set; } = default!;
[JsonPropertyName("source_url")]
public string SourceUrl { get; set; } = default!;
[JsonPropertyName("author")]
public string Author { get; set; } = default!;
[JsonPropertyName("uploader")]
public string Uploader { get; set; } = default!;
}

View File

@@ -10,9 +10,8 @@ namespace Snap.Hutao.Web;
/// 胡桃 API 端点
/// </summary>
[HighQuality]
[SuppressMessage("", "SA1124")]
[SuppressMessage("", "SA1201")]
[SuppressMessage("", "SA1203")]
[SuppressMessage("", "SA1124")]
internal static class HutaoEndpoints
{
#region HomaAPI
@@ -272,15 +271,6 @@ internal static class HutaoEndpoints
}
#endregion
#region Wallpaper
public const string WallpaperBing = $"{ApiSnapGenshin}/wallpaper/bing";
public const string WallpaperGenshinLauncher = $"{ApiSnapGenshin}/wallpaper/genshin-launcher";
public const string WallpaperToday = $"{ApiSnapGenshin}/wallpaper/today";
#endregion
#endregion
private const string ApiSnapGenshin = "https://api.snapgenshin.com";