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"); - } - } }