mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
refactor
This commit is contained in:
@@ -56,6 +56,51 @@ public sealed class UnsafeRuntimeBehaviorTest
|
||||
Console.WriteLine(System.Text.Encoding.UTF8.GetString(bytes));
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public unsafe void UnsafeSizeInt32ToRectInt32Test()
|
||||
{
|
||||
RectInt32 rectInt32 = ToRectInt32(new(100, 200));
|
||||
Assert.AreEqual(rectInt32.X, 0);
|
||||
Assert.AreEqual(rectInt32.Y, 0);
|
||||
Assert.AreEqual(rectInt32.Width, 100);
|
||||
Assert.AreEqual(rectInt32.Height, 200);
|
||||
|
||||
unsafe RectInt32 ToRectInt32(SizeInt32 sizeInt32)
|
||||
{
|
||||
byte* pBytes = stackalloc byte[sizeof(RectInt32)];
|
||||
*(SizeInt32*)(pBytes + 8) = sizeInt32;
|
||||
return *(RectInt32*)pBytes;
|
||||
}
|
||||
}
|
||||
|
||||
private struct RectInt32
|
||||
{
|
||||
public int X;
|
||||
public int Y;
|
||||
public int Width;
|
||||
public int Height;
|
||||
|
||||
public RectInt32(int x, int y, int width, int height)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
}
|
||||
|
||||
private struct SizeInt32
|
||||
{
|
||||
public int Width;
|
||||
public int Height;
|
||||
|
||||
public SizeInt32(int width, int height)
|
||||
{
|
||||
Width = width;
|
||||
Height = height;
|
||||
}
|
||||
}
|
||||
|
||||
private readonly struct TestStruct
|
||||
{
|
||||
public readonly int Value1;
|
||||
|
||||
29
src/Snap.Hutao/Snap.Hutao/Core/Graphics/RectInt32Convert.cs
Normal file
29
src/Snap.Hutao/Snap.Hutao/Core/Graphics/RectInt32Convert.cs
Normal file
@@ -0,0 +1,29 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Win32.Foundation;
|
||||
using System.Numerics;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace Snap.Hutao.Core.Graphics;
|
||||
|
||||
internal static class RectInt32Convert
|
||||
{
|
||||
public static RectInt32 RectInt32(RECT rect)
|
||||
{
|
||||
return new(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
public static RectInt32 RectInt32(int x, int y, Vector2 size)
|
||||
{
|
||||
return new(x, y, (int)size.X, (int)size.Y);
|
||||
}
|
||||
|
||||
public static unsafe RectInt32 RectInt32(PointInt32 position, SizeInt32 size)
|
||||
{
|
||||
RectInt32View view = default;
|
||||
view.Position = position;
|
||||
view.Size = size;
|
||||
return *(RectInt32*)&view;
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Win32.Foundation;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace Snap.Hutao.Core.Graphics;
|
||||
@@ -16,4 +17,14 @@ internal static class RectInt32Extension
|
||||
{
|
||||
return rectInt32.Width * rectInt32.Height;
|
||||
}
|
||||
|
||||
public static unsafe SizeInt32 GetSizeInt32(this RectInt32 rectInt32)
|
||||
{
|
||||
return ((RectInt32View*)&rectInt32)->Size;
|
||||
}
|
||||
|
||||
public static RECT ToRECT(this RectInt32 rect)
|
||||
{
|
||||
return new(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
|
||||
}
|
||||
}
|
||||
12
src/Snap.Hutao/Snap.Hutao/Core/Graphics/RectInt32View.cs
Normal file
12
src/Snap.Hutao/Snap.Hutao/Core/Graphics/RectInt32View.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace Snap.Hutao.Core.Graphics;
|
||||
|
||||
internal struct RectInt32View
|
||||
{
|
||||
public PointInt32 Position;
|
||||
public SizeInt32 Size;
|
||||
}
|
||||
@@ -16,4 +16,11 @@ internal static class SizeInt32Extension
|
||||
{
|
||||
return sizeInt32.Width * sizeInt32.Height;
|
||||
}
|
||||
|
||||
public static unsafe RectInt32 ToRectInt32(this SizeInt32 sizeInt32)
|
||||
{
|
||||
RectInt32View view = default;
|
||||
view.Size = sizeInt32;
|
||||
return *(RectInt32*)&view;
|
||||
}
|
||||
}
|
||||
@@ -149,21 +149,6 @@
|
||||
<None Remove="Service\Game\Automation\ScreenCapture\GameScreenCaptureDebugPreviewWindow.xaml" />
|
||||
<None Remove="stylecop.json" />
|
||||
<None Remove="UI\Xaml\View\Window\WebView2Window.xaml" />
|
||||
<None Remove="View\Card\AchievementCard.xaml" />
|
||||
<None Remove="View\Card\CardBlock.xaml" />
|
||||
<None Remove="View\Card\DailyNoteCard.xaml" />
|
||||
<None Remove="View\Card\GachaStatisticsCard.xaml" />
|
||||
<None Remove="View\Card\LaunchGameCard.xaml" />
|
||||
<None Remove="View\Control\BaseValueSlider.xaml" />
|
||||
<None Remove="View\Control\DescParamComboBox.xaml" />
|
||||
<None Remove="View\Control\HutaoStatisticsCard.xaml" />
|
||||
<None Remove="View\Control\LaunchGameResourceExpander.xaml" />
|
||||
<None Remove="View\Control\RateDeltaTextBlockStyle.xaml" />
|
||||
<None Remove="View\Control\SkillPivot.xaml" />
|
||||
<None Remove="View\Control\SegmentedOverride.xaml" />
|
||||
<None Remove="View\Control\StatisticsCard.xaml" />
|
||||
<None Remove="View\Control\StatisticsSegmented.xaml" />
|
||||
<None Remove="View\Control\WebViewer.xaml" />
|
||||
<None Remove="UI\Xaml\View\Dialog\AchievementArchiveCreateDialog.xaml" />
|
||||
<None Remove="UI\Xaml\View\Dialog\AchievementImportDialog.xaml" />
|
||||
<None Remove="UI\Xaml\View\Dialog\CultivateProjectDialog.xaml" />
|
||||
@@ -187,27 +172,6 @@
|
||||
<None Remove="UI\Xaml\View\Dialog\UpdatePackageDownloadConfirmDialog.xaml" />
|
||||
<None Remove="UI\Xaml\View\Dialog\UserDialog.xaml" />
|
||||
<None Remove="UI\Xaml\View\Dialog\UserQRCodeDialog.xaml" />
|
||||
<None Remove="View\Guide\GuideView.xaml" />
|
||||
<None Remove="View\InfoBarView.xaml" />
|
||||
<None Remove="View\MainView.xaml" />
|
||||
<None Remove="View\Page\AchievementPage.xaml" />
|
||||
<None Remove="View\Page\AnnouncementContentPage.xaml" />
|
||||
<None Remove="View\Page\AnnouncementPage.xaml" />
|
||||
<None Remove="View\Page\AvatarPropertyPage.xaml" />
|
||||
<None Remove="View\Page\CultivationPage.xaml" />
|
||||
<None Remove="View\Page\DailyNotePage.xaml" />
|
||||
<None Remove="View\Page\FeedbackPage.xaml" />
|
||||
<None Remove="View\Page\GachaLogPage.xaml" />
|
||||
<None Remove="View\Page\LaunchGamePage.xaml" />
|
||||
<None Remove="View\Page\LoginMihoyoUserPage.xaml" />
|
||||
<None Remove="View\Page\SettingPage.xaml" />
|
||||
<None Remove="View\Page\SpiralAbyssRecordPage.xaml" />
|
||||
<None Remove="View\Page\TestPage.xaml" />
|
||||
<None Remove="View\Page\WikiAvatarPage.xaml" />
|
||||
<None Remove="View\Page\WikiMonsterPage.xaml" />
|
||||
<None Remove="View\Page\WikiWeaponPage.xaml" />
|
||||
<None Remove="View\TitleView.xaml" />
|
||||
<None Remove="View\UserView.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Analyzer Files -->
|
||||
@@ -375,21 +339,11 @@
|
||||
<ItemGroup Condition="'$(DisableMsixProjectCapabilityAddedByProject)'!='true' and '$(EnablePreviewMsixTooling)'=='true'">
|
||||
<ProjectCapability Include="Msix" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\RateDeltaTextBlockStyle.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Service\Game\Automation\ScreenCapture\GameScreenCaptureDebugPreviewWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\FeedbackPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="Control\Image\CachedImage.xaml">
|
||||
@@ -397,30 +351,12 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Card\CardBlock.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="Control\Loading.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\StatisticsSegmented.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\WebViewer.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="GuideWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -433,152 +369,12 @@
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\HutaoStatisticsCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\InfoBarView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Card\DailyNoteCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Card\AchievementCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Card\GachaStatisticsCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<!-- Pages -->
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\TestPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\SpiralAbyssRecordPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\CultivationPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\WikiWeaponPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\DailyNotePage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\LoginMihoyoUserPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="LaunchGameWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\LaunchGamePage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\AvatarPropertyPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\DescParamComboBox.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\SkillPivot.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\UserView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\TitleView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\AnnouncementContentPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\AnnouncementPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\AnnouncementContentPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\AnnouncementPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\SettingPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\MainView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\WikiAvatarPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\AchievementPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\StatisticsCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\GachaLogPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="Control\Panel\LayoutSwitch.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
@@ -589,31 +385,6 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\LaunchGameResourceExpander.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Page\WikiMonsterPage.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\BaseValueSlider.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Card\LaunchGameCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Guide\GuideView.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="UI\Xaml\Control\Card\HorizontalCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -36,6 +36,12 @@ internal static class ColorHelper
|
||||
return *(Color*)&rgba;
|
||||
}
|
||||
|
||||
public static unsafe Color ToColor(uint value)
|
||||
{
|
||||
uint reversed = BinaryPrimitives.ReverseEndianness(value);
|
||||
return *(Color*)&reversed;
|
||||
}
|
||||
|
||||
public static Hsla32 ToHsla32(Rgba32 rgba32)
|
||||
{
|
||||
const double toDouble = 1.0 / 255;
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Snap.Hutao.Core.Graphics;
|
||||
using Snap.Hutao.UI.Xaml;
|
||||
using Snap.Hutao.UI.Xaml.Media.Backdrop;
|
||||
using Snap.Hutao.Win32;
|
||||
@@ -60,6 +61,6 @@ internal sealed class NotifyIconXamlHostWindow : Window, IWindowNeedEraseBackgro
|
||||
|
||||
public void MoveAndResize(RECT icon)
|
||||
{
|
||||
AppWindow.MoveAndResize(StructMarshal.RectInt32(icon));
|
||||
AppWindow.MoveAndResize(RectInt32Convert.RectInt32(icon));
|
||||
}
|
||||
}
|
||||
@@ -2,7 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Windowing;
|
||||
using Snap.Hutao.Win32;
|
||||
using Snap.Hutao.Core.Graphics;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace Snap.Hutao.UI.Windowing;
|
||||
@@ -10,8 +10,18 @@ namespace Snap.Hutao.UI.Windowing;
|
||||
[HighQuality]
|
||||
internal static class AppWindowExtension
|
||||
{
|
||||
public static RectInt32 GetRect(this AppWindow appWindow)
|
||||
public static unsafe RectInt32 GetRect(this AppWindow appWindow)
|
||||
{
|
||||
return StructMarshal.RectInt32(appWindow.Position, appWindow.Size);
|
||||
RectInt32View view = default;
|
||||
view.Position = appWindow.Position;
|
||||
view.Size = appWindow.Size;
|
||||
return *(RectInt32*)&view;
|
||||
}
|
||||
|
||||
public static unsafe void MoveThenResize(this AppWindow appWindow, RectInt32 rectInt32)
|
||||
{
|
||||
RectInt32View* pView = (RectInt32View*)&rectInt32;
|
||||
appWindow.Move(pView->Position);
|
||||
appWindow.Resize(pView->Size);
|
||||
}
|
||||
}
|
||||
@@ -154,7 +154,7 @@ internal sealed class XamlWindowController
|
||||
|
||||
if (UniversalApiContract.IsPresent(WindowsVersion.Windows11))
|
||||
{
|
||||
RECT primaryRect = StructMarshal.RECT(DisplayArea.Primary.OuterBounds);
|
||||
RECT primaryRect = DisplayArea.Primary.OuterBounds.ToRECT();
|
||||
return IntersectRect(out _, in primaryRect, in iconRect);
|
||||
}
|
||||
|
||||
@@ -246,7 +246,7 @@ internal sealed class XamlWindowController
|
||||
private void RecoverOrInitWindowSize(IXamlWindowHasInitSize xamlWindow)
|
||||
{
|
||||
double scale = window.GetRasterizationScale();
|
||||
RectInt32 rect = StructMarshal.RectInt32(xamlWindow.InitSize.Scale(scale));
|
||||
RectInt32 rect = xamlWindow.InitSize.Scale(scale).ToRectInt32();
|
||||
|
||||
if (window is IXamlWindowRectPersisted rectPersisted)
|
||||
{
|
||||
@@ -333,8 +333,7 @@ internal sealed class XamlWindowController
|
||||
return;
|
||||
}
|
||||
|
||||
// 48 is the navigation button leftInset
|
||||
RectInt32 dragRect = StructMarshal.RectInt32(48, 0, xamlWindow.TitleBarAccess.ActualSize).Scale(window.GetRasterizationScale());
|
||||
RectInt32 dragRect = RectInt32Convert.RectInt32(0, 0, xamlWindow.TitleBarAccess.ActualSize).Scale(window.GetRasterizationScale());
|
||||
window.GetInputNonClientPointerSource().SetRegionRects(NonClientRegionKind.Caption, [dragRect]);
|
||||
}
|
||||
#endregion
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Win32;
|
||||
using Windows.UI;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.Control.Theme;
|
||||
|
||||
internal static class KnownColors
|
||||
{
|
||||
public static readonly Color Orange = StructMarshal.Color(0xFFBC6932);
|
||||
public static readonly Color Purple = StructMarshal.Color(0xFFA156E0);
|
||||
public static readonly Color Blue = StructMarshal.Color(0xFF5180CB);
|
||||
public static readonly Color Green = StructMarshal.Color(0xFF2A8F72);
|
||||
public static readonly Color White = StructMarshal.Color(0xFF72778B);
|
||||
public static readonly Color Orange = ColorHelper.ToColor(0xFFBC6932);
|
||||
public static readonly Color Purple = ColorHelper.ToColor(0xFFA156E0);
|
||||
public static readonly Color Blue = ColorHelper.ToColor(0xFF5180CB);
|
||||
public static readonly Color Green = ColorHelper.ToColor(0xFF2A8F72);
|
||||
public static readonly Color White = ColorHelper.ToColor(0xFF72778B);
|
||||
}
|
||||
@@ -10,16 +10,16 @@ internal static class SystemColors
|
||||
{
|
||||
public static Color BaseLowColor(bool isDarkMode)
|
||||
{
|
||||
return isDarkMode ? StructMarshal.Color(0x33FFFFFF) : StructMarshal.Color(0x33000000);
|
||||
return isDarkMode ? ColorHelper.ToColor(0x33FFFFFF) : ColorHelper.ToColor(0x33000000);
|
||||
}
|
||||
|
||||
public static Color BaseMediumLowColor(bool isDarkMode)
|
||||
{
|
||||
return isDarkMode ? StructMarshal.Color(0x66FFFFFF) : StructMarshal.Color(0x66000000);
|
||||
return isDarkMode ? ColorHelper.ToColor(0x66FFFFFF) : ColorHelper.ToColor(0x66000000);
|
||||
}
|
||||
|
||||
public static Color BaseHighColor(bool isDarkMode)
|
||||
{
|
||||
return isDarkMode ? StructMarshal.Color(0xFFFFFFFF) : StructMarshal.Color(0xFF000000);
|
||||
return isDarkMode ? ColorHelper.ToColor(0xFFFFFFFF) : ColorHelper.ToColor(0xFF000000);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@ internal sealed partial class Int32ToGradientColorConverter : DependencyValueCon
|
||||
{
|
||||
public Int32ToGradientColorConverter()
|
||||
{
|
||||
Maximum = StructMarshal.Color(0xFFFF4949);
|
||||
Minimum = StructMarshal.Color(0xFF48FF7A);
|
||||
Maximum = ColorHelper.ToColor(0xFFFF4949);
|
||||
Minimum = ColorHelper.ToColor(0xFF48FF7A);
|
||||
}
|
||||
|
||||
public override Color Convert(int from)
|
||||
|
||||
@@ -20,8 +20,8 @@ internal sealed partial class UInt32ToGradientColorConverter : DependencyValueCo
|
||||
{
|
||||
public UInt32ToGradientColorConverter()
|
||||
{
|
||||
Maximum = StructMarshal.Color(0xFFFD0093);
|
||||
Minimum = StructMarshal.Color(0xFF4B00D9);
|
||||
Maximum = ColorHelper.ToColor(0xFFFD0093);
|
||||
Minimum = ColorHelper.ToColor(0xFF4B00D9);
|
||||
}
|
||||
|
||||
public override Color Convert(uint from)
|
||||
|
||||
@@ -8,13 +8,16 @@
|
||||
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:shme="using:Snap.Hutao.Model.Entity"
|
||||
xmlns:shux="using:Snap.Hutao.UI.Xaml"
|
||||
xmlns:shuxb="using:Snap.Hutao.UI.Xaml.Behavior"
|
||||
xmlns:shuxba="using:Snap.Hutao.UI.Xaml.Behavior.Action"
|
||||
xmlns:shuxc="using:Snap.Hutao.UI.Xaml.Control"
|
||||
xmlns:shuxcc="using:Snap.Hutao.UI.Xaml.Control.Card"
|
||||
xmlns:shuxci="using:Snap.Hutao.UI.Xaml.Control.Image"
|
||||
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
|
||||
xmlns:shuxvww="using:Snap.Hutao.UI.Xaml.View.Window.WebView2"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
xmlns:shvd="using:Snap.Hutao.ViewModel.DailyNote"
|
||||
d:DataContext="{d:DesignInstance shvd:DailyNoteViewModel}"
|
||||
@@ -448,15 +451,15 @@
|
||||
AllowFocusOnInteraction="True"
|
||||
Icon="{shuxm:FontIcon Glyph=}"
|
||||
Label="{shuxm:ResourceString Name=ViewPageDailyNoteVerify}">
|
||||
<AppBarButton.Flyout>
|
||||
<Flyout
|
||||
FlyoutPresenterStyle="{ThemeResource WebViewerFlyoutPresenterStyle}"
|
||||
LightDismissOverlayMode="On"
|
||||
Placement="Full"
|
||||
ShowMode="Standard">
|
||||
<shvc:WebViewer SourceProvider="{Binding VerifyUrlSource, Mode=OneWay}"/>
|
||||
</Flyout>
|
||||
</AppBarButton.Flyout>
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Click">
|
||||
<shuxba:ShowWebView2WindowAction>
|
||||
<shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider SourceProvider="{Binding VerifyUrlSource, Mode=OneWay}"/>
|
||||
</shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</AppBarButton>
|
||||
<AppBarButton Icon="{shuxm:FontIcon Glyph={StaticResource FontIconContentAdd}}" Label="{shuxm:ResourceString Name=ViewPageDailyNoteAddEntry}">
|
||||
<AppBarButton.Flyout>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:shuxba="using:Snap.Hutao.UI.Xaml.Behavior.Action"
|
||||
xmlns:shuxc="using:Snap.Hutao.UI.Xaml.Control"
|
||||
xmlns:shuxvww="using:Snap.Hutao.UI.Xaml.View.Window.WebView2"
|
||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
d:DataContext="{d:DesignInstance shv:TestViewModel}"
|
||||
@@ -20,61 +21,49 @@
|
||||
<cwc:SettingsCard Header="Adopt Calculator" IsClickEnabled="True">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Click">
|
||||
<shuxba:ShowAttachedFlyoutAction/>
|
||||
<shuxba:ShowWebView2WindowAction>
|
||||
<shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
<shuxvww:StaticJSBridgeUriSourceProvider ChineseSource="http://webstatic.mihoyo.com/ys/event/e20200923adopt_calculator/index.html?bbs_presentation_style=fullscreen&bbs_auth_required=true&utm_source=bbs&utm_medium=mys&utm_campaign=GameRecord"/>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
<FlyoutBase.AttachedFlyout>
|
||||
<Flyout
|
||||
FlyoutPresenterStyle="{ThemeResource WebViewerFlyoutPresenterStyle}"
|
||||
LightDismissOverlayMode="On"
|
||||
Placement="Full">
|
||||
<shvc:WebViewer>
|
||||
<shvc:WebViewer.SourceProvider>
|
||||
<shvc:StaticWebview2ViewerSource ChineseSource="http://webstatic.mihoyo.com/ys/event/e20200923adopt_calculator/index.html?bbs_presentation_style=fullscreen&bbs_auth_required=true&utm_source=bbs&utm_medium=mys&utm_campaign=GameRecord"/>
|
||||
</shvc:WebViewer.SourceProvider>
|
||||
</shvc:WebViewer>
|
||||
</Flyout>
|
||||
</FlyoutBase.AttachedFlyout>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<cwc:SettingsCard Header="Community Game Record" IsClickEnabled="True">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Click">
|
||||
<shuxba:ShowAttachedFlyoutAction/>
|
||||
<shuxba:ShowWebView2WindowAction>
|
||||
<shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
<shuxvww:StaticJSBridgeUriSourceProvider ChineseSource="https://webstatic.mihoyo.com/app/community-game-records/index.html"/>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
<FlyoutBase.AttachedFlyout>
|
||||
<Flyout
|
||||
FlyoutPresenterStyle="{ThemeResource WebViewerFlyoutPresenterStyle}"
|
||||
LightDismissOverlayMode="On"
|
||||
Placement="Full">
|
||||
<shvc:WebViewer>
|
||||
<shvc:WebViewer.SourceProvider>
|
||||
<shvc:StaticWebview2ViewerSource ChineseSource="https://webstatic.mihoyo.com/app/community-game-records/index.html"/>
|
||||
</shvc:WebViewer.SourceProvider>
|
||||
</shvc:WebViewer>
|
||||
</Flyout>
|
||||
</FlyoutBase.AttachedFlyout>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<cwc:SettingsCard Header="SignIn Reward" IsClickEnabled="True">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Click">
|
||||
<shuxba:ShowAttachedFlyoutAction/>
|
||||
<shuxba:ShowWebView2WindowAction>
|
||||
<shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
<shuxvww:StaticJSBridgeUriSourceProvider ChineseSource="https://act.mihoyo.com/bbs/event/signin/hk4e/index.html?act_id=e202311201442471"/>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
<FlyoutBase.AttachedFlyout>
|
||||
<Flyout
|
||||
FlyoutPresenterStyle="{ThemeResource WebViewerFlyoutPresenterStyle}"
|
||||
LightDismissOverlayMode="On"
|
||||
Placement="Full">
|
||||
<shvc:WebViewer>
|
||||
<shvc:WebViewer.SourceProvider>
|
||||
<shvc:StaticWebview2ViewerSource ChineseSource="https://act.mihoyo.com/bbs/event/signin/hk4e/index.html?act_id=e202311201442471"/>
|
||||
</shvc:WebViewer.SourceProvider>
|
||||
</shvc:WebViewer>
|
||||
</Flyout>
|
||||
</FlyoutBase.AttachedFlyout>
|
||||
</cwc:SettingsCard>
|
||||
|
||||
<cwc:SettingsCard Header="Reset Guide State">
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
<shuxb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
||||
</mxi:Interaction.Behaviors>
|
||||
|
||||
<Grid x:Name="DragableGrid">
|
||||
<Grid x:Name="DragableGrid" Margin="48,0,0,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
|
||||
@@ -9,8 +9,10 @@
|
||||
xmlns:mxim="using:Microsoft.Xaml.Interactions.Media"
|
||||
xmlns:shux="using:Snap.Hutao.UI.Xaml"
|
||||
xmlns:shuxb="using:Snap.Hutao.UI.Xaml.Behavior"
|
||||
xmlns:shuxba="using:Snap.Hutao.UI.Xaml.Behavior.Action"
|
||||
xmlns:shuxci="using:Snap.Hutao.UI.Xaml.Control.Image"
|
||||
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
|
||||
xmlns:shuxvww="using:Snap.Hutao.UI.Xaml.View.Window.WebView2"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
xmlns:shvu="using:Snap.Hutao.ViewModel.User"
|
||||
d:DataContext="{d:DesignInstance shvu:UserViewModel}"
|
||||
@@ -333,21 +335,19 @@
|
||||
Icon="{shuxm:FontIcon Glyph={StaticResource FontIconContentHomeGroup}}"
|
||||
Label="{shuxm:ResourceString Name=ViewUserCookieOperationGameRecordIndexAction}"
|
||||
Style="{StaticResource DefaultAppBarButtonStyle}">
|
||||
<AppBarButton.Flyout>
|
||||
<Flyout
|
||||
FlyoutPresenterStyle="{StaticResource WebViewerFlyoutPresenterStyle}"
|
||||
LightDismissOverlayMode="On"
|
||||
Placement="Full"
|
||||
ShouldConstrainToRootBounds="False">
|
||||
<Grid>
|
||||
<shvc:WebViewer>
|
||||
<shvc:WebViewer.SourceProvider>
|
||||
<shvc:StaticWebview2ViewerSource ChineseSource="https://webstatic.mihoyo.com/bbs/event/e20200511toolbox/index.html?game_biz=ys_cn"/>
|
||||
</shvc:WebViewer.SourceProvider>
|
||||
</shvc:WebViewer>
|
||||
</Grid>
|
||||
</Flyout>
|
||||
</AppBarButton.Flyout>
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Click">
|
||||
<shuxba:ShowWebView2WindowAction>
|
||||
<shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
<shuxvww:StaticJSBridgeUriSourceProvider ChineseSource="https://webstatic.mihoyo.com/bbs/event/e20200511toolbox/index.html?game_biz=ys_cn"/>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
x:Name="SignInRewardButton"
|
||||
@@ -360,21 +360,19 @@
|
||||
Icon="{shuxm:FontIcon Glyph={StaticResource FontIconContentGiftboxOpen}}"
|
||||
Label="{shuxm:ResourceString Name=ViewUserCookieOperationSignInRewardAction}"
|
||||
Style="{StaticResource DefaultAppBarButtonStyle}">
|
||||
<FlyoutBase.AttachedFlyout>
|
||||
<Flyout
|
||||
FlyoutPresenterStyle="{StaticResource WebViewerFlyoutPresenterStyle}"
|
||||
LightDismissOverlayMode="On"
|
||||
Placement="Full"
|
||||
ShouldConstrainToRootBounds="False">
|
||||
<Grid>
|
||||
<shvc:WebViewer>
|
||||
<shvc:WebViewer.SourceProvider>
|
||||
<shvu:SignInWebViewerSouce/>
|
||||
</shvc:WebViewer.SourceProvider>
|
||||
</shvc:WebViewer>
|
||||
</Grid>
|
||||
</Flyout>
|
||||
</FlyoutBase.AttachedFlyout>
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Click">
|
||||
<shuxba:ShowWebView2WindowAction>
|
||||
<shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
<shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
<shvu:SignInJSBridgeUriSourceProvider/>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider.SourceProvider>
|
||||
</shuxvww:MiHoYoJSBridgeWebView2ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction.ContentProvider>
|
||||
</shuxba:ShowWebView2WindowAction>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</AppBarButton>
|
||||
<AppBarButton
|
||||
Width="{StaticResource LargeAppBarButtonWidth}"
|
||||
@@ -438,10 +436,10 @@
|
||||
</Button.Flyout>
|
||||
<Button.Style>
|
||||
<Style BasedOn="{StaticResource DefaultButtonStyle}" TargetType="Button">
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="HorizontalAlignment" Value="Stretch"/>
|
||||
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
|
||||
<Setter Property="BorderThickness" Value="0"/>
|
||||
<Setter Property="Padding" Value="0"/>
|
||||
</Style>
|
||||
</Button.Style>
|
||||
</Button>
|
||||
|
||||
@@ -23,8 +23,8 @@ internal sealed partial class IdentifyMonitorWindow : Microsoft.UI.Xaml.Window
|
||||
AppWindow.SetPresenter(presenter);
|
||||
|
||||
PointInt32 point = new(40, 32);
|
||||
SizeInt32 size = StructMarshal.SizeInt32(displayArea.WorkArea).Scale(0.1);
|
||||
AppWindow.MoveAndResize(StructMarshal.RectInt32(point, size), displayArea);
|
||||
SizeInt32 size = displayArea.WorkArea.GetSizeInt32().Scale(0.1);
|
||||
AppWindow.MoveAndResize(RectInt32Convert.RectInt32(point, size), displayArea);
|
||||
}
|
||||
|
||||
public string Monitor { get; private set; }
|
||||
|
||||
@@ -41,7 +41,7 @@ internal sealed partial class AnnouncementWebView2ContentProvider : DependencyOb
|
||||
|
||||
public CoreWebView2? CoreWebView2 { get; set; }
|
||||
|
||||
public async ValueTask InitializeAsync(CancellationToken token)
|
||||
public async ValueTask InitializeAsync(IServiceProvider serviceProvider, CancellationToken token)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(CoreWebView2);
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ using Snap.Hutao.Web.Bridge;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
|
||||
|
||||
internal interface IJSBridgeUriSource
|
||||
internal interface IJSBridgeUriSourceProvider
|
||||
{
|
||||
MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid);
|
||||
|
||||
@@ -13,7 +13,7 @@ internal interface IWebView2ContentProvider
|
||||
|
||||
CoreWebView2? CoreWebView2 { get; set; }
|
||||
|
||||
ValueTask InitializeAsync(CancellationToken token);
|
||||
ValueTask InitializeAsync(IServiceProvider serviceProvider, CancellationToken token);
|
||||
|
||||
RectInt32 InitializePosition(RectInt32 parentRect);
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Bridge;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
|
||||
|
||||
[DependencyProperty("SourceProvider", typeof(IJSBridgeUriSourceProvider))]
|
||||
internal sealed partial class MiHoYoJSBridgeWebView2ContentProvider : DependencyObject, IWebView2ContentProvider
|
||||
{
|
||||
private MiHoYoJSBridgeFacade? jsBridge;
|
||||
|
||||
public ElementTheme ActualTheme { get; set; }
|
||||
|
||||
public CoreWebView2? CoreWebView2 { get; set; }
|
||||
|
||||
public async ValueTask InitializeAsync(IServiceProvider serviceProvider, CancellationToken token)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(CoreWebView2);
|
||||
|
||||
if (SourceProvider is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
User? user = serviceProvider.GetRequiredService<IUserService>().Current;
|
||||
if (user is null || user.SelectedUserGameRole is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IInfoBarService infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
if (!UserAndUid.TryFromUser(user, out UserAndUid? userAndUid))
|
||||
{
|
||||
infoBarService.Warning(SH.MustSelectUserAndUid);
|
||||
return;
|
||||
}
|
||||
|
||||
string source = SourceProvider.GetSource(userAndUid);
|
||||
if (!string.IsNullOrEmpty(source))
|
||||
{
|
||||
CoreWebView2Navigator navigator = new(CoreWebView2);
|
||||
await navigator.NavigateAsync("about:blank").ConfigureAwait(true);
|
||||
|
||||
try
|
||||
{
|
||||
await CoreWebView2.Profile.ClearBrowsingDataAsync();
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
infoBarService.Warning(SH.ViewControlWebViewerCoreWebView2ProfileQueryInterfaceFailed);
|
||||
await CoreWebView2.DeleteCookiesAsync(userAndUid.IsOversea).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
CoreWebView2
|
||||
.SetCookie(user.CookieToken, user.LToken, userAndUid.IsOversea)
|
||||
.SetMobileUserAgent(userAndUid.IsOversea);
|
||||
jsBridge = SourceProvider.CreateJSBridge(serviceProvider, CoreWebView2, userAndUid);
|
||||
|
||||
await navigator.NavigateAsync(source).ConfigureAwait(true);
|
||||
await CoreWebView2.Profile.ClearBrowsingDataAsync(CoreWebView2BrowsingDataKinds.BrowsingHistory);
|
||||
}
|
||||
}
|
||||
|
||||
public void Unload()
|
||||
{
|
||||
jsBridge?.Detach();
|
||||
}
|
||||
|
||||
public RectInt32 InitializePosition(RectInt32 parentRect)
|
||||
{
|
||||
return parentRect;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
|
||||
|
||||
[DependencyProperty("ChineseSource", typeof(string))]
|
||||
[DependencyProperty("OverseaSource", typeof(string))]
|
||||
internal sealed partial class StaticJSBridgeUriSource : DependencyObject, IJSBridgeUriSource
|
||||
internal sealed partial class StaticJSBridgeUriSourceProvider : DependencyObject, IJSBridgeUriSourceProvider
|
||||
{
|
||||
public MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
|
||||
{
|
||||
@@ -13,8 +13,28 @@
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid x:Name="TitleArea">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button
|
||||
x:Name="GoBackButton"
|
||||
Grid.Column="0"
|
||||
MinWidth="42"
|
||||
Command="{x:Bind GoBackCommand}"
|
||||
FontSize="12"
|
||||
Style="{StaticResource NavigationBackButtonSmallStyle}"/>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
MinWidth="42"
|
||||
Command="{x:Bind RefreshCommand}"
|
||||
Content=""
|
||||
FontSize="12"
|
||||
Style="{StaticResource NavigationBackButtonSmallStyle}"/>
|
||||
<TextBlock
|
||||
x:Name="DocumentTitle"
|
||||
Grid.Column="2"
|
||||
Margin="12,0,0,0"
|
||||
VerticalAlignment="Center"/>
|
||||
</Grid>
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.ComponentModel;
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Snap.Hutao.Core.Graphics;
|
||||
using Snap.Hutao.UI.Windowing;
|
||||
using Snap.Hutao.UI.Windowing.Abstraction;
|
||||
using Snap.Hutao.Web.WebView2;
|
||||
using Snap.Hutao.Win32.Foundation;
|
||||
using Snap.Hutao.Win32.UI.WindowsAndMessaging;
|
||||
using Windows.Graphics;
|
||||
using static Snap.Hutao.Win32.User32;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
|
||||
|
||||
[SuppressMessage("", "CA1001")]
|
||||
[INotifyPropertyChanged]
|
||||
internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWindowExtendContentIntoTitleBar, IXamlWindowClosedHandler
|
||||
{
|
||||
private readonly CancellationTokenSource loadCts = new();
|
||||
@@ -56,7 +60,8 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
|
||||
{
|
||||
EnableWindow(parentHWND, false);
|
||||
base.Activate();
|
||||
AppWindow.MoveAndResize(contentProvider.InitializePosition(parentAppWindow.GetRect()));
|
||||
|
||||
AppWindow.MoveThenResize(contentProvider.InitializePosition(parentAppWindow.GetRect()));
|
||||
}
|
||||
|
||||
public void OnWindowClosed()
|
||||
@@ -68,6 +73,21 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
|
||||
windowScope.Dispose();
|
||||
}
|
||||
|
||||
[Command("GoBackCommand")]
|
||||
private void GoBack()
|
||||
{
|
||||
if (WebView.CoreWebView2.CanGoBack)
|
||||
{
|
||||
WebView.CoreWebView2.GoBack();
|
||||
}
|
||||
}
|
||||
|
||||
[Command("RefreshCommand")]
|
||||
private void Refresh()
|
||||
{
|
||||
WebView.CoreWebView2.Reload();
|
||||
}
|
||||
|
||||
private void OnWebViewLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OnWebViewLoadedAsync().SafeForget();
|
||||
@@ -76,9 +96,10 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
|
||||
{
|
||||
await WebView.EnsureCoreWebView2Async();
|
||||
WebView.CoreWebView2.DocumentTitleChanged += OnDocumentTitleChanged;
|
||||
WebView.CoreWebView2.HistoryChanged += OnHistoryChanged;
|
||||
WebView.CoreWebView2.DisableDevToolsForReleaseBuild();
|
||||
contentProvider.CoreWebView2 = WebView.CoreWebView2;
|
||||
await contentProvider.InitializeAsync(loadCts.Token).ConfigureAwait(false);
|
||||
await contentProvider.InitializeAsync(windowScope.ServiceProvider, loadCts.Token).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +109,12 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
|
||||
loadCts.Dispose();
|
||||
contentProvider.Unload();
|
||||
|
||||
if (WebView.CoreWebView2 is not null)
|
||||
{
|
||||
WebView.CoreWebView2.DocumentTitleChanged += OnDocumentTitleChanged;
|
||||
WebView.CoreWebView2.HistoryChanged += OnHistoryChanged;
|
||||
}
|
||||
|
||||
WebView.Loaded -= OnWebViewLoaded;
|
||||
WebView.Unloaded -= OnWebViewUnloaded;
|
||||
}
|
||||
@@ -97,6 +124,11 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
|
||||
DocumentTitle.Text = sender.DocumentTitle;
|
||||
}
|
||||
|
||||
private void OnHistoryChanged(CoreWebView2 sender, object args)
|
||||
{
|
||||
GoBackButton.IsEnabled = sender.CanGoBack;
|
||||
}
|
||||
|
||||
private void OnActualThemeChanged(FrameworkElement sender, object args)
|
||||
{
|
||||
contentProvider.ActualTheme = sender.ActualTheme;
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
<UserControl
|
||||
x:Class="Snap.Hutao.View.Control.WebViewer"
|
||||
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"
|
||||
Transitions="{ThemeResource EntranceThemeTransitions}"
|
||||
mc:Ignorable="d">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
<RowDefinition Height="auto"/>
|
||||
</Grid.RowDefinitions>
|
||||
<StackPanel Grid.Row="0" Orientation="Horizontal">
|
||||
<Button
|
||||
MinWidth="42"
|
||||
Command="{x:Bind GoBackCommand}"
|
||||
FontSize="12"
|
||||
IsEnabled="{x:Bind CanGoBack, Mode=OneWay}"
|
||||
Style="{StaticResource NavigationBackButtonSmallStyle}"/>
|
||||
<Button
|
||||
MinWidth="42"
|
||||
Command="{x:Bind RefreshCommand}"
|
||||
Content=""
|
||||
FontSize="12"
|
||||
Style="{StaticResource NavigationBackButtonSmallStyle}"/>
|
||||
<TextBlock
|
||||
MaxWidth="240"
|
||||
Margin="6"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Center"
|
||||
Text="{x:Bind DocumentTitle, Mode=OneWay}"
|
||||
TextTrimming="CharacterEllipsis"
|
||||
TextWrapping="NoWrap"/>
|
||||
</StackPanel>
|
||||
|
||||
<WebView2
|
||||
x:Name="WebView"
|
||||
Grid.Row="1"
|
||||
DefaultBackgroundColor="Transparent"/>
|
||||
|
||||
<Rectangle
|
||||
Grid.Row="2"
|
||||
Height="8"
|
||||
Fill="{ThemeResource SystemControlAccentAcrylicElementAccentMediumHighBrush}"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
@@ -1,163 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.Mvvm.Messaging;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Snap.Hutao.Message;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.UI.Xaml.View.Window.WebView2;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Bridge;
|
||||
using Snap.Hutao.Web.WebView2;
|
||||
using Windows.Foundation;
|
||||
|
||||
namespace Snap.Hutao.View.Control;
|
||||
|
||||
[DependencyProperty("SourceProvider", typeof(IJSBridgeUriSource))]
|
||||
[DependencyProperty("DocumentTitle", typeof(string))]
|
||||
[DependencyProperty("CanGoBack", typeof(bool))]
|
||||
internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly RoutedEventHandler loadEventHandler;
|
||||
private readonly TypedEventHandler<CoreWebView2, object> documentTitleChangedEventHandler;
|
||||
private readonly TypedEventHandler<CoreWebView2, object> historyChangedEventHandler;
|
||||
|
||||
private MiHoYoJSBridgeFacade? jsBridge;
|
||||
private bool isInitializingOrInitialized;
|
||||
|
||||
public WebViewer()
|
||||
{
|
||||
Environment.SetEnvironmentVariable("WEBVIEW2_DEFAULT_BACKGROUND_COLOR", "00000000");
|
||||
InitializeComponent();
|
||||
serviceProvider = Ioc.Default;
|
||||
infoBarService = serviceProvider.GetRequiredService<IInfoBarService>();
|
||||
serviceProvider.GetRequiredService<IMessenger>().Register(this);
|
||||
|
||||
loadEventHandler = OnLoaded;
|
||||
documentTitleChangedEventHandler = OnDocumentTitleChanged;
|
||||
historyChangedEventHandler = OnHistoryChanged;
|
||||
|
||||
Loaded += loadEventHandler;
|
||||
}
|
||||
|
||||
public void Receive(UserChangedMessage message)
|
||||
{
|
||||
if (message.IsOnlyRoleChanged)
|
||||
{
|
||||
// Only role changed, we can't respond to this
|
||||
// since we only set selection locally.
|
||||
return;
|
||||
}
|
||||
|
||||
ITaskContext taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
taskContext.InvokeOnMainThread(RefreshWebview2Content);
|
||||
}
|
||||
|
||||
[Command("GoBackCommand")]
|
||||
private void GoBack()
|
||||
{
|
||||
if (WebView.CoreWebView2.CanGoBack)
|
||||
{
|
||||
WebView.CoreWebView2.GoBack();
|
||||
}
|
||||
}
|
||||
|
||||
[Command("RefreshCommand")]
|
||||
private void Refresh()
|
||||
{
|
||||
WebView.CoreWebView2.Reload();
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
InitializeAsync().SafeForget();
|
||||
}
|
||||
|
||||
private async ValueTask InitializeAsync()
|
||||
{
|
||||
if (!isInitializingOrInitialized)
|
||||
{
|
||||
isInitializingOrInitialized = true;
|
||||
|
||||
await WebView.EnsureCoreWebView2Async();
|
||||
WebView.CoreWebView2.DisableDevToolsForReleaseBuild();
|
||||
WebView.CoreWebView2.DocumentTitleChanged += documentTitleChangedEventHandler;
|
||||
WebView.CoreWebView2.HistoryChanged += historyChangedEventHandler;
|
||||
}
|
||||
|
||||
RefreshWebview2Content();
|
||||
}
|
||||
|
||||
private void OnDocumentTitleChanged(CoreWebView2 sender, object args)
|
||||
{
|
||||
DocumentTitle = sender.DocumentTitle;
|
||||
}
|
||||
|
||||
private void OnHistoryChanged(CoreWebView2 sender, object args)
|
||||
{
|
||||
CanGoBack = sender.CanGoBack;
|
||||
}
|
||||
|
||||
private async void RefreshWebview2Content()
|
||||
{
|
||||
User? user = serviceProvider.GetRequiredService<IUserService>().Current;
|
||||
if (user is null || user.SelectedUserGameRole is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (WebView.IsDisposed())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CoreWebView2? coreWebView2 = WebView?.CoreWebView2;
|
||||
|
||||
if (coreWebView2 is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SourceProvider is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UserAndUid.TryFromUser(user, out UserAndUid? userAndUid))
|
||||
{
|
||||
infoBarService.Warning(SH.MustSelectUserAndUid);
|
||||
return;
|
||||
}
|
||||
|
||||
string source = SourceProvider.GetSource(userAndUid);
|
||||
if (!string.IsNullOrEmpty(source))
|
||||
{
|
||||
CoreWebView2Navigator navigator = new(coreWebView2);
|
||||
await navigator.NavigateAsync("about:blank").ConfigureAwait(true);
|
||||
|
||||
try
|
||||
{
|
||||
await coreWebView2.Profile.ClearBrowsingDataAsync();
|
||||
}
|
||||
catch (InvalidCastException)
|
||||
{
|
||||
infoBarService.Warning(SH.ViewControlWebViewerCoreWebView2ProfileQueryInterfaceFailed);
|
||||
await coreWebView2.DeleteCookiesAsync(userAndUid.IsOversea).ConfigureAwait(true);
|
||||
}
|
||||
|
||||
coreWebView2
|
||||
.SetCookie(user.CookieToken, user.LToken, userAndUid.IsOversea)
|
||||
.SetMobileUserAgent(userAndUid.IsOversea);
|
||||
jsBridge?.Detach();
|
||||
jsBridge = SourceProvider.CreateJSBridge(serviceProvider, coreWebView2, userAndUid);
|
||||
|
||||
await navigator.NavigateAsync(source).ConfigureAwait(true);
|
||||
await coreWebView2.Profile.ClearBrowsingDataAsync(CoreWebView2BrowsingDataKinds.BrowsingHistory);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ internal sealed partial class DailyNoteViewModel : Abstraction.ViewModel
|
||||
|
||||
public AppOptions AppOptions { get => appOptions; }
|
||||
|
||||
public IJSBridgeUriSource VerifyUrlSource { get; } = new DailyNoteWebViewerSource();
|
||||
public IJSBridgeUriSourceProvider VerifyUrlSource { get; } = new DailyNoteWebViewerSource();
|
||||
|
||||
/// <summary>
|
||||
/// 用户与角色集合
|
||||
|
||||
@@ -9,7 +9,7 @@ using Snap.Hutao.Web.Hoyolab;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.DailyNote;
|
||||
|
||||
internal sealed class DailyNoteWebViewerSource : IJSBridgeUriSource
|
||||
internal sealed class DailyNoteWebViewerSource : IJSBridgeUriSourceProvider
|
||||
{
|
||||
public MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
|
||||
{
|
||||
|
||||
@@ -8,13 +8,13 @@ using Snap.Hutao.Web.Bridge;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.User;
|
||||
|
||||
internal sealed class SignInWebViewerSouce : DependencyObject, IJSBridgeUriSource
|
||||
internal sealed class SignInJSBridgeUriSourceProvider : DependencyObject, IJSBridgeUriSourceProvider
|
||||
{
|
||||
public MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
|
||||
{
|
||||
return userAndUid.User.IsOversea
|
||||
? serviceProvider.CreateInstance<SignInJSBridgeOversea>(coreWebView2, userAndUid)
|
||||
: serviceProvider.CreateInstance<SignInJSBridge>(coreWebView2, userAndUid);
|
||||
? ActivatorUtilities.CreateInstance<SignInJSBridgeOversea>(serviceProvider, coreWebView2, userAndUid)
|
||||
: ActivatorUtilities.CreateInstance<SignInJSBridge>(serviceProvider, coreWebView2, userAndUid);
|
||||
}
|
||||
|
||||
public string GetSource(UserAndUid userAndUid)
|
||||
@@ -12,8 +12,8 @@ namespace Snap.Hutao.Web.Bridge;
|
||||
[HighQuality]
|
||||
internal sealed class SignInJSBridge : MiHoYoJSBridgeFacade
|
||||
{
|
||||
public SignInJSBridge(CoreWebView2 webView, UserAndUid userAndUid)
|
||||
: base(webView, userAndUid)
|
||||
public SignInJSBridge(IServiceProvider serviceProvider, CoreWebView2 webView, UserAndUid userAndUid)
|
||||
: base(serviceProvider, webView, userAndUid)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -18,8 +18,8 @@ internal sealed class SignInJSBridgeOversea : MiHoYoJSBridgeFacade
|
||||
landscape.remove();
|
||||
""";
|
||||
|
||||
public SignInJSBridgeOversea(CoreWebView2 webView, UserAndUid userAndUid)
|
||||
: base(webView, userAndUid)
|
||||
public SignInJSBridgeOversea(IServiceProvider serviceProvider, CoreWebView2 webView, UserAndUid userAndUid)
|
||||
: base(serviceProvider, webView, userAndUid)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -1,70 +0,0 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Win32.Foundation;
|
||||
using System.Buffers.Binary;
|
||||
using System.Numerics;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Windows.Foundation;
|
||||
using Windows.Graphics;
|
||||
|
||||
namespace Snap.Hutao.Win32;
|
||||
|
||||
/// <summary>
|
||||
/// 结构体封送
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal static class StructMarshal
|
||||
{
|
||||
/// <summary>
|
||||
/// 使用四字节颜色代码初始化一个新的颜色
|
||||
/// </summary>
|
||||
/// <param name="value">颜色代码</param>
|
||||
/// <returns>对应的颜色</returns>
|
||||
public static unsafe Windows.UI.Color Color(uint value)
|
||||
{
|
||||
Unsafe.SkipInit(out Windows.UI.Color color);
|
||||
*(uint*)&color = BinaryPrimitives.ReverseEndianness(value);
|
||||
return color;
|
||||
}
|
||||
|
||||
public static Rect Rect(Vector2 size)
|
||||
{
|
||||
return new(0, 0, size.X, size.Y);
|
||||
}
|
||||
|
||||
public static RECT RECT(RectInt32 rect)
|
||||
{
|
||||
return new(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
|
||||
}
|
||||
|
||||
public static RectInt32 RectInt32(RECT rect)
|
||||
{
|
||||
return new(rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
public static RectInt32 RectInt32(SizeInt32 size)
|
||||
{
|
||||
return new(0, 0, size.Width, size.Height);
|
||||
}
|
||||
|
||||
public static RectInt32 RectInt32(PointInt32 point, Vector2 size)
|
||||
{
|
||||
return RectInt32(point.X, point.Y, size);
|
||||
}
|
||||
|
||||
public static RectInt32 RectInt32(int x, int y, Vector2 size)
|
||||
{
|
||||
return new(x, y, (int)size.X, (int)size.Y);
|
||||
}
|
||||
|
||||
public static RectInt32 RectInt32(PointInt32 point, SizeInt32 size)
|
||||
{
|
||||
return new(point.X, point.Y, size.Width, size.Height);
|
||||
}
|
||||
|
||||
public static SizeInt32 SizeInt32(RectInt32 rect)
|
||||
{
|
||||
return new(rect.Width, rect.Height);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user