mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
implement #431
This commit is contained in:
@@ -2877,6 +2877,24 @@ namespace Snap.Hutao.Resource.Localization {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 请输入 Url 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string ViewDialogDailyNoteWebhookUrlInputPlaceholder {
|
||||
get {
|
||||
return ResourceManager.GetString("ViewDialogDailyNoteWebhookUrlInputPlaceholder", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 实时便笺 Webhook Url 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string ViewDialogDailyNoteWebhookUrlTitle {
|
||||
get {
|
||||
return ResourceManager.GetString("ViewDialogDailyNoteWebhookUrlTitle", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 导入祈愿记录 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -3561,6 +3579,15 @@ namespace Snap.Hutao.Resource.Localization {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 配置实时便笺 Webhook Url 完成 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string ViewModelDailyNoteConfigWebhookUrlComplete {
|
||||
get {
|
||||
return ResourceManager.GetString("ViewModelDailyNoteConfigWebhookUrlComplete", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 HoYoLab 账号不支持验证实时便笺 的本地化字符串。
|
||||
/// </summary>
|
||||
@@ -4533,6 +4560,33 @@ namespace Snap.Hutao.Resource.Localization {
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 在实时便笺刷新后推送到指定的 Webhook 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string ViewPageDailyNoteConfigWebhookDescription {
|
||||
get {
|
||||
return ResourceManager.GetString("ViewPageDailyNoteConfigWebhookDescription", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 配置 Webhook 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string ViewPageDailyNoteConfigWebhookHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("ViewPageDailyNoteConfigWebhookHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 数据互操作 的本地化字符串。
|
||||
/// </summary>
|
||||
internal static string ViewPageDailyNoteDataInteropHeader {
|
||||
get {
|
||||
return ResourceManager.GetString("ViewPageDailyNoteDataInteropHeader", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查找类似 通知 的本地化字符串。
|
||||
/// </summary>
|
||||
|
||||
@@ -1112,6 +1112,12 @@
|
||||
<data name="ViewDialogDailyNoteNotificationTransformerNotify" xml:space="preserve">
|
||||
<value>参量质变仪提醒</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlInputPlaceholder" xml:space="preserve">
|
||||
<value>请输入 Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogDailyNoteWebhookUrlTitle" xml:space="preserve">
|
||||
<value>实时便笺 Webhook Url</value>
|
||||
</data>
|
||||
<data name="ViewDialogGachaLogImportTitle" xml:space="preserve">
|
||||
<value>导入祈愿记录</value>
|
||||
</data>
|
||||
@@ -1340,6 +1346,9 @@
|
||||
<data name="ViewModelCultivationProjectInvalidName" xml:space="preserve">
|
||||
<value>不能添加名称无效的计划</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteConfigWebhookUrlComplete" xml:space="preserve">
|
||||
<value>配置实时便笺 Webhook Url 完成</value>
|
||||
</data>
|
||||
<data name="ViewModelDailyNoteHoyolabVerificationUnsupported" xml:space="preserve">
|
||||
<value>HoYoLab 账号不支持验证实时便笺</value>
|
||||
</data>
|
||||
@@ -1664,6 +1673,15 @@
|
||||
<data name="ViewPageDailyNoteAddEntryToolTip" xml:space="preserve">
|
||||
<value>添加</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookDescription" xml:space="preserve">
|
||||
<value>在实时便笺刷新后推送到指定的 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteConfigWebhookHeader" xml:space="preserve">
|
||||
<value>配置 Webhook</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteDataInteropHeader" xml:space="preserve">
|
||||
<value>数据互操作</value>
|
||||
</data>
|
||||
<data name="ViewPageDailyNoteNotificationHeader" xml:space="preserve">
|
||||
<value>通知</value>
|
||||
</data>
|
||||
|
||||
@@ -153,7 +153,7 @@ internal abstract partial class DbStoreOptions : ObservableObject, IOptions<DbSt
|
||||
/// <param name="key">键</param>
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="propertyName">属性名称</param>
|
||||
protected void SetOption(ref string? storage, string key, string value, [CallerMemberName] string? propertyName = null)
|
||||
protected void SetOption(ref string? storage, string key, string? value, [CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
if (!SetProperty(ref storage, value, propertyName))
|
||||
{
|
||||
|
||||
@@ -27,6 +27,7 @@ internal sealed partial class DailyNoteOptions : DbStoreOptions
|
||||
private NameValue<int>? selectedRefreshTime;
|
||||
private bool? isReminderNotification;
|
||||
private bool? isSilentWhenPlayingGame;
|
||||
private string? webhookUrl;
|
||||
|
||||
/// <summary>
|
||||
/// 刷新时间
|
||||
@@ -122,4 +123,10 @@ internal sealed partial class DailyNoteOptions : DbStoreOptions
|
||||
get => GetOption(ref isSilentWhenPlayingGame, SettingEntry.DailyNoteSilentWhenPlayingGame);
|
||||
set => SetOption(ref isSilentWhenPlayingGame, SettingEntry.DailyNoteSilentWhenPlayingGame, value);
|
||||
}
|
||||
|
||||
public string? WebhookUrl
|
||||
{
|
||||
get => GetOption(ref webhookUrl, SettingEntry.DailyNoteSilentWhenPlayingGame);
|
||||
set => SetOption(ref webhookUrl, SettingEntry.DailyNoteSilentWhenPlayingGame, value);
|
||||
}
|
||||
}
|
||||
@@ -3,12 +3,15 @@
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Snap.Hutao.Core.DependencyInjection.Abstraction;
|
||||
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
|
||||
using Snap.Hutao.Message;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Hoyolab;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
|
||||
using Snap.Hutao.Web.Request.Builder;
|
||||
using Snap.Hutao.Web.Request.Builder.Abstraction;
|
||||
using System.Collections.ObjectModel;
|
||||
using WebDailyNote = Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote.DailyNote;
|
||||
|
||||
@@ -108,6 +111,8 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient<U
|
||||
|
||||
private async ValueTask RefreshDailyNotesCoreAsync(bool forceRefresh)
|
||||
{
|
||||
DailyNoteWebhookOperation dailyNoteWebhookOperation = serviceProvider.GetRequiredService<DailyNoteWebhookOperation>();
|
||||
|
||||
foreach (DailyNoteEntry entry in await dailyNoteDbService.GetDailyNoteEntryIncludeUserListAsync().ConfigureAwait(false))
|
||||
{
|
||||
if (!forceRefresh && entry.DailyNote is not null)
|
||||
@@ -144,6 +149,7 @@ internal sealed partial class DailyNoteService : IDailyNoteService, IRecipient<U
|
||||
// database
|
||||
entry.UpdateDailyNote(dailyNote);
|
||||
await dailyNoteDbService.UpdateDailyNoteEntryAsync(entry).ConfigureAwait(false);
|
||||
await dailyNoteWebhookOperation.TryPostDailyNoteToWebhookAsync(dailyNote).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
// 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 System.Net.Http;
|
||||
using WebDailyNote = Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.DailyNote.DailyNote;
|
||||
|
||||
namespace Snap.Hutao.Service.DailyNote;
|
||||
|
||||
[ConstructorGenerated(ResolveHttpClient = true)]
|
||||
[HttpClient(HttpClientConfiguration.Default)]
|
||||
internal sealed partial class DailyNoteWebhookOperation
|
||||
{
|
||||
private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory;
|
||||
private readonly ILogger<DailyNoteWebhookOperation> logger;
|
||||
private readonly DailyNoteOptions dailyNoteOptions;
|
||||
private readonly HttpClient httpClient;
|
||||
|
||||
public async ValueTask TryPostDailyNoteToWebhookAsync(WebDailyNote dailyNote, CancellationToken token = default)
|
||||
{
|
||||
string? targetUrl = dailyNoteOptions.WebhookUrl;
|
||||
if (string.IsNullOrEmpty(targetUrl) || !Uri.TryCreate(targetUrl, UriKind.Absolute, out Uri? targetUri))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
HttpRequestMessageBuilder builder = httpRequestMessageBuilderFactory.Create()
|
||||
.SetRequestUri(targetUri)
|
||||
.PostJson(dailyNote);
|
||||
|
||||
await builder.TryCatchSendAsync(httpClient, logger, token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -144,6 +144,7 @@
|
||||
<None Remove="View\Dialog\CultivatePromotionDeltaBatchDialog.xaml" />
|
||||
<None Remove="View\Dialog\CultivatePromotionDeltaDialog.xaml" />
|
||||
<None Remove="View\Dialog\DailyNoteNotificationDialog.xaml" />
|
||||
<None Remove="View\Dialog\DailyNoteWebhookDialog.xaml" />
|
||||
<None Remove="View\Dialog\GachaLogImportDialog.xaml" />
|
||||
<None Remove="View\Dialog\GachaLogRefreshProgressDialog.xaml" />
|
||||
<None Remove="View\Dialog\GachaLogUrlDialog.xaml" />
|
||||
@@ -312,6 +313,12 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Dialog\DailyNoteWebhookDialog.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="Control\Theme\NumericValue.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<ContentDialog
|
||||
x:Class="Snap.Hutao.View.Dialog.DailyNoteWebhookDialog"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
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:shcm="using:Snap.Hutao.Control.Markup"
|
||||
Title="{shcm:ResourceString Name=ViewDialogDailyNoteWebhookUrlTitle}"
|
||||
CloseButtonText="{shcm:ResourceString Name=ContentDialogCancelCloseButtonText}"
|
||||
DefaultButton="Primary"
|
||||
PrimaryButtonText="{shcm:ResourceString Name=ContentDialogConfirmPrimaryButtonText}"
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewDialogDailyNoteWebhookUrlInputPlaceholder}" Text="{x:Bind Text, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Snap.Hutao.View.Dialog;
|
||||
|
||||
[DependencyProperty("Text", typeof(string))]
|
||||
internal sealed partial class DailyNoteWebhookDialog : ContentDialog
|
||||
{
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
public DailyNoteWebhookDialog(IServiceProvider serviceProvider)
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取输入的Url
|
||||
/// </summary>
|
||||
/// <returns>输入的结果</returns>
|
||||
public async ValueTask<ValueResult<bool, string>> GetInputUrlAsync()
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
|
||||
return new(result == ContentDialogResult.Primary, Text);
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,6 @@
|
||||
mc:Ignorable="d">
|
||||
|
||||
<Grid>
|
||||
<TextBox x:Name="InputText" PlaceholderText="{shcm:ResourceString Name=ViewDialogGachaLogUrlInputPlaceholder}"/>
|
||||
<TextBox PlaceholderText="{shcm:ResourceString Name=ViewDialogGachaLogUrlInputPlaceholder}" Text="{x:Bind Text, Mode=TwoWay}"/>
|
||||
</Grid>
|
||||
</ContentDialog>
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Snap.Hutao.View.Dialog;
|
||||
/// 祈愿记录Url对话框
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[DependencyProperty("Text", typeof(string))]
|
||||
internal sealed partial class GachaLogUrlDialog : ContentDialog
|
||||
{
|
||||
private readonly ITaskContext taskContext;
|
||||
@@ -32,8 +33,8 @@ internal sealed partial class GachaLogUrlDialog : ContentDialog
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
ContentDialogResult result = await ShowAsync();
|
||||
string url = InputText.Text.TrimEnd("#/log");
|
||||
string url = Text.TrimEnd("#/log");
|
||||
|
||||
return new(result == ContentDialogResult.Primary, url);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -159,7 +159,6 @@
|
||||
</StackPanel>
|
||||
</cwc:HeaderedContentControl>
|
||||
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageDailyNoteNotificationHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Description="{shcm:ResourceString Name=ViewPageDailyNoteSlientModeDescription}"
|
||||
@@ -173,6 +172,14 @@
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}">
|
||||
<ToggleSwitch Margin="24,0,0,0" IsOn="{Binding Options.IsReminderNotification, Mode=TwoWay}"/>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageDailyNoteDataInteropHeader}"/>
|
||||
<cwc:SettingsCard
|
||||
Command="{Binding ConfigDailyNoteWebhookUrlCommand}"
|
||||
Description="{shcm:ResourceString Name=ViewPageDailyNoteConfigWebhookDescription}"
|
||||
Header="{shcm:ResourceString Name=ViewPageDailyNoteConfigWebhookHeader}"
|
||||
HeaderIcon="{shcm:FontIcon Glyph=}"
|
||||
IsClickEnabled="True"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</SplitView.Pane>
|
||||
|
||||
@@ -123,4 +123,17 @@ internal sealed partial class DailyNoteViewModel : Abstraction.ViewModel
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Command("ConfigDailyNoteWebhookUrlCommand")]
|
||||
private async Task ConfigDailyNoteWebhookUrlAsync()
|
||||
{
|
||||
DailyNoteWebhookDialog dialog = await contentDialogFactory.CreateInstanceAsync<DailyNoteWebhookDialog>().ConfigureAwait(false);
|
||||
(bool isOk, string url) = await dialog.GetInputUrlAsync().ConfigureAwait(false);
|
||||
|
||||
if (isOk)
|
||||
{
|
||||
options.WebhookUrl = url;
|
||||
infoBarService.Information(SH.ViewModelDailyNoteConfigWebhookUrlComplete);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,4 +44,32 @@ internal static class HttpRequestMessageBuilderExtension
|
||||
return default;
|
||||
}
|
||||
}
|
||||
|
||||
internal static async ValueTask TryCatchSendAsync(this HttpRequestMessageBuilder builder, HttpClient httpClient, ILogger logger, CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
HttpResponseMessage message = await httpClient.SendAsync(builder.HttpRequestMessage, token).ConfigureAwait(false);
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage);
|
||||
}
|
||||
catch (IOException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage);
|
||||
}
|
||||
catch (JsonException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage);
|
||||
}
|
||||
catch (HttpContentSerializationException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage);
|
||||
}
|
||||
catch (SocketException ex)
|
||||
{
|
||||
logger.LogWarning(ex, RequestErrorMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user