refine navigation icons

This commit is contained in:
DismissedLight
2023-08-27 15:57:39 +08:00
parent 14c75d7c04
commit 00f083608e
37 changed files with 861 additions and 175 deletions

View File

@@ -35,7 +35,6 @@ Snap Hutao is an open-source Genshin Impact toolbox on Windows platform, aim to
* [dotnet/runtime](https://github.com/dotnet/runtime)
* [DotNetAnalyzers/StyleCopAnalyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers)
* [microsoft/CsWin32](https://github.com/microsoft/CsWin32)
* [microsoft/vs-threading](https://github.com/microsoft/vs-threading)
* [microsoft/vs-validation](https://github.com/microsoft/vs-validation)
* [microsoft/WindowsAppSDK](https://github.com/microsoft/WindowsAppSDK)
* [microsoft/microsoft-ui-xaml](https://github.com/microsoft/microsoft-ui-xaml)

View File

@@ -2,9 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.WinUI.Behaviors;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Controls.Primitives;
namespace Snap.Hutao.Control.Behavior;

View File

@@ -21,7 +21,7 @@ internal sealed class BitmapIconExtension : MarkupExtension
/// <summary>
/// Gets or sets a value indicating whether to display the icon as monochrome.
/// </summary>
public bool ShowAsMonochrome { get; set; } = true;
public bool ShowAsMonochrome { get; set; }
/// <inheritdoc/>
protected override object ProvideValue()

View File

@@ -1,12 +1,15 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.Diagnostics;
namespace Snap.Hutao.Core.Annotation;
/// <summary>
/// 高质量代码
/// </summary>
[AttributeUsage(AttributeTargets.All, Inherited = false)]
[Conditional("DEBUG")]
internal sealed class HighQualityAttribute : Attribute
{
}

View File

@@ -243,6 +243,11 @@ internal sealed class Activation : IActivation
{
try
{
if (serviceProvider.GetRequiredService<IHutaoUserService>() is IHutaoUserServiceInitialization hutaoUserServiceInitialization)
{
await hutaoUserServiceInitialization.InitializeInternalAsync().ConfigureAwait(false);
}
await serviceProvider
.GetRequiredService<IDailyNoteService>()
.RefreshDailyNotesAsync()

View File

@@ -0,0 +1,546 @@
// <auto-generated />
using System;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Snap.Hutao.Model.Entity.Database;
#nullable disable
namespace Snap.Hutao.Migrations
{
[DbContext(typeof(AppDbContext))]
[Migration("20230827040435_AddRefreshTimeOnAvatarInfo")]
partial class AddRefreshTimeOnAvatarInfo
{
/// <inheritdoc />
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "7.0.10");
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<Guid>("ArchiveId")
.HasColumnType("TEXT");
b.Property<uint>("Current")
.HasColumnType("INTEGER");
b.Property<uint>("Id")
.HasColumnType("INTEGER");
b.Property<int>("Status")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset>("Time")
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.HasIndex("ArchiveId");
b.ToTable("achievements");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.AchievementArchive", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<bool>("IsSelected")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.ToTable("achievement_archives");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.AvatarInfo", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("CalculatorRefreshTime")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("GameRecordRefreshTime")
.HasColumnType("TEXT");
b.Property<string>("Info")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("ShowcaseRefreshTime")
.HasColumnType("TEXT");
b.Property<string>("Uid")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.ToTable("avatar_infos");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<uint>("Id")
.HasColumnType("INTEGER");
b.Property<Guid>("ProjectId")
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("InnerId");
b.HasIndex("ProjectId");
b.ToTable("cultivate_entries");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<int>("Count")
.HasColumnType("INTEGER");
b.Property<Guid>("EntryId")
.HasColumnType("TEXT");
b.Property<bool>("IsFinished")
.HasColumnType("INTEGER");
b.Property<int>("ItemId")
.HasColumnType("INTEGER");
b.HasKey("InnerId");
b.HasIndex("EntryId");
b.ToTable("cultivate_items");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateProject", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("AttachedUid")
.HasColumnType("TEXT");
b.Property<bool>("IsSelected")
.HasColumnType("INTEGER");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.ToTable("cultivate_projects");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("DailyNote")
.HasColumnType("TEXT");
b.Property<bool>("DailyTaskNotify")
.HasColumnType("INTEGER");
b.Property<bool>("DailyTaskNotifySuppressed")
.HasColumnType("INTEGER");
b.Property<bool>("ExpeditionNotify")
.HasColumnType("INTEGER");
b.Property<bool>("ExpeditionNotifySuppressed")
.HasColumnType("INTEGER");
b.Property<bool>("HomeCoinNotifySuppressed")
.HasColumnType("INTEGER");
b.Property<int>("HomeCoinNotifyThreshold")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset>("RefreshTime")
.HasColumnType("TEXT");
b.Property<bool>("ResinNotifySuppressed")
.HasColumnType("INTEGER");
b.Property<int>("ResinNotifyThreshold")
.HasColumnType("INTEGER");
b.Property<bool>("TransformerNotify")
.HasColumnType("INTEGER");
b.Property<bool>("TransformerNotifySuppressed")
.HasColumnType("INTEGER");
b.Property<string>("Uid")
.IsRequired()
.HasColumnType("TEXT");
b.Property<Guid>("UserId")
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.HasIndex("UserId");
b.ToTable("daily_notes");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaArchive", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<bool>("IsSelected")
.HasColumnType("INTEGER");
b.Property<string>("Uid")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.ToTable("gacha_archives");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<Guid>("ArchiveId")
.HasColumnType("TEXT");
b.Property<int>("GachaType")
.HasColumnType("INTEGER");
b.Property<long>("Id")
.HasColumnType("INTEGER");
b.Property<uint>("ItemId")
.HasColumnType("INTEGER");
b.Property<int>("QueryType")
.HasColumnType("INTEGER");
b.Property<DateTimeOffset>("Time")
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.HasIndex("ArchiveId");
b.ToTable("gacha_items");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.GameAccount", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("AttachUid")
.HasColumnType("TEXT");
b.Property<string>("MihoyoSDK")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("Type")
.HasColumnType("INTEGER");
b.HasKey("InnerId");
b.ToTable("game_accounts");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<uint>("Count")
.HasColumnType("INTEGER");
b.Property<uint>("ItemId")
.HasColumnType("INTEGER");
b.Property<Guid>("ProjectId")
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.HasIndex("ProjectId");
b.ToTable("inventory_items");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("AppendPropIdList")
.IsRequired()
.HasColumnType("TEXT");
b.Property<int>("ItemId")
.HasColumnType("INTEGER");
b.Property<int>("Level")
.HasColumnType("INTEGER");
b.Property<int>("MainPropId")
.HasColumnType("INTEGER");
b.Property<Guid>("ProjectId")
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.HasIndex("ProjectId");
b.ToTable("inventory_reliquaries");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<int>("ItemId")
.HasColumnType("INTEGER");
b.Property<int>("Level")
.HasColumnType("INTEGER");
b.Property<Guid>("ProjectId")
.HasColumnType("TEXT");
b.Property<int>("PromoteLevel")
.HasColumnType("INTEGER");
b.HasKey("InnerId");
b.HasIndex("ProjectId");
b.ToTable("inventory_weapons");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.ObjectCacheEntry", b =>
{
b.Property<string>("Key")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("ExpireTime")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("Key");
b.ToTable("object_cache");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.SettingEntry", b =>
{
b.Property<string>("Key")
.HasColumnType("TEXT");
b.Property<string>("Value")
.HasColumnType("TEXT");
b.HasKey("Key");
b.ToTable("settings");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.SpiralAbyssEntry", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<int>("ScheduleId")
.HasColumnType("INTEGER");
b.Property<string>("SpiralAbyss")
.IsRequired()
.HasColumnType("TEXT");
b.Property<string>("Uid")
.IsRequired()
.HasColumnType("TEXT");
b.HasKey("InnerId");
b.ToTable("spiral_abysses");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.User", b =>
{
b.Property<Guid>("InnerId")
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<string>("Aid")
.HasColumnType("TEXT");
b.Property<string>("CookieToken")
.HasColumnType("TEXT");
b.Property<bool>("IsOversea")
.HasColumnType("INTEGER");
b.Property<bool>("IsSelected")
.HasColumnType("INTEGER");
b.Property<string>("LToken")
.HasColumnType("TEXT")
.HasColumnName("Ltoken");
b.Property<string>("Mid")
.HasColumnType("TEXT");
b.Property<string>("SToken")
.HasColumnType("TEXT")
.HasColumnName("Stoken");
b.HasKey("InnerId");
b.ToTable("users");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.Achievement", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.AchievementArchive", "Archive")
.WithMany()
.HasForeignKey("ArchiveId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Archive");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateEntry", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
.WithMany()
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.CultivateItem", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.CultivateEntry", "Entry")
.WithMany()
.HasForeignKey("EntryId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Entry");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.DailyNoteEntry", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.User", "User")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.GachaItem", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.GachaArchive", "Archive")
.WithMany()
.HasForeignKey("ArchiveId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Archive");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryItem", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
.WithMany()
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryReliquary", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
.WithMany()
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
});
modelBuilder.Entity("Snap.Hutao.Model.Entity.InventoryWeapon", b =>
{
b.HasOne("Snap.Hutao.Model.Entity.CultivateProject", "Project")
.WithMany()
.HasForeignKey("ProjectId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("Project");
});
#pragma warning restore 612, 618
}
}
}

View File

@@ -0,0 +1,52 @@
// <auto-generated />
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Snap.Hutao.Migrations
{
/// <inheritdoc />
public partial class AddRefreshTimeOnAvatarInfo : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTimeOffset>(
name: "CalculatorRefreshTime",
table: "avatar_infos",
type: "TEXT",
nullable: false,
defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)));
migrationBuilder.AddColumn<DateTimeOffset>(
name: "GameRecordRefreshTime",
table: "avatar_infos",
type: "TEXT",
nullable: false,
defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)));
migrationBuilder.AddColumn<DateTimeOffset>(
name: "ShowcaseRefreshTime",
table: "avatar_infos",
type: "TEXT",
nullable: false,
defaultValue: new DateTimeOffset(new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified), new TimeSpan(0, 0, 0, 0, 0)));
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "CalculatorRefreshTime",
table: "avatar_infos");
migrationBuilder.DropColumn(
name: "GameRecordRefreshTime",
table: "avatar_infos");
migrationBuilder.DropColumn(
name: "ShowcaseRefreshTime",
table: "avatar_infos");
}
}
}

View File

@@ -69,10 +69,19 @@ namespace Snap.Hutao.Migrations
.ValueGeneratedOnAdd()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("CalculatorRefreshTime")
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("GameRecordRefreshTime")
.HasColumnType("TEXT");
b.Property<string>("Info")
.IsRequired()
.HasColumnType("TEXT");
b.Property<DateTimeOffset>("ShowcaseRefreshTime")
.HasColumnType("TEXT");
b.Property<string>("Uid")
.IsRequired()
.HasColumnType("TEXT");

View File

@@ -31,6 +31,12 @@ internal sealed class AvatarInfo : IMappingFrom<AvatarInfo, string, Web.Enka.Mod
/// </summary>
public Web.Enka.Model.AvatarInfo Info { get; set; } = default!;
public DateTimeOffset ShowcaseRefreshTime { get; set; }
public DateTimeOffset GameRecordRefreshTime { get; set; }
public DateTimeOffset CalculatorRefreshTime { get; set; }
/// <summary>
/// 创建一个新的实体角色信息
/// </summary>

View File

@@ -5,6 +5,7 @@ using Snap.Hutao.Model.Calculable;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata.Abstraction;
using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.ViewModel.Complex;
using Snap.Hutao.ViewModel.GachaLog;
@@ -22,6 +23,12 @@ internal sealed partial class Weapon : IStatisticsItemSource, ISummaryItemSource
[JsonIgnore]
public WeaponCollocationView? Collocation { get; set; }
/// <summary>
/// [非元数据] 养成物品视图
/// </summary>
[JsonIgnore]
public List<Material>? CultivationItemsView { get; set; }
/// <inheritdoc cref="INameQuality.Quality" />
[JsonIgnore]
public QualityType Quality

View File

@@ -61,4 +61,9 @@ internal sealed partial class Weapon
/// 被动信息, 无被动的武器为 <see langword="null"/>
/// </summary>
public NameDescriptions? Affix { get; set; } = default!;
/// <summary>
/// 养成物品
/// </summary>
public List<MaterialId> CultivationItems { get; set; } = default!;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

View File

@@ -13,9 +13,10 @@ using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord;
using Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Avatar;
using Snap.Hutao.Web.Response;
using System.Runtime.CompilerServices;
using Windows.Perception.Spatial;
using CalculateAvatar = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.Avatar;
using EnkaAvatarInfo = Snap.Hutao.Web.Enka.Model.AvatarInfo;
using ModelAvatarInfo = Snap.Hutao.Model.Entity.AvatarInfo;
using EntityAvatarInfo = Snap.Hutao.Model.Entity.AvatarInfo;
using RecordCharacter = Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.Avatar.Character;
using RecordPlayerInfo = Snap.Hutao.Web.Hoyolab.Takumi.GameRecord.PlayerInfo;
@@ -39,10 +40,10 @@ internal sealed partial class AvatarInfoDbBulkOperation
/// <param name="webInfos">Enka信息</param>
/// <param name="token">取消令牌</param>
/// <returns>角色列表</returns>
public List<EnkaAvatarInfo> UpdateDbAvatarInfos(string uid, IEnumerable<EnkaAvatarInfo> webInfos, CancellationToken token)
public List<EnkaAvatarInfo> UpdateDbAvatarInfosByShowcase(string uid, IEnumerable<EnkaAvatarInfo> webInfos, CancellationToken token)
{
token.ThrowIfCancellationRequested();
List<ModelAvatarInfo> dbInfos = avatarInfoDbService.GetAvatarInfoListByUid(uid);
List<EntityAvatarInfo> dbInfos = avatarInfoDbService.GetAvatarInfoListByUid(uid);
EnsureItemsAvatarIdDistinct(ref dbInfos, uid);
using (IServiceScope scope = serviceProvider.CreateScope())
@@ -57,7 +58,7 @@ internal sealed partial class AvatarInfoDbBulkOperation
}
token.ThrowIfCancellationRequested();
ModelAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == webInfo.AvatarId);
EntityAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == webInfo.AvatarId);
AddOrUpdateAvatarInfo(entity, uid, appDbContext, webInfo);
}
@@ -76,7 +77,7 @@ internal sealed partial class AvatarInfoDbBulkOperation
{
token.ThrowIfCancellationRequested();
string uid = userAndUid.Uid.Value;
List<ModelAvatarInfo> dbInfos = avatarInfoDbService.GetAvatarInfoListByUid(uid);
List<EntityAvatarInfo> dbInfos = avatarInfoDbService.GetAvatarInfoListByUid(uid);
EnsureItemsAvatarIdDistinct(ref dbInfos, uid);
using (IServiceScope scope = serviceProvider.CreateScope())
@@ -113,7 +114,7 @@ internal sealed partial class AvatarInfoDbBulkOperation
}
token.ThrowIfCancellationRequested();
ModelAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == character.Id);
EntityAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == character.Id);
AddOrUpdateAvatarInfo(entity, character.Id, uid, appDbContext, transformer, character);
}
}
@@ -133,7 +134,7 @@ internal sealed partial class AvatarInfoDbBulkOperation
{
token.ThrowIfCancellationRequested();
string uid = userAndUid.Uid.Value;
List<ModelAvatarInfo> dbInfos = avatarInfoDbService.GetAvatarInfoListByUid(uid);
List<EntityAvatarInfo> dbInfos = avatarInfoDbService.GetAvatarInfoListByUid(uid);
EnsureItemsAvatarIdDistinct(ref dbInfos, uid);
using (IServiceScope scope = serviceProvider.CreateScope())
@@ -167,7 +168,7 @@ internal sealed partial class AvatarInfoDbBulkOperation
}
token.ThrowIfCancellationRequested();
ModelAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == avatar.Id);
EntityAvatarInfo? entity = dbInfos.SingleOrDefault(i => i.Info.AvatarId == avatar.Id);
AddOrUpdateAvatarInfo(entity, avatar.Id, uid, appDbContext, transformer, detailAvatarResponse.Data);
}
}
@@ -176,13 +177,31 @@ internal sealed partial class AvatarInfoDbBulkOperation
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AddOrUpdateAvatarInfo<TSource>(ModelAvatarInfo? entity, in AvatarId avatarId, string uid, AppDbContext appDbContext, IAvatarInfoTransformer<TSource> transformer, TSource source)
private static void AddOrUpdateAvatarInfo(EntityAvatarInfo? entity, string uid, AppDbContext appDbContext, EnkaAvatarInfo webInfo)
{
if (entity is null)
{
entity = EntityAvatarInfo.From(uid, webInfo);
entity.ShowcaseRefreshTime = DateTimeOffset.Now;
appDbContext.AvatarInfos.AddAndSave(entity);
}
else
{
entity.Info = webInfo;
entity.ShowcaseRefreshTime = DateTimeOffset.Now;
appDbContext.AvatarInfos.UpdateAndSave(entity);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AddOrUpdateAvatarInfo(EntityAvatarInfo? entity, in AvatarId avatarId, string uid, AppDbContext appDbContext, CalculateAvatarDetailAvatarInfoTransformer transformer, AvatarDetail source)
{
if (entity is null)
{
EnkaAvatarInfo avatarInfo = new() { AvatarId = avatarId };
transformer.Transform(ref avatarInfo, source);
entity = ModelAvatarInfo.From(uid, avatarInfo);
entity = EntityAvatarInfo.From(uid, avatarInfo);
entity.CalculatorRefreshTime = DateTimeOffset.Now;
appDbContext.AvatarInfos.AddAndSave(entity);
}
else
@@ -190,26 +209,33 @@ internal sealed partial class AvatarInfoDbBulkOperation
EnkaAvatarInfo avatarInfo = entity.Info;
transformer.Transform(ref avatarInfo, source);
entity.Info = avatarInfo;
entity.CalculatorRefreshTime = DateTimeOffset.Now;
appDbContext.AvatarInfos.UpdateAndSave(entity);
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private static void AddOrUpdateAvatarInfo(ModelAvatarInfo? entity, string uid, AppDbContext appDbContext, EnkaAvatarInfo webInfo)
private static void AddOrUpdateAvatarInfo(EntityAvatarInfo? entity, in AvatarId avatarId, string uid, AppDbContext appDbContext, GameRecordCharacterAvatarInfoTransformer transformer, Character source)
{
if (entity is null)
{
entity = ModelAvatarInfo.From(uid, webInfo);
EnkaAvatarInfo avatarInfo = new() { AvatarId = avatarId };
transformer.Transform(ref avatarInfo, source);
entity = EntityAvatarInfo.From(uid, avatarInfo);
entity.GameRecordRefreshTime = DateTimeOffset.Now;
appDbContext.AvatarInfos.AddAndSave(entity);
}
else
{
entity.Info = webInfo;
EnkaAvatarInfo avatarInfo = entity.Info;
transformer.Transform(ref avatarInfo, source);
entity.Info = avatarInfo;
entity.GameRecordRefreshTime = DateTimeOffset.Now;
appDbContext.AvatarInfos.UpdateAndSave(entity);
}
}
private void EnsureItemsAvatarIdDistinct(ref List<ModelAvatarInfo> dbInfos, string uid)
private void EnsureItemsAvatarIdDistinct(ref List<EntityAvatarInfo> dbInfos, string uid)
{
int distinctCount = dbInfos.Select(info => info.Info.AvatarId).ToHashSet().Count;

View File

@@ -56,7 +56,7 @@ internal sealed partial class AvatarInfoService : IAvatarInfoService
return new(RefreshResult.ShowcaseNotOpen, default);
}
List<EnkaAvatarInfo> list = avatarInfoDbBulkOperation.UpdateDbAvatarInfos(userAndUid.Uid.Value, resp.AvatarInfoList, token);
List<EnkaAvatarInfo> list = avatarInfoDbBulkOperation.UpdateDbAvatarInfosByShowcase(userAndUid.Uid.Value, resp.AvatarInfoList, token);
Summary summary = await GetSummaryCoreAsync(list, token).ConfigureAwait(false);
return new(RefreshResult.Ok, summary);
}

View File

@@ -3,12 +3,10 @@
using Snap.Hutao.Core.ExceptionService;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Intrinsic.Format;
using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Model.Metadata.Reliquary;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.ViewModel.AvatarProperty;
using Snap.Hutao.Web.Enka.Model;
using System.Runtime.InteropServices;
using MetadataReliquary = Snap.Hutao.Model.Metadata.Reliquary.Reliquary;
using ModelAvatarInfo = Snap.Hutao.Web.Enka.Model.AvatarInfo;

View File

@@ -2,15 +2,8 @@
// Licensed under the MIT license.
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Intrinsic.Format;
using Snap.Hutao.Model.Metadata.Converter;
using Snap.Hutao.Model.Metadata.Reliquary;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.ViewModel.AvatarProperty;
using Snap.Hutao.Web.Enka.Model;
using System.Runtime.InteropServices;
using MetadataReliquary = Snap.Hutao.Model.Metadata.Reliquary.Reliquary;
using ModelAvatarInfo = Snap.Hutao.Web.Enka.Model.AvatarInfo;
namespace Snap.Hutao.Service.AvatarInfo.Factory;

View File

@@ -102,6 +102,18 @@
<None Remove="Resource\Icon\UI_MarkCustom_TagMonster.png" />
<None Remove="Resource\Icon\UI_MarkTower.png" />
<None Remove="Resource\Icon\UI_MarkTower_Tower.png" />
<None Remove="Resource\Navigation\Achievement.png" />
<None Remove="Resource\Navigation\Announcement.png" />
<None Remove="Resource\Navigation\AvatarProperty.png" />
<None Remove="Resource\Navigation\Cultivation.png" />
<None Remove="Resource\Navigation\DailyNote.png" />
<None Remove="Resource\Navigation\Database.png" />
<None Remove="Resource\Navigation\GachaLog.png" />
<None Remove="Resource\Navigation\LaunchGame.png" />
<None Remove="Resource\Navigation\SpiralAbyss.png" />
<None Remove="Resource\Navigation\WikiAvatar.png" />
<None Remove="Resource\Navigation\WikiMonster.png" />
<None Remove="Resource\Navigation\WikiWeapon.png" />
<None Remove="Resource\Segoe Fluent Icons.ttf" />
<None Remove="Resource\WelcomeView_Background.png" />
<None Remove="stylecop.json" />
@@ -229,6 +241,18 @@
<Content Include="Resource\Icon\UI_MarkCustom_TagMonster.png" />
<Content Include="Resource\Icon\UI_MarkTower.png" />
<Content Include="Resource\Icon\UI_MarkTower_Tower.png" />
<Content Include="Resource\Navigation\Achievement.png" />
<Content Include="Resource\Navigation\Announcement.png" />
<Content Include="Resource\Navigation\AvatarProperty.png" />
<Content Include="Resource\Navigation\Cultivation.png" />
<Content Include="Resource\Navigation\DailyNote.png" />
<Content Include="Resource\Navigation\Database.png" />
<Content Include="Resource\Navigation\GachaLog.png" />
<Content Include="Resource\Navigation\LaunchGame.png" />
<Content Include="Resource\Navigation\SpiralAbyss.png" />
<Content Include="Resource\Navigation\WikiAvatar.png" />
<Content Include="Resource\Navigation\WikiMonster.png" />
<Content Include="Resource\Navigation\WikiWeapon.png" />
<Content Include="Resource\WelcomeView_Background.png" />
</ItemGroup>

View File

@@ -2,14 +2,19 @@
x:Class="Snap.Hutao.View.Control.BottomTextControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cw="using:CommunityToolkit.WinUI"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Border Style="{StaticResource BorderCardStyle}">
<StackPanel Background="{x:Bind Fill}">
<ContentPresenter Content="{x:Bind TopContent, Mode=OneWay}"/>
<ContentPresenter
x:Name="ContentHost"
cw:FrameworkElementExtensions.EnableActualSizeBinding="True"
Content="{x:Bind TopContent, Mode=OneWay}"/>
<TextBlock
MaxWidth="{x:Bind ContentHost.(cw:FrameworkElementExtensions.ActualWidth), Mode=OneWay}"
Margin="0,0,0,2"
HorizontalAlignment="Stretch"
HorizontalTextAlignment="Center"

View File

@@ -15,7 +15,7 @@ namespace Snap.Hutao.View.Control;
[ContentProperty(Name = nameof(TopContent))]
[DependencyProperty("Text", typeof(string), "")]
[DependencyProperty("Fill", typeof(Brush), default!)]
[DependencyProperty("TopContent", typeof(UIElement), default!)]
[DependencyProperty("TopContent", typeof(FrameworkElement), default!)]
internal sealed partial class BottomTextControl : ContentControl
{
/// <summary>

View File

@@ -9,7 +9,7 @@ namespace Snap.Hutao.View.Control;
[ContentProperty(Name = nameof(TopContent))]
[DependencyProperty("Text", typeof(string), "")]
[DependencyProperty("TopContent", typeof(UIElement), default!)]
[DependencyProperty("TopContent", typeof(FrameworkElement), default!)]
internal sealed partial class BottomTextSmallControl : UserControl
{
public BottomTextSmallControl()

View File

@@ -3,7 +3,6 @@
using Microsoft.UI.Xaml;
using Snap.Hutao.Control;
using Snap.Hutao.Control.Theme;
using Snap.Hutao.Win32;
using System.Runtime.CompilerServices;
using Windows.UI;

View File

@@ -11,6 +11,7 @@
mc:Ignorable="d">
<UserControl.Resources>
<Thickness x:Key="NavigationViewContentMargin">0,44,0,0</Thickness>
<x:Double x:Key="NavigationViewItemOnLeftIconBoxHeight">24</x:Double>
</UserControl.Resources>
<Grid>
<NavigationView
@@ -19,79 +20,82 @@
IsBackEnabled="{Binding ElementName=ContentFrame, Path=CanGoBack}"
IsPaneOpen="True"
OpenPaneLength="188"
PaneDisplayMode="Left">
PaneDisplayMode="Left"
UseLayoutRounding="False">
<NavigationView.MenuItems>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:AnnouncementPage"
Content="{shcm:ResourceString Name=ViewAnnouncementHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_BtnIcon_ActivityEntry.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/Announcement.png}"/>
<NavigationViewItemHeader Content="{shcm:ResourceString Name=ViewToolHeader}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:LaunchGamePage"
Content="{shcm:ResourceString Name=ViewLaunchGameHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_GuideIcon_PlayMethod.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/LaunchGame.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:GachaLogPage"
Content="{shcm:ResourceString Name=ViewGachaLogHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_BtnIcon_Gacha.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/GachaLog.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:AchievementPage"
Content="{shcm:ResourceString Name=ViewAchievementHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_Icon_Achievement.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/Achievement.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:DailyNotePage"
Content="{shcm:ResourceString Name=ViewDailyNoteHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_ItemIcon_210.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/DailyNote.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:AvatarPropertyPage"
Content="{shcm:ResourceString Name=ViewAvatarPropertyHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_Icon_BoostUp.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/AvatarProperty.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:SpiralAbyssRecordPage"
Content="{shcm:ResourceString Name=ViewSpiralAbyssHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_MarkTower_Tower.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/SpiralAbyss.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:CultivationPage"
Content="{shcm:ResourceString Name=ViewCultivationHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_HomeWorldTabIcon_2_Team.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/Cultivation.png}"/>
<NavigationViewItemHeader Content="{shcm:ResourceString Name=ViewDataHeader}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:HutaoDatabasePage"
Content="{shcm:ResourceString Name=ViewHutaoDatabaseHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_ChapterIcon_Hutao.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/Database.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:WikiAvatarPage"
Content="{shcm:ResourceString Name=ViewWikiAvatarHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_BagTabIcon_Avatar.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/WikiAvatar.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:WikiWeaponPage"
Content="{shcm:ResourceString Name=ViewWikiWeaponHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_BagTabIcon_Weapon.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/WikiWeapon.png}"/>
<NavigationViewItem
shvh:NavHelper.NavigateTo="shvp:WikiMonsterPage"
Content="{shcm:ResourceString Name=ViewWikiMonsterHeader}"
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Icon/UI_MarkCustom_TagMonster.png}"/>
Icon="{shcm:BitmapIcon Source=ms-appx:///Resource/Navigation/WikiMonster.png}"/>
</NavigationView.MenuItems>
<NavigationView.PaneFooter>
<shv:UserView/>
</NavigationView.PaneFooter>
<Frame x:Name="ContentFrame">
<Frame x:Name="ContentFrame" UseLayoutRounding="True">
<Frame.ContentTransitions>
<NavigationThemeTransition/>
<TransitionCollection>
<NavigationThemeTransition/>
</TransitionCollection>
</Frame.ContentTransitions>
</Frame>
</NavigationView>

View File

@@ -182,21 +182,6 @@
HeaderIcon="{shcm:FontIcon Glyph=&#xEBC4;}"
IsClickEnabled="True"/>
<TextBlock Style="{StaticResource SettingsSectionHeaderTextBlockStyle}" Text="测试功能"/>
<InfoBar
IsClosable="False"
IsOpen="True"
Message="测试功能是尚未完善,仅用于 Pollyfill 的功能,未来可能会存在更合理的位置放置这些功能"
Severity="Warning"/>
<cwc:SettingsCard
ActionIcon="{shcm:FontIcon Glyph=&#xE76C;}"
ActionIconToolTip="打开签到对话框"
Command="{Binding ShowSignInWebViewDialogCommand}"
Description="对当前选中的账号进行签到"
Header="米游社每日签到"
HeaderIcon="{shcm:FontIcon Glyph=&#xE9D5;}"
IsClickEnabled="True"/>
<TextBlock
Foreground="{ThemeResource SystemFillColorCriticalBrush}"
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
@@ -216,9 +201,7 @@
<shvc:Elevation Visibility="{Binding HutaoOptions.IsElevated, Converter={StaticResource BoolToVisibilityRevertConverter}}"/>
<ToggleSwitch Width="120" IsOn="{Binding Options.IsAdvancedLaunchOptionsEnabled, Mode=TwoWay}"/>
</StackPanel>
</cwc:SettingsCard>
<InfoBar
Margin="0,4,0,0"
IsClosable="False"

View File

@@ -113,117 +113,135 @@
</SplitView.Pane>
<SplitView.Content>
<ScrollViewer>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="800"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<StackPanel Margin="0,0,16,0">
<Border
Margin="16,16,0,0"
BorderBrush="{StaticResource CardStrokeColorDefault}"
BorderThickness="1"
CornerRadius="{StaticResource CompatCornerRadius}">
<Border.Background>
<ImageBrush ImageSource="ms-appx:///Resource/Icon/UI_GachaShowPanel_Bg_Weapon.png"/>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<mxi:Interaction.Behaviors>
<shcb:AutoHeightBehavior TargetHeight="1024" TargetWidth="2048"/>
</mxi:Interaction.Behaviors>
<ScrollViewer Grid.Column="0" Margin="16">
<StackPanel>
<shvc:BottomTextControl RequestedTheme="Light" Text="{shcm:ResourceString Name=ViewPageWiKiWeaponBeforeAscensionTitle}">
<shvc:ItemIcon Icon="{Binding Selected.Icon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
</shvc:BottomTextControl>
<shvc:BottomTextControl
Margin="0,16,0,0"
RequestedTheme="Light"
Text="{shcm:ResourceString Name=ViewPageWiKiWeaponAfterAscensionTitle}">
<shvc:ItemIcon Icon="{Binding Selected.AwakenIcon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
</shvc:BottomTextControl>
</StackPanel>
</ScrollViewer>
<Grid Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="176*"/>
<ColumnDefinition Width="848*"/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Source="{Binding Selected.Icon, Converter={StaticResource GachaEquipIconConverter}}"/>
</Grid>
<TextBlock
Grid.Column="1"
Margin="16"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding Selected.Name}"/>
</Grid>
</Border>
<TextBlock
Margin="16,16,0,0"
Text="{Binding Selected.Description}"
TextWrapping="Wrap"/>
<shvc:BaseValueSlider
Margin="16,16,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"/>
<StackPanel Visibility="{Binding Selected.Affix, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
<TextBlock
Margin="16,32,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Selected.Affix.Name}"/>
<Pivot ItemsSource="{Binding Selected.Affix.Descriptions}">
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{Binding LevelFormatted}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<shct:DescriptionTextBlock Margin="16,16,0,0" Description="{Binding Description}">
<shct:DescriptionTextBlock.Resources>
<Style BasedOn="{StaticResource BodyTextBlockStyle}" TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</shct:DescriptionTextBlock.Resources>
</shct:DescriptionTextBlock>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
</StackPanel>
<TextBlock
Margin="16,32,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageWiKiAvatarTeamCombinationHeader}"/>
<GridView
Margin="16,16,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Selected.Collocation.Avatars}"
SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<shvc:BottomTextControl Text="{Binding Rate}" ToolTipService.ToolTip="{Binding Name}">
<shvc:ItemIcon Icon="{Binding Icon}" Quality="{Binding Quality}"/>
<StackPanel
MaxWidth="800"
Margin="0,0,16,0"
HorizontalAlignment="Left">
<Border
Margin="16,16,0,0"
BorderBrush="{StaticResource CardStrokeColorDefault}"
BorderThickness="1"
CornerRadius="{StaticResource CompatCornerRadius}">
<Border.Background>
<ImageBrush ImageSource="ms-appx:///Resource/Icon/UI_GachaShowPanel_Bg_Weapon.png"/>
</Border.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<mxi:Interaction.Behaviors>
<shcb:AutoHeightBehavior TargetHeight="1024" TargetWidth="2048"/>
</mxi:Interaction.Behaviors>
<ScrollViewer Grid.Column="0" Margin="16">
<StackPanel>
<shvc:BottomTextControl
MaxWidth="80"
RequestedTheme="Light"
Text="{shcm:ResourceString Name=ViewPageWiKiWeaponBeforeAscensionTitle}">
<shvc:ItemIcon Icon="{Binding Selected.Icon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
</shvc:BottomTextControl>
<shvc:BottomTextControl
Margin="0,16,0,0"
RequestedTheme="Light"
Text="{shcm:ResourceString Name=ViewPageWiKiWeaponAfterAscensionTitle}">
<shvc:ItemIcon Icon="{Binding Selected.AwakenIcon, Converter={StaticResource EquipIconConverter}}" Quality="{Binding Selected.RankLevel}"/>
</shvc:BottomTextControl>
</StackPanel>
</ScrollViewer>
<Grid Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="176*"/>
<ColumnDefinition Width="848*"/>
</Grid.ColumnDefinitions>
<shci:CachedImage
Grid.Column="1"
HorizontalAlignment="Center"
VerticalAlignment="Stretch"
Source="{Binding Selected.Icon, Converter={StaticResource GachaEquipIconConverter}}"/>
</Grid>
<TextBlock
Grid.Column="1"
Margin="16"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Style="{StaticResource SubtitleTextBlockStyle}"
Text="{Binding Selected.Name}"/>
</Grid>
</Border>
<TextBlock
Margin="16,16,0,0"
Text="{Binding Selected.Description}"
TextWrapping="Wrap"/>
<shvc:BaseValueSlider
Margin="16,16,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
BaseValueInfo="{Binding BaseValueInfo, Mode=OneWay}"/>
<TextBlock
Margin="16,32,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageWiKiAvatarAscensionMaterialsHeader}"/>
<GridView
Margin="16,16,0,0"
ItemsSource="{Binding Selected.CultivationItemsView}"
SelectionMode="None">
<ItemsControl.ItemTemplate>
<DataTemplate>
<shvc:BottomTextControl Text="{Binding Name}">
<shvc:ItemIcon Icon="{Binding Icon, Converter={StaticResource ItemIconConverter}}" Quality="{Binding RankLevel}"/>
</shvc:BottomTextControl>
</DataTemplate>
</ItemsControl.ItemTemplate>
</GridView>
<StackPanel Visibility="{Binding Selected.Affix, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
<TextBlock
Margin="16,16,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{Binding Selected.Affix.Name}"/>
<Pivot ItemsSource="{Binding Selected.Affix.Descriptions}">
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Style="{StaticResource CaptionTextBlockStyle}" Text="{Binding LevelFormatted}"/>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</Pivot.HeaderTemplate>
<Pivot.ItemTemplate>
<DataTemplate>
<shct:DescriptionTextBlock Margin="16,16,0,0" Description="{Binding Description}">
<shct:DescriptionTextBlock.Resources>
<Style BasedOn="{StaticResource BodyTextBlockStyle}" TargetType="TextBlock">
<Setter Property="TextWrapping" Value="Wrap"/>
</Style>
</shct:DescriptionTextBlock.Resources>
</shct:DescriptionTextBlock>
</DataTemplate>
</Pivot.ItemTemplate>
</Pivot>
</StackPanel>
</Grid>
<TextBlock
Margin="16,32,0,0"
Style="{StaticResource BaseTextBlockStyle}"
Text="{shcm:ResourceString Name=ViewPageWiKiAvatarTeamCombinationHeader}"/>
<GridView
Margin="16,16,0,0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
ItemsSource="{Binding Selected.Collocation.Avatars}"
SelectionMode="None">
<GridView.ItemTemplate>
<DataTemplate>
<shvc:BottomTextControl Text="{Binding Rate}" ToolTipService.ToolTip="{Binding Name}">
<shvc:ItemIcon Icon="{Binding Icon}" Quality="{Binding Quality}"/>
</shvc:BottomTextControl>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
</StackPanel>
</ScrollViewer>
</SplitView.Content>
</SplitView>

View File

@@ -7,6 +7,7 @@ using Snap.Hutao.Model.Calculable;
using Snap.Hutao.Model.Entity.Primitive;
using Snap.Hutao.Model.Intrinsic;
using Snap.Hutao.Model.Metadata;
using Snap.Hutao.Model.Metadata.Item;
using Snap.Hutao.Model.Metadata.Weapon;
using Snap.Hutao.Model.Primitive;
using Snap.Hutao.Service.Cultivation;
@@ -83,6 +84,7 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
{
levelWeaponCurveMap = await metadataService.GetLevelToWeaponCurveMapAsync().ConfigureAwait(false);
promotes = await metadataService.GetWeaponPromotesAsync().ConfigureAwait(false);
Dictionary<MaterialId, Material> idMaterialMap = await metadataService.GetIdToMaterialMapAsync().ConfigureAwait(false);
List<Weapon> weapons = await metadataService.GetWeaponsAsync().ConfigureAwait(false);
List<Weapon> sorted = weapons
@@ -91,7 +93,7 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
.ThenByDescending(weapon => weapon.Id.Value)
.ToList();
await CombineWithWeaponCollocationsAsync(sorted).ConfigureAwait(false);
await CombineComplexDataAsync(sorted, idMaterialMap).ConfigureAwait(false);
await taskContext.SwitchToMainThreadAsync();
@@ -100,12 +102,17 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
}
}
private async ValueTask CombineWithWeaponCollocationsAsync(List<Weapon> weapons)
private async ValueTask CombineComplexDataAsync(List<Weapon> weapons, Dictionary<MaterialId, Material> idMaterialMap)
{
if (await hutaoCache.InitializeForWikiWeaponViewModelAsync().ConfigureAwait(false))
{
ArgumentNullException.ThrowIfNull(hutaoCache.WeaponCollocations);
weapons.ForEach(w => w.Collocation = hutaoCache.WeaponCollocations.GetValueOrDefault(w.Id));
foreach (Weapon weapon in weapons)
{
weapon.Collocation = hutaoCache.WeaponCollocations.GetValueOrDefault(weapon.Id);
weapon.CultivationItemsView ??= weapon.CultivationItems.SelectList(i => idMaterialMap.GetValueOrDefault(i, Material.Default));
}
}
}

View File

@@ -3,7 +3,6 @@
using Snap.Hutao.Core.DependencyInjection.Annotation.HttpClient;
using Snap.Hutao.ViewModel.User;
using Snap.Hutao.Web.Geetest;
using Snap.Hutao.Web.Hoyolab.DynamicSecret;
using Snap.Hutao.Web.Hutao.Geetest;
using Snap.Hutao.Web.Response;