mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
make webview2 great again
This commit is contained in:
@@ -15,7 +15,7 @@ internal sealed class AdvancedDbCollectionView<TEntity> : AdvancedCollectionView
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
private bool detached;
|
||||
private bool savingToDatabase = true;
|
||||
|
||||
public AdvancedDbCollectionView(IList<TEntity> source, IServiceProvider serviceProvider)
|
||||
: base(source, true)
|
||||
@@ -23,14 +23,14 @@ internal sealed class AdvancedDbCollectionView<TEntity> : AdvancedCollectionView
|
||||
this.serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public void Detach()
|
||||
public IDisposable SuppressSavingToDatabase()
|
||||
{
|
||||
detached = true;
|
||||
return new SavingToDatabaseSuppression(this);
|
||||
}
|
||||
|
||||
protected override void OnCurrentChangedOverride()
|
||||
{
|
||||
if (serviceProvider is null || detached)
|
||||
if (serviceProvider is null || !savingToDatabase)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -53,6 +53,22 @@ internal sealed class AdvancedDbCollectionView<TEntity> : AdvancedCollectionView
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SavingToDatabaseSuppression : IDisposable
|
||||
{
|
||||
private readonly AdvancedDbCollectionView<TEntity> view;
|
||||
|
||||
public SavingToDatabaseSuppression(AdvancedDbCollectionView<TEntity> view)
|
||||
{
|
||||
this.view = view;
|
||||
view.savingToDatabase = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
view.savingToDatabase = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// The scope of the view follows the scope of the service provider.
|
||||
@@ -63,7 +79,7 @@ internal sealed class AdvancedDbCollectionView<TEntityAccess, TEntity> : Advance
|
||||
{
|
||||
private readonly IServiceProvider serviceProvider;
|
||||
|
||||
private bool detached;
|
||||
private bool savingToDatabase = true;
|
||||
|
||||
public AdvancedDbCollectionView(IList<TEntityAccess> source, IServiceProvider serviceProvider)
|
||||
: base(source, true)
|
||||
@@ -71,14 +87,14 @@ internal sealed class AdvancedDbCollectionView<TEntityAccess, TEntity> : Advance
|
||||
this.serviceProvider = serviceProvider;
|
||||
}
|
||||
|
||||
public void Detach()
|
||||
public IDisposable SuppressSavingToDatabase()
|
||||
{
|
||||
detached = true;
|
||||
return new SavingToDatabaseSuppression(this);
|
||||
}
|
||||
|
||||
protected override void OnCurrentChangedOverride()
|
||||
{
|
||||
if (serviceProvider is null || detached)
|
||||
if (serviceProvider is null || !savingToDatabase)
|
||||
{
|
||||
return;
|
||||
}
|
||||
@@ -101,4 +117,20 @@ internal sealed class AdvancedDbCollectionView<TEntityAccess, TEntity> : Advance
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class SavingToDatabaseSuppression : IDisposable
|
||||
{
|
||||
private readonly AdvancedDbCollectionView<TEntityAccess, TEntity> view;
|
||||
|
||||
public SavingToDatabaseSuppression(AdvancedDbCollectionView<TEntityAccess, TEntity> view)
|
||||
{
|
||||
this.view = view;
|
||||
view.savingToDatabase = false;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
view.savingToDatabase = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,5 +8,5 @@ namespace Snap.Hutao.Core.Database;
|
||||
internal interface IAdvancedDbCollectionView<TEntity> : IAdvancedCollectionView<TEntity>
|
||||
where TEntity : class
|
||||
{
|
||||
void Detach();
|
||||
IDisposable SuppressSavingToDatabase();
|
||||
}
|
||||
17
src/Snap.Hutao/Snap.Hutao/Core/Graphics/PointInt32Kind.cs
Normal file
17
src/Snap.Hutao/Snap.Hutao/Core/Graphics/PointInt32Kind.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Core.Graphics;
|
||||
|
||||
internal enum PointInt32Kind
|
||||
{
|
||||
TopLeft,
|
||||
TopCenter,
|
||||
TopRight,
|
||||
CenterLeft,
|
||||
Center,
|
||||
CenterRight,
|
||||
BottomLeft,
|
||||
BottomCenter,
|
||||
BottomRight,
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Snap.Hutao.Win32.Foundation;
|
||||
using Windows.Graphics;
|
||||
|
||||
@@ -23,6 +24,26 @@ internal static class RectInt32Extension
|
||||
return ((RectInt32View*)&rectInt32)->Size;
|
||||
}
|
||||
|
||||
public static unsafe PointInt32 GetPointInt32(this RectInt32 rectInt32, PointInt32Kind kind)
|
||||
{
|
||||
RectInt32View* pView = (RectInt32View*)&rectInt32;
|
||||
PointInt32 topLeft = pView->Position;
|
||||
SizeInt32 size = pView->Size;
|
||||
return kind switch
|
||||
{
|
||||
PointInt32Kind.TopLeft => topLeft,
|
||||
PointInt32Kind.TopCenter => new PointInt32(topLeft.X + (size.Width / 2), topLeft.Y),
|
||||
PointInt32Kind.TopRight => new PointInt32(topLeft.X + size.Width, topLeft.Y),
|
||||
PointInt32Kind.CenterLeft => new PointInt32(topLeft.X, topLeft.Y + (size.Height / 2)),
|
||||
PointInt32Kind.Center => new PointInt32(topLeft.X + (size.Width / 2), topLeft.Y + (size.Height / 2)),
|
||||
PointInt32Kind.CenterRight => new PointInt32(topLeft.X + size.Width, topLeft.Y + (size.Height / 2)),
|
||||
PointInt32Kind.BottomLeft => new PointInt32(topLeft.X, topLeft.Y + size.Height),
|
||||
PointInt32Kind.BottomCenter => new PointInt32(topLeft.X + (size.Width / 2), topLeft.Y + size.Height),
|
||||
PointInt32Kind.BottomRight => new PointInt32(topLeft.X + size.Width, topLeft.Y + size.Height),
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
|
||||
public static RECT ToRECT(this RectInt32 rect)
|
||||
{
|
||||
return new(rect.X, rect.Y, rect.X + rect.Width, rect.Y + rect.Height);
|
||||
|
||||
@@ -287,10 +287,10 @@
|
||||
|
||||
<AppBarElementContainer>
|
||||
<shuxc:SizeRestrictedContentControl Margin="2,6,3,6">
|
||||
<!-- SelectedItem="{Binding Archives.CurrentItem, Mode=TwoWay}" -->
|
||||
<ComboBox
|
||||
DisplayMemberPath="Name"
|
||||
ItemsSource="{Binding Archives, Mode=OneWay}"
|
||||
SelectedItem="{Binding Archives.CurrentItem, Mode=TwoWay}"
|
||||
Style="{ThemeResource CommandBarComboBoxStyle}"/>
|
||||
</shuxc:SizeRestrictedContentControl>
|
||||
</AppBarElementContainer>
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Windowing;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Snap.Hutao.Core.Graphics;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.Web.Bridge;
|
||||
@@ -35,6 +38,7 @@ internal sealed partial class MiHoYoJSBridgeWebView2ContentProvider : Dependency
|
||||
return;
|
||||
}
|
||||
|
||||
await serviceProvider.GetRequiredService<ITaskContext>().SwitchToMainThreadAsync();
|
||||
string source = SourceProvider.GetSource(userAndUid);
|
||||
if (!string.IsNullOrEmpty(source))
|
||||
{
|
||||
@@ -68,6 +72,47 @@ internal sealed partial class MiHoYoJSBridgeWebView2ContentProvider : Dependency
|
||||
|
||||
public RectInt32 InitializePosition(RectInt32 parentRect)
|
||||
{
|
||||
return parentRect;
|
||||
PointInt32 center = parentRect.GetPointInt32(PointInt32Kind.Center);
|
||||
RectInt32 target = new(center.X - 240, center.Y - 400, 450, 800);
|
||||
|
||||
RectInt32 workArea = DisplayArea.GetFromRect(parentRect, DisplayAreaFallback.None).WorkArea;
|
||||
RectInt32 workAreaShrink = new(workArea.X + 48, workArea.Y + 48, workArea.Width - 96, workArea.Height - 96);
|
||||
|
||||
if (target.Width > workAreaShrink.Width)
|
||||
{
|
||||
target.Width = workAreaShrink.Width;
|
||||
}
|
||||
|
||||
if (target.Height > workAreaShrink.Height)
|
||||
{
|
||||
target.Height = workAreaShrink.Height;
|
||||
}
|
||||
|
||||
PointInt32 topLeft = target.GetPointInt32(PointInt32Kind.TopLeft);
|
||||
|
||||
if (topLeft.X < workAreaShrink.X)
|
||||
{
|
||||
target.X = workAreaShrink.X;
|
||||
}
|
||||
|
||||
if (topLeft.Y < workAreaShrink.Y)
|
||||
{
|
||||
target.Y = workAreaShrink.Y;
|
||||
}
|
||||
|
||||
PointInt32 bottomRight = target.GetPointInt32(PointInt32Kind.BottomRight);
|
||||
PointInt32 workAreeShrinkBottomRight = workAreaShrink.GetPointInt32(PointInt32Kind.BottomRight);
|
||||
|
||||
if (bottomRight.X > workAreeShrinkBottomRight.X)
|
||||
{
|
||||
target.X = workAreeShrinkBottomRight.X - target.Width;
|
||||
}
|
||||
|
||||
if (bottomRight.Y > workAreeShrinkBottomRight.Y)
|
||||
{
|
||||
target.Y = workAreeShrinkBottomRight.Y - target.Height;
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
|
||||
<Grid ActualThemeChanged="OnActualThemeChanged">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="44"/>
|
||||
<RowDefinition Height="32"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
@@ -21,14 +21,12 @@
|
||||
<Button
|
||||
x:Name="GoBackButton"
|
||||
Grid.Column="0"
|
||||
Height="44"
|
||||
MinWidth="44"
|
||||
Command="{x:Bind GoBackCommand}"
|
||||
FontSize="12"
|
||||
Style="{StaticResource NavigationBackButtonSmallStyle}"/>
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Height="44"
|
||||
MinWidth="44"
|
||||
Command="{x:Bind RefreshCommand}"
|
||||
Content=""
|
||||
|
||||
@@ -39,6 +39,7 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
|
||||
{
|
||||
presenter.IsModal = true;
|
||||
presenter.IsResizable = false;
|
||||
presenter.IsMinimizable = false;
|
||||
presenter.IsMaximizable = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ internal abstract partial class ViewModel : ObservableObject, IViewModel
|
||||
|
||||
public void Uninitialize()
|
||||
{
|
||||
IsInitialized = false;
|
||||
UninitializeOverride();
|
||||
IsViewDisposed = true;
|
||||
DeferContentLoader = default;
|
||||
|
||||
@@ -148,10 +148,12 @@ internal sealed partial class AchievementViewModel : Abstraction.ViewModel, INav
|
||||
|
||||
protected override void UninitializeOverride()
|
||||
{
|
||||
Archives?.Detach();
|
||||
Archives = default;
|
||||
using (Archives?.SuppressSavingToDatabase())
|
||||
{
|
||||
Archives = default;
|
||||
}
|
||||
|
||||
AchievementGoals = default;
|
||||
Achievements = default;
|
||||
}
|
||||
|
||||
[GeneratedRegex("\\d\\.\\d")]
|
||||
|
||||
@@ -82,8 +82,10 @@ internal sealed partial class CultivationViewModel : Abstraction.ViewModel
|
||||
|
||||
protected override void UninitializeOverride()
|
||||
{
|
||||
Projects?.Detach();
|
||||
Projects = default;
|
||||
using (Projects?.SuppressSavingToDatabase())
|
||||
{
|
||||
Projects = default;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCurrentProjectChanged(object? sender, object? e)
|
||||
|
||||
@@ -104,8 +104,10 @@ internal sealed partial class GachaLogViewModel : Abstraction.ViewModel
|
||||
|
||||
protected override void UninitializeOverride()
|
||||
{
|
||||
Archives?.Detach();
|
||||
Archives = default;
|
||||
using (Archives?.SuppressSavingToDatabase())
|
||||
{
|
||||
Archives = default;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnCurrentArchiveChanged(object? sender, object? e)
|
||||
|
||||
Reference in New Issue
Block a user