mirror of
https://github.com/wangdage12/Snap.Hutao.git
synced 2026-07-31 04:10:25 +08:00
Compare commits
7 Commits
0777180df5
..
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 9200f44e33 | |||
| 2e17a50e6f | |||
| 27871adc63 | |||
| 41cfb8c8f4 | |||
| 9da2c2eb8b | |||
| ed3f2270b3 | |||
| 0eb8b58711 |
@@ -64,7 +64,7 @@ jobs:
|
|||||||
-Body $r2Data `
|
-Body $r2Data `
|
||||||
-ContentType "application/json"
|
-ContentType "application/json"
|
||||||
Write-Output $response2.Content
|
Write-Output $response2.Content
|
||||||
- uses: benc-uk/workflow-dispatch@v1.3.1
|
- uses: benc-uk/workflow-dispatch@v1.3.2
|
||||||
with:
|
with:
|
||||||
workflow: Build
|
workflow: Build
|
||||||
repo: DGP-Studio/hutao-installer
|
repo: DGP-Studio/hutao-installer
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
<Package
|
<Package
|
||||||
Name="Snap.Hutao"
|
Name="Snap.Hutao"
|
||||||
Manufacturer="Millennium Science Technology R-D Inst"
|
Manufacturer="Millennium Science Technology R-D Inst"
|
||||||
Version="1.18.6.0"
|
Version="1.18.7.0"
|
||||||
UpgradeCode="121203be-60cb-408f-92cc-7080f6598e68"
|
UpgradeCode="121203be-60cb-408f-92cc-7080f6598e68"
|
||||||
Language="2052"
|
Language="2052"
|
||||||
Scope="perMachine">
|
Scope="perMachine">
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="WixToolset.Sdk/6.0.2">
|
<Project Sdk="WixToolset.Sdk/6.0.2">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SuppressIces>ICE03;ICE60</SuppressIces>
|
<SuppressIces>ICE03;ICE60</SuppressIces>
|
||||||
<Platform>x64</Platform>
|
<Platform>x64</Platform>
|
||||||
@@ -9,11 +9,11 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Snap.Hutao\Snap.Hutao.csproj" />
|
<ProjectReference Include="..\Snap.Hutao\Snap.Hutao.csproj" SetPlatform="Platform=x64" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<HarvestDirectory Include="..\Snap.Hutao\bin\Release\net10.0-windows10.0.26100.0\win-x64">
|
<HarvestDirectory Include="..\Snap.Hutao\bin\x64\Release\net10.0-windows10.0.26100.0\win-x64">
|
||||||
<ComponentGroupName>MainAppComponents</ComponentGroupName>
|
<ComponentGroupName>MainAppComponents</ComponentGroupName>
|
||||||
<DirectoryRefId>INSTALLFOLDER</DirectoryRefId>
|
<DirectoryRefId>INSTALLFOLDER</DirectoryRefId>
|
||||||
<SuppressCom>true</SuppressCom>
|
<SuppressCom>true</SuppressCom>
|
||||||
|
|||||||
+2
-2
@@ -1,4 +1,4 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<IsPackable>true</IsPackable>
|
<IsPackable>true</IsPackable>
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<PackageId>Snap.Hutao.SourceGeneration</PackageId>
|
<PackageId>Snap.Hutao.SourceGeneration</PackageId>
|
||||||
<Version>1.3.14</Version>
|
<Version>1.3.15</Version>
|
||||||
<Authors>DGP Studio</Authors>
|
<Authors>DGP Studio</Authors>
|
||||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||||
<DevelopmentDependency>true</DevelopmentDependency>
|
<DevelopmentDependency>true</DevelopmentDependency>
|
||||||
|
|||||||
+3
-1
@@ -4,6 +4,7 @@
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Snap.Hutao.Core.IO.Http;
|
using Snap.Hutao.Core.IO.Http;
|
||||||
using Snap.Hutao.Core.IO.Http.Proxy;
|
using Snap.Hutao.Core.IO.Http.Proxy;
|
||||||
|
using Snap.Hutao.Service;
|
||||||
using Snap.Hutao.Service.Game.Package.Advanced;
|
using Snap.Hutao.Service.Game.Package.Advanced;
|
||||||
using Snap.Hutao.Web.Hoyolab;
|
using Snap.Hutao.Web.Hoyolab;
|
||||||
using Snap.Hutao.Win32;
|
using Snap.Hutao.Win32;
|
||||||
@@ -36,10 +37,11 @@ internal static partial class ServiceCollectionExtension
|
|||||||
{
|
{
|
||||||
SocketsHttpHandler typedHandler = Unsafe.As<SocketsHttpHandler>(handler);
|
SocketsHttpHandler typedHandler = Unsafe.As<SocketsHttpHandler>(handler);
|
||||||
typedHandler.UseProxy = true;
|
typedHandler.UseProxy = true;
|
||||||
typedHandler.Proxy = HttpProxyUsingSystemProxy.Instance;
|
typedHandler.Proxy = provider.GetRequiredService<HutaoWebProxy>();
|
||||||
})
|
})
|
||||||
.AddHttpMessageHandler<RetryHttpHandler>();
|
.AddHttpMessageHandler<RetryHttpHandler>();
|
||||||
})
|
})
|
||||||
|
.AddSingleton(sp => new HutaoWebProxy(sp.GetRequiredService<AppOptions>(), HttpProxyUsingSystemProxy.Instance))
|
||||||
.AddHttpClients();
|
.AddHttpClients();
|
||||||
|
|
||||||
services
|
services
|
||||||
|
|||||||
@@ -0,0 +1,160 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Model.Intrinsic;
|
||||||
|
using Snap.Hutao.Service;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core.IO.Http.Proxy;
|
||||||
|
|
||||||
|
internal sealed class HutaoWebProxy : IWebProxy
|
||||||
|
{
|
||||||
|
private static readonly IWebProxy NoProxy = new DirectWebProxy();
|
||||||
|
private readonly AppOptions appOptions;
|
||||||
|
private readonly HttpProxyUsingSystemProxy systemProxy;
|
||||||
|
|
||||||
|
public HutaoWebProxy(AppOptions appOptions, HttpProxyUsingSystemProxy systemProxy)
|
||||||
|
{
|
||||||
|
this.appOptions = appOptions;
|
||||||
|
this.systemProxy = systemProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICredentials? Credentials
|
||||||
|
{
|
||||||
|
get => InnerProxy.Credentials;
|
||||||
|
set => InnerProxy.Credentials = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public string DisplayProxyUri
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!appOptions.ProxyEnabled.Value)
|
||||||
|
{
|
||||||
|
return "DIRECT";
|
||||||
|
}
|
||||||
|
|
||||||
|
return appOptions.ProxyType.Value switch
|
||||||
|
{
|
||||||
|
ProxyType.SystemProxy => systemProxy.DisplayProxyUri,
|
||||||
|
ProxyType.Http => string.IsNullOrEmpty(appOptions.ProxyAddress.Value)
|
||||||
|
? systemProxy.DisplayProxyUri
|
||||||
|
: $"http://{appOptions.ProxyAddress.Value}:{appOptions.ProxyPort.Value}",
|
||||||
|
ProxyType.Socks5 => string.IsNullOrEmpty(appOptions.ProxyAddress.Value)
|
||||||
|
? systemProxy.DisplayProxyUri
|
||||||
|
: $"socks5://{appOptions.ProxyAddress.Value}:{appOptions.ProxyPort.Value}",
|
||||||
|
ProxyType.None => "DIRECT",
|
||||||
|
_ => systemProxy.DisplayProxyUri,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private IWebProxy InnerProxy
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (!appOptions.ProxyEnabled.Value)
|
||||||
|
{
|
||||||
|
return NoProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return appOptions.ProxyType.Value switch
|
||||||
|
{
|
||||||
|
ProxyType.SystemProxy => systemProxy,
|
||||||
|
ProxyType.Http => CreateHttpProxy(),
|
||||||
|
ProxyType.Socks5 => CreateSocks5Proxy(),
|
||||||
|
ProxyType.None => NoProxy,
|
||||||
|
_ => systemProxy,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Uri? GetProxy(Uri destination)
|
||||||
|
{
|
||||||
|
return InnerProxy.GetProxy(destination);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsBypassed(Uri host)
|
||||||
|
{
|
||||||
|
return InnerProxy.IsBypassed(host);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IWebProxy CreateHttpProxy()
|
||||||
|
{
|
||||||
|
string address = appOptions.ProxyAddress.Value;
|
||||||
|
int port = appOptions.ProxyPort.Value;
|
||||||
|
|
||||||
|
if (!IsValidProxyAddress(address) || !IsValidProxyPort(port))
|
||||||
|
{
|
||||||
|
return systemProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
WebProxy webProxy = new()
|
||||||
|
{
|
||||||
|
Address = new Uri($"http://{address}:{port}"),
|
||||||
|
BypassProxyOnLocal = false,
|
||||||
|
UseDefaultCredentials = false,
|
||||||
|
};
|
||||||
|
|
||||||
|
return webProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
private IWebProxy CreateSocks5Proxy()
|
||||||
|
{
|
||||||
|
string address = appOptions.ProxyAddress.Value;
|
||||||
|
int port = appOptions.ProxyPort.Value;
|
||||||
|
|
||||||
|
if (!IsValidProxyAddress(address) || !IsValidProxyPort(port))
|
||||||
|
{
|
||||||
|
return systemProxy;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Socks5WebProxy(address, port);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsValidProxyAddress(string address)
|
||||||
|
{
|
||||||
|
return !string.IsNullOrEmpty(address) &&
|
||||||
|
(Uri.CheckHostName(address) != UriHostNameType.Unknown ||
|
||||||
|
System.Net.IPAddress.TryParse(address, out _));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsValidProxyPort(int port)
|
||||||
|
{
|
||||||
|
return port is >= 1 and <= 65535;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sealed class DirectWebProxy : IWebProxy
|
||||||
|
{
|
||||||
|
public ICredentials? Credentials { get; set; }
|
||||||
|
|
||||||
|
public Uri? GetProxy(Uri destination) => destination;
|
||||||
|
|
||||||
|
public bool IsBypassed(Uri host) => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal sealed class Socks5WebProxy : IWebProxy
|
||||||
|
{
|
||||||
|
private readonly string address;
|
||||||
|
private readonly int port;
|
||||||
|
|
||||||
|
public Socks5WebProxy(string address, int port)
|
||||||
|
{
|
||||||
|
this.address = address;
|
||||||
|
this.port = port;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ICredentials? Credentials { get; set; }
|
||||||
|
|
||||||
|
public Uri? GetProxy(Uri destination)
|
||||||
|
{
|
||||||
|
return new Uri($"socks5://{address}:{port}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsBypassed(Uri host)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -152,4 +152,10 @@ internal static class SettingKeys
|
|||||||
public const string CompactWebView2WindowInactiveOpacity = "Snap::Hutao::Web::WebView::Compact::InactiveOpacity";
|
public const string CompactWebView2WindowInactiveOpacity = "Snap::Hutao::Web::WebView::Compact::InactiveOpacity";
|
||||||
public const string CompactWebView2WindowPreviousSourceUrl = "Snap::Hutao::Web::WebView::Compact::PreviousSourceUrl";
|
public const string CompactWebView2WindowPreviousSourceUrl = "Snap::Hutao::Web::WebView::Compact::PreviousSourceUrl";
|
||||||
public const string WebView2VideoFastForwardOrRewindSeconds = "Snap::Hutao::Web::WebView::Video::FastForwardOrRewind::Seconds";
|
public const string WebView2VideoFastForwardOrRewindSeconds = "Snap::Hutao::Web::WebView::Video::FastForwardOrRewind::Seconds";
|
||||||
|
|
||||||
|
// Proxy
|
||||||
|
public const string ProxyType = "Snap::Hutao::Web::Proxy::Type";
|
||||||
|
public const string ProxyAddress = "Snap::Hutao::Web::Proxy::Address";
|
||||||
|
public const string ProxyPort = "Snap::Hutao::Web::Proxy::Port";
|
||||||
|
public const string ProxyEnabled = "Snap::Hutao::Web::Proxy::Enabled";
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Model.Intrinsic;
|
||||||
|
|
||||||
|
[ExtendedEnum]
|
||||||
|
internal enum ProxyType
|
||||||
|
{
|
||||||
|
[LocalizationKey(nameof(SH.ServiceProxyTypeNone))]
|
||||||
|
None = 0,
|
||||||
|
|
||||||
|
[LocalizationKey(nameof(SH.ServiceProxyTypeSystemProxy))]
|
||||||
|
SystemProxy = 1,
|
||||||
|
|
||||||
|
[LocalizationKey(nameof(SH.ServiceProxyTypeHttp))]
|
||||||
|
Http = 2,
|
||||||
|
|
||||||
|
[LocalizationKey(nameof(SH.ServiceProxyTypeSocks5))]
|
||||||
|
Socks5 = 3,
|
||||||
|
}
|
||||||
@@ -129,6 +129,11 @@ internal static class AvatarIds
|
|||||||
public static readonly AvatarId Columbina = 10000125;
|
public static readonly AvatarId Columbina = 10000125;
|
||||||
public static readonly AvatarId Zibai = 10000126;
|
public static readonly AvatarId Zibai = 10000126;
|
||||||
public static readonly AvatarId Illuga = 10000127;
|
public static readonly AvatarId Illuga = 10000127;
|
||||||
|
public static readonly AvatarId Varka = 10000128;
|
||||||
|
public static readonly AvatarId Lohen = 10000129;
|
||||||
|
public static readonly AvatarId Linnea = 10000130;
|
||||||
|
public static readonly AvatarId Nicole = 10000131;
|
||||||
|
public static readonly AvatarId Prune = 10000132;
|
||||||
|
|
||||||
private static readonly FrozenSet<AvatarId> StandardWishIds =
|
private static readonly FrozenSet<AvatarId> StandardWishIds =
|
||||||
[
|
[
|
||||||
|
|||||||
@@ -28,13 +28,11 @@ internal static class WeaponIds
|
|||||||
|
|
||||||
public static readonly FrozenSet<WeaponId> OrangeStandardWishIds =
|
public static readonly FrozenSet<WeaponId> OrangeStandardWishIds =
|
||||||
[
|
[
|
||||||
11501U, 11502U,
|
11501U, 11502U, 11518U, 11519U,
|
||||||
12501U, 12502U,
|
12501U, 12502U,
|
||||||
13502U, 13505U,
|
13502U, 13505U, 13517U,
|
||||||
14501U, 14502U,
|
14501U, 14502U, 14522U, 14523U,
|
||||||
15501U, 15502U,
|
15501U, 15502U, 15515U
|
||||||
15515U, 11518U,
|
|
||||||
14522U, 11519U
|
|
||||||
];
|
];
|
||||||
|
|
||||||
public static bool IsOrangeStandardWish(in WeaponId weaponId)
|
public static bool IsOrangeStandardWish(in WeaponId weaponId)
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<Identity
|
<Identity
|
||||||
Name="60568DGPStudio.SnapHutao"
|
Name="60568DGPStudio.SnapHutao"
|
||||||
Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52"
|
Publisher="CN=35C8E923-85DF-49A7-9172-B39DC6312C52"
|
||||||
Version="1.18.6.0" />
|
Version="1.18.7.0" />
|
||||||
|
|
||||||
<Properties>
|
<Properties>
|
||||||
<DisplayName>Snap Hutao</DisplayName>
|
<DisplayName>Snap Hutao</DisplayName>
|
||||||
|
|||||||
@@ -875,6 +875,18 @@
|
|||||||
<data name="ServiceBackgroundImageTypeNone" xml:space="preserve">
|
<data name="ServiceBackgroundImageTypeNone" xml:space="preserve">
|
||||||
<value>无背景图片</value>
|
<value>无背景图片</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ServiceProxyTypeNone" xml:space="preserve">
|
||||||
|
<value>无代理</value>
|
||||||
|
</data>
|
||||||
|
<data name="ServiceProxyTypeSystemProxy" xml:space="preserve">
|
||||||
|
<value>系统代理</value>
|
||||||
|
</data>
|
||||||
|
<data name="ServiceProxyTypeHttp" xml:space="preserve">
|
||||||
|
<value>HTTP 代理</value>
|
||||||
|
</data>
|
||||||
|
<data name="ServiceProxyTypeSocks5" xml:space="preserve">
|
||||||
|
<value>SOCKS5 代理</value>
|
||||||
|
</data>
|
||||||
<data name="ServiceCloseButtonBehaviorTypeExit" xml:space="preserve">
|
<data name="ServiceCloseButtonBehaviorTypeExit" xml:space="preserve">
|
||||||
<value>退出胡桃</value>
|
<value>退出胡桃</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -2255,6 +2267,24 @@
|
|||||||
<data name="ViewModelSettingDeleteServerCacheFolderTitle" xml:space="preserve">
|
<data name="ViewModelSettingDeleteServerCacheFolderTitle" xml:space="preserve">
|
||||||
<value>删除转换服务器游戏客户端缓存</value>
|
<value>删除转换服务器游戏客户端缓存</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ViewModelSettingProxySaveSuccess" xml:space="preserve">
|
||||||
|
<value>代理设置已保存</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewModelSettingProxyTesting" xml:space="preserve">
|
||||||
|
<value>正在测试代理连接...</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewModelSettingProxyTestSuccess" xml:space="preserve">
|
||||||
|
<value>可用 [{0}ms]</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewModelSettingProxyTestFailed" xml:space="preserve">
|
||||||
|
<value>不可用</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewModelSettingProxyTestAction" xml:space="preserve">
|
||||||
|
<value>测试</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewModelSettingProxySaveAction" xml:space="preserve">
|
||||||
|
<value>保存</value>
|
||||||
|
</data>
|
||||||
<data name="ViewModelSettingFolderSizeDescription" xml:space="preserve">
|
<data name="ViewModelSettingFolderSizeDescription" xml:space="preserve">
|
||||||
<value>已使用磁盘空间:{0}</value>
|
<value>已使用磁盘空间:{0}</value>
|
||||||
</data>
|
</data>
|
||||||
@@ -3330,6 +3360,33 @@
|
|||||||
<data name="ViewPageSettingGeetestVerificationHeader" xml:space="preserve">
|
<data name="ViewPageSettingGeetestVerificationHeader" xml:space="preserve">
|
||||||
<value>无感验证</value>
|
<value>无感验证</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyHeader" xml:space="preserve">
|
||||||
|
<value>网络代理</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyEnabledDescription" xml:space="preserve">
|
||||||
|
<value>启用自定义代理设置</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyEnabledHeader" xml:space="preserve">
|
||||||
|
<value>启用代理</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyTypeDescription" xml:space="preserve">
|
||||||
|
<value>选择代理类型</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyTypeHeader" xml:space="preserve">
|
||||||
|
<value>代理类型</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyAddressDescription" xml:space="preserve">
|
||||||
|
<value>代理服务器地址</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyAddressHeader" xml:space="preserve">
|
||||||
|
<value>代理地址</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyPortDescription" xml:space="preserve">
|
||||||
|
<value>代理服务器端口</value>
|
||||||
|
</data>
|
||||||
|
<data name="ViewPageSettingProxyPortHeader" xml:space="preserve">
|
||||||
|
<value>代理端口</value>
|
||||||
|
</data>
|
||||||
<data name="ViewPageSettingHomeAnnouncementRegionDescription" xml:space="preserve">
|
<data name="ViewPageSettingHomeAnnouncementRegionDescription" xml:space="preserve">
|
||||||
<value>选择想要获取公告的游戏服务器</value>
|
<value>选择想要获取公告的游戏服务器</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Microsoft.UI.Xaml;
|
|||||||
using Snap.Hutao.Core.Property;
|
using Snap.Hutao.Core.Property;
|
||||||
using Snap.Hutao.Core.Setting;
|
using Snap.Hutao.Core.Setting;
|
||||||
using Snap.Hutao.Model;
|
using Snap.Hutao.Model;
|
||||||
|
using Snap.Hutao.Model.Intrinsic;
|
||||||
using Snap.Hutao.Service.Abstraction;
|
using Snap.Hutao.Service.Abstraction;
|
||||||
using Snap.Hutao.Service.BackgroundImage;
|
using Snap.Hutao.Service.BackgroundImage;
|
||||||
using Snap.Hutao.UI.Xaml.Media.Backdrop;
|
using Snap.Hutao.UI.Xaml.Media.Backdrop;
|
||||||
@@ -49,6 +50,8 @@ internal sealed partial class AppOptions : DbStoreOptions
|
|||||||
|
|
||||||
public ImmutableArray<NameValue<BridgeShareSaveType>> BridgeShareSaveTypes { get; } = ImmutableCollectionsNameValue.FromEnum<BridgeShareSaveType>(type => type.GetLocalizedDescription(SH.ResourceManager, CultureInfo.CurrentCulture) ?? string.Empty);
|
public ImmutableArray<NameValue<BridgeShareSaveType>> BridgeShareSaveTypes { get; } = ImmutableCollectionsNameValue.FromEnum<BridgeShareSaveType>(type => type.GetLocalizedDescription(SH.ResourceManager, CultureInfo.CurrentCulture) ?? string.Empty);
|
||||||
|
|
||||||
|
public ImmutableArray<NameValue<ProxyType>> ProxyTypes { get; } = ImmutableCollectionsNameValue.FromEnum<ProxyType>(static @enum => @enum.GetLocalizedDescription(SH.ResourceManager, CultureInfo.CurrentCulture) ?? string.Empty);
|
||||||
|
|
||||||
public ImmutableArray<NameValue<LastWindowCloseBehavior>> LastWindowCloseBehaviors { get; } = ImmutableCollectionsNameValue.FromEnum<LastWindowCloseBehavior>(static @enum => @enum.GetLocalizedDescription(SH.ResourceManager, CultureInfo.CurrentCulture) ?? string.Empty);
|
public ImmutableArray<NameValue<LastWindowCloseBehavior>> LastWindowCloseBehaviors { get; } = ImmutableCollectionsNameValue.FromEnum<LastWindowCloseBehavior>(static @enum => @enum.GetLocalizedDescription(SH.ResourceManager, CultureInfo.CurrentCulture) ?? string.Empty);
|
||||||
|
|
||||||
[field: MaybeNull]
|
[field: MaybeNull]
|
||||||
@@ -83,4 +86,16 @@ internal sealed partial class AppOptions : DbStoreOptions
|
|||||||
|
|
||||||
[field: MaybeNull]
|
[field: MaybeNull]
|
||||||
public IObservableProperty<LastWindowCloseBehavior> LastWindowCloseBehavior { get => field ??= CreateProperty(SettingKeys.LastWindowCloseBehavior, Service.LastWindowCloseBehavior.EnsureNotifyIconCreated); }
|
public IObservableProperty<LastWindowCloseBehavior> LastWindowCloseBehavior { get => field ??= CreateProperty(SettingKeys.LastWindowCloseBehavior, Service.LastWindowCloseBehavior.EnsureNotifyIconCreated); }
|
||||||
|
|
||||||
|
[field: MaybeNull]
|
||||||
|
public IObservableProperty<ProxyType> ProxyType { get => field ??= CreateProperty(SettingKeys.ProxyType, Model.Intrinsic.ProxyType.SystemProxy); }
|
||||||
|
|
||||||
|
[field: MaybeNull]
|
||||||
|
public IObservableProperty<string> ProxyAddress { get => field ??= CreateProperty(SettingKeys.ProxyAddress, string.Empty); }
|
||||||
|
|
||||||
|
[field: MaybeNull]
|
||||||
|
public IObservableProperty<int> ProxyPort { get => field ??= CreateProperty(SettingKeys.ProxyPort, 1080); }
|
||||||
|
|
||||||
|
[field: MaybeNull]
|
||||||
|
public IObservableProperty<bool> ProxyEnabled { get => field ??= CreateProperty(SettingKeys.ProxyEnabled, false); }
|
||||||
}
|
}
|
||||||
@@ -297,6 +297,7 @@ internal sealed partial class CultivationService : ICultivationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
ArgumentNullException.ThrowIfNull(projects.CurrentItem);
|
ArgumentNullException.ThrowIfNull(projects.CurrentItem);
|
||||||
|
Guid projectId = projects.CurrentItem.InnerId;
|
||||||
|
|
||||||
await taskContext.SwitchToBackgroundAsync();
|
await taskContext.SwitchToBackgroundAsync();
|
||||||
|
|
||||||
@@ -310,7 +311,7 @@ internal sealed partial class CultivationService : ICultivationService
|
|||||||
if (inputConsumption.Strategy is not ConsumptionSaveStrategyKind.CreateNewEntry)
|
if (inputConsumption.Strategy is not ConsumptionSaveStrategyKind.CreateNewEntry)
|
||||||
{
|
{
|
||||||
// Check for existing entries
|
// Check for existing entries
|
||||||
ImmutableArray<CultivateEntry> entries = cultivationRepository.GetCultivateEntryImmutableArrayByProjectIdAndItemId(projects.CurrentItem.InnerId, inputConsumption.ItemId);
|
ImmutableArray<CultivateEntry> entries = cultivationRepository.GetCultivateEntryImmutableArrayByProjectIdAndItemId(projectId, inputConsumption.ItemId);
|
||||||
|
|
||||||
if (entries.Length > 0)
|
if (entries.Length > 0)
|
||||||
{
|
{
|
||||||
@@ -330,6 +331,7 @@ internal sealed partial class CultivationService : ICultivationService
|
|||||||
|
|
||||||
if (inputConsumption.Items is [])
|
if (inputConsumption.Items is [])
|
||||||
{
|
{
|
||||||
|
entryCollectionCache.TryRemove(projectId, out _);
|
||||||
return new(ConsumptionSaveResultKind.Removed);
|
return new(ConsumptionSaveResultKind.Removed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -344,7 +346,7 @@ internal sealed partial class CultivationService : ICultivationService
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
CultivateEntry entry = CultivateEntry.From(projects.CurrentItem.InnerId, inputConsumption.Type, inputConsumption.ItemId);
|
CultivateEntry entry = CultivateEntry.From(projectId, inputConsumption.Type, inputConsumption.ItemId);
|
||||||
entry.RelatedEntryId = inputConsumption.RelatedEntryId;
|
entry.RelatedEntryId = inputConsumption.RelatedEntryId;
|
||||||
cultivationRepository.AddCultivateEntry(entry);
|
cultivationRepository.AddCultivateEntry(entry);
|
||||||
|
|
||||||
@@ -356,7 +358,7 @@ internal sealed partial class CultivationService : ICultivationService
|
|||||||
|
|
||||||
// The consumption save operation is always performed outside cultivation page
|
// The consumption save operation is always performed outside cultivation page
|
||||||
// and without touching the cache. So we have to invalidate the cache manually.
|
// and without touching the cache. So we have to invalidate the cache manually.
|
||||||
entryCollectionCache.TryRemove(projects.CurrentItem.InnerId, out _);
|
entryCollectionCache.TryRemove(projectId, out _);
|
||||||
|
|
||||||
return new(ConsumptionSaveResultKind.Added, entry.InnerId);
|
return new(ConsumptionSaveResultKind.Added, entry.InnerId);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
<UseWinUI>true</UseWinUI>
|
<UseWinUI>true</UseWinUI>
|
||||||
<UseWPF>False</UseWPF>
|
<UseWPF>False</UseWPF>
|
||||||
<!-- 配置版本号 -->
|
<!-- 配置版本号 -->
|
||||||
<Version>1.18.6.0</Version>
|
<Version>1.18.7.0</Version>
|
||||||
|
|
||||||
<UseWindowsForms>False</UseWindowsForms>
|
<UseWindowsForms>False</UseWindowsForms>
|
||||||
<ImplicitUsings>False</ImplicitUsings>
|
<ImplicitUsings>False</ImplicitUsings>
|
||||||
|
|||||||
@@ -9,13 +9,18 @@ namespace Snap.Hutao.UI.Xaml.Markup;
|
|||||||
[MarkupExtensionReturnType(ReturnType = typeof(string))]
|
[MarkupExtensionReturnType(ReturnType = typeof(string))]
|
||||||
internal sealed partial class ResourceStringExtension : MarkupExtension
|
internal sealed partial class ResourceStringExtension : MarkupExtension
|
||||||
{
|
{
|
||||||
public SHName Name { get; set; }
|
public string? Name { get; set; }
|
||||||
|
|
||||||
public string? CultureName { get; set; }
|
public string? CultureName { get; set; }
|
||||||
|
|
||||||
protected override object ProvideValue()
|
protected override object ProvideValue()
|
||||||
{
|
{
|
||||||
|
if (string.IsNullOrEmpty(Name))
|
||||||
|
{
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
CultureInfo cultureInfo = CultureName is not null ? CultureInfo.GetCultureInfo(CultureName) : CultureInfo.CurrentCulture;
|
CultureInfo cultureInfo = CultureName is not null ? CultureInfo.GetCultureInfo(CultureName) : CultureInfo.CurrentCulture;
|
||||||
return SH.ResourceManager.GetString(string.Intern(Name.ToString()), cultureInfo) ?? string.Empty;
|
return SH.ResourceManager.GetString(string.Intern(Name), cultureInfo) ?? string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -210,6 +210,78 @@
|
|||||||
</Border>
|
</Border>
|
||||||
</Border>
|
</Border>
|
||||||
|
|
||||||
|
<!-- 网络代理 -->
|
||||||
|
<Border cw:Effects.Shadow="{ThemeResource CompatCardShadow}" DataContext="{Binding Proxy}">
|
||||||
|
<Border Padding="16" Style="{ThemeResource AcrylicBorderCardStyle}">
|
||||||
|
<StackPanel Spacing="{ThemeResource SettingsCardSpacing}">
|
||||||
|
<TextBlock Style="{StaticResource SettingsCardHeaderTextBlockStyle}" Text="{shuxm:ResourceString Name=ViewPageSettingProxyHeader}"/>
|
||||||
|
<cwc:SettingsCard
|
||||||
|
Description="{shuxm:ResourceString Name=ViewPageSettingProxyEnabledDescription}"
|
||||||
|
Header="{shuxm:ResourceString Name=ViewPageSettingProxyEnabledHeader}"
|
||||||
|
HeaderIcon="{shuxm:FontIcon Glyph=}">
|
||||||
|
<ToggleSwitch
|
||||||
|
MinWidth="120"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsEnabled="{Binding IsTestingProxy, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||||
|
IsOn="{Binding AppOptions.ProxyEnabled.Value, Mode=TwoWay}"/>
|
||||||
|
</cwc:SettingsCard>
|
||||||
|
<cwc:SettingsCard
|
||||||
|
Description="{shuxm:ResourceString Name=ViewPageSettingProxyTypeDescription}"
|
||||||
|
Header="{shuxm:ResourceString Name=ViewPageSettingProxyTypeHeader}"
|
||||||
|
HeaderIcon="{shuxm:FontIcon Glyph=}">
|
||||||
|
<shuxc:SizeRestrictedContentControl>
|
||||||
|
<ComboBox
|
||||||
|
DisplayMemberPath="Name"
|
||||||
|
ItemsSource="{Binding AppOptions.ProxyTypes}"
|
||||||
|
IsEnabled="{Binding IsTestingProxy, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||||
|
SelectedItem="{Binding SelectedProxyType, Mode=TwoWay}"/>
|
||||||
|
</shuxc:SizeRestrictedContentControl>
|
||||||
|
</cwc:SettingsCard>
|
||||||
|
<cwc:SettingsCard
|
||||||
|
Description="{shuxm:ResourceString Name=ViewPageSettingProxyAddressDescription}"
|
||||||
|
Header="{shuxm:ResourceString Name=ViewPageSettingProxyAddressHeader}"
|
||||||
|
HeaderIcon="{shuxm:FontIcon Glyph=}">
|
||||||
|
<TextBox
|
||||||
|
MinWidth="{ThemeResource SettingsCardContentControlMinWidth}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
IsEnabled="{Binding IsTestingProxy, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||||
|
Text="{Binding AppOptions.ProxyAddress.Value, Mode=TwoWay}"/>
|
||||||
|
</cwc:SettingsCard>
|
||||||
|
<cwc:SettingsCard
|
||||||
|
Description="{shuxm:ResourceString Name=ViewPageSettingProxyPortDescription}"
|
||||||
|
Header="{shuxm:ResourceString Name=ViewPageSettingProxyPortHeader}"
|
||||||
|
HeaderIcon="{shuxm:FontIcon Glyph=}">
|
||||||
|
<NumberBox
|
||||||
|
MinWidth="{ThemeResource SettingsCardContentControlMinWidth}"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
AcceptsExpression="False"
|
||||||
|
IsEnabled="{Binding IsTestingProxy, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"
|
||||||
|
Maximum="65535"
|
||||||
|
Minimum="1"
|
||||||
|
Value="{Binding AppOptions.ProxyPort.Value, Mode=TwoWay}"/>
|
||||||
|
</cwc:SettingsCard>
|
||||||
|
<cwc:SettingsCard
|
||||||
|
Header="{shuxm:ResourceString Name=ViewModelSettingProxyTestAction}"
|
||||||
|
HeaderIcon="{shuxm:FontIcon Glyph=}">
|
||||||
|
<StackPanel Orientation="Horizontal" Spacing="8">
|
||||||
|
<Button
|
||||||
|
Command="{Binding TestProxyCommand}"
|
||||||
|
Content="{shuxm:ResourceString Name=ViewModelSettingProxyTestAction}"
|
||||||
|
IsEnabled="{Binding IsTestingProxy, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"/>
|
||||||
|
<Button
|
||||||
|
Command="{Binding SaveProxyCommand}"
|
||||||
|
Content="{shuxm:ResourceString Name=ViewModelSettingProxySaveAction}"
|
||||||
|
IsEnabled="{Binding IsTestingProxy, Converter={StaticResource BoolNegationConverter}, Mode=OneWay}"/>
|
||||||
|
<TextBlock
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Text="{Binding ProxyTestResult}"
|
||||||
|
Visibility="{Binding ProxyTestResult, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</cwc:SettingsCard>
|
||||||
|
</StackPanel>
|
||||||
|
</Border>
|
||||||
|
</Border>
|
||||||
|
|
||||||
<!-- 外观 -->
|
<!-- 外观 -->
|
||||||
<Border cw:Effects.Shadow="{ThemeResource CompatCardShadow}" DataContext="{Binding Appearance}">
|
<Border cw:Effects.Shadow="{ThemeResource CompatCardShadow}" DataContext="{Binding Appearance}">
|
||||||
<Border Padding="16" Style="{ThemeResource AcrylicBorderCardStyle}">
|
<Border Padding="16" Style="{ThemeResource AcrylicBorderCardStyle}">
|
||||||
|
|||||||
@@ -230,7 +230,10 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
|
|||||||
if (!await SaveCultivationAsync(batchConsumption.Items.Single(), deltaOptions).ConfigureAwait(false))
|
if (!await SaveCultivationAsync(batchConsumption.Items.Single(), deltaOptions).ConfigureAwait(false))
|
||||||
{
|
{
|
||||||
scopeContext.Messenger.Send(InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning));
|
scopeContext.Messenger.Send(InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
scopeContext.Messenger.Send(CultivationProjectEntriesChangedMessage.Empty);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Command("BatchCultivateCommand")]
|
[Command("BatchCultivateCommand")]
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ internal sealed partial class FeedbackViewModel : Abstraction.ViewModel
|
|||||||
[GeneratedConstructor]
|
[GeneratedConstructor]
|
||||||
public partial FeedbackViewModel(IServiceProvider serviceProvider);
|
public partial FeedbackViewModel(IServiceProvider serviceProvider);
|
||||||
|
|
||||||
public static HttpProxyUsingSystemProxy DynamicHttpProxy { get => HttpProxyUsingSystemProxy.Instance; }
|
public partial HutaoWebProxy DynamicHttpProxy { get; }
|
||||||
|
|
||||||
public partial RuntimeOptions RuntimeOptions { get; }
|
public partial RuntimeOptions RuntimeOptions { get; }
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,96 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using Snap.Hutao.Core;
|
||||||
|
using Snap.Hutao.Core.IO.Http.Proxy;
|
||||||
|
using Snap.Hutao.Model;
|
||||||
|
using Snap.Hutao.Model.Intrinsic;
|
||||||
|
using Snap.Hutao.Service;
|
||||||
|
using Snap.Hutao.Service.Notification;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.ViewModel.Setting;
|
||||||
|
|
||||||
|
[BindableCustomPropertyProvider]
|
||||||
|
[Service(ServiceLifetime.Scoped)]
|
||||||
|
internal sealed partial class SettingProxyViewModel : Abstraction.ViewModel
|
||||||
|
{
|
||||||
|
private readonly ITaskContext taskContext;
|
||||||
|
private readonly IMessenger messenger;
|
||||||
|
private readonly HutaoWebProxy hutaoWebProxy;
|
||||||
|
|
||||||
|
[GeneratedConstructor]
|
||||||
|
public partial SettingProxyViewModel(IServiceProvider serviceProvider);
|
||||||
|
|
||||||
|
public partial AppOptions AppOptions { get; }
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial string? ProxyTestResult { get; set; }
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
public partial bool IsTestingProxy { get; set; }
|
||||||
|
|
||||||
|
public NameValue<ProxyType>? SelectedProxyType
|
||||||
|
{
|
||||||
|
get => field ??= AppOptions.ProxyTypes.Single(t => t.Value == AppOptions.ProxyType.Value);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref field, value) && value is not null)
|
||||||
|
{
|
||||||
|
AppOptions.ProxyType.Value = value.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("SaveProxyCommand")]
|
||||||
|
private void SaveProxy()
|
||||||
|
{
|
||||||
|
messenger.Send(InfoBarMessage.Success(SH.ViewModelSettingProxySaveSuccess));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Command("TestProxyCommand")]
|
||||||
|
private async Task TestProxyAsync()
|
||||||
|
{
|
||||||
|
IsTestingProxy = true;
|
||||||
|
ProxyTestResult = SH.ViewModelSettingProxyTesting;
|
||||||
|
|
||||||
|
await taskContext.SwitchToBackgroundAsync();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
using HttpClient httpClient = new(new SocketsHttpHandler
|
||||||
|
{
|
||||||
|
Proxy = hutaoWebProxy,
|
||||||
|
UseProxy = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
httpClient.Timeout = TimeSpan.FromSeconds(10);
|
||||||
|
|
||||||
|
Stopwatch stopwatch = Stopwatch.StartNew();
|
||||||
|
HttpResponseMessage response = await httpClient.GetAsync("https://hut.ao").ConfigureAwait(false);
|
||||||
|
stopwatch.Stop();
|
||||||
|
|
||||||
|
await taskContext.SwitchToMainThreadAsync();
|
||||||
|
|
||||||
|
if (response.IsSuccessStatusCode)
|
||||||
|
{
|
||||||
|
ProxyTestResult = SH.FormatViewModelSettingProxyTestSuccess(stopwatch.ElapsedMilliseconds);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ProxyTestResult = SH.ViewModelSettingProxyTestFailed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
|
await taskContext.SwitchToMainThreadAsync();
|
||||||
|
ProxyTestResult = SH.ViewModelSettingProxyTestFailed;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
IsTestingProxy = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -45,6 +45,8 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel, INavigat
|
|||||||
|
|
||||||
public partial SettingWebViewViewModel WebView { get; }
|
public partial SettingWebViewViewModel WebView { get; }
|
||||||
|
|
||||||
|
public partial SettingProxyViewModel Proxy { get; }
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
public partial string? UpdateInfo { get; set; }
|
public partial string? UpdateInfo { get; set; }
|
||||||
|
|
||||||
@@ -80,7 +82,7 @@ internal sealed partial class SettingViewModel : Abstraction.ViewModel, INavigat
|
|||||||
|
|
||||||
protected override ValueTask<bool> LoadOverrideAsync(CancellationToken token)
|
protected override ValueTask<bool> LoadOverrideAsync(CancellationToken token)
|
||||||
{
|
{
|
||||||
MakeSubViewModel([Geetest, Appearance, Storage, HotKey, Home, Game, GachaLog, WebView]);
|
MakeSubViewModel([Geetest, Appearance, Storage, HotKey, Home, Game, GachaLog, WebView, Proxy]);
|
||||||
|
|
||||||
Storage.CacheFolderView = new(taskContext, HutaoRuntime.LocalCacheDirectory);
|
Storage.CacheFolderView = new(taskContext, HutaoRuntime.LocalCacheDirectory);
|
||||||
Storage.DataFolderView = new(taskContext, HutaoRuntime.DataDirectory);
|
Storage.DataFolderView = new(taskContext, HutaoRuntime.DataDirectory);
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ using Snap.Hutao.Service.Notification;
|
|||||||
using Snap.Hutao.UI.Xaml.Control.AutoSuggestBox;
|
using Snap.Hutao.UI.Xaml.Control.AutoSuggestBox;
|
||||||
using Snap.Hutao.UI.Xaml.Data;
|
using Snap.Hutao.UI.Xaml.Data;
|
||||||
using Snap.Hutao.UI.Xaml.View.Dialog;
|
using Snap.Hutao.UI.Xaml.View.Dialog;
|
||||||
|
using Snap.Hutao.ViewModel.Cultivation;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using CalculateBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
|
using CalculateBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
|
||||||
|
|
||||||
@@ -155,7 +156,8 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
|||||||
Strategy = deltaOptions.Strategy,
|
Strategy = deltaOptions.Strategy,
|
||||||
};
|
};
|
||||||
|
|
||||||
InfoBarMessage? message = (await cultivationService.SaveConsumptionAsync(input).ConfigureAwait(false)).Kind switch
|
ConsumptionSaveResult result = await cultivationService.SaveConsumptionAsync(input).ConfigureAwait(false);
|
||||||
|
InfoBarMessage? message = result.Kind switch
|
||||||
{
|
{
|
||||||
ConsumptionSaveResultKind.NoProject => InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning),
|
ConsumptionSaveResultKind.NoProject => InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning),
|
||||||
ConsumptionSaveResultKind.Skipped => InfoBarMessage.Information(SH.ViewModelCultivationConsumptionSaveSkippedHint),
|
ConsumptionSaveResultKind.Skipped => InfoBarMessage.Information(SH.ViewModelCultivationConsumptionSaveSkippedHint),
|
||||||
@@ -168,6 +170,11 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
|||||||
{
|
{
|
||||||
messenger.Send(message);
|
messenger.Send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.Kind is not ConsumptionSaveResultKind.NoProject)
|
||||||
|
{
|
||||||
|
messenger.Send(CultivationProjectEntriesChangedMessage.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (HutaoException ex)
|
catch (HutaoException ex)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ using Snap.Hutao.Service.Notification;
|
|||||||
using Snap.Hutao.UI.Xaml.Control.AutoSuggestBox;
|
using Snap.Hutao.UI.Xaml.Control.AutoSuggestBox;
|
||||||
using Snap.Hutao.UI.Xaml.Data;
|
using Snap.Hutao.UI.Xaml.Data;
|
||||||
using Snap.Hutao.UI.Xaml.View.Dialog;
|
using Snap.Hutao.UI.Xaml.View.Dialog;
|
||||||
|
using Snap.Hutao.ViewModel.Cultivation;
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using CalculateBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
|
using CalculateBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
|
||||||
|
|
||||||
@@ -146,7 +147,8 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
|||||||
Strategy = deltaOptions.Strategy,
|
Strategy = deltaOptions.Strategy,
|
||||||
};
|
};
|
||||||
|
|
||||||
InfoBarMessage? message = (await cultivationService.SaveConsumptionAsync(input).ConfigureAwait(false)).Kind switch
|
ConsumptionSaveResult result = await cultivationService.SaveConsumptionAsync(input).ConfigureAwait(false);
|
||||||
|
InfoBarMessage? message = result.Kind switch
|
||||||
{
|
{
|
||||||
ConsumptionSaveResultKind.NoProject => InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning),
|
ConsumptionSaveResultKind.NoProject => InfoBarMessage.Warning(SH.ViewModelCultivationEntryAddWarning),
|
||||||
ConsumptionSaveResultKind.Skipped => InfoBarMessage.Information(SH.ViewModelCultivationConsumptionSaveSkippedHint),
|
ConsumptionSaveResultKind.Skipped => InfoBarMessage.Information(SH.ViewModelCultivationConsumptionSaveSkippedHint),
|
||||||
@@ -159,6 +161,11 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
|||||||
{
|
{
|
||||||
messenger.Send(message);
|
messenger.Send(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (result.Kind is not ConsumptionSaveResultKind.NoProject)
|
||||||
|
{
|
||||||
|
messenger.Send(CultivationProjectEntriesChangedMessage.Empty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (HutaoException ex)
|
catch (HutaoException ex)
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user