This commit is contained in:
qhy040404
2024-01-02 21:14:48 +08:00
parent 802951edd7
commit fcd0b65257
4 changed files with 160 additions and 3 deletions

View 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;
}
}
}

View File

@@ -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">

View File

@@ -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),
};

View File

@@ -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
}