diff --git a/src/Snap.Hutao/Snap.Hutao/Model/Entity/SettingEntry.Constant.cs b/src/Snap.Hutao/Snap.Hutao/Model/Entity/SettingEntry.Constant.cs index 1263d84f..66d3fa06 100644 --- a/src/Snap.Hutao/Snap.Hutao/Model/Entity/SettingEntry.Constant.cs +++ b/src/Snap.Hutao/Snap.Hutao/Model/Entity/SettingEntry.Constant.cs @@ -19,6 +19,7 @@ internal sealed partial class SettingEntry public const string AnnouncementRegion = "AnnouncementRegion"; public const string IsEmptyHistoryWishVisible = "IsEmptyHistoryWishVisible"; + public const string IsNeverHeldStatisticsItemVisible = "IsNeverHeldStatisticsItemVisible"; public const string GeetestCustomCompositeUrl = "GeetestCustomCompositeUrl"; diff --git a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx index 34f52421..3246063b 100644 --- a/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx +++ b/src/Snap.Hutao/Snap.Hutao/Resource/Localization/SH.resx @@ -2636,6 +2636,12 @@ 快捷键 + + 在祈愿记录页面显示或隐藏未持有过的角色或武器 + + + 未持有过的角色或武器 + 前往官网 diff --git a/src/Snap.Hutao/Snap.Hutao/Service/AppOptions.cs b/src/Snap.Hutao/Snap.Hutao/Service/AppOptions.cs index b09b066b..a8538a73 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/AppOptions.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/AppOptions.cs @@ -15,6 +15,7 @@ namespace Snap.Hutao.Service; [Injection(InjectAs.Singleton)] internal sealed partial class AppOptions : DbStoreOptions { + private bool? isNeverHeldStatisticsItemVisible; private bool? isEmptyHistoryWishVisible; private BackdropType? backdropType; private ElementTheme? elementTheme; @@ -28,6 +29,12 @@ internal sealed partial class AppOptions : DbStoreOptions set => SetOption(ref isEmptyHistoryWishVisible, SettingEntry.IsEmptyHistoryWishVisible, value); } + public bool IsNeverHeldStatisticsItemVisible + { + get => GetOption(ref isNeverHeldStatisticsItemVisible, SettingEntry.IsNeverHeldStatisticsItemVisible); + set => SetOption(ref isNeverHeldStatisticsItemVisible, SettingEntry.IsNeverHeldStatisticsItemVisible, value); + } + public List> BackdropTypes { get; } = CollectionsNameValue.FromEnum(type => type >= 0); public BackdropType BackdropType diff --git a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs index 035fb8bd..69e2c5fc 100644 --- a/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs +++ b/src/Snap.Hutao/Snap.Hutao/Service/GachaLog/Factory/GachaStatisticsFactory.cs @@ -3,6 +3,7 @@ using Snap.Hutao.Core.ExceptionService; using Snap.Hutao.Model.Intrinsic; +using Snap.Hutao.Model.Metadata; using Snap.Hutao.Model.Metadata.Avatar; using Snap.Hutao.Model.Metadata.Weapon; using Snap.Hutao.Service.Metadata; @@ -10,6 +11,7 @@ using Snap.Hutao.Service.Metadata.ContextAbstraction; using Snap.Hutao.ViewModel.GachaLog; using Snap.Hutao.Web.Hoyolab.Hk4e.Event.GachaInfo; using Snap.Hutao.Web.Hutao.GachaLog; +using System.Collections.Frozen; using System.Runtime.InteropServices; namespace Snap.Hutao.Service.GachaLog.Factory; @@ -22,6 +24,16 @@ namespace Snap.Hutao.Service.GachaLog.Factory; [Injection(InjectAs.Scoped, typeof(IGachaStatisticsFactory))] internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory { + private static readonly FrozenSet BlueStandardWeaponIdsSet = FrozenSet.ToFrozenSet( + [ + 11301U, 11302U, 11306U, 12301U, 12302U, 12305U, 13303U, 14301U, 14302U, 14304U, 15301U, 15302U, 15304U + ]); + + private static readonly FrozenSet PurpleStandardWeaponIdsSet = FrozenSet.ToFrozenSet( + [ + 11401U, 11402U, 11403U, 11405U, 12401U, 12402U, 12403U, 12405U, 13401U, 13407U, 14401U, 14402U, 14403U, 14409U, 15401U, 15402U, 15403U, 15405U + ]); + private readonly IMetadataService metadataService; private readonly HomaGachaLogClient homaGachaLogClient; private readonly ITaskContext taskContext; @@ -33,7 +45,7 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory await taskContext.SwitchToBackgroundAsync(); List historyWishBuilders = context.GachaEvents.SelectList(gachaEvent => new HistoryWishBuilder(gachaEvent, context)); - return CreateCore(taskContext, homaGachaLogClient, items, historyWishBuilders, context, options.IsEmptyHistoryWishVisible); + return CreateCore(taskContext, homaGachaLogClient, items, historyWishBuilders, context, options.IsEmptyHistoryWishVisible, options.IsNeverHeldStatisticsItemVisible); } private static GachaStatistics CreateCore( @@ -42,7 +54,8 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory List items, List historyWishBuilders, in GachaLogServiceMetadataContext context, - bool isEmptyHistoryWishVisible) + bool isEmptyHistoryWishVisible, + bool isNeverHeldStatisticsItemVisible) { TypedWishSummaryBuilderContext standardContext = TypedWishSummaryBuilderContext.StandardWish(taskContext, gachaLogClient); TypedWishSummaryBuilder standardWishBuilder = new(standardContext); @@ -62,6 +75,45 @@ internal sealed partial class GachaStatisticsFactory : IGachaStatisticsFactory Dictionary purpleWeaponCounter = []; Dictionary blueWeaponCounter = []; + if (isNeverHeldStatisticsItemVisible) + { + orangeAvatarCounter = context.IdAvatarMap.Values + .Where(avatar => avatar.Quality == QualityType.QUALITY_ORANGE) + .ToDictionary(avatar => avatar, _ => 0); + purpleAvatarCounter = context.IdAvatarMap.Values + .Where(avatar => avatar.Quality == QualityType.QUALITY_PURPLE) + .ToDictionary(avatar => avatar, _ => 0); + orangeWeaponCounter = context.IdWeaponMap.Values + .Where(weapon => weapon.Quality == QualityType.QUALITY_ORANGE) + .ToDictionary(weapon => weapon, _ => 0); + + HashSet purpleWeapons = []; + foreach (uint weaponId in PurpleStandardWeaponIdsSet) + { + purpleWeapons.Add(context.IdWeaponMap[weaponId]); + } + + foreach (GachaEvent gachaEvent in context.GachaEvents) + { + if (gachaEvent.Type is GachaType.ActivityWeapon) + { + foreach (uint weaponId in gachaEvent.UpPurpleList) + { + purpleWeapons.Add(context.IdWeaponMap[weaponId]); + } + } + } + + HashSet blueWeapons = []; + foreach (uint weaponId in BlueStandardWeaponIdsSet) + { + blueWeapons.Add(context.IdWeaponMap[weaponId]); + } + + purpleWeaponCounter = purpleWeapons.ToDictionary(weapon => weapon, _ => 0); + blueWeaponCounter = blueWeapons.ToDictionary(weapon => weapon, _ => 0); + } + // Pre group builders Dictionary> historyWishBuilderMap = historyWishBuilders .GroupBy(b => b.ConfigType) diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml index 84c93d6c..c832a6ca 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/GachaLogPage.xaml @@ -3,7 +3,8 @@ xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:cw="using:CommunityToolkit.WinUI" - xmlns:cwc="using:CommunityToolkit.WinUI.Controls" + xmlns:cwcont="using:CommunityToolkit.WinUI.Controls" + xmlns:cwconv="using:CommunityToolkit.WinUI.Converters" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mxi="using:Microsoft.Xaml.Interactivity" @@ -24,6 +25,11 @@ + + 1.0 + 0.4 + + @@ -120,12 +126,12 @@ Style="{StaticResource SubtitleTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageGachaLogHutaoCloudNotAllowed}" TextAlignment="Center"/> - - - + - + @@ -507,35 +514,35 @@ Style="{StaticResource SubtitleTextBlockStyle}" Text="{shcm:ResourceString Name=ViewPageGachaLogHint}"/> - - - - - - + diff --git a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml index 3a701268..660c9935 100644 --- a/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml +++ b/src/Snap.Hutao/Snap.Hutao/View/Page/SettingPage.xaml @@ -559,6 +559,15 @@ OffContent="{shcm:ResourceString Name=ViewPageSettingEmptyHistoryVisibleOff}" OnContent="{shcm:ResourceString Name=ViewPageSettingEmptyHistoryVisibleOn}"/> + + +