mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
add avatar page
This commit is contained in:
@@ -2,8 +2,7 @@
|
||||
x:Class="Snap.Hutao.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
|
||||
xmlns:system="using:System">
|
||||
xmlns:muxc="using:Microsoft.UI.Xaml.Controls">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
@@ -19,14 +18,16 @@
|
||||
|
||||
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
||||
|
||||
<FontFamily x:Key="SymbolThemeFontFamily">ms-appx:///Resource/Font/Segoe Fluent Icons.ttf#Segoe Fluent Icons</FontFamily>
|
||||
|
||||
<Thickness x:Key="InfoBarIconMargin">6,16,16,16</Thickness>
|
||||
<Thickness x:Key="InfoBarContentRootPadding">16,0,0,0</Thickness>
|
||||
|
||||
<CornerRadius x:Key="CompatCornerRadius">4</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusTop">4,4,0,0</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusRight">0,4,4,0</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusBottom">0,0,4,4</CornerRadius>
|
||||
<CornerRadius x:Key="SmallCompatCornerRadius">2,2,2,2</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadius">6</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusTop">6,6,0,0</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusRight">0,6,6,0</CornerRadius>
|
||||
<CornerRadius x:Key="CompatCornerRadiusBottom">0,0,6,6</CornerRadius>
|
||||
<CornerRadius x:Key="SmallCompatCornerRadius">4</CornerRadius>
|
||||
</ResourceDictionary>
|
||||
</Application.Resources>
|
||||
</Application>
|
||||
|
||||
@@ -6,7 +6,9 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Snap.Hutao.Core.Logging;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using System.Diagnostics;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
|
||||
@@ -66,6 +68,11 @@ public partial class App : Application
|
||||
Window = Ioc.Default.GetRequiredService<MainWindow>();
|
||||
Window.Activate();
|
||||
|
||||
if (Ioc.Default.GetRequiredService<IMetadataService>() is IMetadataInitializer initializer)
|
||||
{
|
||||
initializer.InitializeInternalAsync().SafeForget();
|
||||
}
|
||||
|
||||
if (uri != null)
|
||||
{
|
||||
Ioc.Default.GetRequiredService<IInfoBarService>().Information(uri.ToString());
|
||||
|
||||
24
src/Snap.Hutao/Snap.Hutao/Control/BindingProxy.cs
Normal file
24
src/Snap.Hutao/Snap.Hutao/Control/BindingProxy.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Snap.Hutao.Core;
|
||||
|
||||
namespace Snap.Hutao.Control;
|
||||
|
||||
/// <summary>
|
||||
/// 绑定探针
|
||||
/// </summary>
|
||||
public class BindingProxy : DependencyObject
|
||||
{
|
||||
private static readonly DependencyProperty DataProperty = Property<BindingProxy>.Depend<object>(nameof(DataContext));
|
||||
|
||||
/// <summary>
|
||||
/// 数据上下文
|
||||
/// </summary>
|
||||
public object? DataContext
|
||||
{
|
||||
get => GetValue(DataProperty);
|
||||
set => SetValue(DataProperty, value);
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ public class CachedImage : ImageEx
|
||||
{
|
||||
static CachedImage()
|
||||
{
|
||||
ImageCache.Instance.CacheDuration = Timeout.InfiniteTimeSpan;
|
||||
ImageCache.Instance.CacheDuration = TimeSpan.FromDays(30);
|
||||
ImageCache.Instance.RetryCount = 3;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,4 +32,9 @@ internal static class SettingKeys
|
||||
/// 窗体底部
|
||||
/// </summary>
|
||||
public const string WindowBottom = "WindowBottom";
|
||||
|
||||
/// <summary>
|
||||
/// 导航侧栏是否展开
|
||||
/// </summary>
|
||||
public const string IsNavPaneOpen = "IsNavPaneOpen";
|
||||
}
|
||||
@@ -14,8 +14,8 @@ public struct POINT
|
||||
|
||||
public POINT(int x, int y)
|
||||
{
|
||||
this.X = x;
|
||||
this.Y = y;
|
||||
X = x;
|
||||
Y = y;
|
||||
}
|
||||
|
||||
public static implicit operator System.Drawing.Point(POINT p)
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<view:TitleView
|
||||
Margin="48,0,0,0"
|
||||
Grid.Row="0"
|
||||
x:Name="TitleBarView"/>
|
||||
<view:MainView
|
||||
Grid.Row="1"/>
|
||||
Grid.Row="0"
|
||||
Grid.RowSpan="2"/>
|
||||
</Grid>
|
||||
</Window>
|
||||
|
||||
@@ -54,20 +54,19 @@ public sealed partial class MainWindow : Window
|
||||
private void InitializeWindow()
|
||||
{
|
||||
RECT rect = RetriveWindowRect();
|
||||
if (rect.Size.IsEmpty)
|
||||
if (!rect.Size.IsEmpty)
|
||||
{
|
||||
return;
|
||||
WINDOWPLACEMENT windowPlacement = new()
|
||||
{
|
||||
Length = Marshal.SizeOf<WINDOWPLACEMENT>(),
|
||||
MaxPosition = new Point(-1, -1),
|
||||
NormalPosition = rect,
|
||||
ShowCmd = ShowWindowCommand.Normal,
|
||||
};
|
||||
|
||||
User32.SetWindowPlacement(handle, ref windowPlacement);
|
||||
}
|
||||
|
||||
WINDOWPLACEMENT windowPlacement = new()
|
||||
{
|
||||
Length = Marshal.SizeOf<WINDOWPLACEMENT>(),
|
||||
MaxPosition = new Point(-1, -1),
|
||||
NormalPosition = rect,
|
||||
ShowCmd = ShowWindowCommand.Normal,
|
||||
};
|
||||
|
||||
User32.SetWindowPlacement(handle, ref windowPlacement);
|
||||
User32.SetWindowText(handle, "胡桃");
|
||||
|
||||
bool micaApplied = new SystemBackdrop(this).TrySetBackdrop();
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Metadata.Annotation;
|
||||
|
||||
namespace Snap.Hutao.Model.Intrinsic;
|
||||
|
||||
/// <summary>
|
||||
@@ -18,6 +20,7 @@ public enum FightProperty
|
||||
/// 基础生命值
|
||||
/// </summary>
|
||||
[Description("基础生命值")]
|
||||
[Format(FormatMethod.Integer)]
|
||||
FIGHT_PROP_BASE_HP = 1,
|
||||
|
||||
/// <summary>
|
||||
@@ -29,12 +32,14 @@ public enum FightProperty
|
||||
/// 生命值加成百分比
|
||||
/// </summary>
|
||||
[Description("生命值")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_HP_PERCENT = 3,
|
||||
|
||||
/// <summary>
|
||||
/// 基础攻击力
|
||||
/// </summary>
|
||||
[Description("基础攻击力")]
|
||||
[Format(FormatMethod.Integer)]
|
||||
FIGHT_PROP_BASE_ATTACK = 4,
|
||||
|
||||
/// <summary>
|
||||
@@ -46,12 +51,14 @@ public enum FightProperty
|
||||
/// 攻击力百分比
|
||||
/// </summary>
|
||||
[Description("攻击力")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_ATTACK_PERCENT = 6,
|
||||
|
||||
/// <summary>
|
||||
/// 基础防御力
|
||||
/// </summary>
|
||||
[Description("基础防御力")]
|
||||
[Format(FormatMethod.Integer)]
|
||||
FIGHT_PROP_BASE_DEFENSE = 7,
|
||||
|
||||
/// <summary>
|
||||
@@ -63,6 +70,7 @@ public enum FightProperty
|
||||
/// 防御力百分比
|
||||
/// </summary>
|
||||
[Description("防御力")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_DEFENSE_PERCENT = 9,
|
||||
|
||||
/// <summary>
|
||||
@@ -89,6 +97,7 @@ public enum FightProperty
|
||||
/// 暴击率
|
||||
/// </summary>
|
||||
[Description("暴击率")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_CRITICAL = 20,
|
||||
|
||||
/// <summary>
|
||||
@@ -100,12 +109,14 @@ public enum FightProperty
|
||||
/// 暴击伤害
|
||||
/// </summary>
|
||||
[Description("暴击伤害")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_CRITICAL_HURT = 22,
|
||||
|
||||
/// <summary>
|
||||
/// 元素充能效率
|
||||
/// </summary>
|
||||
[Description("元素充能效率")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_CHARGE_EFFICIENCY = 23,
|
||||
|
||||
/// <summary>
|
||||
@@ -122,6 +133,7 @@ public enum FightProperty
|
||||
/// 治疗提升
|
||||
/// </summary>
|
||||
[Description("治疗加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_HEAL_ADD = 26,
|
||||
|
||||
/// <summary>
|
||||
@@ -133,6 +145,7 @@ public enum FightProperty
|
||||
/// 元素精通
|
||||
/// </summary>
|
||||
[Description("元素精通")]
|
||||
[Format(FormatMethod.Integer)]
|
||||
FIGHT_PROP_ELEMENT_MASTERY = 28,
|
||||
|
||||
/// <summary>
|
||||
@@ -144,6 +157,7 @@ public enum FightProperty
|
||||
/// 物理伤害加成
|
||||
/// </summary>
|
||||
[Description("物理伤害加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_PHYSICAL_ADD_HURT = 30,
|
||||
|
||||
/// <summary>
|
||||
@@ -160,18 +174,21 @@ public enum FightProperty
|
||||
/// 火元素伤害加成
|
||||
/// </summary>
|
||||
[Description("火元素伤害加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_FIRE_ADD_HURT = 40,
|
||||
|
||||
/// <summary>
|
||||
/// 雷元素伤害加成
|
||||
/// </summary>
|
||||
[Description("雷元素伤害加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_ELEC_ADD_HURT = 41,
|
||||
|
||||
/// <summary>
|
||||
/// 水元素伤害加成
|
||||
/// </summary>
|
||||
[Description("水元素伤害加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_WATER_ADD_HURT = 42,
|
||||
|
||||
/// <summary>
|
||||
@@ -183,18 +200,21 @@ public enum FightProperty
|
||||
/// 风元素伤害加成
|
||||
/// </summary>
|
||||
[Description("风元素伤害加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_WIND_ADD_HURT = 44,
|
||||
|
||||
/// <summary>
|
||||
/// 岩元素伤害加成
|
||||
/// </summary>
|
||||
[Description("岩元素伤害加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_ROCK_ADD_HURT = 45,
|
||||
|
||||
/// <summary>
|
||||
/// 冰元素伤害加成
|
||||
/// </summary>
|
||||
[Description("冰元素伤害加成")]
|
||||
[Format(FormatMethod.Percent)]
|
||||
FIGHT_PROP_ICE_ADD_HURT = 46,
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Reflection;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Annotation;
|
||||
|
||||
/// <summary>
|
||||
/// 枚举拓展
|
||||
/// </summary>
|
||||
internal static class EnumExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取枚举的描述
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">枚举的类型</typeparam>
|
||||
/// <param name="enum">枚举值</param>
|
||||
/// <returns>描述</returns>
|
||||
internal static FormatMethod GetFormat<TEnum>(this TEnum @enum)
|
||||
where TEnum : struct, Enum
|
||||
{
|
||||
string enumName = Must.NotNull(Enum.GetName(@enum)!);
|
||||
FieldInfo? field = @enum.GetType().GetField(enumName);
|
||||
FormatAttribute? attr = field?.GetCustomAttribute<FormatAttribute>();
|
||||
return attr?.Method ?? FormatMethod.None;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Annotation;
|
||||
|
||||
/// <summary>
|
||||
/// 格式特性
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
|
||||
internal class FormatAttribute : Attribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 指示该字段应用的格式化方法
|
||||
/// </summary>
|
||||
/// <param name="method">格式化方法</param>
|
||||
public FormatAttribute(FormatMethod method)
|
||||
{
|
||||
Method = method;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 格式化方法
|
||||
/// </summary>
|
||||
public FormatMethod Method { get; init; }
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
namespace Snap.Hutao.Model.Metadata.Annotation;
|
||||
|
||||
/// <summary>
|
||||
/// 格式化方法
|
||||
/// </summary>
|
||||
internal enum FormatMethod
|
||||
{
|
||||
/// <summary>
|
||||
/// 无格式化
|
||||
/// </summary>
|
||||
None,
|
||||
|
||||
/// <summary>
|
||||
/// 取整
|
||||
/// </summary>
|
||||
Integer,
|
||||
|
||||
/// <summary>
|
||||
/// 百分比
|
||||
/// </summary>
|
||||
Percent,
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Snap.Hutao.Extension;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
|
||||
/// <summary>
|
||||
/// 战斗属性转换器
|
||||
/// </summary>
|
||||
internal class FightPropertyConverter : IValueConverter
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
return ((FightProperty)value).GetDescription();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw Must.NeverHappen();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Metadata.Annotation;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
|
||||
/// <summary>
|
||||
/// 战斗属性数值格式化器
|
||||
/// </summary>
|
||||
internal class FightPropertyValueFormatter : IValueConverter
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
FormatMethod method = ((FightProperty)parameter).GetFormat();
|
||||
|
||||
return method switch
|
||||
{
|
||||
FormatMethod.Integer => Math.Round((double)value, MidpointRounding.AwayFromZero),
|
||||
FormatMethod.Percent => string.Format("{0:P1}", value),
|
||||
_ => value,
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw Must.NeverHappen();
|
||||
}
|
||||
}
|
||||
@@ -23,4 +23,4 @@ internal class IconConverter : IValueConverter
|
||||
{
|
||||
throw Must.NeverHappen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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;
|
||||
|
||||
/// <summary>
|
||||
/// 物品等级转换器
|
||||
/// </summary>
|
||||
internal class QualityConverter : IValueConverter
|
||||
{
|
||||
private const string BaseUrl = "https://static.snapgenshin.com/Bg/UI_{0}.png";
|
||||
|
||||
/// <inheritdoc/>
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
string? name = value.ToString();
|
||||
if (name == nameof(ItemQuality.QUALITY_ORANGE_SP))
|
||||
{
|
||||
name = "QUALITY_RED";
|
||||
}
|
||||
|
||||
return new Uri(string.Format(BaseUrl, name));
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw Must.NeverHappen();
|
||||
}
|
||||
}
|
||||
@@ -19,5 +19,5 @@ public class LevelParam<TLevel>
|
||||
/// <summary>
|
||||
/// 参数
|
||||
/// </summary>
|
||||
public IEnumerable<double> Parameters { get; set; } = default!;
|
||||
public IList<double> Parameters { get; set; } = default!;
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
<Identity
|
||||
Name="7f0db578-026f-4e0b-a75b-d5d06bb0a74d"
|
||||
Publisher="CN=DGP Studio"
|
||||
Version="1.0.9.0" />
|
||||
Version="1.0.10.0" />
|
||||
|
||||
<Properties>
|
||||
<DisplayName>胡桃</DisplayName>
|
||||
|
||||
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Font/Segoe Fluent Icons.ttf
Normal file
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Font/Segoe Fluent Icons.ttf
Normal file
Binary file not shown.
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_BagTabIcon_Avatar.png
Normal file
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_BagTabIcon_Avatar.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.2 KiB |
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_BagTabIcon_Weapon.png
Normal file
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_BagTabIcon_Weapon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 4.2 KiB |
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_Icon_Achievement.png
Normal file
BIN
src/Snap.Hutao/Snap.Hutao/Resource/Icon/UI_Icon_Achievement.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.2 KiB |
17
src/Snap.Hutao/Snap.Hutao/Service/IMetadataInitializer.cs
Normal file
17
src/Snap.Hutao/Snap.Hutao/Service/IMetadataInitializer.cs
Normal file
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Service.Metadata;
|
||||
|
||||
/// <summary>
|
||||
/// 指示该类为元数据初始化器
|
||||
/// </summary>
|
||||
public interface IMetadataInitializer
|
||||
{
|
||||
/// <summary>
|
||||
/// 异步初始化元数据
|
||||
/// </summary>
|
||||
/// <param name="token">取消令牌</param>
|
||||
/// <returns>任务</returns>
|
||||
Task InitializeInternalAsync(CancellationToken token = default);
|
||||
}
|
||||
@@ -21,7 +21,7 @@ namespace Snap.Hutao.Service.Metadata;
|
||||
/// 元数据服务
|
||||
/// </summary>
|
||||
[Injection(InjectAs.Singleton, typeof(IMetadataService))]
|
||||
internal class MetadataService : IMetadataService, ISupportAsyncInitialization
|
||||
internal class MetadataService : IMetadataService, IMetadataInitializer, ISupportAsyncInitialization
|
||||
{
|
||||
private const string MetaAPIHost = "http://hutao-metadata.snapgenshin.com";
|
||||
private const string MetaFileName = "Meta.json";
|
||||
@@ -32,6 +32,11 @@ internal class MetadataService : IMetadataService, ISupportAsyncInitialization
|
||||
private readonly ILogger<MetadataService> logger;
|
||||
private readonly IMemoryCache memoryCache;
|
||||
|
||||
/// <summary>
|
||||
/// 用于指示初始化是否完成
|
||||
/// </summary>
|
||||
private readonly TaskCompletionSource initializeCompletionSource = new();
|
||||
|
||||
private bool isInitialized = false;
|
||||
|
||||
/// <summary>
|
||||
@@ -65,36 +70,23 @@ internal class MetadataService : IMetadataService, ISupportAsyncInitialization
|
||||
/// <inheritdoc/>
|
||||
public async ValueTask<bool> InitializeAsync(CancellationToken token = default)
|
||||
{
|
||||
if (IsInitialized)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
metadataContext.EnsureDirectory();
|
||||
if (metadataContext.FileExists(MetaFileName))
|
||||
{
|
||||
IDictionary<string, string>? metaMd5Map;
|
||||
using (Stream metaFile = metadataContext.OpenRead(MetaFileName))
|
||||
{
|
||||
metaMd5Map = await JsonSerializer
|
||||
.DeserializeAsync<IDictionary<string, string>>(metaFile, options, token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await CheckMetadataAsync(Must.NotNull(metaMd5Map!), token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
IsInitialized = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
IsInitialized = await UpdateMetadataAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await initializeCompletionSource.Task;
|
||||
return IsInitialized;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task InitializeInternalAsync(CancellationToken token = default)
|
||||
{
|
||||
logger.LogInformation("元数据初始化开始");
|
||||
metadataContext.EnsureDirectory();
|
||||
|
||||
IsInitialized = await UpdateMetadataAsync(token)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
initializeCompletionSource.SetResult();
|
||||
logger.LogInformation("元数据初始化完成");
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task<bool> UpdateMetadataAsync(CancellationToken token = default)
|
||||
{
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Core.Logging;
|
||||
using Snap.Hutao.Core.Setting;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
using Snap.Hutao.View.Helper;
|
||||
using Snap.Hutao.View.Page;
|
||||
@@ -47,6 +48,8 @@ internal class NavigationService : INavigationService
|
||||
{
|
||||
navigationView.ItemInvoked -= OnItemInvoked;
|
||||
navigationView.BackRequested -= OnBackRequested;
|
||||
navigationView.PaneClosed -= OnPaneStateChanged;
|
||||
navigationView.PaneOpened -= OnPaneStateChanged;
|
||||
}
|
||||
|
||||
navigationView = Must.NotNull(value!);
|
||||
@@ -56,6 +59,8 @@ internal class NavigationService : INavigationService
|
||||
{
|
||||
navigationView.ItemInvoked += OnItemInvoked;
|
||||
navigationView.BackRequested += OnBackRequested;
|
||||
navigationView.PaneClosed += OnPaneStateChanged;
|
||||
navigationView.PaneOpened += OnPaneStateChanged;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -154,6 +159,8 @@ internal class NavigationService : INavigationService
|
||||
{
|
||||
NavigationView = navigationView;
|
||||
Frame = frame;
|
||||
|
||||
NavigationView.IsPaneOpen = LocalSetting.GetValueType(SettingKeys.IsNavPaneOpen, true);
|
||||
}
|
||||
|
||||
private void OnItemInvoked(NavigationView sender, NavigationViewItemInvokedEventArgs args)
|
||||
@@ -175,4 +182,9 @@ internal class NavigationService : INavigationService
|
||||
SyncSelectedNavigationViewItemWith(Frame.Content.GetType());
|
||||
}
|
||||
}
|
||||
|
||||
private void OnPaneStateChanged(NavigationView sender, object args)
|
||||
{
|
||||
LocalSetting.SetValueType(SettingKeys.IsNavPaneOpen, NavigationView!.IsPaneOpen);
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Remove="Resource\Icon\UI_BagTabIcon_Avatar.png" />
|
||||
<None Remove="Resource\Icon\UI_BagTabIcon_Weapon.png" />
|
||||
<None Remove="Resource\Icon\UI_BtnIcon_ActivityEntry.png" />
|
||||
<None Remove="Resource\Icon\UI_Icon_Achievement.png" />
|
||||
<None Remove="Resource\Segoe Fluent Icons.ttf" />
|
||||
<None Remove="stylecop.json" />
|
||||
<None Remove="View\Control\ItemIcon.xaml" />
|
||||
<None Remove="View\Dialog\UserDialog.xaml" />
|
||||
<None Remove="View\MainView.xaml" />
|
||||
<None Remove="View\Page\AchievementPage.xaml" />
|
||||
@@ -53,6 +59,11 @@
|
||||
<Content Include="Assets\Square44x44Logo.targetsize-24_altform-unplated.png" />
|
||||
<Content Include="Assets\StoreLogo.png" />
|
||||
<Content Include="Assets\Wide310x150Logo.scale-200.png" />
|
||||
<Content Include="Resource\Font\Segoe Fluent Icons.ttf" />
|
||||
<Content Include="Resource\Icon\UI_BagTabIcon_Avatar.png" />
|
||||
<Content Include="Resource\Icon\UI_BagTabIcon_Weapon.png" />
|
||||
<Content Include="Resource\Icon\UI_BtnIcon_ActivityEntry.png" />
|
||||
<Content Include="Resource\Icon\UI_Icon_Achievement.png" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
@@ -153,4 +164,9 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Update="View\Control\ItemIcon.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
||||
27
src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml
Normal file
27
src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml
Normal file
@@ -0,0 +1,27 @@
|
||||
<UserControl
|
||||
x:Class="Snap.Hutao.View.Control.ItemIcon"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Snap.Hutao.View.Control"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:shci="using:Snap.Hutao.Control.Image"
|
||||
xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter"
|
||||
mc:Ignorable="d"
|
||||
Width="64"
|
||||
Height="64">
|
||||
<UserControl.Resources>
|
||||
<shmmc:IconConverter x:Key="IconConverter"/>
|
||||
<shmmc:QualityConverter x:Key="QualityConverter"/>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<Grid CornerRadius="{StaticResource CompatCornerRadius}">
|
||||
<shci:CachedImage
|
||||
Source="{x:Bind Quality,Converter={StaticResource QualityConverter},Mode=OneWay}"/>
|
||||
<shci:CachedImage
|
||||
Source="https://static.snapgenshin.com/Bg/UI_ImgSign_ItemIcon.png"/>
|
||||
<shci:CachedImage
|
||||
Source="{x:Bind Icon,Mode=OneWay}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
44
src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml.cs
Normal file
44
src/Snap.Hutao/Snap.Hutao/View/Control/ItemIcon.xaml.cs
Normal file
@@ -0,0 +1,44 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Snap.Hutao.Core;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
|
||||
namespace Snap.Hutao.View.Control;
|
||||
|
||||
/// <summary>
|
||||
/// 物品图标
|
||||
/// </summary>
|
||||
public sealed partial class ItemIcon : UserControl
|
||||
{
|
||||
private static readonly DependencyProperty QualityProperty = Property<ItemIcon>.Depend(nameof(Quality), ItemQuality.QUALITY_NONE);
|
||||
private static readonly DependencyProperty IconProperty = Property<ItemIcon>.Depend<Uri>(nameof(Icon));
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的物品图标
|
||||
/// </summary>
|
||||
public ItemIcon()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 等阶
|
||||
/// </summary>
|
||||
public ItemQuality Quality
|
||||
{
|
||||
get => (ItemQuality)GetValue(QualityProperty);
|
||||
set => SetValue(QualityProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 图标
|
||||
/// </summary>
|
||||
public Uri Icon
|
||||
{
|
||||
get => (Uri)GetValue(IconProperty);
|
||||
set => SetValue(IconProperty, value);
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,9 @@
|
||||
xmlns:page="using:Snap.Hutao.View.Page"
|
||||
xmlns:view="using:Snap.Hutao.View"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<UserControl.Resources>
|
||||
<Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<!-- x:Bind can't get property update here seems like a WinUI 3 bug-->
|
||||
<NavigationView
|
||||
@@ -24,19 +26,19 @@
|
||||
|
||||
<NavigationViewItem Content="活动" helper:NavHelper.NavigateTo="page:AnnouncementPage">
|
||||
<NavigationViewItem.Icon>
|
||||
<FontIcon Glyph=""/>
|
||||
<BitmapIcon UriSource="ms-appx:///Resource/Icon/UI_BtnIcon_ActivityEntry.png"/>
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
|
||||
<NavigationViewItem Content="成就" helper:NavHelper.NavigateTo="page:AchievementPage">
|
||||
<NavigationViewItem.Icon>
|
||||
<FontIcon Glyph=""/>
|
||||
<BitmapIcon UriSource="ms-appx:///Resource/Icon/UI_Icon_Achievement.png"/>
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
|
||||
<NavigationViewItem Content="角色" helper:NavHelper.NavigateTo="page:WikiAvatarPage">
|
||||
<NavigationViewItem.Icon>
|
||||
<FontIcon Glyph=""/>
|
||||
<BitmapIcon UriSource="ms-appx:///Resource/Icon/UI_BagTabIcon_Avatar.png"/>
|
||||
</NavigationViewItem.Icon>
|
||||
</NavigationViewItem>
|
||||
|
||||
|
||||
@@ -1,32 +1,206 @@
|
||||
<Page
|
||||
x:Class="Snap.Hutao.View.Page.WikiAvatarPage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="using:Snap.Hutao.View.Page"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance Type=shv:WikiAvatarViewModel}"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Loaded">
|
||||
<mxic:InvokeCommandAction Command="{Binding OpenUICommand}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
<Page.Resources>
|
||||
<shmmc:IconConverter x:Key="IconConverter"/>
|
||||
<shmmc:FightPropertyConverter x:Key="FightPropertyConverter"/>
|
||||
<shmmc:FightPropertyValueFormatter x:Key="FightPropertyValueFormatter"/>
|
||||
<shc:BindingProxy
|
||||
x:Key="FightPropertyBindingProxy"
|
||||
DataContext="{Binding Selected.Property.Properties}"/>
|
||||
|
||||
<SolidColorBrush
|
||||
x:Key="SystemControlPageBackgroundChromeLowBrush"
|
||||
Color="{StaticResource SystemChromeLowColor}"
|
||||
Opacity="0.2"/>
|
||||
</Page.Resources>
|
||||
<Grid>
|
||||
<SplitView IsPaneOpen="True" DisplayMode="Inline">
|
||||
<SplitView
|
||||
IsPaneOpen="True"
|
||||
DisplayMode="Inline"
|
||||
OpenPaneLength="374">
|
||||
<SplitView.Pane>
|
||||
<ListView
|
||||
<GridView
|
||||
SelectionMode="Single"
|
||||
ItemsSource="{Binding Avatars}"
|
||||
SelectedItem="{Binding Selected,Mode=TwoWay}"/>
|
||||
Padding="16,16,0,12"
|
||||
SelectedItem="{Binding Selected,Mode=TwoWay}">
|
||||
<GridView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<shvc:ItemIcon
|
||||
Quality="{Binding Quality,Mode=OneWay}"
|
||||
Icon="{Binding Icon,Converter={StaticResource IconConverter},Mode=OneWay}"/>
|
||||
</DataTemplate>
|
||||
</GridView.ItemTemplate>
|
||||
</GridView>
|
||||
</SplitView.Pane>
|
||||
<SplitView.Content>
|
||||
<Grid>
|
||||
<TextBlock
|
||||
Text="{Binding Selected.Name}"/>
|
||||
</Grid>
|
||||
<ScrollViewer>
|
||||
<StackPanel Margin="0,0,16,16">
|
||||
<!--头图-->
|
||||
<Grid
|
||||
Margin="16,16,0,16"
|
||||
VerticalAlignment="Top">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<shvc:ItemIcon
|
||||
Grid.Column="0"
|
||||
Height="100"
|
||||
Width="100"
|
||||
Quality="{Binding Selected.Quality,Mode=OneWay}"
|
||||
Icon="{Binding Selected.Icon,Converter={StaticResource IconConverter},Mode=OneWay}"/>
|
||||
<StackPanel
|
||||
Margin="16,0,0,0"
|
||||
Grid.Column="1">
|
||||
<TextBlock
|
||||
Text="{Binding Selected.Name}"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"/>
|
||||
<TextBlock
|
||||
Margin="0,6,0,0"
|
||||
Text="{Binding Selected.Description}"
|
||||
MaxLines="2"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"/>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
<!--属性-->
|
||||
<Expander
|
||||
Margin="16,0,0,0"
|
||||
Header="基础数值"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch">
|
||||
<Grid Margin="16">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<cwuc:UniformGrid
|
||||
Grid.Row="0"
|
||||
Columns="5"
|
||||
DataContext="{Binding Selected.Property}"
|
||||
x:Name="PropertyGrid">
|
||||
<TextBlock
|
||||
Style="{StaticResource BaseTextBlockStyle}"
|
||||
TextWrapping="NoWrap"
|
||||
Text="等级"/>
|
||||
<TextBlock
|
||||
TextWrapping="NoWrap"
|
||||
Style="{StaticResource BaseTextBlockStyle}"
|
||||
Text="{Binding Properties[0], Converter={StaticResource FightPropertyConverter}}"/>
|
||||
<TextBlock
|
||||
TextWrapping="NoWrap"
|
||||
Style="{StaticResource BaseTextBlockStyle}"
|
||||
Text="{Binding Properties[1], Converter={StaticResource FightPropertyConverter}}"/>
|
||||
<TextBlock
|
||||
TextWrapping="NoWrap"
|
||||
Style="{StaticResource BaseTextBlockStyle}"
|
||||
Text="{Binding Properties[2], Converter={StaticResource FightPropertyConverter}}"/>
|
||||
<TextBlock
|
||||
TextWrapping="NoWrap"
|
||||
Style="{StaticResource BaseTextBlockStyle}"
|
||||
Text="{Binding Properties[3], Converter={StaticResource FightPropertyConverter}}"/>
|
||||
</cwuc:UniformGrid>
|
||||
<ItemsControl
|
||||
Margin="0,6,0,0"
|
||||
Grid.Row="1"
|
||||
ItemsSource="{Binding Selected.Property.Parameters}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<cwuc:UniformGrid
|
||||
Columns="5">
|
||||
<TextBlock
|
||||
Text="{Binding Level}"/>
|
||||
<TextBlock
|
||||
Text="{Binding Parameters[0],
|
||||
Converter={StaticResource FightPropertyValueFormatter},
|
||||
ConverterParameter={Binding DataContext[0],Source={StaticResource FightPropertyBindingProxy}}}"/>
|
||||
<TextBlock
|
||||
Text="{Binding Parameters[1],
|
||||
Converter={StaticResource FightPropertyValueFormatter},
|
||||
ConverterParameter={Binding DataContext[1],Source={StaticResource FightPropertyBindingProxy}}}"/>
|
||||
<TextBlock
|
||||
Text="{Binding Parameters[2],
|
||||
Converter={StaticResource FightPropertyValueFormatter},
|
||||
ConverterParameter={Binding DataContext[2],Source={StaticResource FightPropertyBindingProxy}}}"/>
|
||||
<TextBlock
|
||||
Text="{Binding Parameters[3],
|
||||
Converter={StaticResource FightPropertyValueFormatter},
|
||||
ConverterParameter={Binding DataContext[3],Source={StaticResource FightPropertyBindingProxy}}}"/>
|
||||
</cwuc:UniformGrid>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Grid>
|
||||
</Expander>
|
||||
<!--资料-->
|
||||
<Expander
|
||||
Margin="16,16,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Header="语音">
|
||||
<ItemsControl
|
||||
ItemsSource="{Binding Selected.FetterInfo.Fetters}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Margin="0,0,0,-4">
|
||||
<TextBlock
|
||||
Margin="16,16,16,0"
|
||||
Text="{Binding Title}"/>
|
||||
<TextBlock
|
||||
Margin="16,8,16,16"
|
||||
Text="{Binding Context}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"/>
|
||||
<MenuFlyoutSeparator Margin="16,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Expander>
|
||||
<!--故事-->
|
||||
<Expander
|
||||
Margin="16,16,0,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
Header="故事">
|
||||
<ItemsControl
|
||||
ItemsSource="{Binding Selected.FetterInfo.FetterStories}">
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel Margin="0,0,0,-4">
|
||||
<TextBlock
|
||||
Margin="16,16,16,0"
|
||||
Text="{Binding Title}"/>
|
||||
<TextBlock
|
||||
Margin="16,8,16,16"
|
||||
Text="{Binding Context}"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"/>
|
||||
<MenuFlyoutSeparator Margin="16,0"/>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</Expander>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</SplitView.Content>
|
||||
</SplitView>
|
||||
</Grid>
|
||||
|
||||
@@ -1,21 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using Snap.Hutao.ViewModel;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
|
||||
namespace Snap.Hutao.View.Page;
|
||||
|
||||
|
||||
@@ -13,6 +13,6 @@
|
||||
TextWrapping="NoWrap"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="12,0,0,0"/>
|
||||
Margin="4,0,0,0"/>
|
||||
</Grid>
|
||||
</UserControl>
|
||||
|
||||
@@ -6,6 +6,7 @@ using Snap.Hutao.Factory.Abstraction;
|
||||
using Snap.Hutao.Model.Metadata.Avatar;
|
||||
using Snap.Hutao.Service.Metadata;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Snap.Hutao.ViewModel;
|
||||
|
||||
@@ -51,7 +52,12 @@ internal class WikiAvatarViewModel : ObservableObject
|
||||
if (await metadataService.InitializeAsync())
|
||||
{
|
||||
IEnumerable<Avatar>? avatars = await metadataService.GetAvatarsAsync();
|
||||
Avatars = new List<Avatar>(avatars);
|
||||
IOrderedEnumerable<Avatar> sorted = avatars
|
||||
.OrderBy(avatar => avatar.BeginTime)
|
||||
.ThenBy(avatar => avatar.Sort);
|
||||
|
||||
Avatars = new List<Avatar>(sorted);
|
||||
Selected = Avatars[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user