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}"/>
+
+
+