mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
impl #1244
This commit is contained in:
54
src/Snap.Hutao/Snap.Hutao/Core/IO/ValueFileExtensions.cs
Normal file
54
src/Snap.Hutao/Snap.Hutao/Core/IO/ValueFileExtensions.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.IO;
|
||||
using System.Net.Http;
|
||||
|
||||
namespace Snap.Hutao.Core.IO;
|
||||
|
||||
internal static class ValueFileExtensions
|
||||
{
|
||||
public static async ValueTask<bool> DownloadAsync(this ValueFile valueFile, string url)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (HttpClient httpClient = new())
|
||||
{
|
||||
using (HttpResponseMessage response = await httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false))
|
||||
{
|
||||
long contentLength = response.Content.Headers.ContentLength ?? 0;
|
||||
using (Stream content = await response.Content.ReadAsStreamAsync().ConfigureAwait(false))
|
||||
{
|
||||
using (FileStream stream = File.Create((string)valueFile))
|
||||
{
|
||||
Progress<StreamCopyStatus> progress = new();
|
||||
await new StreamCopyWorker(content, stream, contentLength).CopyAsync(progress).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static async ValueTask<bool> WritePngBase64Async(this ValueFile valueFile, string base64)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (FileStream stream = File.Create((string)valueFile))
|
||||
{
|
||||
byte[] bytes = System.Convert.FromBase64String(base64);
|
||||
await stream.WriteAsync(bytes).ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -310,6 +310,7 @@
|
||||
<PackageReference Include="Microsoft.VisualStudio.Validation" Version="17.8.8" />
|
||||
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.22621.2428" />
|
||||
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.4.231115000" />
|
||||
<PackageReference Include="Qhy04.WebView2.DevTools.Protocol.WinUI3" Version="1.0.0" />
|
||||
<PackageReference Include="QRCoder" Version="1.4.3" />
|
||||
<PackageReference Include="Snap.Discord.GameSDK" Version="1.6.0" />
|
||||
<PackageReference Include="Snap.Hutao.Deployment.Runtime" Version="1.9.0">
|
||||
|
||||
@@ -2,8 +2,12 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Qhy04.WebView2.DevTools.Protocol.WinUI3;
|
||||
using Snap.Hutao.Core.DependencyInjection.Abstraction;
|
||||
using Snap.Hutao.Core.IO;
|
||||
using Snap.Hutao.Factory.Picker;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Bridge.Model;
|
||||
@@ -84,6 +88,7 @@ internal class MiHoYoJSBridge
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly ITaskContext taskContext;
|
||||
private readonly ILogger<MiHoYoJSBridge> logger;
|
||||
private readonly DevToolsProtocolHelper devToolsProtocolHelper;
|
||||
|
||||
private readonly TypedEventHandler<CoreWebView2, CoreWebView2WebMessageReceivedEventArgs> webMessageReceivedEventHandler;
|
||||
private readonly TypedEventHandler<CoreWebView2, CoreWebView2DOMContentLoadedEventArgs> domContentLoadedEventHandler;
|
||||
@@ -100,6 +105,7 @@ internal class MiHoYoJSBridge
|
||||
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
logger = serviceProvider.GetRequiredService<ILogger<MiHoYoJSBridge>>();
|
||||
devToolsProtocolHelper = coreWebView2.GetDevToolsProtocolHelper();
|
||||
|
||||
webMessageReceivedEventHandler = OnWebMessageReceived;
|
||||
domContentLoadedEventHandler = OnDOMContentLoaded;
|
||||
@@ -362,8 +368,89 @@ internal class MiHoYoJSBridge
|
||||
return null;
|
||||
}
|
||||
|
||||
protected virtual IJsBridgeResult? Share(JsParam<SharePayload> param)
|
||||
protected virtual async ValueTask<IJsBridgeResult?> Share(JsParam<SharePayload> param)
|
||||
{
|
||||
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
IFileSystemPickerInteraction fileSystemPickerInteraction = serviceProvider.GetRequiredService<IFileSystemPickerInteraction>();
|
||||
|
||||
string shareType = param.Payload.Type;
|
||||
ShareContent shareContent = param.Payload.Content;
|
||||
if (shareType == "image")
|
||||
{
|
||||
if (shareContent.ImageUrl is not null)
|
||||
{
|
||||
string fileName = shareContent.ImageUrl.Split("/").Last();
|
||||
string format = fileName.Split(".").Last();
|
||||
|
||||
(bool isOk, ValueFile file) = fileSystemPickerInteraction.SaveFile(
|
||||
"保存分享图片",
|
||||
fileName,
|
||||
[("图片文件", format)]);
|
||||
|
||||
if (isOk)
|
||||
{
|
||||
if (await file.DownloadAsync(shareContent.ImageUrl).ConfigureAwait(false))
|
||||
{
|
||||
infoBarService.Success("保存成功", "成功保存到指定位置");
|
||||
}
|
||||
else
|
||||
{
|
||||
infoBarService.Error("保存失败", "无法保存到指定位置");
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shareContent.ImageBase64 is not null)
|
||||
{
|
||||
string fileName = "image.png";
|
||||
string format = "png";
|
||||
|
||||
(bool isOk, ValueFile file) = fileSystemPickerInteraction.SaveFile(
|
||||
"保存分享图片",
|
||||
fileName,
|
||||
[("图片文件", format)]);
|
||||
|
||||
if (isOk)
|
||||
{
|
||||
if (await file.WritePngBase64Async(shareContent.ImageBase64).ConfigureAwait(false))
|
||||
{
|
||||
infoBarService.Success("保存成功", "成功保存到指定位置");
|
||||
}
|
||||
else
|
||||
{
|
||||
infoBarService.Error("保存失败", "无法保存到指定位置");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (shareType == "screenshot")
|
||||
{
|
||||
string fileName = "image.png";
|
||||
string format = "png";
|
||||
|
||||
(bool isOk, ValueFile file) = fileSystemPickerInteraction.SaveFile(
|
||||
"保存分享图片",
|
||||
fileName,
|
||||
[("图片文件", format)]);
|
||||
|
||||
if (isOk)
|
||||
{
|
||||
if (shareContent.Preview)
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
string base64 = await devToolsProtocolHelper.Page.CaptureScreenshotAsync(format: "png", captureBeyondViewport: true).ConfigureAwait(false);
|
||||
|
||||
if (await file.WritePngBase64Async(base64).ConfigureAwait(false))
|
||||
{
|
||||
infoBarService.Success("保存成功", "成功保存到指定位置");
|
||||
}
|
||||
else
|
||||
{
|
||||
infoBarService.Error("保存失败", "无法保存到指定位置");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new JsResult<Dictionary<string, string>>()
|
||||
{
|
||||
Data = new()
|
||||
@@ -503,7 +590,7 @@ internal class MiHoYoJSBridge
|
||||
"hideLoading" => null,
|
||||
"login" => null,
|
||||
"pushPage" => await PushPageAsync(param).ConfigureAwait(false),
|
||||
"share" => Share(param),
|
||||
"share" => await Share(param).ConfigureAwait(false),
|
||||
"showLoading" => null,
|
||||
_ => LogUnhandledMessage("Unhandled Message Type: {Method}", param.Method),
|
||||
};
|
||||
|
||||
@@ -3,8 +3,23 @@
|
||||
|
||||
namespace Snap.Hutao.Web.Bridge.Model;
|
||||
|
||||
[SuppressMessage("", "SA1124")]
|
||||
internal sealed class ShareContent
|
||||
{
|
||||
#region Screenshot
|
||||
|
||||
[JsonPropertyName("preview")]
|
||||
public bool Preview { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Image
|
||||
|
||||
[JsonPropertyName("image_url")]
|
||||
public string? ImageUrl { get; set; }
|
||||
|
||||
[JsonPropertyName("image_base64")]
|
||||
public string? ImageBase64 { get; set; }
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user