From 93da7cdac4358460397e10233b5349092eeb528e Mon Sep 17 00:00:00 2001 From: DismissedLight <1686188646@qq.com> Date: Thu, 14 Jul 2022 22:44:47 +0800 Subject: [PATCH] update avatar page style --- README.md | 2 +- src/Snap.Hutao/Snap.Hutao/App.xaml.cs | 2 + .../Database/AppDbContextDesignTimeFactory.cs | 7 +- .../Context/FileSystem/FileSystemContext.cs | 33 +- .../Backdroping/BackbdropFallBackBehavior.cs | 20 - .../Control/Backdroping/SystemBackdrop.cs | 39 +- .../Snap.Hutao/Control/BindingProxy.cs | 8 +- .../Snap.Hutao/Control/Image/CachedImage.cs | 11 +- .../Control/Text/DescriptionTextBlock.cs | 101 ++++ .../Extension/EnumerableExtensions.cs | 47 +- .../Snap.Hutao/Factory/PickerFactory.cs | 2 +- src/Snap.Hutao/Snap.Hutao/IocConfiguration.cs | 1 - .../Snap.Hutao/Model/Entity/User.cs | 7 - .../Model/Metadata/Avatar/DescParam.cs | 2 +- .../Model/Metadata/Avatar/FetterInfo.cs | 21 +- ...conConverter.cs => AvatarIconConverter.cs} | 2 +- ...onverter.cs => AvatarSideIconConverter.cs} | 2 +- .../Metadata/Converter/DescParamDescriptor.cs | 115 ++++ .../Converter/ElementNameIconConverter.cs | 38 ++ .../Metadata/Converter/QualityConverter.cs | 2 +- .../Converter/WeaponTypeIconConverter.cs | 37 ++ .../Snap.Hutao/Model/Metadata/LevelParam.cs | 5 +- .../Snap.Hutao/Model/Metadata/PropertyInfo.cs | 2 +- .../Snap.Hutao/Package.appxmanifest | 2 +- src/Snap.Hutao/Snap.Hutao/Program.cs | 2 +- .../{ => Metadata}/IMetadataInitializer.cs | 0 .../IMetadataService.cs | 7 - .../Service/{ => Metadata}/MetadataService.cs | 102 ++-- ...INavigationExtra.cs => INavigationData.cs} | 2 +- .../Service/Navigation/NavigationExtra.cs | 2 +- .../Service/Navigation/NavigationService.cs | 30 +- .../Snap.Hutao/Service/User/IUserService.cs | 2 +- .../Snap.Hutao/Service/User/UserService.cs | 3 +- src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj | 6 - .../Snap.Hutao/View/Control/ItemIcon.xaml | 6 +- .../Snap.Hutao/View/Helper/NavHelper.cs | 8 +- src/Snap.Hutao/Snap.Hutao/View/MainView.xaml | 8 +- .../View/Page/AchievementPage.xaml.cs | 13 + .../View/Page/AnnouncementContentPage.xaml.cs | 4 +- .../View/Page/AnnouncementPage.xaml | 4 +- .../View/Page/AnnouncementPage.xaml.cs | 13 + .../Snap.Hutao/View/Page/SettingPage.xaml.cs | 13 + .../Snap.Hutao/View/Page/WelcomePage.xaml | 16 - .../Snap.Hutao/View/Page/WelcomePage.xaml.cs | 18 - .../Snap.Hutao/View/Page/WikiAvatarPage.xaml | 548 +++++++++++++++--- .../View/Page/WikiAvatarPage.xaml.cs | 13 + src/Snap.Hutao/Snap.Hutao/View/UserView.xaml | 20 +- .../ViewModel/AnnouncementViewModel.cs | 23 +- .../Snap.Hutao/ViewModel/SettingViewModel.cs | 1 - .../Snap.Hutao/ViewModel/UserViewModel.cs | 47 +- .../Snap.Hutao/Web/Hutao/HutaoClient.cs | 41 -- 51 files changed, 1017 insertions(+), 443 deletions(-) delete mode 100644 src/Snap.Hutao/Snap.Hutao/Control/Backdroping/BackbdropFallBackBehavior.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Control/Text/DescriptionTextBlock.cs rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/{IconConverter.cs => AvatarIconConverter.cs} (92%) rename src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/{SideIconConverter.cs => AvatarSideIconConverter.cs} (92%) create mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescParamDescriptor.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ElementNameIconConverter.cs create mode 100644 src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/WeaponTypeIconConverter.cs rename src/Snap.Hutao/Snap.Hutao/Service/{ => Metadata}/IMetadataInitializer.cs (100%) rename src/Snap.Hutao/Snap.Hutao/Service/{Abstraction => Metadata}/IMetadataService.cs (91%) rename src/Snap.Hutao/Snap.Hutao/Service/{ => Metadata}/MetadataService.cs (96%) rename src/Snap.Hutao/Snap.Hutao/Service/Navigation/{INavigationExtra.cs => INavigationData.cs} (94%) delete mode 100644 src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml delete mode 100644 src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml.cs diff --git a/README.md b/README.md index 43fe9bcc..035f4979 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,2 @@ # Snap.Hutao -Snap Genshin but WinUI3 +唷,找本堂主有何贵干呀? diff --git a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs index 62cf50bc..ca782daa 100644 --- a/src/Snap.Hutao/Snap.Hutao/App.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/App.xaml.cs @@ -4,6 +4,7 @@ using CommunityToolkit.Mvvm.Messaging; using Microsoft.Extensions.DependencyInjection; using Microsoft.UI.Xaml; +using Microsoft.VisualStudio.Threading; using Microsoft.Windows.AppLifecycle; using Snap.Hutao.Core.Logging; using Snap.Hutao.Extension; @@ -68,6 +69,7 @@ public partial class App : Application Window = Ioc.Default.GetRequiredService(); Window.Activate(); + logger.LogInformation("Image cache folder : {folder}", Windows.Storage.ApplicationData.Current.TemporaryFolder.Path); if (Ioc.Default.GetRequiredService() is IMetadataInitializer initializer) { initializer.InitializeInternalAsync().SafeForget(); diff --git a/src/Snap.Hutao/Snap.Hutao/Context/Database/AppDbContextDesignTimeFactory.cs b/src/Snap.Hutao/Snap.Hutao/Context/Database/AppDbContextDesignTimeFactory.cs index 774fe791..2338e28c 100644 --- a/src/Snap.Hutao/Snap.Hutao/Context/Database/AppDbContextDesignTimeFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Context/Database/AppDbContextDesignTimeFactory.cs @@ -17,11 +17,6 @@ public class AppDbContextDesignTimeFactory : IDesignTimeDbContextFactory @@ -62,22 +63,6 @@ internal abstract class FileSystemContext } } - /// - /// 检查根目录 - /// - /// 是否创建了路径 - public bool EnsureDirectory() - { - string folder = location.GetPath(); - if (!Directory.Exists(folder)) - { - Directory.CreateDirectory(folder); - return true; - } - - return false; - } - /// /// 检查文件是否存在 /// @@ -170,4 +155,20 @@ internal abstract class FileSystemContext { return File.Create(Locate(file)); } + + /// + /// 检查根目录 + /// + /// 是否创建了路径 + private bool EnsureDirectory() + { + string folder = location.GetPath(); + if (!Directory.Exists(folder)) + { + Directory.CreateDirectory(folder); + return true; + } + + return false; + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Backdroping/BackbdropFallBackBehavior.cs b/src/Snap.Hutao/Snap.Hutao/Control/Backdroping/BackbdropFallBackBehavior.cs deleted file mode 100644 index 678a2b43..00000000 --- a/src/Snap.Hutao/Snap.Hutao/Control/Backdroping/BackbdropFallBackBehavior.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.Control.HostBackdrop; - -/// -/// 回退行为 -/// -public enum BackbdropFallBackBehavior -{ - /// - /// 回退到无 - /// - None, - - /// - /// 回退到亚克力 - /// - Acrylic, -} diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Backdroping/SystemBackdrop.cs b/src/Snap.Hutao/Snap.Hutao/Control/Backdroping/SystemBackdrop.cs index b9286d1b..97ef4e43 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Backdroping/SystemBackdrop.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Backdroping/SystemBackdrop.cs @@ -16,10 +16,9 @@ namespace Snap.Hutao.Control.HostBackdrop; public class SystemBackdrop { private readonly Window window; - private readonly BackbdropFallBackBehavior fallBackBehavior; private WindowsSystemDispatcherQueueHelper? dispatcherQueueHelper; - private ISystemBackdropControllerWithTargets? backdropController; + private MicaController? backdropController; private SystemBackdropConfiguration? configurationSource; /// @@ -27,16 +26,14 @@ public class SystemBackdrop /// /// 窗体 /// 回退行为 - public SystemBackdrop(Window window, BackbdropFallBackBehavior fallBackBehavior = BackbdropFallBackBehavior.Acrylic) + public SystemBackdrop(Window window) { this.window = window; - this.fallBackBehavior = fallBackBehavior; } private enum BackDropType { None, - Acrylic, Mica, } @@ -46,9 +43,7 @@ public class SystemBackdrop /// 是否设置成功 public bool TrySetBackdrop() { - BackDropType targetBackDropType = ResolveBackdropType(); - - if (targetBackDropType == BackDropType.None) + if (!MicaController.IsSupported()) { return false; } @@ -67,12 +62,7 @@ public class SystemBackdrop configurationSource.IsInputActive = true; SetConfigurationSourceTheme(); - backdropController = targetBackDropType switch - { - BackDropType.Mica => new MicaController(), - BackDropType.Acrylic => new DesktopAcrylicController(), - _ => throw Must.NeverHappen(), - }; + backdropController = new MicaController(); ICompositionSupportsSystemBackdrop target = window.As(); backdropController.AddSystemBackdropTarget(target); @@ -82,27 +72,6 @@ public class SystemBackdrop } } - private BackDropType ResolveBackdropType() - { - BackDropType targetBackDropType = BackDropType.None; - if (MicaController.IsSupported()) - { - targetBackDropType = BackDropType.Mica; - } - else - { - if (fallBackBehavior == BackbdropFallBackBehavior.Acrylic) - { - if (DesktopAcrylicController.IsSupported()) - { - targetBackDropType = BackDropType.Acrylic; - } - } - } - - return targetBackDropType; - } - private void WindowActivated(object sender, WindowActivatedEventArgs args) { Must.NotNull(configurationSource!); diff --git a/src/Snap.Hutao/Snap.Hutao/Control/BindingProxy.cs b/src/Snap.Hutao/Snap.Hutao/Control/BindingProxy.cs index ce7e1076..21d9cc24 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/BindingProxy.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/BindingProxy.cs @@ -11,14 +11,14 @@ namespace Snap.Hutao.Control; /// public class BindingProxy : DependencyObject { - private static readonly DependencyProperty DataProperty = Property.Depend(nameof(DataContext)); + private static readonly DependencyProperty DataContextProperty = Property.Depend(nameof(DataContext)); /// /// 数据上下文 /// public object? DataContext { - get => GetValue(DataProperty); - set => SetValue(DataProperty, value); + get => GetValue(DataContextProperty); + set => SetValue(DataContextProperty, value); } -} +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Image/CachedImage.cs b/src/Snap.Hutao/Snap.Hutao/Control/Image/CachedImage.cs index e2a77220..99e3e270 100644 --- a/src/Snap.Hutao/Snap.Hutao/Control/Image/CachedImage.cs +++ b/src/Snap.Hutao/Snap.Hutao/Control/Image/CachedImage.cs @@ -32,16 +32,21 @@ public class CachedImage : ImageEx /// protected override async Task ProvideCachedResourceAsync(Uri imageUri, CancellationToken token) { - BitmapImage image; + BitmapImage? image; try { image = await ImageCache.Instance.GetFromCacheAsync(imageUri, true, token); } + catch (TaskCanceledException) + { + // task was explicitly canceled + throw; + } catch { - // maybe the image is corrupted remove it and re-download + // maybe the image is corrupted, remove it. await ImageCache.Instance.RemoveAsync(imageUri.Enumerate()); - image = await ImageCache.Instance.GetFromCacheAsync(imageUri, false, token); + throw; } // check token state to determine whether the operation should be canceled. diff --git a/src/Snap.Hutao/Snap.Hutao/Control/Text/DescriptionTextBlock.cs b/src/Snap.Hutao/Snap.Hutao/Control/Text/DescriptionTextBlock.cs new file mode 100644 index 00000000..4dbd84be --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Control/Text/DescriptionTextBlock.cs @@ -0,0 +1,101 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. +// some part of this file came from: +// https://github.com/xunkong/desktop/tree/main/src/Desktop/Desktop/Pages/CharacterInfoPage.xaml.cs + +using Microsoft.UI.Xaml; +using Microsoft.UI.Xaml.Controls; +using Microsoft.UI.Xaml.Documents; +using Microsoft.UI.Xaml.Media; +using Snap.Hutao.Core; +using System.Linq; +using System.Text.RegularExpressions; +using Windows.UI; + +namespace Snap.Hutao.Control.Text; + +/// +/// 专用于呈现描述文本的文本块 +/// +public class DescriptionTextBlock : ContentControl +{ + private static readonly DependencyProperty DescriptionProperty = + Property.Depend(nameof(Description), string.Empty, OnDescriptionChanged); + + /// + /// 构造一个新的呈现描述文本的文本块 + /// + public DescriptionTextBlock() + { + Content = new TextBlock(); + } + + /// + /// 可绑定的描述文本 + /// + public string Description + { + get => (string)GetValue(DescriptionProperty); + set => SetValue(DescriptionProperty, value); + } + + private static void OnDescriptionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + TextBlock text = (TextBlock)((DescriptionTextBlock)d).Content; + text.Inlines.Clear(); + + string[] lines = ((string)e.NewValue).Split('\n'); + foreach (string line in lines) + { + MatchCollection matches = Regex.Matches(line, @"]+)>([^<]+)"); + string left, right = line; + + foreach (Match match in matches) + { + string matched = match.Groups[0].Value; + int matchPosition = right.IndexOf(matched); + left = right[..matchPosition]; + right = right[(matchPosition + matched.Length)..]; + + if (!string.IsNullOrWhiteSpace(left)) + { + text.Inlines.Add(new Run { Text = left }); + } + + string hexColor = match.Groups[1].Value; + string content = match.Groups[2].Value; + + text.Inlines.Add(new Run { Text = content, Foreground = GetSolidColorBrush(hexColor[..7]) }); + } + + if (!string.IsNullOrWhiteSpace(right)) + { + if (right.Contains("")) + { + string italic = right.Replace("", string.Empty).Replace("", string.Empty); + text.Inlines.Add(new Run { Text = italic, FontStyle = Windows.UI.Text.FontStyle.Italic }); + } + else + { + text.Inlines.Add(new Run { Text = right }); + } + } + + text.Inlines.Add(new LineBreak()); + } + + if (text.Inlines.LastOrDefault() is LineBreak newline) + { + text.Inlines.Remove(newline); + } + } + + private static SolidColorBrush GetSolidColorBrush(string hex) + { + hex = hex.Replace("#", string.Empty); + byte r = (byte)Convert.ToUInt32(hex.Substring(0, 2), 16); + byte g = (byte)Convert.ToUInt32(hex.Substring(2, 2), 16); + byte b = (byte)Convert.ToUInt32(hex.Substring(4, 2), 16); + return new SolidColorBrush(Color.FromArgb(255, r, g, b)); + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtensions.cs b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtensions.cs index 3863aa25..26c749b8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtensions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Extension/EnumerableExtensions.cs @@ -12,7 +12,7 @@ namespace Snap.Hutao.Extension; public static class EnumerableExtensions { /// - /// 将源转换为仅包含单个元素的集合 + /// 将源转换为仅包含单个元素的枚举 /// /// 源的类型 /// 源 @@ -79,51 +79,6 @@ public static class EnumerableExtensions return source.FirstOrDefault(predicate) ?? source.FirstOrDefault(); } - /// - /// 将二维可枚举对象一维化 - /// - /// 源类型 - /// 源 - /// 扁平的对象 - public static IEnumerable Flatten(this IEnumerable> source) - { - return source.SelectMany(x => x); - } - - /// - /// 对集合中的每个物品执行指定的操作 - /// - /// 集合类型 - /// 集合 - /// 指定的操作 - /// 修改后的集合 - public static IEnumerable ForEach(this IEnumerable source, Action action) - { - foreach (TSource item in source) - { - action(item); - } - - return source; - } - - /// - /// 对集合中的每个物品执行指定的操作 - /// - /// 集合类型 - /// 集合 - /// 指定的操作 - /// 修改后的集合 - public static async Task> ForEachAsync(this IEnumerable source, Func func) - { - foreach (TSource item in source) - { - await func(item); - } - - return source; - } - /// /// 表示一个对 类型的计数器 /// diff --git a/src/Snap.Hutao/Snap.Hutao/Factory/PickerFactory.cs b/src/Snap.Hutao/Snap.Hutao/Factory/PickerFactory.cs index d890e524..42cc6e1f 100644 --- a/src/Snap.Hutao/Snap.Hutao/Factory/PickerFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Factory/PickerFactory.cs @@ -8,7 +8,7 @@ using WinRT.Interop; namespace Snap.Hutao.Factory; /// -[Injection(InjectAs.Transient)] +[Injection(InjectAs.Transient, typeof(IPickerFactory))] internal class PickerFactory : IPickerFactory { private readonly MainWindow mainWindow; diff --git a/src/Snap.Hutao/Snap.Hutao/IocConfiguration.cs b/src/Snap.Hutao/Snap.Hutao/IocConfiguration.cs index 1c3eb592..dda74bf2 100644 --- a/src/Snap.Hutao/Snap.Hutao/IocConfiguration.cs +++ b/src/Snap.Hutao/Snap.Hutao/IocConfiguration.cs @@ -42,7 +42,6 @@ internal static class IocConfiguration public static IServiceCollection AddDatebase(this IServiceCollection services) { MyDocumentContext myDocument = new(new()); - myDocument.EnsureDirectory(); string dbFile = myDocument.Locate("Userdata.db"); string sqlConnectionString = $"Data Source={dbFile}"; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs index 442e45ab..570f2f17 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/User.cs @@ -66,12 +66,6 @@ public class User : Observable private set => Set(ref selectedUserGameRole, value); } - /// - /// 移除命令 - /// - [NotMapped] - public ICommand? RemoveCommand { get; set; } - /// /// 复制Cookie命令 /// @@ -126,7 +120,6 @@ public class User : Observable } CopyCookieCommand = new RelayCommand(CopyCookie); - Must.NotNull(RemoveCommand!); UserInfo = await userClient .GetUserFullInfoAsync(this, token) diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/DescParam.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/DescParam.cs index 452982c5..52157c4b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/DescParam.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/DescParam.cs @@ -18,5 +18,5 @@ public class DescParam /// /// 参数 /// - public IEnumerable> Parameters { get; set; } = default!; + public IEnumerable> Parameters { get; set; } = default!; } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs index e7487d0e..93631b6e 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Avatar/FetterInfo.cs @@ -40,26 +40,27 @@ public class FetterInfo /// public int BirthDay { get; set; } + /// + /// 格式化的生日日期 + /// + public string BirthFormatted + { + get + { + return $"{BirthMonth} 月 {BirthDay} 日"; + } + } + /// /// 神之眼属性-前 /// public string VisionBefore { get; set; } = default!; - /// - /// 神之眼属性-后 - /// - public string VisionAfter { get; set; } = default!; - /// /// 命座-前 /// public string ConstellationBefore { get; set; } = default!; - /// - /// 命座-后 - /// - public string ConstellationAfter { get; set; } = default!; - /// /// 中文CV /// diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/IconConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/AvatarIconConverter.cs similarity index 92% rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/IconConverter.cs rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/AvatarIconConverter.cs index e2095dc9..c3fa3dee 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/IconConverter.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/AvatarIconConverter.cs @@ -8,7 +8,7 @@ namespace Snap.Hutao.Model.Metadata.Converter; /// /// 角色头像转换器 /// -internal class IconConverter : IValueConverter +internal class AvatarIconConverter : IValueConverter { private const string BaseUrl = "https://upload-bbs.mihoyo.com/game_record/genshin/character_icon/{0}.png"; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/SideIconConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/AvatarSideIconConverter.cs similarity index 92% rename from src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/SideIconConverter.cs rename to src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/AvatarSideIconConverter.cs index ef595504..be2ae510 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/SideIconConverter.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/AvatarSideIconConverter.cs @@ -8,7 +8,7 @@ namespace Snap.Hutao.Model.Metadata.Converter; /// /// 角色侧面头像转换器 /// -internal class SideIconConverter : IValueConverter +internal class AvatarSideIconConverter : IValueConverter { private const string BaseUrl = "https://upload-bbs.mihoyo.com/game_record/genshin/character_side_icon/{0}.png"; diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescParamDescriptor.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescParamDescriptor.cs new file mode 100644 index 00000000..ead0aad4 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/DescParamDescriptor.cs @@ -0,0 +1,115 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Microsoft.UI.Xaml.Data; +using Snap.Hutao.Model.Metadata.Avatar; +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + +namespace Snap.Hutao.Model.Metadata.Converter; + +/// +/// 描述参数解析器 +/// +internal class DescParamDescriptor : IValueConverter +{ + /// + public object Convert(object value, Type targetType, object parameter, string language) + { + DescParam descParam = (DescParam)value; + IEnumerable parsedDescriptions = descParam.Descriptions.Select(desc => + { + string[] parts = desc.Split('|', 2); + return new DescFormat(parts[0], parts[1]); + }); + + IList> parameters = descParam.Parameters + .Select(param => + { + IList parameters = GetFormattedParameters(parsedDescriptions, param.Parameters); + parameters.Insert(0, param.Level.ToString()); + return parameters; + }) + .ToList(); + + List descList = parsedDescriptions.Select(p => p.Description).ToList(); + descList.Insert(0, "等级"); + return new DescParamInternal(descList, parameters); + } + + /// + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw Must.NeverHappen(); + } + + private IList GetFormattedParameters(IEnumerable formats, IList param) + { + List results = new(); + foreach (DescFormat descFormat in formats) + { + string format = descFormat.Format; + string resultFormatted = Regex.Replace(format, @"{param\d+.*?}", match => EvaluateMatch(match, param)); + results.Add(resultFormatted); + } + + return results; + } + + private string EvaluateMatch(Match match, IList param) + { + if (match.Success) + { + string[] parts = match.Value[1..^1].Split(':', 2); + + int index = int.Parse(parts[0][5..]) - 1; + if (parts[1] == "I") + { + return ((int)param[index]).ToString(); + } + + if (parts[1] == "F1P") + { + return string.Format("{0:P1}", param[index]); + } + + if (parts[1] == "F2P") + { + return string.Format("{0:P2}", param[index]); + } + + return string.Format($"{{0:{parts[1]}}}", param[index]); + } + else + { + return string.Empty; + } + } + + private class DescFormat + { + public DescFormat(string description, string format) + { + Description = description; + Format = format; + } + + public string Description { get; set; } + + public string Format { get; set; } + } + + private class DescParamInternal + { + public DescParamInternal(IList descriptions, IList> parameters) + { + Descriptions = descriptions; + Parameters = parameters; + } + + public IList Descriptions { get; set; } + + public IList> Parameters { get; set; } + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ElementNameIconConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ElementNameIconConverter.cs new file mode 100644 index 00000000..95c34619 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/ElementNameIconConverter.cs @@ -0,0 +1,38 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Microsoft.UI.Xaml.Data; + +namespace Snap.Hutao.Model.Metadata.Converter; + +/// +/// 元素名称图标转换器 +/// +internal class ElementNameIconConverter : IValueConverter +{ + private const string BaseUrl = "https://static.snapgenshin.com/IconElement/UI_Icon_Element_{0}.png"; + + /// + public object Convert(object value, Type targetType, object parameter, string language) + { + string element = (string)value switch + { + "雷" => "Electric", + "火" => "Fire", + "草" => "Grass", + "冰" => "Ice", + "岩" => "Rock", + "水" => "Water", + "风" => "Wind", + _ => throw Must.NeverHappen(), + }; + + return new Uri(string.Format(BaseUrl, element)); + } + + /// + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw Must.NeverHappen(); + } +} diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs index dad9776d..0e693a96 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/QualityConverter.cs @@ -30,4 +30,4 @@ internal class QualityConverter : IValueConverter { throw Must.NeverHappen(); } -} \ No newline at end of file +} diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/WeaponTypeIconConverter.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/WeaponTypeIconConverter.cs new file mode 100644 index 00000000..8f25be85 --- /dev/null +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/Converter/WeaponTypeIconConverter.cs @@ -0,0 +1,37 @@ +// Copyright (c) DGP Studio. All rights reserved. +// Licensed under the MIT license. + +using Microsoft.UI.Xaml.Data; +using Snap.Hutao.Model.Intrinsic; + +namespace Snap.Hutao.Model.Metadata.Converter; + +/// +/// 元素名称图标转换器 +/// +internal class WeaponTypeIconConverter : IValueConverter +{ + private const string BaseUrl = "https://static.snapgenshin.com/Skill/Skill_A_{0}.png"; + + /// + public object Convert(object value, Type targetType, object parameter, string language) + { + string element = (WeaponType)value switch + { + WeaponType.WEAPON_SWORD_ONE_HAND => "01", + WeaponType.WEAPON_BOW => "02", + WeaponType.WEAPON_POLE => "03", + WeaponType.WEAPON_CLAYMORE => "04", + WeaponType.WEAPON_CATALYST => "Catalyst_MD", + _ => throw Must.NeverHappen(), + }; + + return new Uri(string.Format(BaseUrl, element)); + } + + /// + public object ConvertBack(object value, Type targetType, object parameter, string language) + { + throw Must.NeverHappen(); + } +} \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/LevelParam.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/LevelParam.cs index 4e0aed69..14eba6bf 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/LevelParam.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/LevelParam.cs @@ -9,7 +9,8 @@ namespace Snap.Hutao.Model.Metadata; /// 等级与参数 /// /// 等级的类型 -public class LevelParam +/// 参数的类型 +public class LevelParam { /// /// 等级 @@ -19,5 +20,5 @@ public class LevelParam /// /// 参数 /// - public IList Parameters { get; set; } = default!; + public IList Parameters { get; set; } = default!; } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/PropertyInfo.cs b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/PropertyInfo.cs index f4263a7d..3d31796d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Metadata/PropertyInfo.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Metadata/PropertyInfo.cs @@ -19,5 +19,5 @@ public class PropertyInfo /// /// 参数 /// - public IEnumerable> Parameters { get; set; } = default!; + public IEnumerable> Parameters { get; set; } = default!; } diff --git a/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest b/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest index 9715356d..1fc6f2d8 100644 --- a/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest +++ b/src/Snap.Hutao/Snap.Hutao/Package.appxmanifest @@ -9,7 +9,7 @@ + Version="1.0.11.0" /> 胡桃 diff --git a/src/Snap.Hutao/Snap.Hutao/Program.cs b/src/Snap.Hutao/Snap.Hutao/Program.cs index 8fd06c9a..2bb05a55 100644 --- a/src/Snap.Hutao/Snap.Hutao/Program.cs +++ b/src/Snap.Hutao/Snap.Hutao/Program.cs @@ -24,7 +24,7 @@ public static class Program Application.Start(p => { - DispatcherQueueSynchronizationContext context = new(DispatcherQueue.GetForCurrentThread()); + SynchronizationContext context = new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread()); SynchronizationContext.SetSynchronizationContext(context); _ = new App(); }); diff --git a/src/Snap.Hutao/Snap.Hutao/Service/IMetadataInitializer.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataInitializer.cs similarity index 100% rename from src/Snap.Hutao/Snap.Hutao/Service/IMetadataInitializer.cs rename to src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataInitializer.cs diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/IMetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs similarity index 91% rename from src/Snap.Hutao/Snap.Hutao/Service/Abstraction/IMetadataService.cs rename to src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs index 597ed47b..e5208d3a 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Abstraction/IMetadataService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/IMetadataService.cs @@ -69,11 +69,4 @@ internal interface IMetadataService /// 取消令牌 /// 武器列表 ValueTask> GetWeaponsAsync(CancellationToken token = default); - - /// - /// 异步更新元数据 - /// - /// 取消令牌 - /// 更新是否完成 - Task UpdateMetadataAsync(CancellationToken token = default); } diff --git a/src/Snap.Hutao/Snap.Hutao/Service/MetadataService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs similarity index 96% rename from src/Snap.Hutao/Snap.Hutao/Service/MetadataService.cs rename to src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs index 4056d4ff..18158429 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/MetadataService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Metadata/MetadataService.cs @@ -25,6 +25,7 @@ internal class MetadataService : IMetadataService, IMetadataInitializer, ISuppor { private const string MetaAPIHost = "http://hutao-metadata.snapgenshin.com"; private const string MetaFileName = "Meta.json"; + private readonly IInfoBarService infoBarService; private readonly HttpClient httpClient; private readonly FileSystemContext metadataContext; @@ -78,40 +79,14 @@ internal class MetadataService : IMetadataService, IMetadataInitializer, ISuppor public async Task InitializeInternalAsync(CancellationToken token = default) { logger.LogInformation("元数据初始化开始"); - metadataContext.EnsureDirectory(); - IsInitialized = await UpdateMetadataAsync(token) + IsInitialized = await TryUpdateMetadataAsync(token) .ConfigureAwait(false); initializeCompletionSource.SetResult(); logger.LogInformation("元数据初始化完成"); } - /// - public async Task UpdateMetadataAsync(CancellationToken token = default) - { - IDictionary? metaMd5Map = await httpClient - .GetFromJsonAsync>($"{MetaAPIHost}/{MetaFileName}", options, token) - .ConfigureAwait(false); - - if (metaMd5Map is null) - { - infoBarService.Error("元数据校验文件解析失败"); - return false; - } - - await CheckMetadataAsync(metaMd5Map, token).ConfigureAwait(false); - - using (FileStream metaFileStream = metadataContext.Create(MetaFileName)) - { - await JsonSerializer - .SerializeAsync(metaFileStream, metaMd5Map, options, token) - .ConfigureAwait(false); - } - - return true; - } - /// public ValueTask> GetAchievementGoalsAsync(CancellationToken token = default) { @@ -154,34 +129,30 @@ internal class MetadataService : IMetadataService, IMetadataInitializer, ISuppor return GetMetadataAsync>("Weapon", token); } - private async ValueTask GetMetadataAsync(string fileName, CancellationToken token) - where T : class + private async Task TryUpdateMetadataAsync(CancellationToken token = default) { - Verify.Operation(IsInitialized, "元数据服务尚未初始化,或初始化失败"); - string cacheKey = $"{nameof(MetadataService)}.Cache.{fileName}"; - - if (memoryCache.TryGetValue(cacheKey, out object? value)) - { - return Must.NotNull((value as T)!); - } - - T? result = await JsonSerializer - .DeserializeAsync(metadataContext.OpenRead($"{fileName}.json"), options, token) + // download meta check file + IDictionary? metaMd5Map = await httpClient + .GetFromJsonAsync>($"{MetaAPIHost}/{MetaFileName}", options, token) .ConfigureAwait(false); - return memoryCache.Set(cacheKey, Must.NotNull(result!)); - } - - private async Task GetFileMd5Async(string fileFullName, CancellationToken token) - { - using (FileStream stream = metadataContext.OpenRead(fileFullName)) + if (metaMd5Map is null) { - byte[] bytes = await MD5.Create() - .ComputeHashAsync(stream, token) - .ConfigureAwait(false); - - return Convert.ToHexString(bytes); + infoBarService.Error("元数据校验文件解析失败"); + return false; } + + await CheckMetadataAsync(metaMd5Map, token).ConfigureAwait(false); + + // save metadataFile + using (FileStream metaFileStream = metadataContext.Create(MetaFileName)) + { + await JsonSerializer + .SerializeAsync(metaFileStream, metaMd5Map, options, token) + .ConfigureAwait(false); + } + + return true; } /// @@ -193,6 +164,7 @@ internal class MetadataService : IMetadataService, IMetadataInitializer, ISuppor /// 令牌 private async Task CheckMetadataAsync(IDictionary metaMd5Map, CancellationToken token) { + // TODO: Make this foreach async to imporve speed // enumerate files and compare md5 foreach ((string fileName, string md5) in metaMd5Map) { @@ -215,6 +187,18 @@ internal class MetadataService : IMetadataService, IMetadataInitializer, ISuppor } } + private async Task GetFileMd5Async(string fileFullName, CancellationToken token) + { + using (FileStream stream = metadataContext.OpenRead(fileFullName)) + { + byte[] bytes = await MD5.Create() + .ComputeHashAsync(stream, token) + .ConfigureAwait(false); + + return Convert.ToHexString(bytes); + } + } + private async Task DownloadMetadataAsync(string fileFullName, CancellationToken token) { Stream sourceStream = await httpClient @@ -238,4 +222,22 @@ internal class MetadataService : IMetadataService, IMetadataInitializer, ISuppor logger.LogInformation("{file} 下载完成", fileFullName); } + + private async ValueTask GetMetadataAsync(string fileName, CancellationToken token) + where T : class + { + Verify.Operation(IsInitialized, "元数据服务尚未初始化,或初始化失败"); + string cacheKey = $"{nameof(MetadataService)}.Cache.{fileName}"; + + if (memoryCache.TryGetValue(cacheKey, out object? value)) + { + return Must.NotNull((value as T)!); + } + + T? result = await JsonSerializer + .DeserializeAsync(metadataContext.OpenRead($"{fileName}.json"), options, token) + .ConfigureAwait(false); + + return memoryCache.Set(cacheKey, Must.NotNull(result!)); + } } \ No newline at end of file diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationExtra.cs b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationData.cs similarity index 94% rename from src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationExtra.cs rename to src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationData.cs index 6d286a04..50eb8232 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationExtra.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/INavigationData.cs @@ -6,7 +6,7 @@ namespace Snap.Hutao.Service.Navigation; /// /// 为 提供抽象接口 /// -public interface INavigationExtra +public interface INavigationData { /// /// 数据 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationExtra.cs b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationExtra.cs index 7b120f6f..927d4d6b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationExtra.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationExtra.cs @@ -6,7 +6,7 @@ namespace Snap.Hutao.Service.Navigation; /// /// 导航额外信息 /// -public class NavigationExtra : INavigationExtra, INavigationAwaiter +public class NavigationExtra : INavigationData, INavigationAwaiter { /// /// 任务完成源 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs index 46df5a45..af4cdf57 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/Navigation/NavigationService.cs @@ -7,6 +7,7 @@ using Snap.Hutao.Core.Setting; using Snap.Hutao.Service.Abstraction; using Snap.Hutao.View.Helper; using Snap.Hutao.View.Page; +using System.Collections.Generic; using System.Linq; namespace Snap.Hutao.Service.Navigation; @@ -85,8 +86,7 @@ internal class NavigationService : INavigationService } else { - NavigationViewItem? target = NavigationView.MenuItems - .OfType() + NavigationViewItem? target = EnumerateMenuItems(NavigationView.MenuItems) .SingleOrDefault(menuItem => NavHelper.GetNavigateTo(menuItem) == pageType); NavigationView.SelectedItem = target; @@ -163,6 +163,24 @@ internal class NavigationService : INavigationService NavigationView.IsPaneOpen = LocalSetting.GetValueType(SettingKeys.IsNavPaneOpen, true); } + /// + /// 遍历所有子菜单项 + /// + /// 项列表 + /// 枚举器 + private IEnumerable EnumerateMenuItems(IList items) + { + foreach (NavigationViewItem item in items.OfType()) + { + yield return item; + + foreach (NavigationViewItem subItem in EnumerateMenuItems(item.MenuItems)) + { + yield return subItem; + } + } + } + private void OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args) { Selected = NavigationView?.SelectedItem as NavigationViewItem; @@ -170,8 +188,12 @@ internal class NavigationService : INavigationService ? typeof(SettingPage) : NavHelper.GetNavigateTo(Selected); - INavigationAwaiter navigationAwaiter = new NavigationExtra(NavHelper.GetExtraData(Selected)); - Navigate(Must.NotNull(targetType!), navigationAwaiter, false); + // ignore item that doesn't have nav type specified + if (targetType != null) + { + INavigationAwaiter navigationAwaiter = new NavigationExtra(NavHelper.GetExtraData(Selected)); + Navigate(targetType, navigationAwaiter, false); + } } private void OnBackRequested(NavigationView sender, NavigationViewBackRequestedEventArgs args) diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs index 8a31ef6a..4c741b65 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/User/IUserService.cs @@ -24,7 +24,7 @@ public interface IUserService /// /// 移除用户命令 /// 准备完成的用户信息枚举 - Task> GetInitializedUsersAsync(ICommand removeCommand); + Task> GetInitializedUsersAsync(); /// /// 异步添加用户 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs b/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs index ea8a6a97..8b463e00 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/User/UserService.cs @@ -121,7 +121,7 @@ internal class UserService : IUserService } /// - public async Task> GetInitializedUsersAsync(ICommand removeCommand) + public async Task> GetInitializedUsersAsync() { if (cachedUsers == null) { @@ -133,7 +133,6 @@ internal class UserService : IUserService foreach (User user in cachedUsers) { - user.RemoveCommand = removeCommand; await user .InitializeAsync(userClient, userGameRoleClient) .ConfigureAwait(false); diff --git a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj index b808dfc7..210a974d 100644 --- a/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj +++ b/src/Snap.Hutao/Snap.Hutao/Snap.Hutao.csproj @@ -41,7 +41,6 @@ - @@ -154,11 +153,6 @@ MSBuild:Compile - - - MSBuild:Compile - - MSBuild:Compile diff --git a/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml b/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml index 4d38c999..116256bb 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml @@ -8,10 +8,10 @@ xmlns:shci="using:Snap.Hutao.Control.Image" xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter" mc:Ignorable="d" - Width="64" - Height="64"> + Width="80" + Height="80"> - + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Helper/NavHelper.cs b/src/Snap.Hutao/Snap.Hutao/View/Helper/NavHelper.cs index 7e1ab005..976b33c9 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Helper/NavHelper.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Helper/NavHelper.cs @@ -14,7 +14,7 @@ namespace Snap.Hutao.View.Helper; public sealed class NavHelper { private static readonly DependencyProperty NavigateToProperty = Property.Attach("NavigateTo"); - private static readonly DependencyProperty ExtraDataProperty = Property.Attach("ExtraData"); + private static readonly DependencyProperty ExtraDataProperty = Property.Attach("ExtraData"); /// /// 获取导航项的目标页面类型 @@ -41,9 +41,9 @@ public sealed class NavHelper /// /// 待获取的导航项 /// 目标页面类型的额外数据 - public static INavigationExtra? GetExtraData(NavigationViewItem? item) + public static INavigationData? GetExtraData(NavigationViewItem? item) { - return item?.GetValue(ExtraDataProperty) as INavigationExtra; + return item?.GetValue(ExtraDataProperty) as INavigationData; } /// @@ -51,7 +51,7 @@ public sealed class NavHelper /// /// 待设置的导航项 /// 新的目标页面类型 - public static void SetExtraData(NavigationViewItem item, INavigationExtra value) + public static void SetExtraData(NavigationViewItem item, INavigationData value) { item.SetValue(ExtraDataProperty, value); } diff --git a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml index bc4f3fdb..a8d35926 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/MainView.xaml @@ -12,13 +12,12 @@ 0,48,0,0 - @@ -26,7 +25,8 @@ - + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AchievementPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/AchievementPage.xaml.cs index c4cfb5f9..4a2dc3da 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/AchievementPage.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AchievementPage.xaml.cs @@ -1,7 +1,9 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Microsoft.UI.Xaml.Navigation; using Snap.Hutao.Control.Cancellable; +using Snap.Hutao.Service.Navigation; using Snap.Hutao.ViewModel; namespace Snap.Hutao.View.Page; @@ -19,4 +21,15 @@ public sealed partial class AchievementPage : CancellablePage InitializeWith(); InitializeComponent(); } + + /// + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + if (e.Parameter is INavigationData extra) + { + extra.NotifyNavigationCompleted(); + } + } } diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs index f9d36df9..57ad832b 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementContentPage.xaml.cs @@ -36,14 +36,14 @@ openInWebview: function(url){ location.href = url }}"; { base.OnNavigatedTo(e); - if (e.Parameter is INavigationExtra extra) + if (e.Parameter is INavigationData extra) { targetContent = extra.Data as string; LoadAnnouncementAsync(extra).SafeForget(); } } - private async Task LoadAnnouncementAsync(INavigationExtra extra) + private async Task LoadAnnouncementAsync(INavigationData extra) { try { diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml index d2c5bf77..d3d93806 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/AnnouncementPage.xaml @@ -27,9 +27,7 @@ - + (); InitializeComponent(); } + + /// + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + if (e.Parameter is INavigationData extra) + { + extra.NotifyNavigationCompleted(); + } + } } diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs index 90ff8d72..9f47d33c 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml.cs @@ -1,6 +1,8 @@ // Copyright (c) DGP Studio. All rights reserved. // Licensed under the MIT license. +using Microsoft.UI.Xaml.Navigation; +using Snap.Hutao.Service.Navigation; using Snap.Hutao.ViewModel; namespace Snap.Hutao.View.Page; @@ -18,4 +20,15 @@ public sealed partial class SettingPage : Microsoft.UI.Xaml.Controls.Page DataContext = Ioc.Default.GetRequiredService(); InitializeComponent(); } + + /// + protected override void OnNavigatedTo(NavigationEventArgs e) + { + base.OnNavigatedTo(e); + + if (e.Parameter is INavigationData extra) + { + extra.NotifyNavigationCompleted(); + } + } } diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml deleted file mode 100644 index 5f7fba55..00000000 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml.cs b/src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml.cs deleted file mode 100644 index 3ac10f4e..00000000 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WelcomePage.xaml.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright (c) DGP Studio. All rights reserved. -// Licensed under the MIT license. - -namespace Snap.Hutao.View.Page; - -/// -/// 欢迎页 -/// -public sealed partial class WelcomePage : Microsoft.UI.Xaml.Controls.Page -{ - /// - /// 构造一个新的欢迎页 - /// - public WelcomePage() - { - InitializeComponent(); - } -} diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml index eff27daf..fdca4c1b 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/WikiAvatarPage.xaml @@ -8,6 +8,8 @@ xmlns:mxic="using:Microsoft.Xaml.Interactions.Core" xmlns:mxi="using:Microsoft.Xaml.Interactivity" xmlns:shc="using:Snap.Hutao.Control" + xmlns:shci="using:Snap.Hutao.Control.Image" + xmlns:shct="using:Snap.Hutao.Control.Text" xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter" xmlns:shvc="using:Snap.Hutao.View.Control" xmlns:shv="using:Snap.Hutao.ViewModel" @@ -20,42 +22,166 @@ - + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + OpenPaneLength="200"> + + + - - + - + + + + + + + + - - + + - + @@ -63,23 +189,130 @@ - + + + + + + + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -88,75 +321,209 @@ Header="基础数值" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"> - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + - - - - - - - - - - - - + VerticalScrollMode="Disabled" + HorizontalScrollBarVisibility="Auto"> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Header="资料"> @@ -165,10 +532,15 @@ - + Description="{Binding Context}"> + +