mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
impl #1497
This commit is contained in:
@@ -13,7 +13,7 @@ namespace Snap.Hutao.Model.Entity;
|
||||
/// 成就存档
|
||||
/// </summary>
|
||||
[Table("achievement_archives")]
|
||||
internal sealed class AchievementArchive : ISelectable,
|
||||
internal sealed partial class AchievementArchive : ISelectable,
|
||||
IAdvancedCollectionViewItem,
|
||||
IMappingFrom<AchievementArchive, string>
|
||||
{
|
||||
@@ -43,12 +43,4 @@ internal sealed class AchievementArchive : ISelectable,
|
||||
{
|
||||
return new() { Name = name };
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
_ => default!,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace Snap.Hutao.Model.Entity;
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[Table("cultivate_projects")]
|
||||
internal sealed class CultivateProject : ISelectable,
|
||||
internal sealed partial class CultivateProject : ISelectable,
|
||||
IAdvancedCollectionViewItem,
|
||||
IMappingFrom<CultivateProject, string, string>
|
||||
{
|
||||
@@ -50,12 +50,4 @@ internal sealed class CultivateProject : ISelectable,
|
||||
{
|
||||
return new() { Name = name, AttachedUid = attachedUid };
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -42,12 +42,4 @@ internal sealed partial class GachaArchive : ISelectable,
|
||||
{
|
||||
return new() { Uid = uid };
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,7 @@ namespace Snap.Hutao.Model.Entity;
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[Table("game_accounts")]
|
||||
internal sealed class GameAccount : ObservableObject,
|
||||
internal sealed partial class GameAccount : ObservableObject,
|
||||
IAppDbEntity,
|
||||
IReorderable,
|
||||
IAdvancedCollectionViewItem,
|
||||
@@ -82,12 +82,4 @@ internal sealed class GameAccount : ObservableObject,
|
||||
Name = name;
|
||||
OnPropertyChanged($"{nameof(Name)}");
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string propertyName)
|
||||
{
|
||||
return propertyName switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -117,12 +117,4 @@ internal partial class Avatar : INameQualityAccess,
|
||||
IsUp = isUp,
|
||||
};
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string propertyName)
|
||||
{
|
||||
return propertyName switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Snap.Hutao.Model.Metadata.Monster;
|
||||
/// <summary>
|
||||
/// 敌对生物
|
||||
/// </summary>
|
||||
internal sealed class Monster : IAdvancedCollectionViewItem
|
||||
internal sealed partial class Monster : IAdvancedCollectionViewItem
|
||||
{
|
||||
internal const uint MaxLevel = 100;
|
||||
|
||||
@@ -90,12 +90,4 @@ internal sealed class Monster : IAdvancedCollectionViewItem
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public List<DisplayItem>? DropsView { get; set; }
|
||||
|
||||
public object? GetPropertyValue(string propertyName)
|
||||
{
|
||||
return propertyName switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -106,12 +106,4 @@ internal sealed partial class Weapon : INameQualityAccess,
|
||||
IsUp = isUp,
|
||||
};
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string propertyName)
|
||||
{
|
||||
return propertyName switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -1568,6 +1568,12 @@
|
||||
<data name="ViewModelAvatarPropertyShowcaseNotOpen" xml:space="preserve">
|
||||
<value>角色展柜尚未开启,请前往游戏操作后重试</value>
|
||||
</data>
|
||||
<data name="ViewModelAvatatPropertyExportTextError" xml:space="preserve">
|
||||
<value>复制角色详情失败</value>
|
||||
</data>
|
||||
<data name="ViewModelAvatatPropertyExportTextSuccess" xml:space="preserve">
|
||||
<value>复制角色详情成功</value>
|
||||
</data>
|
||||
<data name="ViewModelComplexReliquarySetViewEmptyName" xml:space="preserve">
|
||||
<value>无圣遗物或散件</value>
|
||||
</data>
|
||||
@@ -1889,6 +1895,9 @@
|
||||
<data name="ViewPageAvatarPropertyExportAsImage" xml:space="preserve">
|
||||
<value>导出图片</value>
|
||||
</data>
|
||||
<data name="ViewPageAvatarPropertyExportToTextLabel" xml:space="preserve">
|
||||
<value>导出文本到剪贴板</value>
|
||||
</data>
|
||||
<data name="ViewPageAvatarPropertyHeader" xml:space="preserve">
|
||||
<value>角色属性</value>
|
||||
</data>
|
||||
|
||||
@@ -10,6 +10,13 @@ namespace Snap.Hutao.Service.AvatarInfo.Factory.Builder;
|
||||
|
||||
internal static class EquipViewBuilderExtension
|
||||
{
|
||||
public static TBuilder SetEquipType<TBuilder, T>(this TBuilder builder, EquipType equipType)
|
||||
where TBuilder : IEquipViewBuilder<T>
|
||||
where T : EquipView
|
||||
{
|
||||
return builder.Configure(b => b.View.EquipType = equipType);
|
||||
}
|
||||
|
||||
public static TBuilder SetLevel<TBuilder, T>(this TBuilder builder, string level)
|
||||
where TBuilder : IEquipViewBuilder<T>
|
||||
where T : EquipView
|
||||
|
||||
@@ -22,6 +22,12 @@ internal static class ReliquaryViewBuilderExtension
|
||||
return builder.SetDescription<TBuilder, ReliquaryView>(description);
|
||||
}
|
||||
|
||||
public static TBuilder SetEquipType<TBuilder>(this TBuilder builder, EquipType equipType)
|
||||
where TBuilder : IReliquaryViewBuilder
|
||||
{
|
||||
return builder.SetEquipType<TBuilder, ReliquaryView>(equipType);
|
||||
}
|
||||
|
||||
public static TBuilder SetIcon<TBuilder>(this TBuilder builder, Uri icon)
|
||||
where TBuilder : IReliquaryViewBuilder
|
||||
{
|
||||
@@ -63,4 +69,10 @@ internal static class ReliquaryViewBuilderExtension
|
||||
{
|
||||
return builder.Configure(b => b.View.SecondarySubProperties = secondarySubProperties);
|
||||
}
|
||||
|
||||
public static TBuilder SetSetName<TBuilder>(this TBuilder builder, string setName)
|
||||
where TBuilder : IReliquaryViewBuilder
|
||||
{
|
||||
return builder.Configure(b => b.View.SetName = setName);
|
||||
}
|
||||
}
|
||||
@@ -37,6 +37,12 @@ internal static class WeaponViewBuilderExtension
|
||||
return builder.SetDescription<TBuilder, WeaponView>(description);
|
||||
}
|
||||
|
||||
public static TBuilder SetEquipType<TBuilder>(this TBuilder builder, EquipType equipType)
|
||||
where TBuilder : IWeaponViewBuilder
|
||||
{
|
||||
return builder.SetEquipType<TBuilder, WeaponView>(equipType);
|
||||
}
|
||||
|
||||
public static TBuilder SetIcon<TBuilder>(this TBuilder builder, Uri icon)
|
||||
where TBuilder : IWeaponViewBuilder
|
||||
{
|
||||
@@ -85,7 +91,7 @@ internal static class WeaponViewBuilderExtension
|
||||
return builder.SetQuality<TBuilder, WeaponView>(quality);
|
||||
}
|
||||
|
||||
public static TBuilder SetSubProperty<TBuilder>(this TBuilder builder, NameDescription subProperty)
|
||||
public static TBuilder SetSubProperty<TBuilder>(this TBuilder builder, NameValue<string> subProperty)
|
||||
where TBuilder : IWeaponViewBuilder
|
||||
{
|
||||
return builder.Configure(b => b.View.SubProperty = subProperty);
|
||||
|
||||
@@ -102,17 +102,17 @@ internal sealed class SummaryAvatarFactory
|
||||
WeaponStat? mainStat = equip.Flat.WeaponStats?.ElementAtOrDefault(0);
|
||||
WeaponStat? subStat = equip.Flat.WeaponStats?.ElementAtOrDefault(1);
|
||||
|
||||
NameDescription subProperty;
|
||||
NameValue<string> subProperty;
|
||||
if (subStat is null)
|
||||
{
|
||||
subProperty = NameDescription.Default;
|
||||
subProperty = NameValueDefaults.String;
|
||||
}
|
||||
else
|
||||
{
|
||||
float statValue = subStat.AppendPropId.GetFormatMethod() is FormatMethod.Percent
|
||||
? subStat.StatValue / 100F
|
||||
: subStat.StatValue;
|
||||
subProperty = FightPropertyFormat.ToNameDescription(subStat.AppendPropId, statValue);
|
||||
subProperty = FightPropertyFormat.ToNameValue(subStat.AppendPropId, statValue);
|
||||
}
|
||||
|
||||
ArgumentNullException.ThrowIfNull(equip.Weapon);
|
||||
@@ -123,6 +123,7 @@ internal sealed class SummaryAvatarFactory
|
||||
.SetDescription(weapon.Description)
|
||||
.SetLevel(LevelFormat.Format(equip.Weapon.Level))
|
||||
.SetQuality(weapon.Quality)
|
||||
.SetEquipType(EquipType.EQUIP_WEAPON)
|
||||
.SetMainProperty(mainStat)
|
||||
.SetId(weapon.Id)
|
||||
.SetLevelNumber(equip.Weapon.Level)
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace Snap.Hutao.Service.AvatarInfo.Factory;
|
||||
internal sealed partial class SummaryFactory : ISummaryFactory
|
||||
{
|
||||
private readonly IMetadataService metadataService;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async ValueTask<Summary> CreateAsync(IEnumerable<Model.Entity.AvatarInfo> avatarInfos, CancellationToken token)
|
||||
@@ -34,9 +35,13 @@ internal sealed partial class SummaryFactory : ISummaryFactory
|
||||
.ThenBy(a => a.Weapon?.WeaponType)
|
||||
.ThenByDescending(a => a.FetterLevel);
|
||||
|
||||
IList<AvatarView> views = [.. avatars];
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
|
||||
return new()
|
||||
{
|
||||
Avatars = [.. avatars],
|
||||
Avatars = new(views, true),
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@ internal sealed class SummaryFactoryMetadataContext : IMetadataContext,
|
||||
IMetadataDictionaryIdWeaponSource,
|
||||
IMetadataDictionaryIdReliquaryAffixWeightSource,
|
||||
IMetadataDictionaryIdReliquaryMainPropertySource,
|
||||
IMetadataDictionaryIdReliquarySetSource,
|
||||
IMetadataDictionaryIdReliquarySubAffixSource,
|
||||
IMetadataDictionaryIdReliquarySource,
|
||||
IMetadataListReliquaryMainAffixLevelSource
|
||||
@@ -31,6 +32,8 @@ internal sealed class SummaryFactoryMetadataContext : IMetadataContext,
|
||||
|
||||
public Dictionary<ReliquarySubAffixId, ReliquarySubAffix> IdReliquarySubAffixMap { get; set; } = default!;
|
||||
|
||||
public Dictionary<ReliquarySetId, ReliquarySet> IdReliquarySetMap { get; set; } = default!;
|
||||
|
||||
public List<ReliquaryMainAffixLevel> ReliquaryMainAffixLevels { get; set; } = default!;
|
||||
|
||||
public Dictionary<ReliquaryId, MetadataReliquary> IdReliquaryMap { get; set; } = default!;
|
||||
|
||||
@@ -36,6 +36,7 @@ internal sealed class SummaryReliquaryFactory
|
||||
public ReliquaryView Create()
|
||||
{
|
||||
MetadataReliquary reliquary = metadataContext.IdReliquaryMap[equip.ItemId];
|
||||
ReliquarySet reliquarySet = metadataContext.IdReliquarySetMap[reliquary.SetId];
|
||||
|
||||
ArgumentNullException.ThrowIfNull(equip.Reliquary);
|
||||
List<ReliquarySubProperty> subProperties = equip.Reliquary.AppendPropIdList.EmptyIfNull().SelectList(CreateSubProperty);
|
||||
@@ -45,7 +46,9 @@ internal sealed class SummaryReliquaryFactory
|
||||
.SetIcon(RelicIconConverter.IconNameToUri(reliquary.Icon))
|
||||
.SetDescription(reliquary.Description)
|
||||
.SetLevel($"+{equip.Reliquary.Level - 1U}")
|
||||
.SetQuality(reliquary.RankLevel);
|
||||
.SetQuality(reliquary.RankLevel)
|
||||
.SetEquipType(reliquary.EquipType)
|
||||
.SetSetName(reliquarySet.Name);
|
||||
|
||||
int affixCount = GetSecondaryAffixCount(reliquary, equip.Reliquary);
|
||||
|
||||
|
||||
@@ -18,13 +18,6 @@ internal interface IGameServiceFacade
|
||||
/// 游戏内账号集合
|
||||
/// </summary>
|
||||
ObservableReorderableDbCollection<GameAccount> GameAccountCollection { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 将账号绑定到对应的Uid
|
||||
/// 清除老账号的绑定状态
|
||||
/// </summary>
|
||||
/// <param name="gameAccount">游戏内账号</param>
|
||||
/// <param name="uid">uid</param>
|
||||
ValueTask AttachGameAccountToUidAsync(GameAccount gameAccount, string uid);
|
||||
|
||||
ValueTask<GameAccount?> DetectGameAccountAsync(SchemeType scheme);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Metadata.Reliquary;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
|
||||
namespace Snap.Hutao.Service.Metadata.ContextAbstraction;
|
||||
|
||||
internal interface IMetadataDictionaryIdReliquarySetSource
|
||||
{
|
||||
Dictionary<ReliquarySetId, ReliquarySet> IdReliquarySetMap { get; set; }
|
||||
}
|
||||
@@ -86,6 +86,11 @@ internal static class MetadataServiceContextExtension
|
||||
dictionaryIdReliquaryMainPropertySource.IdReliquaryMainPropertyMap = await metadataService.GetIdToReliquaryMainPropertyMapAsync(token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (context is IMetadataDictionaryIdReliquarySetSource dictionaryIdReliquarySetSource)
|
||||
{
|
||||
dictionaryIdReliquarySetSource.IdReliquarySetMap = await metadataService.GetIdToReliquarySetMapAsync(token).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
if (context is IMetadataDictionaryIdReliquarySubAffixSource dictionaryIdReliquarySubAffixSource)
|
||||
{
|
||||
dictionaryIdReliquarySubAffixSource.IdReliquarySubAffixMap = await metadataService.GetIdToReliquarySubAffixMapAsync(token).ConfigureAwait(false);
|
||||
|
||||
@@ -86,6 +86,11 @@ internal static class MetadataServiceDictionaryExtension
|
||||
return metadataService.FromCacheAsDictionaryAsync<ReliquaryMainAffix, ReliquaryMainAffixId, FightProperty>(FileNameReliquaryMainAffix, r => r.Id, r => r.Type, token);
|
||||
}
|
||||
|
||||
public static ValueTask<Dictionary<ReliquarySetId, ReliquarySet>> GetIdToReliquarySetMapAsync(this IMetadataService metadataService, CancellationToken token = default)
|
||||
{
|
||||
return metadataService.FromCacheAsDictionaryAsync<ReliquarySetId, ReliquarySet>(FileNameReliquarySet, r => r.SetId, token);
|
||||
}
|
||||
|
||||
public static ValueTask<Dictionary<ReliquarySubAffixId, ReliquarySubAffix>> GetIdToReliquarySubAffixMapAsync(this IMetadataService metadataService, CancellationToken token = default)
|
||||
{
|
||||
return metadataService.FromCacheAsDictionaryAsync<ReliquarySubAffixId, ReliquarySubAffix>(FileNameReliquarySubAffix, a => a.Id, token);
|
||||
|
||||
@@ -8,20 +8,15 @@ namespace Snap.Hutao.Service.Notification;
|
||||
|
||||
/// <inheritdoc/>
|
||||
[HighQuality]
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Singleton, typeof(IInfoBarService))]
|
||||
internal sealed class InfoBarService : IInfoBarService
|
||||
internal sealed partial class InfoBarService : IInfoBarService
|
||||
{
|
||||
private readonly ILogger<InfoBarService> logger;
|
||||
private readonly ITaskContext taskContext;
|
||||
|
||||
private ObservableCollection<InfoBarOptions>? collection;
|
||||
|
||||
public InfoBarService(IServiceProvider serviceProvider)
|
||||
{
|
||||
logger = serviceProvider.GetRequiredService<ILogger<InfoBarService>>();
|
||||
taskContext = serviceProvider.GetRequiredService<ITaskContext>();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public ObservableCollection<InfoBarOptions> Collection
|
||||
{
|
||||
|
||||
@@ -315,7 +315,7 @@
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Snap.Hutao.SourceGeneration" Version="1.1.1">
|
||||
<PackageReference Include="Snap.Hutao.SourceGeneration" Version="1.1.3">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -556,12 +556,16 @@
|
||||
Content="{shuxm:ResourceString Name=ViewPageAvatarPropertyRefreshTimeToggle}"/>
|
||||
</StackPanel>
|
||||
</CommandBar.Content>
|
||||
<AppBarButton
|
||||
Command="{Binding ExportToTextCommand}"
|
||||
Icon="{shuxm:FontIcon Glyph=}"
|
||||
Label="{shuxm:ResourceString Name=ViewPageAvatarPropertyExportToTextLabel}"/>
|
||||
<AppBarButton Icon="{shuxm:FontIcon Glyph=}" Label="{shuxm:ResourceString Name=ViewPageCultivateCalculate}">
|
||||
<AppBarButton.Flyout>
|
||||
<MenuFlyout>
|
||||
<MenuFlyoutItem
|
||||
Command="{Binding CultivateCommand}"
|
||||
CommandParameter="{Binding SelectedAvatar}"
|
||||
CommandParameter="{Binding Summary.Avatars.CurrentItem}"
|
||||
Text="{shuxm:ResourceString Name=ViewPageAvatarPropertyCalculateCurrent}"/>
|
||||
<MenuFlyoutItem Command="{Binding BatchCultivateCommand}" Text="{shuxm:ResourceString Name=ViewPageAvatarPropertyCalculateAll}"/>
|
||||
</MenuFlyout>
|
||||
@@ -592,7 +596,7 @@
|
||||
ItemContainerStyle="{StaticResource LargeGridViewItemStyle}"
|
||||
ItemTemplate="{StaticResource AvatarGridViewTemplate}"
|
||||
ItemsSource="{Binding Summary.Avatars}"
|
||||
SelectedItem="{Binding SelectedAvatar, Mode=TwoWay}"/>
|
||||
SelectedItem="{Binding Summary.Avatars.CurrentItem, Mode=TwoWay}"/>
|
||||
</cwcont:Case>
|
||||
<cwcont:Case Value="List">
|
||||
<SplitView
|
||||
@@ -606,7 +610,7 @@
|
||||
Padding="{ThemeResource ListViewInSplitPanePadding}"
|
||||
ItemTemplate="{StaticResource AvatarListViewTemplate}"
|
||||
ItemsSource="{Binding Summary.Avatars}"
|
||||
SelectedItem="{Binding SelectedAvatar, Mode=TwoWay}"/>
|
||||
SelectedItem="{Binding Summary.Avatars.CurrentItem, Mode=TwoWay}"/>
|
||||
</SplitView.Pane>
|
||||
<SplitView.Content>
|
||||
<ScrollViewer>
|
||||
@@ -638,7 +642,7 @@
|
||||
Grid.ColumnSpan="2"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Source="{Binding SelectedAvatar.NameCard}"
|
||||
Source="{Binding Summary.Avatars.CurrentItem.NameCard}"
|
||||
Stretch="UniformToFill"/>
|
||||
</cwcont:ConstrainedBox>
|
||||
<Border
|
||||
@@ -658,18 +662,18 @@
|
||||
</Grid.ColumnDefinitions>
|
||||
<shuxc:ItemIcon
|
||||
cw:Effects.Shadow="{ThemeResource CompatCardShadow}"
|
||||
Icon="{Binding SelectedAvatar.Icon}"
|
||||
Quality="{Binding SelectedAvatar.Quality}"/>
|
||||
Icon="{Binding Summary.Avatars.CurrentItem.Icon}"
|
||||
Quality="{Binding Summary.Avatars.CurrentItem.Quality}"/>
|
||||
<StackPanel Grid.Column="1" Margin="16,0,0,0">
|
||||
<TextBlock
|
||||
Foreground="#FFFFFFFF"
|
||||
Style="{StaticResource SubtitleTextBlockStyle}"
|
||||
Text="{Binding SelectedAvatar.Name}"/>
|
||||
Text="{Binding Summary.Avatars.CurrentItem.Name}"/>
|
||||
<TextBlock
|
||||
Margin="0,4,0,0"
|
||||
Foreground="#FFFFFFFF"
|
||||
Style="{StaticResource BaseTextBlockStyle}"
|
||||
Text="{Binding SelectedAvatar.Level}"/>
|
||||
Text="{Binding Summary.Avatars.CurrentItem.Level}"/>
|
||||
<StackPanel Margin="0,2,0,0" Orientation="Horizontal">
|
||||
<Image
|
||||
Width="16"
|
||||
@@ -681,7 +685,7 @@
|
||||
Foreground="#FFFFFFFF"
|
||||
HorizontalTextAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding SelectedAvatar.FetterLevel}"
|
||||
Text="{Binding Summary.Avatars.CurrentItem.FetterLevel}"
|
||||
TextAlignment="Center"
|
||||
TextTrimming="None"
|
||||
TextWrapping="NoWrap"/>
|
||||
@@ -691,7 +695,7 @@
|
||||
<Grid
|
||||
Margin="0,16,0,0"
|
||||
HorizontalAlignment="Left"
|
||||
DataContext="{Binding SelectedAvatar.Weapon}">
|
||||
DataContext="{Binding Summary.Avatars.CurrentItem.Weapon}">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
@@ -723,7 +727,7 @@
|
||||
Margin="0,2,0,0"
|
||||
Padding="12"
|
||||
Header="{Binding SubProperty.Name}">
|
||||
<TextBlock Text="{Binding SubProperty.Description}"/>
|
||||
<TextBlock Text="{Binding SubProperty.Value}"/>
|
||||
</cwcont:SettingsCard>
|
||||
<shuxct:DescriptionTextBlock
|
||||
MaxWidth="320"
|
||||
@@ -757,7 +761,7 @@
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="#FFFFFFFF"
|
||||
Style="{StaticResource TitleTextBlockStyle}"
|
||||
Text="{Binding SelectedAvatar.ScoreFormatted}"/>
|
||||
Text="{Binding Summary.Avatars.CurrentItem.ScoreFormatted}"/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="#FFFFFFFF"
|
||||
@@ -769,7 +773,7 @@
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="#FFFFFFFF"
|
||||
Style="{StaticResource TitleTextBlockStyle}"
|
||||
Text="{Binding SelectedAvatar.CritScoreFormatted}"/>
|
||||
Text="{Binding Summary.Avatars.CurrentItem.CritScoreFormatted}"/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Right"
|
||||
Foreground="#FFFFFFFF"
|
||||
@@ -784,7 +788,7 @@
|
||||
Margin="16"
|
||||
VerticalAlignment="Bottom"
|
||||
ItemTemplate="{StaticResource AvatarSkillTemplate}"
|
||||
ItemsSource="{Binding SelectedAvatar.Skills}"/>
|
||||
ItemsSource="{Binding Summary.Avatars.CurrentItem.Skills}"/>
|
||||
|
||||
<ItemsControl
|
||||
Grid.Row="1"
|
||||
@@ -792,7 +796,7 @@
|
||||
Margin="16"
|
||||
ItemTemplate="{StaticResource AvatarConstellationTemplate}"
|
||||
ItemsPanel="{StaticResource HorizontalStackPanelSpacing0Template}"
|
||||
ItemsSource="{Binding SelectedAvatar.Constellations}"/>
|
||||
ItemsSource="{Binding Summary.Avatars.CurrentItem.Constellations}"/>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
@@ -808,14 +812,14 @@
|
||||
<ItemsControl
|
||||
Margin="0,-1,0,0"
|
||||
ItemTemplate="{StaticResource AvatarPropertyTemplate}"
|
||||
ItemsSource="{Binding SelectedAvatar.Properties}"/>
|
||||
ItemsSource="{Binding Summary.Avatars.CurrentItem.Properties}"/>
|
||||
</Border>
|
||||
</Expander>
|
||||
<!-- 圣遗物 -->
|
||||
<ItemsControl
|
||||
Margin="16,16,16,0"
|
||||
ItemTemplate="{StaticResource AvatarReliquaryTemplate}"
|
||||
ItemsSource="{Binding SelectedAvatar.Reliquaries}"/>
|
||||
ItemsSource="{Binding Summary.Avatars.CurrentItem.Reliquaries}"/>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
</SplitView.Content>
|
||||
|
||||
@@ -333,11 +333,11 @@
|
||||
Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
|
||||
ItemTemplate="{StaticResource SpiralAbyssListTemplate}"
|
||||
ItemsSource="{Binding SpiralAbyssEntries}"
|
||||
SelectedItem="{Binding SelectedView, Mode=TwoWay}"/>
|
||||
SelectedItem="{Binding SpiralAbyssEntries.CurrentItem, Mode=TwoWay}"/>
|
||||
</SplitView.Pane>
|
||||
<SplitView.Content>
|
||||
<ScrollViewer>
|
||||
<StackPanel DataContext="{Binding SelectedView}">
|
||||
<StackPanel DataContext="{Binding SpiralAbyssEntries.CurrentItem}">
|
||||
<Grid Margin="16,12,16,0">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<UserControl.Resources>
|
||||
<Thickness x:Key="SettingsCardPadding">16,8</Thickness>
|
||||
<x:Double x:Key="SettingsCardMinHeight">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapNoIconThreshold">0</x:Double>
|
||||
|
||||
<DataTemplate x:Key="BaseValueTemplate">
|
||||
<cwc:SettingsCard
|
||||
|
||||
@@ -7,16 +7,10 @@ using Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
namespace Snap.Hutao.UI.Xaml.View.Specialized;
|
||||
|
||||
/// <summary>
|
||||
/// 基础数值滑动条
|
||||
/// </summary>
|
||||
[DependencyProperty("BaseValueInfo", typeof(BaseValueInfo))]
|
||||
[DependencyProperty("IsPromoteVisible", typeof(bool), true)]
|
||||
internal sealed partial class BaseValueSlider : UserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的基础数值滑动条
|
||||
/// </summary>
|
||||
public BaseValueSlider()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
@@ -144,6 +144,7 @@
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="HoYoLAB"
|
||||
Visibility="{Binding IsOversea}"/>
|
||||
<StackPanel
|
||||
|
||||
@@ -11,7 +11,7 @@ using Snap.Hutao.UI.Xaml.Data;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Achievement;
|
||||
|
||||
internal sealed class AchievementGoalView : ObservableObject,
|
||||
internal sealed partial class AchievementGoalView : ObservableObject,
|
||||
INameIcon,
|
||||
IAdvancedCollectionViewItem,
|
||||
IMappingFrom<AchievementGoalView, AchievementGoal>
|
||||
@@ -49,14 +49,4 @@ internal sealed class AchievementGoalView : ObservableObject,
|
||||
FinishDescription = AchievementStatistics.Format(statistics.Finished, statistics.TotalCount, out double finishPercent);
|
||||
FinishPercent = finishPercent;
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string propertyName)
|
||||
{
|
||||
return propertyName switch
|
||||
{
|
||||
nameof(Order) => Order,
|
||||
nameof(FinishPercent) => FinishPercent,
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,7 @@ using Snap.Hutao.UI.Xaml.Data;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Achievement;
|
||||
|
||||
/// <summary>
|
||||
/// 用于视图绑定的成就
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class AchievementView : ObservableObject,
|
||||
internal sealed partial class AchievementView : ObservableObject,
|
||||
IEntityAccessWithMetadata<Model.Entity.Achievement, Model.Metadata.Achievement.Achievement>,
|
||||
IAdvancedCollectionViewItem
|
||||
{
|
||||
@@ -57,15 +53,4 @@ internal sealed class AchievementView : ObservableObject,
|
||||
{
|
||||
get => $"{Entity.Time.ToLocalTime():yyyy.MM.dd HH:mm:ss}";
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string propertyName)
|
||||
{
|
||||
return propertyName switch
|
||||
{
|
||||
nameof(Order) => Order,
|
||||
nameof(IsChecked) => IsChecked,
|
||||
nameof(Time) => Time,
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -13,10 +13,12 @@ using Snap.Hutao.Service.Cultivation;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.UI.Xaml.Control;
|
||||
using Snap.Hutao.UI.Xaml.Data;
|
||||
using Snap.Hutao.UI.Xaml.View.Dialog;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Globalization;
|
||||
using CalculatorAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
|
||||
using CalculatorBatchConsumption = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.BatchConsumption;
|
||||
using CalculatorClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
|
||||
@@ -26,10 +28,6 @@ using CalculatorItemHelper = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.ItemH
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
/// 角色属性视图模型
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, IRecipient<UserAndUidChangedMessage>
|
||||
@@ -38,14 +36,13 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
|
||||
private readonly IAppResourceProvider appResourceProvider;
|
||||
private readonly ICultivationService cultivationService;
|
||||
private readonly IAvatarInfoService avatarInfoService;
|
||||
private readonly IClipboardProvider clipboardInterop;
|
||||
private readonly IClipboardProvider clipboardProvider;
|
||||
private readonly CalculatorClient calculatorClient;
|
||||
private readonly IInfoBarService infoBarService;
|
||||
private readonly ITaskContext taskContext;
|
||||
private readonly IUserService userService;
|
||||
|
||||
private Summary? summary;
|
||||
private AvatarView? selectedAvatar;
|
||||
|
||||
private enum CultivateCoreResult
|
||||
{
|
||||
@@ -54,17 +51,8 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
|
||||
SaveConsumptionFailed,
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 简述对象
|
||||
/// </summary>
|
||||
public Summary? Summary { get => summary; set => SetProperty(ref summary, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 选中的角色
|
||||
/// </summary>
|
||||
public AvatarView? SelectedAvatar { get => selectedAvatar; set => SetProperty(ref selectedAvatar, value); }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Receive(UserAndUidChangedMessage message)
|
||||
{
|
||||
if (message.UserAndUid is { } userAndUid)
|
||||
@@ -133,11 +121,11 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
|
||||
}
|
||||
|
||||
(RefreshResultKind result, Summary? summary) = summaryResult;
|
||||
if (result == RefreshResultKind.Ok)
|
||||
if (result is RefreshResultKind.Ok)
|
||||
{
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
Summary = summary;
|
||||
SelectedAvatar = Summary?.Avatars.FirstOrDefault();
|
||||
Summary?.Avatars.MoveCurrentToFirstOrDefault();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -313,4 +301,22 @@ internal sealed partial class AvatarPropertyViewModel : Abstraction.ViewModel, I
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
[Command("ExportToTextCommand")]
|
||||
private void ExportToText()
|
||||
{
|
||||
if (Summary is not { Avatars.CurrentItem: { } avatar })
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (clipboardProvider.SetText(AvatarViewTextTemplating.GetTemplatedText(avatar)))
|
||||
{
|
||||
infoBarService.Success(SH.ViewModelAvatatPropertyExportTextSuccess);
|
||||
}
|
||||
else
|
||||
{
|
||||
infoBarService.Warning(SH.ViewModelAvatatPropertyExportTextError);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5,13 +5,16 @@ using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.UI.Xaml.Data;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
/// 角色信息
|
||||
/// </summary>
|
||||
internal sealed class AvatarView : INameIconSide, ICalculableSource<ICalculableAvatar>
|
||||
internal sealed partial class AvatarView : INameIconSide,
|
||||
ICalculableSource<ICalculableAvatar>,
|
||||
IAdvancedCollectionViewItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称
|
||||
|
||||
@@ -0,0 +1,112 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
internal static class AvatarViewTextTemplating
|
||||
{
|
||||
public static string GetTemplatedText(AvatarView avatar)
|
||||
{
|
||||
string avatarTemplate = $"""
|
||||
// {avatar.Name} [{avatar.Level}, ☆{avatar.Quality:D}, C{avatar.Constellations.Where(c => c.IsActivated).Count()}] [{FormatSkills(avatar.Skills)}]
|
||||
|
||||
""";
|
||||
string weaponTemplate = avatar.Weapon is { } weapon
|
||||
? $"""
|
||||
// ---------------------
|
||||
// {weapon.Name} [{weapon.Level}, ☆{weapon.Quality:D}, R{weapon.AffixLevelNumber}]
|
||||
// [{weapon.MainProperty.Name}: {weapon.MainProperty.Value}] [{weapon.SubProperty.Name}: {weapon.SubProperty.Value}]
|
||||
|
||||
"""
|
||||
: string.Empty;
|
||||
|
||||
string propertiesTemplate = avatar.Properties.Count > 0
|
||||
? $"""
|
||||
// ---------------------
|
||||
{FormatProperties(avatar.Properties)}
|
||||
"""
|
||||
: string.Empty;
|
||||
|
||||
string reliquariesTemplate = avatar.Reliquaries.Count > 0
|
||||
? $"""
|
||||
// ---------------------
|
||||
{FormatReliquaries(avatar.Reliquaries)}
|
||||
"""
|
||||
: string.Empty;
|
||||
|
||||
return $"""
|
||||
// =====================
|
||||
{avatarTemplate}{weaponTemplate}{propertiesTemplate}{reliquariesTemplate}// =====================
|
||||
""";
|
||||
}
|
||||
|
||||
private static string FormatSkills(List<SkillView> skills)
|
||||
{
|
||||
StringBuilder result = new();
|
||||
Span<SkillView> skillSpan = CollectionsMarshal.AsSpan(skills);
|
||||
for (int index = 0; index < skillSpan.Length; index++)
|
||||
{
|
||||
ref readonly SkillView skill = ref skillSpan[index];
|
||||
result.Append(skill.Level);
|
||||
if (index < skillSpan.Length - 1)
|
||||
{
|
||||
result.Append(", ");
|
||||
}
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
private static string FormatProperties(List<AvatarProperty> properties)
|
||||
{
|
||||
StringBuilder result = new();
|
||||
foreach (ref readonly AvatarProperty property in CollectionsMarshal.AsSpan(properties))
|
||||
{
|
||||
result.Append("// [").Append(property.Name).Append(": ").Append(property.Value).Append(']').AppendLine();
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
[SuppressMessage("", "CA1305")]
|
||||
private static string FormatReliquaries(List<ReliquaryView> reliquaries)
|
||||
{
|
||||
StringBuilder result = new();
|
||||
foreach (ref readonly ReliquaryView reliquary in CollectionsMarshal.AsSpan(reliquaries))
|
||||
{
|
||||
NameValue<string>? mainProperty = reliquary.MainProperty;
|
||||
result.Append($"""
|
||||
// {ReliquaryEmoji(reliquary.EquipType)} {mainProperty?.Name}: {mainProperty?.Value} [☆{reliquary.Quality:D} {reliquary.Level} {reliquary.SetName}]
|
||||
|
||||
""");
|
||||
result.Append("// ");
|
||||
|
||||
foreach (ref readonly ReliquaryComposedSubProperty subProperty in CollectionsMarshal.AsSpan(reliquary.ComposedSubProperties))
|
||||
{
|
||||
result.Append('[').Append(subProperty.Name).Append(": ").Append(subProperty.Value).Append(']');
|
||||
}
|
||||
|
||||
result.AppendLine();
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
private static string ReliquaryEmoji(EquipType type)
|
||||
{
|
||||
return type switch
|
||||
{
|
||||
EquipType.EQUIP_BRACER => "🌷",
|
||||
EquipType.EQUIP_NECKLACE => "🪶",
|
||||
EquipType.EQUIP_SHOES => "⏳",
|
||||
EquipType.EQUIP_RING => "🍷",
|
||||
EquipType.EQUIP_DRESS => "👑",
|
||||
_ => string.Empty,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -26,4 +26,6 @@ internal abstract class EquipView : NameIconDescription
|
||||
/// 主属性
|
||||
/// </summary>
|
||||
public NameValue<string> MainProperty { get; set; } = default!;
|
||||
|
||||
internal EquipType EquipType { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
@@ -33,4 +35,6 @@ internal sealed class ReliquaryView : EquipView
|
||||
/// 评分
|
||||
/// </summary>
|
||||
internal float Score { get; set; }
|
||||
|
||||
internal string SetName { get; set; } = default!;
|
||||
}
|
||||
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.UI.Xaml.Data;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
|
||||
/// <summary>
|
||||
@@ -9,13 +11,7 @@ namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
[HighQuality]
|
||||
internal sealed class Summary
|
||||
{
|
||||
/// <summary>
|
||||
/// 角色列表
|
||||
/// </summary>
|
||||
public List<AvatarView> Avatars { get; set; } = default!;
|
||||
public AdvancedCollectionView<AvatarView> Avatars { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 服务器消息
|
||||
/// </summary>
|
||||
public string Message { get; set; } = default!;
|
||||
}
|
||||
@@ -17,7 +17,7 @@ internal sealed class WeaponView : EquipView, ICalculableSource<ICalculableWeapo
|
||||
/// <summary>
|
||||
/// 副属性
|
||||
/// </summary>
|
||||
public NameDescription SubProperty { get; set; } = default!;
|
||||
public NameValue<string> SubProperty { get; set; } = default!;
|
||||
|
||||
/// <summary>
|
||||
/// 精炼等级
|
||||
|
||||
@@ -7,10 +7,6 @@ using Snap.Hutao.Web.Hutao.SpiralAbyss;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Complex;
|
||||
|
||||
/// <summary>
|
||||
/// 胡桃数据库视图模型
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal sealed partial class HutaoDatabaseViewModel : Abstraction.ViewModel
|
||||
|
||||
@@ -9,7 +9,7 @@ namespace Snap.Hutao.ViewModel.GachaLog;
|
||||
/// 历史卡池概览
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class HistoryWish : Wish, IAdvancedCollectionViewItem
|
||||
internal sealed partial class HistoryWish : Wish, IAdvancedCollectionViewItem
|
||||
{
|
||||
/// <summary>
|
||||
/// 版本
|
||||
@@ -45,12 +45,4 @@ internal sealed class HistoryWish : Wish, IAdvancedCollectionViewItem
|
||||
/// 三星Up
|
||||
/// </summary>
|
||||
public List<StatisticsItem> BlueList { get; set; } = default!;
|
||||
|
||||
public object? GetPropertyValue(string name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -9,21 +9,17 @@ using Snap.Hutao.Service.Navigation;
|
||||
using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.SpiralAbyss;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.UI.Xaml.Data;
|
||||
using Snap.Hutao.UI.Xaml.View.Dialog;
|
||||
using Snap.Hutao.UI.Xaml.View.Page;
|
||||
using Snap.Hutao.ViewModel.Complex;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using Snap.Hutao.Web.Hutao.Response;
|
||||
using Snap.Hutao.Web.Hutao.SpiralAbyss;
|
||||
using Snap.Hutao.Web.Hutao.SpiralAbyss.Post;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.SpiralAbyss;
|
||||
|
||||
/// <summary>
|
||||
/// 深渊记录视图模型
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[ConstructorGenerated]
|
||||
[Injection(InjectAs.Scoped)]
|
||||
internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel, IRecipient<UserAndUidChangedMessage>
|
||||
@@ -38,18 +34,12 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
|
||||
private readonly HutaoDatabaseViewModel hutaoDatabaseViewModel;
|
||||
private readonly HutaoUserOptions hutaoUserOptions;
|
||||
|
||||
private ObservableCollection<SpiralAbyssView>? spiralAbyssEntries;
|
||||
private SpiralAbyssView? selectedView;
|
||||
private AdvancedCollectionView<SpiralAbyssView>? spiralAbyssEntries;
|
||||
|
||||
/// <summary>
|
||||
/// 深渊记录
|
||||
/// </summary>
|
||||
public ObservableCollection<SpiralAbyssView>? SpiralAbyssEntries { get => spiralAbyssEntries; set => SetProperty(ref spiralAbyssEntries, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 选中的深渊信息
|
||||
/// </summary>
|
||||
public SpiralAbyssView? SelectedView { get => selectedView; set => SetProperty(ref selectedView, value); }
|
||||
public AdvancedCollectionView<SpiralAbyssView>? SpiralAbyssEntries { get => spiralAbyssEntries; set => SetProperty(ref spiralAbyssEntries, value); }
|
||||
|
||||
public HutaoDatabaseViewModel HutaoDatabaseViewModel { get => hutaoDatabaseViewModel; }
|
||||
|
||||
@@ -61,7 +51,7 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
|
||||
}
|
||||
else
|
||||
{
|
||||
SelectedView = null;
|
||||
SpiralAbyssEntries?.MoveCurrentTo(default);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +75,7 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
|
||||
|
||||
private async ValueTask UpdateSpiralAbyssCollectionAsync(UserAndUid userAndUid)
|
||||
{
|
||||
ObservableCollection<SpiralAbyssView>? collection = null;
|
||||
ObservableCollection<SpiralAbyssView> collection;
|
||||
try
|
||||
{
|
||||
using (await EnterCriticalSectionAsync().ConfigureAwait(false))
|
||||
@@ -94,14 +84,15 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
|
||||
.GetSpiralAbyssViewCollectionAsync(userAndUid)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
SpiralAbyssEntries = new(collection, true);
|
||||
SpiralAbyssEntries.MoveCurrentTo(SpiralAbyssEntries.SourceCollection.FirstOrDefault(s => s.Engaged));
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
SpiralAbyssEntries = collection;
|
||||
SelectedView = SpiralAbyssEntries?.FirstOrDefault(s => s.Engaged);
|
||||
}
|
||||
|
||||
[Command("RefreshCommand")]
|
||||
@@ -125,7 +116,7 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
|
||||
}
|
||||
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
SelectedView = SpiralAbyssEntries.FirstOrDefault(s => s.Engaged);
|
||||
SpiralAbyssEntries.MoveCurrentTo(SpiralAbyssEntries.SourceCollection.FirstOrDefault(s => s.Engaged));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -158,24 +149,18 @@ internal sealed partial class SpiralAbyssRecordViewModel : Abstraction.ViewModel
|
||||
}
|
||||
}
|
||||
|
||||
SimpleRecord? record = await spiralAbyssClient.GetPlayerRecordAsync(userAndUid).ConfigureAwait(false);
|
||||
if (record is not null)
|
||||
if (await spiralAbyssClient.GetPlayerRecordAsync(userAndUid).ConfigureAwait(false) is { } record)
|
||||
{
|
||||
Web.Response.Response response = await spiralAbyssClient.UploadRecordAsync(record).ConfigureAwait(false);
|
||||
|
||||
if (response is { ReturnCode: 0 })
|
||||
{
|
||||
if (response is ILocalizableResponse localizableResponse)
|
||||
{
|
||||
infoBarService.Success(localizableResponse.GetLocalizationMessage());
|
||||
}
|
||||
}
|
||||
else
|
||||
infoBarService.PrepareInfoBarAndShow(builder =>
|
||||
{
|
||||
if (response is ILocalizableResponse localizableResponse)
|
||||
{
|
||||
infoBarService.Warning(localizableResponse.GetLocalizationMessage());
|
||||
}
|
||||
builder
|
||||
.SetSeverity(response is { ReturnCode: 0 } ? InfoBarSeverity.Success : InfoBarSeverity.Warning)
|
||||
.SetMessage(localizableResponse.GetLocalizationMessage());
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,14 +5,12 @@ using Snap.Hutao.Core.Abstraction;
|
||||
using Snap.Hutao.Model;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Model.Metadata.Tower;
|
||||
using Snap.Hutao.UI.Xaml.Data;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.SpiralAbyss;
|
||||
|
||||
/// <summary>
|
||||
/// 深渊视图
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
internal sealed class SpiralAbyssView : IEntityAccess<SpiralAbyssEntry?>,
|
||||
internal sealed partial class SpiralAbyssView : IEntityAccess<SpiralAbyssEntry?>,
|
||||
IAdvancedCollectionViewItem,
|
||||
IMappingFrom<SpiralAbyssView, SpiralAbyssEntry, SpiralAbyssMetadataContext>,
|
||||
IMappingFrom<SpiralAbyssView, SpiralAbyssEntry?, TowerSchedule, SpiralAbyssMetadataContext>
|
||||
{
|
||||
|
||||
@@ -15,7 +15,7 @@ using EntityUser = Snap.Hutao.Model.Entity.User;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.User;
|
||||
|
||||
internal sealed class User : IEntityAccess<EntityUser>,
|
||||
internal sealed partial class User : IEntityAccess<EntityUser>,
|
||||
IMappingFrom<User, EntityUser, IServiceProvider>,
|
||||
ISelectable,
|
||||
IAdvancedCollectionViewItem
|
||||
@@ -96,14 +96,6 @@ internal sealed class User : IEntityAccess<EntityUser>,
|
||||
return new(user, provider);
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
|
||||
public IDisposable SuppressCurrentUserGameRoleChangedMessage()
|
||||
{
|
||||
return new CurrentUserGameRoleChangedSuppression(this);
|
||||
|
||||
@@ -11,6 +11,7 @@ namespace Snap.Hutao.Web.Hoyolab.Bbs.User;
|
||||
|
||||
[ConstructorGenerated(ResolveHttpClient = true)]
|
||||
[HttpClient(HttpClientConfiguration.Default)]
|
||||
[PrimaryHttpMessageHandler(UseCookies = false)]
|
||||
internal sealed partial class UserClientOversea : IUserClient
|
||||
{
|
||||
private readonly IHttpRequestMessageBuilderFactory httpRequestMessageBuilderFactory;
|
||||
|
||||
@@ -59,14 +59,6 @@ internal sealed partial class UserGameRole : ObservableObject, IAdvancedCollecti
|
||||
return $"{Nickname} | {RegionName} | Lv.{Level}";
|
||||
}
|
||||
|
||||
public object? GetPropertyValue(string name)
|
||||
{
|
||||
return name switch
|
||||
{
|
||||
_ => default,
|
||||
};
|
||||
}
|
||||
|
||||
[Command("RefreshProfilePictureCommand")]
|
||||
private async Task RefreshProfilePictureAsync()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user