This commit is contained in:
DismissedLight
2024-06-27 17:24:34 +08:00
parent 7f06b0a07c
commit 00c9417997
38 changed files with 155 additions and 131 deletions

View File

@@ -0,0 +1,28 @@
using System.Net.Http;
namespace Snap.Hutao.Test.BaseClassLibrary;
[TestClass]
public sealed class HttpClientTest
{
[TestMethod]
public void RedirectionHeaderTest()
{
HttpClient httpClient = new(new HttpClientHandler()
{
UseCookies = false,
AllowAutoRedirect = false,
});
using (httpClient)
{
using (HttpRequestMessage request = new(HttpMethod.Get, "https://api.snapgenshin.com/patch/hutao/download"))
{
using (HttpResponseMessage response = httpClient.Send(request))
{
_ = 1;
}
}
}
}
}

View File

@@ -340,13 +340,13 @@
<PackageReference Include="Microsoft.Windows.SDK.BuildTools" Version="10.0.26100.1" />
<PackageReference Include="Microsoft.WindowsAppSDK" Version="1.5.240607001" />
<PackageReference Include="QRCoder" Version="1.5.1" />
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.9.0" />
<PackageReference Include="Quartz.Extensions.DependencyInjection" Version="3.10.0" />
<PackageReference Include="Snap.Discord.GameSDK" Version="1.6.0" />
<PackageReference Include="Snap.Hutao.Deployment.Runtime" Version="1.16.1">
<PackageReference Include="Snap.Hutao.Deployment.Runtime" Version="1.16.3">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="Snap.Hutao.Elevated.Launcher.Runtime" Version="1.2.0">
<PackageReference Include="Snap.Hutao.Elevated.Launcher.Runtime" Version="1.3.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
@@ -624,10 +624,6 @@
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Folder Include="UI\Xaml\View\Card\" />
<Folder Include="UI\Xaml\View\Page\" />
</ItemGroup>
<ItemGroup>
<Page Update="UI\Xaml\Control\ItemIcon.xaml">
<Generator>MSBuild:Compile</Generator>

View File

@@ -3,7 +3,7 @@
namespace Snap.Hutao.UI.Windowing.Abstraction;
internal interface IXamlWindowClosed
internal interface IXamlWindowClosedHandler
{
void OnWindowClosed();
}

View File

@@ -132,7 +132,7 @@ internal sealed class XamlWindowController
subclass?.Dispose();
windowNonRudeHWND?.Dispose();
if (window is IXamlWindowClosed xamlWindowClosed)
if (window is IXamlWindowClosedHandler xamlWindowClosed)
{
xamlWindowClosed.OnWindowClosed();
}

View File

@@ -3,7 +3,7 @@
using Microsoft.UI.Xaml;
using Microsoft.Xaml.Interactivity;
using Snap.Hutao.UI.Xaml.View.Window;
using Snap.Hutao.UI.Xaml.View.Window.WebView2;
namespace Snap.Hutao.UI.Xaml.Behavior.Action;

View File

@@ -17,7 +17,7 @@
xmlns:shuxci="using:Snap.Hutao.UI.Xaml.Control.Image"
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
xmlns:shuxma="using:Snap.Hutao.UI.Xaml.Media.Animation"
xmlns:shuxvw="using:Snap.Hutao.UI.Xaml.View.Window"
xmlns:shuxvww="using:Snap.Hutao.UI.Xaml.View.Window.WebView2"
xmlns:shvco="using:Snap.Hutao.View.Control"
xmlns:shvh="using:Snap.Hutao.ViewModel.Home"
d:DataContext="{d:DesignInstance shvh:AnnouncementViewModel}"
@@ -131,7 +131,7 @@
<mxic:EventTriggerBehavior EventName="Tapped">
<shuxba:ShowWebView2WindowAction>
<shuxba:ShowWebView2WindowAction.ContentProvider>
<shuxvw:AnnouncementWebView2ContentProvider Announcement="{Binding}"/>
<shuxvww:AnnouncementWebView2ContentProvider Announcement="{Binding}"/>
</shuxba:ShowWebView2WindowAction.ContentProvider>
</shuxba:ShowWebView2WindowAction>
</mxic:EventTriggerBehavior>

View File

@@ -16,6 +16,7 @@
xmlns:shuxci="using:Snap.Hutao.UI.Xaml.Control.Image"
xmlns:shuxcp="using:Snap.Hutao.UI.Xaml.Control.Panel"
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
xmlns:shuxvs="using:Snap.Hutao.UI.Xaml.View.Specialized"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvg="using:Snap.Hutao.ViewModel.GachaLog"
d:DataContext="{d:DesignInstance shvg:GachaLogViewModel}"
@@ -308,10 +309,10 @@
Margin="0,16"
MinItemWidth="302"
Spacing="16">
<shvc:StatisticsCard DataContext="{Binding Statistics.AvatarWish}"/>
<shvc:StatisticsCard DataContext="{Binding Statistics.WeaponWish}"/>
<shvc:StatisticsCard DataContext="{Binding Statistics.StandardWish}" ShowUpPull="False"/>
<shvc:StatisticsCard DataContext="{Binding Statistics.ChronicledWish}" ShowUpPull="False"/>
<shuxvs:StatisticsCard DataContext="{Binding Statistics.AvatarWish}"/>
<shuxvs:StatisticsCard DataContext="{Binding Statistics.WeaponWish}"/>
<shuxvs:StatisticsCard DataContext="{Binding Statistics.StandardWish}" ShowUpPull="False"/>
<shuxvs:StatisticsCard DataContext="{Binding Statistics.ChronicledWish}" ShowUpPull="False"/>
</shuxcp:HorizontalEqualPanel>
</ScrollViewer>
</PivotItem>
@@ -489,10 +490,10 @@
<mxi:Interaction.Behaviors>
<shuxb:InvokeCommandOnLoadedBehavior Command="{Binding HutaoCloudStatisticsViewModel.OpenUICommand}"/>
</mxi:Interaction.Behaviors>
<shvc:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.AvatarEvent}"/>
<shvc:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.AvatarEvent2}"/>
<shvc:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.WeaponEvent}"/>
<shvc:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.Chronicled}" Visibility="{Binding Converter={StaticResource EmptyObjectToVisibilityConverter}, FallbackValue=Collapsed}"/>
<shuxvs:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.AvatarEvent}"/>
<shuxvs:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.AvatarEvent2}"/>
<shuxvs:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.WeaponEvent}"/>
<shuxvs:HutaoStatisticsCard DataContext="{Binding HutaoCloudStatisticsViewModel.Statistics.Chronicled}" Visibility="{Binding Converter={StaticResource EmptyObjectToVisibilityConverter}, FallbackValue=Collapsed}"/>
</shuxcp:HorizontalEqualPanel>
</Grid>
</PivotItem>

View File

@@ -12,6 +12,7 @@
xmlns:shuxc="using:Snap.Hutao.UI.Xaml.Control"
xmlns:shuxci="using:Snap.Hutao.UI.Xaml.Control.Image"
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
xmlns:shuxvs="using:Snap.Hutao.UI.Xaml.View.Specialized"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvg="using:Snap.Hutao.ViewModel.Game"
d:DataContext="{d:DesignInstance shvg:LaunchGameViewModel}"
@@ -29,7 +30,7 @@
<DataTemplate x:Key="GameResourceTemplate">
<Border Margin="16,16,16,0" cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Style="{ThemeResource AcrylicBorderCardStyle}">
<shvc:LaunchGameResourceExpander
<shuxvs:LaunchGameResourceExpander
cw:Effects.Shadow="{ThemeResource CompatCardShadow}"
DataContext="{Binding Mode=OneWay}"
Header="{shuxm:ResourceString Name=ViewPageLaunchGameResourceDiffHeader}"/>
@@ -369,7 +370,7 @@
<StackPanel>
<Border Margin="16,16,16,0" cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Style="{ThemeResource AcrylicBorderCardStyle}">
<shvc:LaunchGameResourceExpander
<shuxvs:LaunchGameResourceExpander
cw:Effects.Shadow="{ThemeResource CompatCardShadow}"
DataContext="{Binding GamePackage.PreDownload.Major, Mode=OneWay}"
Header="{shuxm:ResourceString Name=ViewPageLaunchGameResourcePreDownloadHeader}"
@@ -383,7 +384,7 @@
ItemsSource="{Binding GamePackage.PreDownload.Patches, Mode=OneWay}"/>
<Border Margin="16,16,16,0" cw:Effects.Shadow="{ThemeResource CompatCardShadow}">
<Border Style="{ThemeResource AcrylicBorderCardStyle}">
<shvc:LaunchGameResourceExpander
<shuxvs:LaunchGameResourceExpander
cw:Effects.Shadow="{ThemeResource CompatCardShadow}"
DataContext="{Binding GamePackage.Main.Major, Mode=OneWay}"
Header="{shuxm:ResourceString Name=ViewPageLaunchGameResourceLatestHeader}"/>

View File

@@ -15,6 +15,7 @@
xmlns:shuxct="using:Snap.Hutao.UI.Xaml.Control.TextBlock"
xmlns:shuxdc="using:Snap.Hutao.UI.Xaml.Data.Converter"
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
xmlns:shuxvs="using:Snap.Hutao.UI.Xaml.View.Specialized"
xmlns:shvcont="using:Snap.Hutao.View.Control"
xmlns:shvw="using:Snap.Hutao.ViewModel.Wiki"
d:DataContext="{d:DesignInstance Type=shvw:WikiAvatarViewModel}"
@@ -45,7 +46,7 @@
</Style>
</shuxct:DescriptionTextBlock.Resources>
</shuxct:DescriptionTextBlock>
<shvcont:DescParamComboBox
<shuxvs:DescParamComboBox
x:Name="ProudSelector"
Grid.Column="1"
HorizontalAlignment="Stretch"
@@ -56,7 +57,7 @@
</DataTemplate>
<DataTemplate x:Key="PropertyDataTemplate">
<shvcont:DescParamComboBox
<shuxvs:DescParamComboBox
HorizontalAlignment="Stretch"
PreferredSelectedIndex="13"
Source="{Binding Converter={StaticResource PropertyDescriptor}}"/>
@@ -550,7 +551,7 @@
<SolidColorBrush x:Key="SettingsCardBackgroundPointerOver" Color="Transparent"/>
<SolidColorBrush x:Key="SettingsCardBackgroundPressed" Color="Transparent"/>
</Border.Resources>
<shvcont:BaseValueSlider
<shuxvs:BaseValueSlider
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"/>

View File

@@ -14,6 +14,7 @@
xmlns:shuxci="using:Snap.Hutao.UI.Xaml.Control.Image"
xmlns:shuxct="using:Snap.Hutao.UI.Xaml.Control.TextBlock"
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
xmlns:shuxvs="using:Snap.Hutao.UI.Xaml.View.Specialized"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvw="using:Snap.Hutao.ViewModel.Wiki"
d:DataContext="{d:DesignInstance Type=shvw:WikiMonsterViewModel}"
@@ -153,7 +154,7 @@
Opacity="0.7"
TextStyle="{StaticResource CaptionTextBlockStyle}"/>
<clw:TokenView ItemsSource="{Binding Selected.Affixes}" SelectionMode="None"/>
<shvc:BaseValueSlider
<shuxvs:BaseValueSlider
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"
@@ -218,6 +219,6 @@
</cwc:Case>
</cwc:SwitchPresenter>
</Grid>
<shuxc:Loading Style="{ThemeResource DefaultLoadingViewStyle}" IsLoading="{Binding Monsters, Converter={StaticResource EmptyObjectToBoolRevertConverter}}"/>
<shuxc:Loading IsLoading="{Binding Monsters, Converter={StaticResource EmptyObjectToBoolRevertConverter}}" Style="{ThemeResource DefaultLoadingViewStyle}"/>
</Grid>
</shuxc:ScopedPage>

View File

@@ -14,6 +14,7 @@
xmlns:shuxci="using:Snap.Hutao.UI.Xaml.Control.Image"
xmlns:shuxct="using:Snap.Hutao.UI.Xaml.Control.TextBlock"
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
xmlns:shuxvs="using:Snap.Hutao.UI.Xaml.View.Specialized"
xmlns:shvc="using:Snap.Hutao.View.Control"
xmlns:shvw="using:Snap.Hutao.ViewModel.Wiki"
d:DataContext="{d:DesignInstance Type=shvw:WikiWeaponViewModel}"
@@ -25,7 +26,7 @@
<Page.Resources>
<DataTemplate x:Key="PropertyDataTemplate">
<shvc:DescParamComboBox
<shuxvs:DescParamComboBox
HorizontalAlignment="Stretch"
PreferredSelectedIndex="13"
Source="{Binding Converter={StaticResource PropertyDescriptor}}"/>
@@ -315,7 +316,7 @@
</Border>
<TextBlock Text="{Binding Selected.Description}" TextWrapping="Wrap"/>
<shvc:BaseValueSlider
<shuxvs:BaseValueSlider
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"/>

View File

@@ -1,5 +1,5 @@
<UserControl
x:Class="Snap.Hutao.View.Control.BaseValueSlider"
x:Class="Snap.Hutao.UI.Xaml.View.Specialized.BaseValueSlider"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwc="using:CommunityToolkit.WinUI.Controls"

View File

@@ -5,7 +5,7 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.ViewModel.Wiki;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Specialized;
/// <summary>
/// 基础数值滑动条

View File

@@ -1,5 +1,5 @@
<UserControl
x:Class="Snap.Hutao.View.Control.DescParamComboBox"
x:Class="Snap.Hutao.UI.Xaml.View.Specialized.DescParamComboBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwc="using:CommunityToolkit.WinUI.Controls"
@@ -34,9 +34,10 @@
ItemsSource="{x:Bind SelectedItem.Parameters, Mode=OneWay}">
<shuxc:SizeRestrictedContentControl Margin="0,-8">
<ComboBox
x:Name="LevelSelectorComboBox"
x:Name="LevelComboBox"
DisplayMemberPath="Level"
SelectionChanged="OnLevelSelectorComboBoxSelectionChanged"
ItemsSource="{x:Bind Source, Mode=OneWay}"
SelectedItem="{x:Bind SelectedItem, Mode=TwoWay}"
Style="{StaticResource SettingsContentComboBoxStyle}"/>
</shuxc:SizeRestrictedContentControl>
</cwc:SettingsExpander>

View File

@@ -5,20 +5,14 @@ using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Snap.Hutao.Model.Metadata;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Specialized;
/// <summary>
/// 描述参数组合框
/// </summary>
[HighQuality]
[DependencyProperty("Source", typeof(List<LevelParameters<string, ParameterDescription>>), default!, nameof(OnSourceChanged))]
[DependencyProperty("SelectedItem", typeof(LevelParameters<string, ParameterDescription>), default!)]
[DependencyProperty("PreferredSelectedIndex", typeof(int), 0)]
internal sealed partial class DescParamComboBox : UserControl
{
/// <summary>
/// 构造一个新的描述参数组合框
/// </summary>
public DescParamComboBox()
{
InitializeComponent();
@@ -30,16 +24,9 @@ internal sealed partial class DescParamComboBox : UserControl
{
if (args.NewValue != args.OldValue && args.NewValue is List<LevelParameters<string, ParameterDescription>> list)
{
LevelParameters<string, ParameterDescription>? target = list.ElementAtOrDefault(descParamComboBox.PreferredSelectedIndex) ?? list.LastOrDefault();
descParamComboBox.SelectedItem = target;
descParamComboBox.LevelSelectorComboBox.ItemsSource = list;
descParamComboBox.LevelSelectorComboBox.SelectedItem = target;
descParamComboBox.Bindings.Update();
descParamComboBox.SelectedItem = list.ElementAtOrDefault(descParamComboBox.PreferredSelectedIndex) ?? list.LastOrDefault();
}
}
}
private void OnLevelSelectorComboBoxSelectionChanged(object sender, SelectionChangedEventArgs e)
{
SelectedItem = (LevelParameters<string, ParameterDescription>)((ComboBox)sender).SelectedItem;
}
}

View File

@@ -1,5 +1,5 @@
<UserControl
x:Class="Snap.Hutao.View.Control.HutaoStatisticsCard"
x:Class="Snap.Hutao.UI.Xaml.View.Specialized.HutaoStatisticsCard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cw="using:CommunityToolkit.WinUI"

View File

@@ -3,7 +3,7 @@
using Microsoft.UI.Xaml.Controls;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Specialized;
/// <summary>
/// 胡桃云祈愿统计卡片
@@ -14,4 +14,4 @@ internal sealed partial class HutaoStatisticsCard : UserControl
{
InitializeComponent();
}
}
}

View File

@@ -1,5 +1,5 @@
<cwc:SettingsExpander
x:Class="Snap.Hutao.View.Control.LaunchGameResourceExpander"
x:Class="Snap.Hutao.UI.Xaml.View.Specialized.LaunchGameResourceExpander"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwc="using:CommunityToolkit.WinUI.Controls"

View File

@@ -3,7 +3,7 @@
using CommunityToolkit.WinUI.Controls;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Specialized;
/// <summary>
/// 启动游戏资源 Expander

View File

@@ -26,10 +26,10 @@
<StackPanel>
<cwc:Segmented
x:Name="SkillSelectorSegmented"
HorizontalAlignment="Stretch"
ItemTemplate="{StaticResource SkillHeaderTemplate}"
SelectionChanged="OnSkillSelectorSegmentedSelectionChanged"/>
ItemsSource="{x:Bind Skills, Mode=OneWay}"
SelectedItem="{x:Bind Selected, Mode=TwoWay}"/>
<ContentPresenter Content="{x:Bind Selected, Mode=OneWay}" ContentTemplate="{x:Bind ItemTemplate}"/>
</StackPanel>
</UserControl>

View File

@@ -1,7 +1,6 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using CommunityToolkit.WinUI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System.Collections;
@@ -31,15 +30,9 @@ internal sealed partial class SkillPivot : UserControl
{
if (args.OldValue != args.NewValue && args.NewValue as IList is [object target, ..] list)
{
skillPivot.Bindings.Update();
skillPivot.Selected = target;
skillPivot.SkillSelectorSegmented.ItemsSource = list;
skillPivot.SkillSelectorSegmented.SelectedItem = target;
}
}
}
private void OnSkillSelectorSegmentedSelectionChanged(object sender, SelectionChangedEventArgs e)
{
Selected = ((Segmented)sender).SelectedItem;
}
}

View File

@@ -1,5 +1,5 @@
<UserControl
x:Class="Snap.Hutao.View.Control.StatisticsCard"
x:Class="Snap.Hutao.UI.Xaml.View.Specialized.StatisticsCard"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cw="using:CommunityToolkit.WinUI"
@@ -14,6 +14,7 @@
xmlns:shuxdc="using:Snap.Hutao.UI.Xaml.Data.Converter"
xmlns:shuxdcs="using:Snap.Hutao.UI.Xaml.Data.Converter.Specialized"
xmlns:shuxm="using:Snap.Hutao.UI.Xaml.Markup"
xmlns:shuxvs="using:Snap.Hutao.UI.Xaml.View.Specialized"
xmlns:shvcont="using:Snap.Hutao.View.Control"
xmlns:shvg="using:Snap.Hutao.ViewModel.GachaLog"
cw:Effects.Shadow="{ThemeResource CompatCardShadow}"
@@ -226,7 +227,7 @@
<MenuFlyoutSeparator Grid.Column="2"/>
</Grid>
<shvcont:StatisticsSegmented
<shuxvs:StatisticsSegmented
x:Name="StatisticsSegmented"
Margin="0,12,0,0"
HorizontalAlignment="Stretch"
@@ -415,4 +416,4 @@
</Grid>
</UserControl>
</UserControl>

View File

@@ -4,7 +4,7 @@
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Specialized;
/// <summary>
/// 统计卡片

View File

@@ -1,5 +1,5 @@
<cwc:Segmented
x:Class="Snap.Hutao.View.Control.StatisticsSegmented"
x:Class="Snap.Hutao.UI.Xaml.View.Specialized.StatisticsSegmented"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cwc="using:CommunityToolkit.WinUI.Controls"
@@ -10,5 +10,4 @@
mc:Ignorable="d">
<cwc:SegmentedItem Content="{shuxm:ResourceString Name=ViewControlStatisticsSegmentedItemContentStatistics}" Icon="{shuxm:FontIcon Glyph=&#xE9D2;}"/>
<cwc:SegmentedItem Content="{shuxm:ResourceString Name=ViewControlStatisticsSegmentedItemContentProportion}" Icon="{shuxm:FontIcon Glyph=&#xEB05;}"/>
</cwc:Segmented>
</cwc:Segmented>

View File

@@ -5,7 +5,7 @@ using CommunityToolkit.WinUI.Controls;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Specialized;
[DependencyProperty("IsPredictPullAvailable", typeof(bool), false, nameof(OnIsPredictPullAvailableChanged))]
internal sealed partial class StatisticsSegmented : Segmented

View File

@@ -4,13 +4,15 @@
using Microsoft.UI.Xaml;
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.UI.Xaml.Control.Theme;
using Snap.Hutao.UI.Xaml.View.Window.WebView2;
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
using System.Collections.Frozen;
using System.Text;
using System.Text.RegularExpressions;
using Windows.Graphics;
using Windows.System;
namespace Snap.Hutao.UI.Xaml.View.Window;
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
[DependencyProperty("Announcement", typeof(Announcement))]
internal sealed partial class AnnouncementWebView2ContentProvider : DependencyObject, IWebView2ContentProvider
@@ -39,7 +41,7 @@ internal sealed partial class AnnouncementWebView2ContentProvider : DependencyOb
public CoreWebView2? CoreWebView2 { get; set; }
public async ValueTask LoadAsync(CancellationToken token)
public async ValueTask InitializeAsync(CancellationToken token)
{
ArgumentNullException.ThrowIfNull(CoreWebView2);
@@ -65,6 +67,18 @@ internal sealed partial class AnnouncementWebView2ContentProvider : DependencyOb
}
}
public RectInt32 InitializePosition(RectInt32 parentRect)
{
// Parent Window can never be so small
// if (parentRect.Width < 96 || parentRect.Height < 96)
// {
// return parentRect;
// }
// Shrink 48 px on each side
return new RectInt32(parentRect.X + 48, parentRect.Y + 48, parentRect.Width - 96, parentRect.Height - 96);
}
[GeneratedRegex(" style=\"(?!\")*?vertical-align:middle;\"")]
private static partial Regex StyleRegex();

View File

@@ -5,11 +5,11 @@ using Microsoft.Web.WebView2.Core;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Bridge;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
internal interface IWebViewerSource
internal interface IJSBridgeUriSource
{
MiHoYoJSBridge CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid);
MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid);
string GetSource(UserAndUid userAndUid);
}

View File

@@ -3,8 +3,9 @@
using Microsoft.UI.Xaml;
using Microsoft.Web.WebView2.Core;
using Windows.Graphics;
namespace Snap.Hutao.UI.Xaml.View.Window;
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
internal interface IWebView2ContentProvider
{
@@ -12,7 +13,9 @@ internal interface IWebView2ContentProvider
CoreWebView2? CoreWebView2 { get; set; }
ValueTask LoadAsync(CancellationToken token);
ValueTask InitializeAsync(CancellationToken token);
RectInt32 InitializePosition(RectInt32 parentRect);
void Unload();
}

View File

@@ -3,18 +3,19 @@
using Microsoft.UI.Xaml;
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.UI.Xaml.View.Window.WebView2;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Bridge;
namespace Snap.Hutao.View.Control;
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
[DependencyProperty("ChineseSource", typeof(string))]
[DependencyProperty("OverseaSource", typeof(string))]
internal sealed partial class StaticWebview2ViewerSource : DependencyObject, IWebViewerSource
internal sealed partial class StaticJSBridgeUriSource : DependencyObject, IJSBridgeUriSource
{
public MiHoYoJSBridge CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
public MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
{
return serviceProvider.CreateInstance<MiHoYoJSBridge>(coreWebView2, userAndUid);
return ActivatorUtilities.CreateInstance<MiHoYoJSBridgeFacade>(serviceProvider, coreWebView2, userAndUid);
}
public string GetSource(UserAndUid userAndUid)

View File

@@ -1,5 +1,5 @@
<Window
x:Class="Snap.Hutao.UI.Xaml.View.Window.WebView2Window"
x:Class="Snap.Hutao.UI.Xaml.View.Window.WebView2.WebView2Window"
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"

View File

@@ -12,37 +12,42 @@ using Snap.Hutao.Win32.Foundation;
using Snap.Hutao.Win32.UI.WindowsAndMessaging;
using static Snap.Hutao.Win32.User32;
namespace Snap.Hutao.UI.Xaml.View.Window;
namespace Snap.Hutao.UI.Xaml.View.Window.WebView2;
[SuppressMessage("", "CA1001")]
internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWindowExtendContentIntoTitleBar, IXamlWindowClosed
internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWindowExtendContentIntoTitleBar, IXamlWindowClosedHandler
{
private readonly CancellationTokenSource loadCts = new();
private readonly IServiceScope windowScope;
private readonly IWebView2ContentProvider contentProvider;
private readonly IServiceScope scope;
private readonly AppWindow parentAppWindow;
private readonly HWND parentHWND;
public WebView2Window(WindowId parentWindowId, IWebView2ContentProvider contentProvider)
{
scope = Ioc.Default.CreateScope();
windowScope = Ioc.Default.CreateScope();
parentHWND = Win32Interop.GetWindowFromWindowId(parentWindowId);
parentAppWindow = AppWindow.GetFromWindowId(parentWindowId);
// Make sure this window has a parent window before we make modal
SetWindowLongPtrW(this.GetWindowHandle(), WINDOW_LONG_PTR_INDEX.GWLP_HWNDPARENT, parentHWND);
if (AppWindow.Presenter is OverlappedPresenter presenter)
{
presenter.IsModal = true;
presenter.IsResizable = false;
presenter.IsMaximizable = false;
}
this.contentProvider = contentProvider;
InitializeComponent();
WebView.Loaded += OnWebViewLoaded;
WebView.Unloaded += OnWebViewUnloaded;
this.InitializeController(scope.ServiceProvider);
this.InitializeController(windowScope.ServiceProvider);
}
public FrameworkElement TitleBarAccess { get => TitleArea; }
@@ -51,14 +56,16 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
{
EnableWindow(parentHWND, false);
base.Activate();
AppWindow.MoveAndResize(parentAppWindow.GetRect());
AppWindow.MoveAndResize(contentProvider.InitializePosition(parentAppWindow.GetRect()));
}
public void OnWindowClosed()
{
EnableWindow(parentHWND, true);
// Reactive parent window
SetForegroundWindow(parentHWND);
scope.Dispose();
windowScope.Dispose();
}
private void OnWebViewLoaded(object sender, RoutedEventArgs e)
@@ -71,7 +78,7 @@ internal sealed partial class WebView2Window : Microsoft.UI.Xaml.Window, IXamlWi
WebView.CoreWebView2.DocumentTitleChanged += OnDocumentTitleChanged;
WebView.CoreWebView2.DisableDevToolsForReleaseBuild();
contentProvider.CoreWebView2 = WebView.CoreWebView2;
await contentProvider.LoadAsync(loadCts.Token).ConfigureAwait(false);
await contentProvider.InitializeAsync(loadCts.Token).ConfigureAwait(false);
}
}

View File

@@ -8,6 +8,7 @@ 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;
@@ -15,7 +16,7 @@ using Windows.Foundation;
namespace Snap.Hutao.View.Control;
[DependencyProperty("SourceProvider", typeof(IWebViewerSource))]
[DependencyProperty("SourceProvider", typeof(IJSBridgeUriSource))]
[DependencyProperty("DocumentTitle", typeof(string))]
[DependencyProperty("CanGoBack", typeof(bool))]
internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
@@ -26,7 +27,7 @@ internal partial class WebViewer : UserControl, IRecipient<UserChangedMessage>
private readonly TypedEventHandler<CoreWebView2, object> documentTitleChangedEventHandler;
private readonly TypedEventHandler<CoreWebView2, object> historyChangedEventHandler;
private MiHoYoJSBridge? jsBridge;
private MiHoYoJSBridgeFacade? jsBridge;
private bool isInitializingOrInitialized;
public WebViewer()

View File

@@ -12,10 +12,10 @@ using Snap.Hutao.Service.Metadata;
using Snap.Hutao.Service.Notification;
using Snap.Hutao.Service.User;
using Snap.Hutao.UI.Xaml.Control;
using Snap.Hutao.View.Control;
using Snap.Hutao.UI.Xaml.View.Dialog;
using Snap.Hutao.ViewModel.User;
using System.Collections.ObjectModel;
using Snap.Hutao.UI.Xaml.View.Window.WebView2;
namespace Snap.Hutao.ViewModel.DailyNote;
@@ -46,7 +46,7 @@ internal sealed partial class DailyNoteViewModel : Abstraction.ViewModel
public AppOptions AppOptions { get => appOptions; }
public IWebViewerSource VerifyUrlSource { get; } = new DailyNoteWebViewerSource();
public IJSBridgeUriSource VerifyUrlSource { get; } = new DailyNoteWebViewerSource();
/// <summary>
/// 用户与角色集合

View File

@@ -2,18 +2,18 @@
// Licensed under the MIT license.
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.View.Control;
using Snap.Hutao.UI.Xaml.View.Window.WebView2;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Bridge;
using Snap.Hutao.Web.Hoyolab;
namespace Snap.Hutao.ViewModel.DailyNote;
internal sealed class DailyNoteWebViewerSource : IWebViewerSource
internal sealed class DailyNoteWebViewerSource : IJSBridgeUriSource
{
public MiHoYoJSBridge CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
public MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
{
return serviceProvider.CreateInstance<MiHoYoJSBridge>(coreWebView2, userAndUid);
return serviceProvider.CreateInstance<MiHoYoJSBridgeFacade>(coreWebView2, userAndUid);
}
public string GetSource(UserAndUid userAndUid)

View File

@@ -3,14 +3,14 @@
using Microsoft.UI.Xaml;
using Microsoft.Web.WebView2.Core;
using Snap.Hutao.View.Control;
using Snap.Hutao.UI.Xaml.View.Window.WebView2;
using Snap.Hutao.Web.Bridge;
namespace Snap.Hutao.ViewModel.User;
internal sealed class SignInWebViewerSouce : DependencyObject, IWebViewerSource
internal sealed class SignInWebViewerSouce : DependencyObject, IJSBridgeUriSource
{
public MiHoYoJSBridge CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
public MiHoYoJSBridgeFacade CreateJSBridge(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
{
return userAndUid.User.IsOversea
? serviceProvider.CreateInstance<SignInJSBridgeOversea>(coreWebView2, userAndUid)

View File

@@ -16,16 +16,12 @@ using Snap.Hutao.Web.Hoyolab.Takumi.Auth;
using Snap.Hutao.Web.Response;
using System.Net.Http;
using System.Text;
using Windows.Foundation;
namespace Snap.Hutao.Web.Bridge;
/// <summary>
/// 调用桥
/// </summary>
[HighQuality]
[SuppressMessage("", "CA1001")]
internal class MiHoYoJSBridge
internal class MiHoYoJSBridgeFacade
{
private const string InitializeJsInterfaceScript = """
window.MiHoYoJSInterface = {
@@ -86,40 +82,32 @@ internal class MiHoYoJSBridge
private readonly IServiceProvider serviceProvider;
private readonly ITaskContext taskContext;
private readonly ILogger<MiHoYoJSBridge> logger;
private readonly TypedEventHandler<CoreWebView2, CoreWebView2WebMessageReceivedEventArgs> webMessageReceivedEventHandler;
private readonly TypedEventHandler<CoreWebView2, CoreWebView2DOMContentLoadedEventArgs> domContentLoadedEventHandler;
private readonly TypedEventHandler<CoreWebView2, CoreWebView2NavigationStartingEventArgs> navigationStartingEventHandler;
private readonly ILogger<MiHoYoJSBridgeFacade> logger;
private CoreWebView2 coreWebView2;
public MiHoYoJSBridge(CoreWebView2 coreWebView2, UserAndUid userAndUid)
public MiHoYoJSBridgeFacade(IServiceProvider serviceProvider, CoreWebView2 coreWebView2, UserAndUid userAndUid)
{
// 由于Webview2 的作用域特殊性,我们在此处直接使用根服务
serviceProvider = Ioc.Default;
this.serviceProvider = serviceProvider;
this.coreWebView2 = coreWebView2;
this.userAndUid = userAndUid;
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
logger = serviceProvider.GetRequiredService<ILogger<MiHoYoJSBridge>>();
logger = serviceProvider.GetRequiredService<ILogger<MiHoYoJSBridgeFacade>>();
webMessageReceivedEventHandler = OnWebMessageReceived;
domContentLoadedEventHandler = OnDOMContentLoaded;
navigationStartingEventHandler = OnNavigationStarting;
coreWebView2.WebMessageReceived += webMessageReceivedEventHandler;
coreWebView2.DOMContentLoaded += domContentLoadedEventHandler;
coreWebView2.NavigationStarting += navigationStartingEventHandler;
coreWebView2.WebMessageReceived += OnWebMessageReceived;
coreWebView2.DOMContentLoaded += OnDOMContentLoaded;
coreWebView2.NavigationStarting += OnNavigationStarting;
}
public event Action? ClosePageRequested;
public void Detach()
{
coreWebView2.WebMessageReceived -= webMessageReceivedEventHandler;
coreWebView2.DOMContentLoaded -= domContentLoadedEventHandler;
coreWebView2.NavigationStarting -= navigationStartingEventHandler;
coreWebView2.WebMessageReceived -= OnWebMessageReceived;
coreWebView2.DOMContentLoaded -= OnDOMContentLoaded;
coreWebView2.NavigationStarting -= OnNavigationStarting;
coreWebView2 = default!;
}

View File

@@ -10,7 +10,7 @@ namespace Snap.Hutao.Web.Bridge;
/// 签到页面JS桥
/// </summary>
[HighQuality]
internal sealed class SignInJSBridge : MiHoYoJSBridge
internal sealed class SignInJSBridge : MiHoYoJSBridgeFacade
{
public SignInJSBridge(CoreWebView2 webView, UserAndUid userAndUid)
: base(webView, userAndUid)

View File

@@ -10,7 +10,7 @@ namespace Snap.Hutao.Web.Bridge;
/// HoYoLAB 签到页面JS桥
/// </summary>
[HighQuality]
internal sealed class SignInJSBridgeOversea : MiHoYoJSBridge
internal sealed class SignInJSBridgeOversea : MiHoYoJSBridgeFacade
{
// 移除 请旋转手机 提示所在的HTML元素
private const string RemoveRotationWarningScript = """