diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Behavior/OpenAttachedFlyoutAction.cs b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/OpenAttachedFlyoutAction.cs
new file mode 100644
index 00000000..2f9d4fef
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/Control/Behavior/OpenAttachedFlyoutAction.cs
@@ -0,0 +1,21 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Controls.Primitives;
+using Microsoft.Xaml.Interactivity;
+
+namespace Snap.Hutao.Control.Behavior;
+
+///
+/// 打开附着的浮出控件操作
+///
+internal class OpenAttachedFlyoutAction : DependencyObject, IAction
+{
+ ///
+ public object Execute(object sender, object parameter)
+ {
+ FlyoutBase.ShowAttachedFlyout(sender as FrameworkElement);
+ return null!;
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml
similarity index 64%
rename from src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml
rename to src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml
index b1e4acd2..98b6eb30 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml
@@ -1,21 +1,20 @@
-
-
+
-
-
-
+
-
+
-
+
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs
new file mode 100644
index 00000000..4d1ca8bb
--- /dev/null
+++ b/src/Snap.Hutao/Snap.Hutao/View/Control/AnnouncementContentViewer.xaml.cs
@@ -0,0 +1,164 @@
+// Copyright (c) DGP Studio. All rights reserved.
+// Licensed under the MIT license.
+
+using Microsoft.UI.Xaml;
+using Microsoft.UI.Xaml.Navigation;
+using Microsoft.Web.WebView2.Core;
+using Snap.Hutao.Control;
+using Snap.Hutao.Core;
+using Snap.Hutao.Service.Navigation;
+using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
+using Windows.System;
+
+namespace Snap.Hutao.View.Control;
+
+///
+/// 公告内容页面
+///
+public sealed partial class AnnouncementContentViewer : Microsoft.UI.Xaml.Controls.UserControl
+{
+ // apply in dark mode, Dark theme
+ private const string LightColor1 = "color:rgba(255,255,255,1)";
+ private const string LightColor2 = "color:rgba(238,238,238,1)";
+ private const string LightColor3 = "color:rgba(204,204,204,1)";
+ private const string LightColor4 = "color:rgba(198,196,191,1)";
+ private const string LightColor5 = "color:rgba(170,170,170,1)";
+ private const string LightAccentColor1 = "background-color: rgb(0,40,70)";
+ private const string LightAccentColor2 = "background-color: rgb(1,40,70)";
+
+ // find in content, Light theme
+ private const string DarkColor1 = "color:rgba(0,0,0,1)";
+ private const string DarkColor2 = "color:rgba(17,17,17,1)";
+ private const string DarkColor3 = "color:rgba(51,51,51,1)";
+ private const string DarkColor4 = "color:rgba(57,59,64,1)";
+ private const string DarkColor5 = "color:rgba(85,85,85,1)";
+ private const string DarkAccentColor1 = "background-color: rgb(255, 215, 185);";
+ private const string DarkAccentColor2 = "background-color: rgb(254, 245, 231);";
+
+ // support click open browser.
+ private const string MihoyoSDKDefinition = """
+ window.miHoYoGameJSSDK = {
+ openInBrowser: function(url){ window.chrome.webview.postMessage(url); },
+ openInWebview: function(url){ location.href = url }
+ }
+ """;
+
+ private static readonly DependencyProperty AnnouncementProperty = Property.Depend(nameof(Announcement));
+
+ ///
+ /// 构造一个新的公告窗体
+ ///
+ public AnnouncementContentViewer()
+ {
+ InitializeComponent();
+ }
+
+ ///
+ /// 目标公告
+ ///
+ public Announcement Announcement
+ {
+ get { return (Announcement)GetValue(AnnouncementProperty); }
+ set { SetValue(AnnouncementProperty, value); }
+ }
+
+ private static string? GenerateHtml(Announcement? announcement, ElementTheme theme)
+ {
+ if (announcement == null)
+ {
+ return null;
+ }
+
+ string content = announcement.Content;
+
+ if (string.IsNullOrWhiteSpace(content))
+ {
+ return null;
+ }
+
+ content = content
+ .Replace(@"style=""vertical-align:middle;""", string.Empty)
+ .Replace(@"style=""border:none;vertical-align:middle;""", string.Empty);
+
+ bool isDarkMode = ThemeHelper.IsDarkMode(theme);
+
+ if (isDarkMode)
+ {
+ content = content
+ .Replace(DarkColor5, LightColor5)
+ .Replace(DarkColor4, LightColor4)
+ .Replace(DarkColor3, LightColor3)
+ .Replace(DarkColor2, LightColor2)
+ .Replace(DarkColor1, LightColor1)
+ .Replace(DarkAccentColor1, LightAccentColor1)
+ .Replace(DarkAccentColor2, LightAccentColor2);
+ }
+
+ string document = $$"""
+
+
+
+
+
+
+
+
+ {{announcement.Title}}
+
+
+ {{content}}
+
+
+
+ """;
+
+ return document;
+ }
+
+ private async Task LoadAnnouncementAsync()
+ {
+ try
+ {
+ await WebView.EnsureCoreWebView2Async();
+
+ CoreWebView2Settings settings = WebView.CoreWebView2.Settings;
+ settings.AreBrowserAcceleratorKeysEnabled = false;
+ settings.AreDefaultContextMenusEnabled = false;
+ settings.AreDevToolsEnabled = false;
+ WebView.CoreWebView2.WebMessageReceived += OnWebMessageReceived;
+
+ await WebView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(MihoyoSDKDefinition);
+ }
+ catch (Exception)
+ {
+ return;
+ }
+
+ WebView.NavigateToString(GenerateHtml(Announcement, ActualTheme));
+ }
+
+ private void OnLoaded(object sender, RoutedEventArgs e)
+ {
+ LoadAnnouncementAsync().SafeForget();
+ }
+
+ private void OnWebMessageReceived(CoreWebView2 coreWebView2, CoreWebView2WebMessageReceivedEventArgs args)
+ {
+ string url = args.TryGetWebMessageAsString();
+
+ if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out Uri? uri))
+ {
+ Launcher.LaunchUriAsync(uri).AsTask().SafeForget();
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs
deleted file mode 100644
index eed60ae4..00000000
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs
+++ /dev/null
@@ -1,134 +0,0 @@
-// Copyright (c) DGP Studio. All rights reserved.
-// Licensed under the MIT license.
-
-using Microsoft.UI.Xaml;
-using Microsoft.UI.Xaml.Navigation;
-using Microsoft.Web.WebView2.Core;
-using Snap.Hutao.Core;
-using Snap.Hutao.Service.Navigation;
-using Windows.System;
-
-namespace Snap.Hutao.View.Page;
-
-///
-/// An empty page that can be used on its own or navigated to within a Frame.
-///
-public sealed partial class AnnouncementContentPage : Microsoft.UI.Xaml.Controls.Page
-{
- // apply in dark mode
- private const string LightColor1 = "color:rgba(255,255,255,1)";
- private const string LightColor2 = "color:rgba(238,238,238,1)";
- private const string LightColor3 = "color:rgba(204,204,204,1)";
- private const string LightColor4 = "color:rgba(198,196,191,1)";
- private const string LightColor5 = "color:rgba(170,170,170,1)";
- private const string LightAccentColor1 = "background-color: rgb(0,40,70)";
- private const string LightAccentColor2 = "background-color: rgb(1,40,70)";
-
- // find in content
- private const string DarkColor1 = "color:rgba(0,0,0,1)";
- private const string DarkColor2 = "color:rgba(17,17,17,1)";
- private const string DarkColor3 = "color:rgba(51,51,51,1)";
- private const string DarkColor4 = "color:rgba(57,59,64,1)";
- private const string DarkColor5 = "color:rgba(85,85,85,1)";
- private const string DarkAccentColor1 = "background-color: rgb(255, 215, 185);";
- private const string DarkAccentColor2 = "background-color: rgb(254, 245, 231);";
-
- // support click open browser.
- private const string MihoyoSDKDefinition = """
- window.miHoYoGameJSSDK = {
- openInBrowser: function(url){ window.chrome.webview.postMessage(url); },
- openInWebview: function(url){ location.href = url }
- }
- """;
-
- private string? targetContent;
-
- ///
- /// 构造一个新的公告窗体
- ///
- public AnnouncementContentPage()
- {
- InitializeComponent();
- }
-
- ///
- protected override void OnNavigatedTo(NavigationEventArgs e)
- {
- base.OnNavigatedTo(e);
-
- if (e.Parameter is INavigationData extra)
- {
- targetContent = extra.Data as string;
- LoadAnnouncementAsync(extra).SafeForget();
- }
- }
-
- ///
- protected override void OnNavigatedFrom(NavigationEventArgs e)
- {
- base.OnNavigatedFrom(e);
-
- // WebView.CoreWebView2.Environment.Exit();
- }
-
- private static string? ReplaceForeground(string? rawContent, ElementTheme theme)
- {
- if (string.IsNullOrWhiteSpace(rawContent))
- {
- return rawContent;
- }
-
- bool isDarkMode = ThemeHelper.IsDarkMode(theme);
-
- if (isDarkMode)
- {
- rawContent = rawContent
- .Replace(DarkColor5, LightColor5)
- .Replace(DarkColor4, LightColor4)
- .Replace(DarkColor3, LightColor3)
- .Replace(DarkColor2, LightColor2)
- .Replace(DarkAccentColor1, LightAccentColor1)
- .Replace(DarkAccentColor2, LightAccentColor2);
- }
-
- // wrap a default color body around
- return $@"{rawContent}";
- }
-
- private async Task LoadAnnouncementAsync(INavigationData data)
- {
- try
- {
- await WebView.EnsureCoreWebView2Async();
-
- WebView.CoreWebView2.Settings.AreDefaultContextMenusEnabled = false;
- WebView.CoreWebView2.WebMessageReceived += OnWebMessageReceived;
-
- await WebView.CoreWebView2.AddScriptToExecuteOnDocumentCreatedAsync(MihoyoSDKDefinition);
- }
- catch (Exception ex)
- {
- data.NotifyNavigationException(ex);
- return;
- }
-
- WebView.NavigateToString(ReplaceForeground(targetContent, ActualTheme));
- data.NotifyNavigationCompleted();
- }
-
- private void PageActualThemeChanged(FrameworkElement sender, object args)
- {
- WebView.NavigateToString(ReplaceForeground(targetContent, ActualTheme));
- }
-
- [SuppressMessage("", "VSTHRD100")]
- private async void OnWebMessageReceived(CoreWebView2 coreWebView2, CoreWebView2WebMessageReceivedEventArgs args)
- {
- string url = args.TryGetWebMessageAsString();
-
- if (Uri.TryCreate(url, UriKind.RelativeOrAbsolute, out Uri? uri))
- {
- await Launcher.LaunchUriAsync(uri).AsTask().ConfigureAwait(false);
- }
- }
-}
\ No newline at end of file
diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml
index d85347b9..de69a28a 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml
@@ -15,6 +15,7 @@
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shv="using:Snap.Hutao.ViewModel"
+ xmlns:shvc="using:Snap.Hutao.View.Control"
d:DataContext="{d:DesignInstance shv:AnnouncementViewModel}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
@@ -122,9 +123,21 @@
+
+
+
+
+
+
+
+
-
+
diff --git a/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml b/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml
index 4477c3c9..9031a831 100644
--- a/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml
+++ b/src/Snap.Hutao/Snap.Hutao/View/UserView.xaml
@@ -58,7 +58,6 @@
diff --git a/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs b/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs
index d3562c4b..3c9c25ff 100644
--- a/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs
+++ b/src/Snap.Hutao/Snap.Hutao/ViewModel/AnnouncementViewModel.cs
@@ -2,10 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.Input;
-using Snap.Hutao.Core;
using Snap.Hutao.Service.Abstraction;
-using Snap.Hutao.Service.Navigation;
-using Snap.Hutao.View.Page;
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
namespace Snap.Hutao.ViewModel;
@@ -29,7 +26,6 @@ internal class AnnouncementViewModel : Abstraction.ViewModel
this.announcementService = announcementService;
OpenUICommand = new AsyncRelayCommand(OpenUIAsync);
- OpenAnnouncementUICommand = new RelayCommand(OpenAnnouncementUI);
}
///
@@ -46,11 +42,6 @@ internal class AnnouncementViewModel : Abstraction.ViewModel
///
public ICommand OpenUICommand { get; }
- ///
- /// 打开公告UI触发的命令
- ///
- public ICommand OpenAnnouncementUICommand { get; }
-
private async Task OpenUIAsync()
{
try
@@ -61,18 +52,4 @@ internal class AnnouncementViewModel : Abstraction.ViewModel
{
}
}
-
- private void OpenAnnouncementUI(string? content)
- {
- if (WebView2Helper.IsSupported)
- {
- INavigationService navigationService = Ioc.Default.GetRequiredService();
- navigationService.Navigate(data: new NavigationExtra(content));
- }
- else
- {
- IInfoBarService infoBarService = Ioc.Default.GetRequiredService();
- infoBarService.Warning("尚未安装 WebView2 Runtime");
- }
- }
}