mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
Merge pull request #1421 from DGP-Studio/feat/wikisuggestbox
This commit is contained in:
@@ -6,6 +6,7 @@
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<XamlControlsResources/>
|
||||
<ResourceDictionary Source="ms-appx:///CommunityToolkit.WinUI.Controls.TokenizingTextBox/TokenizingTextBox.xaml"/>
|
||||
<ResourceDictionary Source="ms-appx:///Control/Loading.xaml"/>
|
||||
<ResourceDictionary Source="ms-appx:///Control/Image/CachedImage.xaml"/>
|
||||
<ResourceDictionary Source="ms-appx:///Control/Theme/Card.xaml"/>
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.WinUI;
|
||||
using CommunityToolkit.WinUI.Controls;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Snap.Hutao.Control.Extension;
|
||||
|
||||
namespace Snap.Hutao.Control.AutoSuggestBox;
|
||||
|
||||
[DependencyProperty("FilterCommand", typeof(ICommand))]
|
||||
[DependencyProperty("FilterCommandParameter", typeof(object))]
|
||||
[DependencyProperty("AvailableTokens", typeof(IReadOnlyDictionary<string, SearchToken>))]
|
||||
internal sealed partial class AutoSuggestTokenBox : TokenizingTextBox
|
||||
{
|
||||
public AutoSuggestTokenBox()
|
||||
{
|
||||
DefaultStyleKey = typeof(TokenizingTextBox);
|
||||
TextChanged += OnFilterSuggestionRequested;
|
||||
QuerySubmitted += OnQuerySubmitted;
|
||||
TokenItemAdding += OnTokenItemAdding;
|
||||
TokenItemAdded += OnTokenItemModified;
|
||||
TokenItemRemoved += OnTokenItemModified;
|
||||
}
|
||||
|
||||
private void OnFilterSuggestionRequested(Microsoft.UI.Xaml.Controls.AutoSuggestBox sender, AutoSuggestBoxTextChangedEventArgs args)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Text))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.Reason == AutoSuggestionBoxTextChangeReason.UserInput)
|
||||
{
|
||||
sender.ItemsSource = AvailableTokens.Values.Where(q => q.Value.Contains(Text, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// TODO: CornerRadius
|
||||
// Popup? popup = this.FindDescendant("SuggestionsPopup") as Popup;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnQuerySubmitted(Microsoft.UI.Xaml.Controls.AutoSuggestBox sender, AutoSuggestBoxQuerySubmittedEventArgs args)
|
||||
{
|
||||
if (args.ChosenSuggestion is not null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CommandExtension.TryExecute(FilterCommand, FilterCommandParameter);
|
||||
}
|
||||
|
||||
private void OnTokenItemAdding(TokenizingTextBox sender, TokenItemAddingEventArgs args)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(args.TokenText))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
args.Item = AvailableTokens.GetValueOrDefault(args.TokenText) ?? new SearchToken(SearchTokenKind.None, args.TokenText);
|
||||
}
|
||||
|
||||
private void OnTokenItemModified(TokenizingTextBox sender, object args)
|
||||
{
|
||||
CommandExtension.TryExecute(FilterCommand, FilterCommandParameter);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Windows.UI;
|
||||
|
||||
namespace Snap.Hutao.Control.AutoSuggestBox;
|
||||
|
||||
internal sealed class SearchToken
|
||||
{
|
||||
public SearchToken(SearchTokenKind kind, string value, Uri? iconUri = null, Uri? sideIconUri = null, Color? quality = null)
|
||||
{
|
||||
Value = value;
|
||||
Kind = kind;
|
||||
IconUri = iconUri;
|
||||
SideIconUri = sideIconUri;
|
||||
Quality = quality;
|
||||
}
|
||||
|
||||
public SearchTokenKind Kind { get; }
|
||||
|
||||
public string Value { get; set; } = default!;
|
||||
|
||||
public Uri? IconUri { get; }
|
||||
|
||||
public Uri? SideIconUri { get; }
|
||||
|
||||
public Color? Quality { get; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Control.AutoSuggestBox;
|
||||
|
||||
internal enum SearchTokenKind
|
||||
{
|
||||
None,
|
||||
AssociationType,
|
||||
Avatar,
|
||||
BodyType,
|
||||
ElementName,
|
||||
FightProperty,
|
||||
ItemQuality,
|
||||
Weapon,
|
||||
WeaponType,
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using CommunityToolkit.WinUI.Behaviors;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Snap.Hutao.Control.Extension;
|
||||
|
||||
namespace Snap.Hutao.Control.Behavior;
|
||||
|
||||
@@ -45,10 +46,6 @@ internal sealed partial class InvokeCommandOnLoadedBehavior : BehaviorBase<UIEle
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command is not null && Command.CanExecute(CommandParameter))
|
||||
{
|
||||
Command.Execute(CommandParameter);
|
||||
executed = true;
|
||||
}
|
||||
executed = Command.TryExecute(CommandParameter);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using CommunityToolkit.WinUI.Behaviors;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Snap.Hutao.Control.Extension;
|
||||
|
||||
namespace Snap.Hutao.Control.Behavior;
|
||||
|
||||
@@ -49,10 +50,7 @@ internal sealed partial class PeriodicInvokeCommandOrOnActualThemeChangedBehavio
|
||||
return;
|
||||
}
|
||||
|
||||
if (Command is not null && Command.CanExecute(CommandParameter))
|
||||
{
|
||||
Command.Execute(CommandParameter);
|
||||
}
|
||||
Command.TryExecute(CommandParameter);
|
||||
}
|
||||
|
||||
private async ValueTask RunCoreAsync()
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Snap.Hutao.Control.Extension;
|
||||
|
||||
internal static class CommandExtension
|
||||
{
|
||||
public static bool TryExecute(this ICommand? command, object? parameter = null)
|
||||
{
|
||||
if (command is not null && command.CanExecute(parameter))
|
||||
{
|
||||
command.Execute(parameter);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
using CommunityToolkit.WinUI.Controls;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Snap.Hutao.Core.Setting;
|
||||
using System.Collections.Frozen;
|
||||
|
||||
namespace Snap.Hutao.Control.Panel;
|
||||
|
||||
@@ -19,11 +20,11 @@ internal sealed partial class PanelSelector : Segmented
|
||||
public const string List = nameof(List);
|
||||
public const string Grid = nameof(Grid);
|
||||
|
||||
private static readonly Dictionary<int, string> IndexTypeMap = new()
|
||||
{
|
||||
[0] = List,
|
||||
[1] = Grid,
|
||||
};
|
||||
private static readonly FrozenDictionary<int, string> IndexTypeMap = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(0, List),
|
||||
KeyValuePair.Create(1, Grid),
|
||||
]);
|
||||
|
||||
private readonly RoutedEventHandler loadedEventHandler;
|
||||
private readonly RoutedEventHandler unloadedEventHandler;
|
||||
|
||||
@@ -11,4 +11,6 @@ internal static class KnownColors
|
||||
public static readonly Color Orange = StructMarshal.Color(0xFFBC6932);
|
||||
public static readonly Color Purple = StructMarshal.Color(0xFFA156E0);
|
||||
public static readonly Color Blue = StructMarshal.Color(0xFF5180CB);
|
||||
public static readonly Color Green = StructMarshal.Color(0xFF2A8F72);
|
||||
public static readonly Color White = StructMarshal.Color(0xFF72778B);
|
||||
}
|
||||
@@ -26,12 +26,12 @@ internal sealed partial class ImageCache : IImageCache, IImageCacheFilePathOpera
|
||||
{
|
||||
private const string CacheFolderName = nameof(ImageCache);
|
||||
|
||||
private readonly FrozenDictionary<int, TimeSpan> retryCountToDelay = new Dictionary<int, TimeSpan>()
|
||||
{
|
||||
[0] = TimeSpan.FromSeconds(4),
|
||||
[1] = TimeSpan.FromSeconds(16),
|
||||
[2] = TimeSpan.FromSeconds(64),
|
||||
}.ToFrozenDictionary();
|
||||
private readonly FrozenDictionary<int, TimeSpan> retryCountToDelay = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(0, TimeSpan.FromSeconds(4)),
|
||||
KeyValuePair.Create(1, TimeSpan.FromSeconds(16)),
|
||||
KeyValuePair.Create(2, TimeSpan.FromSeconds(64)),
|
||||
]);
|
||||
|
||||
private readonly ConcurrentDictionary<string, Task> concurrentTasks = new();
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
// Licensed to the .NET Foundation under one or more agreements.
|
||||
// The .NET Foundation licenses this file to you under the MIT license.
|
||||
|
||||
using System.Collections.Frozen;
|
||||
using System.Text;
|
||||
|
||||
namespace Snap.Hutao.Core;
|
||||
@@ -14,25 +15,25 @@ internal static class TypeNameHelper
|
||||
{
|
||||
private const char DefaultNestedTypeDelimiter = '+';
|
||||
|
||||
private static readonly Dictionary<Type, string> BuiltInTypeNames = new()
|
||||
{
|
||||
{ typeof(void), "void" },
|
||||
{ typeof(bool), "bool" },
|
||||
{ typeof(byte), "byte" },
|
||||
{ typeof(char), "char" },
|
||||
{ typeof(decimal), "decimal" },
|
||||
{ typeof(double), "double" },
|
||||
{ typeof(float), "float" },
|
||||
{ typeof(int), "int" },
|
||||
{ typeof(long), "long" },
|
||||
{ typeof(object), "object" },
|
||||
{ typeof(sbyte), "sbyte" },
|
||||
{ typeof(short), "short" },
|
||||
{ typeof(string), "string" },
|
||||
{ typeof(uint), "uint" },
|
||||
{ typeof(ulong), "ulong" },
|
||||
{ typeof(ushort), "ushort" },
|
||||
};
|
||||
private static readonly FrozenDictionary<Type, string> BuiltInTypeNames = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(typeof(void), "void"),
|
||||
KeyValuePair.Create(typeof(bool), "bool"),
|
||||
KeyValuePair.Create(typeof(byte), "byte"),
|
||||
KeyValuePair.Create(typeof(char), "char"),
|
||||
KeyValuePair.Create(typeof(decimal), "decimal"),
|
||||
KeyValuePair.Create(typeof(double), "double"),
|
||||
KeyValuePair.Create(typeof(float), "float"),
|
||||
KeyValuePair.Create(typeof(int), "int"),
|
||||
KeyValuePair.Create(typeof(long), "long"),
|
||||
KeyValuePair.Create(typeof(object), "object"),
|
||||
KeyValuePair.Create(typeof(sbyte), "sbyte"),
|
||||
KeyValuePair.Create(typeof(short), "short"),
|
||||
KeyValuePair.Create(typeof(string), "string"),
|
||||
KeyValuePair.Create(typeof(uint), "uint"),
|
||||
KeyValuePair.Create(typeof(ulong), "ulong"),
|
||||
KeyValuePair.Create(typeof(ushort), "ushort"),
|
||||
]);
|
||||
|
||||
/// <summary>
|
||||
/// 获取对象类型的显示名称
|
||||
|
||||
@@ -15,6 +15,12 @@ namespace Snap.Hutao.Extension;
|
||||
[HighQuality]
|
||||
internal static partial class EnumerableExtension
|
||||
{
|
||||
public static void Deconstruct<TKey, TElement>(this IGrouping<TKey, TElement> grouping, out TKey key, out IEnumerable<TElement> elements)
|
||||
{
|
||||
key = grouping.Key;
|
||||
elements = grouping;
|
||||
}
|
||||
|
||||
public static TElement? ElementAtOrLastOrDefault<TElement>(this IEnumerable<TElement> source, int index)
|
||||
{
|
||||
return source.ElementAtOrDefault(index) ?? source.LastOrDefault();
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using System.Collections.Frozen;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
|
||||
internal sealed class AssociationTypeIconConverter : ValueConverter<AssociationType, Uri?>
|
||||
{
|
||||
private static readonly FrozenDictionary<string, AssociationType> LocalizedNameToAssociationType = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeMondstadt, AssociationType.ASSOC_TYPE_MONDSTADT),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeLiyue, AssociationType.ASSOC_TYPE_LIYUE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeFatui, AssociationType.ASSOC_TYPE_FATUI),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeInazuma, AssociationType.ASSOC_TYPE_INAZUMA),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeRanger, AssociationType.ASSOC_TYPE_RANGER),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeSumeru, AssociationType.ASSOC_TYPE_SUMERU),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeFontaine, AssociationType.ASSOC_TYPE_FONTAINE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeNatlan, AssociationType.ASSOC_TYPE_NATLAN),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicAssociationTypeSnezhnaya, AssociationType.ASSOC_TYPE_SNEZHNAYA),
|
||||
]);
|
||||
|
||||
public static Uri? AssociationTypeNameToIconUri(string associationTypeName)
|
||||
{
|
||||
return AssociationTypeToIconUri(LocalizedNameToAssociationType.GetValueOrDefault(associationTypeName));
|
||||
}
|
||||
|
||||
public static Uri? AssociationTypeToIconUri(AssociationType type)
|
||||
{
|
||||
string? association = type switch
|
||||
{
|
||||
AssociationType.ASSOC_TYPE_MONDSTADT => "Mengde",
|
||||
AssociationType.ASSOC_TYPE_LIYUE => "Liyue",
|
||||
AssociationType.ASSOC_TYPE_FATUI => default,
|
||||
AssociationType.ASSOC_TYPE_INAZUMA => "Inazuma",
|
||||
AssociationType.ASSOC_TYPE_RANGER => default,
|
||||
AssociationType.ASSOC_TYPE_SUMERU => "Sumeru",
|
||||
AssociationType.ASSOC_TYPE_FONTAINE => "Fontaine",
|
||||
AssociationType.ASSOC_TYPE_NATLAN => default,
|
||||
AssociationType.ASSOC_TYPE_SNEZHNAYA => default,
|
||||
_ => throw Must.NeverHappen(),
|
||||
};
|
||||
|
||||
return association is null
|
||||
? default
|
||||
: Web.HutaoEndpoints.StaticRaw("ChapterIcon", $"UI_ChapterIcon_{association}.png").ToUri();
|
||||
}
|
||||
|
||||
public override Uri? Convert(AssociationType from)
|
||||
{
|
||||
return AssociationTypeToIconUri(from);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using System.Collections.Frozen;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
|
||||
@@ -12,27 +13,27 @@ namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
[HighQuality]
|
||||
internal sealed class ElementNameIconConverter : ValueConverter<string, Uri>
|
||||
{
|
||||
private static readonly Dictionary<string, string> LocalizedNameToElementIconName = new()
|
||||
{
|
||||
[SH.ModelIntrinsicElementNameElec] = "Electric",
|
||||
[SH.ModelIntrinsicElementNameFire] = "Fire",
|
||||
[SH.ModelIntrinsicElementNameGrass] = "Grass",
|
||||
[SH.ModelIntrinsicElementNameIce] = "Ice",
|
||||
[SH.ModelIntrinsicElementNameRock] = "Rock",
|
||||
[SH.ModelIntrinsicElementNameWater] = "Water",
|
||||
[SH.ModelIntrinsicElementNameWind] = "Wind",
|
||||
};
|
||||
private static readonly FrozenDictionary<string, string> LocalizedNameToElementIconName = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameElec, "Electric"),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameFire, "Fire"),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameGrass, "Grass"),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameIce, "Ice"),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameRock, "Rock"),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameWater, "Water"),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameWind, "Wind"),
|
||||
]);
|
||||
|
||||
private static readonly Dictionary<string, ElementType> LocalizedNameToElementType = new()
|
||||
{
|
||||
[SH.ModelIntrinsicElementNameElec] = ElementType.Electric,
|
||||
[SH.ModelIntrinsicElementNameFire] = ElementType.Fire,
|
||||
[SH.ModelIntrinsicElementNameGrass] = ElementType.Grass,
|
||||
[SH.ModelIntrinsicElementNameIce] = ElementType.Ice,
|
||||
[SH.ModelIntrinsicElementNameRock] = ElementType.Rock,
|
||||
[SH.ModelIntrinsicElementNameWater] = ElementType.Water,
|
||||
[SH.ModelIntrinsicElementNameWind] = ElementType.Wind,
|
||||
};
|
||||
private static readonly FrozenDictionary<string, ElementType> LocalizedNameToElementType = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameElec, ElementType.Electric),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameFire, ElementType.Fire),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameGrass, ElementType.Grass),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameIce, ElementType.Ice),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameRock, ElementType.Rock),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameWater, ElementType.Water),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicElementNameWind, ElementType.Wind),
|
||||
]);
|
||||
|
||||
/// <summary>
|
||||
/// 将中文元素名称转换为图标链接
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
|
||||
using Microsoft.UI;
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.Control.Theme;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Win32;
|
||||
using System.Collections.Frozen;
|
||||
using Windows.UI;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
@@ -15,17 +16,39 @@ namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
[HighQuality]
|
||||
internal sealed class QualityColorConverter : ValueConverter<QualityType, Color>
|
||||
{
|
||||
private static readonly FrozenDictionary<string, QualityType> LocalizedNameToQualityType = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(SH.ModelIntrinsicItemQualityWhite, QualityType.QUALITY_WHITE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicItemQualityGreen, QualityType.QUALITY_GREEN),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicItemQualityBlue, QualityType.QUALITY_BLUE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicItemQualityPurple, QualityType.QUALITY_PURPLE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicItemQualityOrange, QualityType.QUALITY_ORANGE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicItemQualityRed, QualityType.QUALITY_ORANGE_SP),
|
||||
]);
|
||||
|
||||
private static readonly FrozenDictionary<QualityType, Color> QualityTypeToColor = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(QualityType.QUALITY_WHITE, KnownColors.White),
|
||||
KeyValuePair.Create(QualityType.QUALITY_GREEN, KnownColors.Green),
|
||||
KeyValuePair.Create(QualityType.QUALITY_BLUE, KnownColors.Blue),
|
||||
KeyValuePair.Create(QualityType.QUALITY_PURPLE, KnownColors.Purple),
|
||||
KeyValuePair.Create(QualityType.QUALITY_ORANGE, KnownColors.Orange),
|
||||
KeyValuePair.Create(QualityType.QUALITY_ORANGE_SP, KnownColors.Orange),
|
||||
]);
|
||||
|
||||
public static Color QualityNameToColor(string qualityName)
|
||||
{
|
||||
return QualityToColor(LocalizedNameToQualityType.GetValueOrDefault(qualityName));
|
||||
}
|
||||
|
||||
public static Color QualityToColor(QualityType quality)
|
||||
{
|
||||
return QualityTypeToColor.GetValueOrDefault(quality, Colors.Transparent);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Color Convert(QualityType from)
|
||||
{
|
||||
return from switch
|
||||
{
|
||||
QualityType.QUALITY_WHITE => StructMarshal.Color(0xFF72778B),
|
||||
QualityType.QUALITY_GREEN => StructMarshal.Color(0xFF2A8F72),
|
||||
QualityType.QUALITY_BLUE => StructMarshal.Color(0xFF5180CB),
|
||||
QualityType.QUALITY_PURPLE => StructMarshal.Color(0xFFA156E0),
|
||||
QualityType.QUALITY_ORANGE or QualityType.QUALITY_ORANGE_SP => StructMarshal.Color(0xFFBC6932),
|
||||
_ => Colors.Transparent,
|
||||
};
|
||||
return QualityToColor(from);
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using System.Collections.Frozen;
|
||||
|
||||
namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
|
||||
@@ -12,6 +13,20 @@ namespace Snap.Hutao.Model.Metadata.Converter;
|
||||
[HighQuality]
|
||||
internal sealed class WeaponTypeIconConverter : ValueConverter<WeaponType, Uri>
|
||||
{
|
||||
private static readonly FrozenDictionary<string, WeaponType> LocalizedNameToWeaponType = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(SH.ModelIntrinsicWeaponTypeSwordOneHand, WeaponType.WEAPON_SWORD_ONE_HAND),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicWeaponTypeBow, WeaponType.WEAPON_BOW),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicWeaponTypePole, WeaponType.WEAPON_POLE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicWeaponTypeClaymore, WeaponType.WEAPON_CLAYMORE),
|
||||
KeyValuePair.Create(SH.ModelIntrinsicWeaponTypeCatalyst, WeaponType.WEAPON_CATALYST),
|
||||
]);
|
||||
|
||||
public static Uri WeaponTypeNameToIconUri(string weaponTypeName)
|
||||
{
|
||||
return WeaponTypeToIconUri(LocalizedNameToWeaponType.GetValueOrDefault(weaponTypeName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将武器类型转换为图标链接
|
||||
/// </summary>
|
||||
|
||||
@@ -13,14 +13,14 @@ namespace Snap.Hutao.Service.GachaLog.Factory;
|
||||
internal sealed class GachaConfigTypeComparer : IComparer<GachaConfigType>
|
||||
{
|
||||
private static readonly Lazy<GachaConfigTypeComparer> LazyShared = new(() => new());
|
||||
private static readonly FrozenDictionary<GachaConfigType, int> OrderMap = new Dictionary<GachaConfigType, int>()
|
||||
{
|
||||
[GachaConfigType.AvatarEventWish] = 0,
|
||||
[GachaConfigType.AvatarEventWish2] = 1,
|
||||
[GachaConfigType.WeaponEventWish] = 2,
|
||||
[GachaConfigType.StandardWish] = 3,
|
||||
[GachaConfigType.NoviceWish] = 4,
|
||||
}.ToFrozenDictionary();
|
||||
private static readonly FrozenDictionary<GachaConfigType, int> OrderMap = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(GachaConfigType.AvatarEventWish, 0),
|
||||
KeyValuePair.Create(GachaConfigType.AvatarEventWish2, 1),
|
||||
KeyValuePair.Create(GachaConfigType.WeaponEventWish, 2),
|
||||
KeyValuePair.Create(GachaConfigType.StandardWish, 3),
|
||||
KeyValuePair.Create(GachaConfigType.NoviceWish, 4),
|
||||
]);
|
||||
|
||||
/// <summary>
|
||||
/// 共享的比较器
|
||||
|
||||
@@ -298,6 +298,7 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Primitives" Version="8.0.240109" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.0.240109" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.0.240109" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.TokenizingTextBox" Version="8.0.240109" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.0.240109" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.2" />
|
||||
|
||||
@@ -7,6 +7,7 @@ using Microsoft.Web.WebView2.Core;
|
||||
using Snap.Hutao.Control.Extension;
|
||||
using Snap.Hutao.Control.Theme;
|
||||
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
|
||||
using System.Collections.Frozen;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
using Windows.Foundation;
|
||||
@@ -29,17 +30,17 @@ internal sealed partial class AnnouncementContentViewer : UserControl
|
||||
}
|
||||
""";
|
||||
|
||||
private static readonly Dictionary<string, string> DarkLightReverts = new()
|
||||
{
|
||||
{ "color:rgba(0,0,0,1)", "color:rgba(255,255,255,1)" },
|
||||
{ "color:rgba(17,17,17,1)", "color:rgba(238,238,238,1)" },
|
||||
{ "color:rgba(51,51,51,1)", "color:rgba(204,204,204,1)" },
|
||||
{ "color:rgba(57,59,64,1)", "color:rgba(198,196,191,1)" },
|
||||
{ "color:rgba(85,85,85,1)", "color:rgba(170,170,170,1)" },
|
||||
{ "background-color: rgb(255, 215, 185)", "background-color: rgb(0,40,70)" },
|
||||
{ "background-color: rgb(254, 245, 231)", "background-color: rgb(1,40,70)" },
|
||||
{ "background-color:rgb(244, 244, 245)", "background-color:rgba(11, 11, 10)" },
|
||||
};
|
||||
private static readonly FrozenDictionary<string, string> DarkLightReverts = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create("color:rgba(0,0,0,1)", "color:rgba(255,255,255,1)"),
|
||||
KeyValuePair.Create("color:rgba(17,17,17,1)", "color:rgba(238,238,238,1)"),
|
||||
KeyValuePair.Create("color:rgba(51,51,51,1)", "color:rgba(204,204,204,1)"),
|
||||
KeyValuePair.Create("color:rgba(57,59,64,1)", "color:rgba(198,196,191,1)"),
|
||||
KeyValuePair.Create("color:rgba(85,85,85,1)", "color:rgba(170,170,170,1)"),
|
||||
KeyValuePair.Create("background-color: rgb(255, 215, 185)", "background-color: rgb(0,40,70)"),
|
||||
KeyValuePair.Create("background-color: rgb(254, 245, 231)", "background-color: rgb(1,40,70)"),
|
||||
KeyValuePair.Create("background-color:rgb(244, 244, 245)", "background-color:rgba(11, 11, 10)"),
|
||||
]);
|
||||
|
||||
private readonly RoutedEventHandler loadEventHandler;
|
||||
private readonly RoutedEventHandler unloadEventHandler;
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
xmlns:shca="using:Snap.Hutao.Control.AutoSuggestBox"
|
||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||
xmlns:shci="using:Snap.Hutao.Control.Image"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
@@ -73,6 +73,47 @@
|
||||
</shct:DescriptionTextBlock>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="TokenTemplate">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle
|
||||
Grid.Column="0"
|
||||
Width="4"
|
||||
Height="22"
|
||||
Margin="0,0,8,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Stretch"
|
||||
RadiusX="2"
|
||||
RadiusY="2"
|
||||
Visibility="{Binding Quality, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
|
||||
<Rectangle.Fill>
|
||||
<SolidColorBrush Color="{Binding Quality}"/>
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<shci:MonoChrome
|
||||
Grid.Column="0"
|
||||
Width="22"
|
||||
Height="22"
|
||||
Margin="0,0,4,0"
|
||||
Source="{Binding IconUri, Mode=OneWay}"
|
||||
Visibility="{Binding IconUri, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
|
||||
<shci:CachedImage
|
||||
Grid.Column="0"
|
||||
Width="22"
|
||||
Height="22"
|
||||
Margin="-4,-2,8,2"
|
||||
Source="{Binding SideIconUri, Mode=OneWay}"
|
||||
Visibility="{Binding SideIconUri, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Value}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="AvatarListTemplate">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -263,24 +304,33 @@
|
||||
Margin="8,8,0,0"
|
||||
LocalSettingKeySuffixForCurrent="WikiAvatarPage.Avatars"/>
|
||||
</CommandBar.Content>
|
||||
<!--<AppBarButton Icon="{shcm:FontIcon Glyph=}" Label="搜索提示"/>-->
|
||||
<AppBarElementContainer>
|
||||
<AutoSuggestBox
|
||||
Width="240"
|
||||
Height="36"
|
||||
Margin="6,6,6,0"
|
||||
HorizontalAlignment="Stretch"
|
||||
<shca:AutoSuggestTokenBox
|
||||
Width="600"
|
||||
Height="44"
|
||||
Margin="6,-2,6,6"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalContentAlignment="Center"
|
||||
AvailableTokens="{Binding AvailableTokens}"
|
||||
FilterCommand="{Binding FilterCommand}"
|
||||
ItemsSource="{Binding FilterTokens, Mode=TwoWay}"
|
||||
MaximumTokens="5"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageWiKiAvatarAutoSuggestBoxPlaceHolder}"
|
||||
QueryIcon="{shcm:FontIcon Glyph=}"
|
||||
Style="{StaticResource DefaultAutoSuggestBoxStyle}"
|
||||
Text="{Binding FilterText, Mode=TwoWay}">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="QuerySubmitted">
|
||||
<mxic:InvokeCommandAction Command="{Binding FilterCommand}" CommandParameter="{Binding FilterText}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</AutoSuggestBox>
|
||||
QueryIcon="{cw:FontIconSource Glyph=}"
|
||||
Style="{StaticResource DefaultTokenizingTextBoxStyle}"
|
||||
SuggestedItemTemplate="{StaticResource TokenTemplate}"
|
||||
SuggestedItemsSource="{Binding AvailableTokens.Values}"
|
||||
Text="{Binding FilterToken, Mode=TwoWay}"
|
||||
TokenItemTemplate="{StaticResource TokenTemplate}">
|
||||
<shca:AutoSuggestTokenBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<cwc:WrapPanel
|
||||
cw:FrameworkElementExtensions.AncestorType="shca:AutoSuggestTokenBox"
|
||||
HorizontalSpacing="2"
|
||||
StretchChild="Last"/>
|
||||
</ItemsPanelTemplate>
|
||||
</shca:AutoSuggestTokenBox.ItemsPanel>
|
||||
</shca:AutoSuggestTokenBox>
|
||||
</AppBarElementContainer>
|
||||
<AppBarButton
|
||||
Command="{Binding CultivateCommand}"
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
xmlns:shca="using:Snap.Hutao.Control.AutoSuggestBox"
|
||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||
xmlns:shci="using:Snap.Hutao.Control.Image"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
@@ -32,6 +33,47 @@
|
||||
Source="{Binding Converter={StaticResource PropertyDescriptor}}"/>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="TokenTemplate">
|
||||
<Grid VerticalAlignment="Center">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Rectangle
|
||||
Grid.Column="0"
|
||||
Width="4"
|
||||
Height="22"
|
||||
Margin="0,0,8,0"
|
||||
HorizontalAlignment="Left"
|
||||
VerticalAlignment="Stretch"
|
||||
RadiusX="2"
|
||||
RadiusY="2"
|
||||
Visibility="{Binding Quality, Converter={StaticResource EmptyObjectToVisibilityConverter}}">
|
||||
<Rectangle.Fill>
|
||||
<SolidColorBrush Color="{Binding Quality}"/>
|
||||
</Rectangle.Fill>
|
||||
</Rectangle>
|
||||
<shci:MonoChrome
|
||||
Grid.Column="0"
|
||||
Width="22"
|
||||
Height="22"
|
||||
Margin="0,0,4,0"
|
||||
Source="{Binding IconUri, Mode=OneWay}"
|
||||
Visibility="{Binding IconUri, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
|
||||
<shci:CachedImage
|
||||
Grid.Column="0"
|
||||
Width="22"
|
||||
Height="22"
|
||||
Margin="0,0,4,0"
|
||||
Source="{Binding SideIconUri, Mode=OneWay}"
|
||||
Visibility="{Binding SideIconUri, Converter={StaticResource EmptyObjectToVisibilityConverter}}"/>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding Value}"/>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="WeaponListTemplate">
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
@@ -131,21 +173,32 @@
|
||||
LocalSettingKeySuffixForCurrent="WikiWeaponPage.Weapons"/>
|
||||
</CommandBar.Content>
|
||||
<AppBarElementContainer>
|
||||
<AutoSuggestBox
|
||||
Width="240"
|
||||
Height="36"
|
||||
Margin="16,6,6,0"
|
||||
<shca:AutoSuggestTokenBox
|
||||
x:Name="WeaponSuggestBox"
|
||||
Width="600"
|
||||
Height="44"
|
||||
Margin="6,-2,6,6"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalContentAlignment="Center"
|
||||
AvailableTokens="{Binding AvailableTokens}"
|
||||
FilterCommand="{Binding FilterCommand}"
|
||||
ItemsSource="{Binding FilterTokens, Mode=TwoWay}"
|
||||
MaximumTokens="5"
|
||||
PlaceholderText="{shcm:ResourceString Name=ViewPageWiKiWeaponAutoSuggestBoxPlaceHolder}"
|
||||
QueryIcon="{shcm:FontIcon Glyph=}"
|
||||
Text="{Binding FilterText, Mode=TwoWay}">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="QuerySubmitted">
|
||||
<mxic:InvokeCommandAction Command="{Binding FilterCommand}" CommandParameter="{Binding FilterText}"/>
|
||||
</mxic:EventTriggerBehavior>
|
||||
</mxi:Interaction.Behaviors>
|
||||
</AutoSuggestBox>
|
||||
QueryIcon="{cw:FontIconSource Glyph=}"
|
||||
SuggestedItemTemplate="{StaticResource TokenTemplate}"
|
||||
SuggestedItemsSource="{Binding AvailableTokens.Values}"
|
||||
Text="{Binding FilterToken, Mode=TwoWay}"
|
||||
TokenItemTemplate="{StaticResource TokenTemplate}">
|
||||
<shca:AutoSuggestTokenBox.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<cwc:WrapPanel
|
||||
cw:FrameworkElementExtensions.AncestorType="shca:AutoSuggestTokenBox"
|
||||
HorizontalSpacing="2"
|
||||
StretchChild="Last"/>
|
||||
</ItemsPanelTemplate>
|
||||
</shca:AutoSuggestTokenBox.ItemsPanel>
|
||||
</shca:AutoSuggestTokenBox>
|
||||
</AppBarElementContainer>
|
||||
<AppBarButton
|
||||
Command="{Binding CultivateCommand}"
|
||||
|
||||
@@ -16,27 +16,27 @@ namespace Snap.Hutao.ViewModel.AvatarProperty;
|
||||
[HighQuality]
|
||||
internal sealed class AvatarProperty : ObservableObject, INameIcon, IAlternatingItem
|
||||
{
|
||||
private static readonly FrozenDictionary<FightProperty, Uri> PropertyIcons = new Dictionary<FightProperty, Uri>()
|
||||
{
|
||||
[FightProperty.FIGHT_PROP_SKILL_CD_MINUS_RATIO] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_CDReduce.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_ChargeEfficiency.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_CRITICAL] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Critical.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_CRITICAL_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Critical_Hurt.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_CUR_ATTACK] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_CurAttack.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_CUR_DEFENSE] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_CurDefense.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_ELEMENT_MASTERY] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_ELEC_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Electric.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_FIRE_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Fire.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_GRASS_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Grass.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_ICE_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Ice.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_ROCK_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Rock.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_WATER_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Water.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_WIND_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Wind.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_HEAL_ADD] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Heal.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_MAX_HP] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_MaxHp.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_PHYSICAL_ADD_HURT] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_PhysicalAttackUp.png").ToUri(),
|
||||
[FightProperty.FIGHT_PROP_SHIELD_COST_MINUS_RATIO] = Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_ShieldCostMinus.png").ToUri(),
|
||||
}.ToFrozenDictionary();
|
||||
private static readonly FrozenDictionary<FightProperty, Uri> PropertyIcons = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_SKILL_CD_MINUS_RATIO, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_CDReduce.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_ChargeEfficiency.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_CRITICAL, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Critical.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_CRITICAL_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Critical_Hurt.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_CUR_ATTACK, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_CurAttack.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_CUR_DEFENSE, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_CurDefense.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_ELEMENT_MASTERY, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_ELEC_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Electric.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_FIRE_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Fire.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_GRASS_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Grass.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_ICE_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Ice.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_ROCK_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Rock.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_WATER_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Water.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_WIND_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Element_Wind.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_HEAL_ADD, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_Heal.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_MAX_HP, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_MaxHp.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_PHYSICAL_ADD_HURT, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_PhysicalAttackUp.png").ToUri()),
|
||||
KeyValuePair.Create(FightProperty.FIGHT_PROP_SHIELD_COST_MINUS_RATIO, Web.HutaoEndpoints.StaticRaw("Property", "UI_Icon_ShieldCostMinus.png").ToUri()),
|
||||
]);
|
||||
|
||||
private Brush? background;
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Snap.Hutao.Control.AutoSuggestBox;
|
||||
using Snap.Hutao.Model.Intrinsic.Frozen;
|
||||
using Snap.Hutao.Model.Metadata.Avatar;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
@@ -17,55 +18,61 @@ internal static class AvatarFilter
|
||||
/// </summary>
|
||||
/// <param name="input">输入</param>
|
||||
/// <returns>筛选操作</returns>
|
||||
public static Predicate<Avatar> Compile(string input)
|
||||
public static Predicate<Avatar> Compile(ObservableCollection<SearchToken> input)
|
||||
{
|
||||
return (Avatar avatar) => DoFilter(input, avatar);
|
||||
}
|
||||
|
||||
private static bool DoFilter(string input, Avatar avatar)
|
||||
private static bool DoFilter(ObservableCollection<SearchToken> input, Avatar avatar)
|
||||
{
|
||||
List<bool> matches = [];
|
||||
foreach (StringSegment segment in new StringTokenizer(input, [' ']))
|
||||
|
||||
foreach ((SearchTokenKind kind, IEnumerable<string> tokens) in input.GroupBy(token => token.Kind, token => token.Value))
|
||||
{
|
||||
string value = segment.ToString();
|
||||
|
||||
if (avatar.Name == value)
|
||||
switch (kind)
|
||||
{
|
||||
matches.Add(true);
|
||||
continue;
|
||||
}
|
||||
case SearchTokenKind.ElementName:
|
||||
if (IntrinsicFrozen.ElementNames.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(avatar.FetterInfo.VisionBefore));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.ElementNames.Contains(value))
|
||||
{
|
||||
matches.Add(avatar.FetterInfo.VisionBefore == value);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SearchTokenKind.AssociationType:
|
||||
if (IntrinsicFrozen.AssociationTypes.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(avatar.FetterInfo.Association.GetLocalizedDescriptionOrDefault()));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.AssociationTypes.Contains(value))
|
||||
{
|
||||
matches.Add(avatar.FetterInfo.Association.GetLocalizedDescriptionOrDefault() == value);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SearchTokenKind.WeaponType:
|
||||
if (IntrinsicFrozen.WeaponTypes.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(avatar.Weapon.GetLocalizedDescriptionOrDefault()));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.WeaponTypes.Contains(value))
|
||||
{
|
||||
matches.Add(avatar.Weapon.GetLocalizedDescriptionOrDefault() == value);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SearchTokenKind.ItemQuality:
|
||||
if (IntrinsicFrozen.ItemQualities.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(avatar.Quality.GetLocalizedDescriptionOrDefault()));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.ItemQualities.Contains(value))
|
||||
{
|
||||
matches.Add(avatar.Quality.GetLocalizedDescriptionOrDefault() == value);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SearchTokenKind.BodyType:
|
||||
if (IntrinsicFrozen.BodyTypes.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(avatar.Body.GetLocalizedDescriptionOrDefault()));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.BodyTypes.Contains(value))
|
||||
{
|
||||
matches.Add(avatar.Body.GetLocalizedDescriptionOrDefault() == value);
|
||||
continue;
|
||||
break;
|
||||
case SearchTokenKind.Avatar:
|
||||
matches.Add(tokens.Contains(avatar.Name));
|
||||
break;
|
||||
default:
|
||||
matches.Add(false);
|
||||
break;
|
||||
}
|
||||
|
||||
matches.Add(false);
|
||||
}
|
||||
|
||||
return matches.Count > 0 && matches.Aggregate((a, b) => a && b);
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Extensions.Primitives;
|
||||
using Snap.Hutao.Control.AutoSuggestBox;
|
||||
using Snap.Hutao.Model.Intrinsic.Frozen;
|
||||
using Snap.Hutao.Model.Metadata.Weapon;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.Wiki;
|
||||
|
||||
@@ -17,41 +18,46 @@ internal static class WeaponFilter
|
||||
/// </summary>
|
||||
/// <param name="input">输入</param>
|
||||
/// <returns>筛选操作</returns>
|
||||
public static Predicate<Weapon> Compile(string input)
|
||||
public static Predicate<Weapon> Compile(ObservableCollection<SearchToken> input)
|
||||
{
|
||||
return (Weapon weapon) => DoFilter(input, weapon);
|
||||
}
|
||||
|
||||
private static bool DoFilter(string input, Weapon weapon)
|
||||
private static bool DoFilter(ObservableCollection<SearchToken> input, Weapon weapon)
|
||||
{
|
||||
List<bool> matches = [];
|
||||
|
||||
foreach (StringSegment segment in new StringTokenizer(input, [' ']))
|
||||
foreach ((SearchTokenKind kind, IEnumerable<string> tokens) in input.GroupBy(token => token.Kind, token => token.Value))
|
||||
{
|
||||
string value = segment.ToString();
|
||||
|
||||
if (weapon.Name == value)
|
||||
switch (kind)
|
||||
{
|
||||
matches.Add(true);
|
||||
continue;
|
||||
}
|
||||
case SearchTokenKind.WeaponType:
|
||||
if (IntrinsicFrozen.WeaponTypes.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(weapon.WeaponType.GetLocalizedDescriptionOrDefault()));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.WeaponTypes.Contains(value))
|
||||
{
|
||||
matches.Add(weapon.WeaponType.GetLocalizedDescriptionOrDefault() == value);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SearchTokenKind.ItemQuality:
|
||||
if (IntrinsicFrozen.ItemQualities.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(weapon.Quality.GetLocalizedDescriptionOrDefault()));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.ItemQualities.Contains(value))
|
||||
{
|
||||
matches.Add(weapon.Quality.GetLocalizedDescriptionOrDefault() == value);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case SearchTokenKind.FightProperty:
|
||||
if (IntrinsicFrozen.FightProperties.Overlaps(tokens))
|
||||
{
|
||||
matches.Add(tokens.Contains(weapon.GrowCurves.ElementAtOrDefault(1)?.Type.GetLocalizedDescriptionOrDefault()));
|
||||
}
|
||||
|
||||
if (IntrinsicFrozen.FightProperties.Contains(value))
|
||||
{
|
||||
matches.Add(weapon.GrowCurves.ElementAtOrDefault(1)?.Type.GetLocalizedDescriptionOrDefault() == value);
|
||||
continue;
|
||||
break;
|
||||
case SearchTokenKind.Weapon:
|
||||
matches.Add(tokens.Contains(weapon.Name));
|
||||
break;
|
||||
default:
|
||||
matches.Add(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Control.AutoSuggestBox;
|
||||
using Snap.Hutao.Control.Collection.AdvancedCollectionView;
|
||||
using Snap.Hutao.Factory.ContentDialog;
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Entity.Primitive;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Intrinsic.Frozen;
|
||||
using Snap.Hutao.Model.Metadata;
|
||||
using Snap.Hutao.Model.Metadata.Avatar;
|
||||
using Snap.Hutao.Model.Metadata.Converter;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
using Snap.Hutao.Service.Cultivation;
|
||||
@@ -17,6 +20,8 @@ using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
|
||||
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
|
||||
@@ -45,10 +50,12 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
|
||||
private AdvancedCollectionView<Avatar>? avatars;
|
||||
private Avatar? selected;
|
||||
private string? filterText;
|
||||
private ObservableCollection<SearchToken>? filterTokens;
|
||||
private string? filterToken;
|
||||
private BaseValueInfo? baseValueInfo;
|
||||
private Dictionary<Level, Dictionary<GrowCurveType, float>>? levelAvatarCurveMap;
|
||||
private List<Promote>? promotes;
|
||||
private FrozenDictionary<string, SearchToken> availableTokens;
|
||||
|
||||
/// <summary>
|
||||
/// 角色列表
|
||||
@@ -75,9 +82,13 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
public BaseValueInfo? BaseValueInfo { get => baseValueInfo; set => SetProperty(ref baseValueInfo, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 筛选文本
|
||||
/// 保存的筛选标志
|
||||
/// </summary>
|
||||
public string? FilterText { get => filterText; set => SetProperty(ref filterText, value); }
|
||||
public ObservableCollection<SearchToken>? FilterTokens { get => filterTokens; set => SetProperty(ref filterTokens, value); }
|
||||
|
||||
public string? FilterToken { get => filterToken; set => SetProperty(ref filterToken, value); }
|
||||
|
||||
public FrozenDictionary<string, SearchToken>? AvailableTokens { get => availableTokens; }
|
||||
|
||||
protected override async ValueTask<bool> InitializeUIAsync()
|
||||
{
|
||||
@@ -101,6 +112,18 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
await taskContext.SwitchToMainThreadAsync();
|
||||
Avatars = new(list, true);
|
||||
Selected = Avatars.View.ElementAtOrDefault(0);
|
||||
FilterTokens = [];
|
||||
|
||||
availableTokens = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
.. avatars.Select(avatar => KeyValuePair.Create(avatar.Name, new SearchToken(SearchTokenKind.Avatar, avatar.Name, sideIconUri: AvatarSideIconConverter.IconNameToUri(avatar.SideIcon)))),
|
||||
.. IntrinsicFrozen.AssociationTypes.Select(assoc => KeyValuePair.Create(assoc, new SearchToken(SearchTokenKind.AssociationType, assoc, iconUri: AssociationTypeIconConverter.AssociationTypeNameToIconUri(assoc)))),
|
||||
.. IntrinsicFrozen.BodyTypes.Select(b => KeyValuePair.Create(b, new SearchToken(SearchTokenKind.BodyType, b))),
|
||||
.. IntrinsicFrozen.ElementNames.Select(e => KeyValuePair.Create(e, new SearchToken(SearchTokenKind.ElementName, e, iconUri: ElementNameIconConverter.ElementNameToIconUri(e)))),
|
||||
.. IntrinsicFrozen.ItemQualities.Select(i => KeyValuePair.Create(i, new SearchToken(SearchTokenKind.ItemQuality, i, quality: QualityColorConverter.QualityNameToColor(i)))),
|
||||
.. IntrinsicFrozen.WeaponTypes.Select(w => KeyValuePair.Create(w, new SearchToken(SearchTokenKind.WeaponType, w, iconUri: WeaponTypeIconConverter.WeaponTypeNameToIconUri(w)))),
|
||||
]);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -203,20 +226,20 @@ internal sealed partial class WikiAvatarViewModel : Abstraction.ViewModel
|
||||
}
|
||||
|
||||
[Command("FilterCommand")]
|
||||
private void ApplyFilter(string? input)
|
||||
private void ApplyFilter()
|
||||
{
|
||||
if (Avatars is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
if (FilterTokens.IsNullOrEmpty())
|
||||
{
|
||||
Avatars.Filter = default!;
|
||||
return;
|
||||
}
|
||||
|
||||
Avatars.Filter = AvatarFilter.Compile(input);
|
||||
Avatars.Filter = AvatarFilter.Compile(FilterTokens);
|
||||
|
||||
if (Selected is not null && Avatars.Contains(Selected))
|
||||
{
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Control.AutoSuggestBox;
|
||||
using Snap.Hutao.Control.Collection.AdvancedCollectionView;
|
||||
using Snap.Hutao.Factory.ContentDialog;
|
||||
using Snap.Hutao.Model.Calculable;
|
||||
using Snap.Hutao.Model.Entity.Primitive;
|
||||
using Snap.Hutao.Model.Intrinsic;
|
||||
using Snap.Hutao.Model.Intrinsic.Frozen;
|
||||
using Snap.Hutao.Model.Metadata;
|
||||
using Snap.Hutao.Model.Metadata.Converter;
|
||||
using Snap.Hutao.Model.Metadata.Item;
|
||||
using Snap.Hutao.Model.Metadata.Weapon;
|
||||
using Snap.Hutao.Model.Primitive;
|
||||
@@ -17,6 +20,8 @@ using Snap.Hutao.Service.Notification;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.Web.Response;
|
||||
using System.Collections.Frozen;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Runtime.InteropServices;
|
||||
using CalculateAvatarPromotionDelta = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.AvatarPromotionDelta;
|
||||
using CalculateClient = Snap.Hutao.Web.Hoyolab.Takumi.Event.Calculate.CalculateClient;
|
||||
@@ -42,10 +47,12 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
|
||||
private AdvancedCollectionView<Weapon>? weapons;
|
||||
private Weapon? selected;
|
||||
private string? filterText;
|
||||
private ObservableCollection<SearchToken>? filterTokens;
|
||||
private string? filterToken;
|
||||
private BaseValueInfo? baseValueInfo;
|
||||
private Dictionary<Level, Dictionary<GrowCurveType, float>>? levelWeaponCurveMap;
|
||||
private List<Promote>? promotes;
|
||||
private FrozenDictionary<string, SearchToken> availableTokens;
|
||||
|
||||
/// <summary>
|
||||
/// 角色列表
|
||||
@@ -72,9 +79,13 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
public BaseValueInfo? BaseValueInfo { get => baseValueInfo; set => SetProperty(ref baseValueInfo, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 筛选文本
|
||||
/// 保存的筛选标志
|
||||
/// </summary>
|
||||
public string? FilterText { get => filterText; set => SetProperty(ref filterText, value); }
|
||||
public ObservableCollection<SearchToken>? FilterTokens { get => filterTokens; set => SetProperty(ref filterTokens, value); }
|
||||
|
||||
public string? FilterToken { get => filterToken; set => SetProperty(ref filterToken, value); }
|
||||
|
||||
public FrozenDictionary<string, SearchToken>? AvailableTokens { get => availableTokens; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OpenUIAsync()
|
||||
@@ -98,6 +109,15 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
|
||||
Weapons = new(list, true);
|
||||
Selected = Weapons.View.ElementAtOrDefault(0);
|
||||
FilterTokens = [];
|
||||
|
||||
availableTokens = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
.. weapons.Select(w => KeyValuePair.Create(w.Name, new SearchToken(SearchTokenKind.Weapon, w.Name, sideIconUri: EquipIconConverter.IconNameToUri(w.Icon)))),
|
||||
.. IntrinsicFrozen.FightProperties.Select(f => KeyValuePair.Create(f, new SearchToken(SearchTokenKind.FightProperty, f))),
|
||||
.. IntrinsicFrozen.ItemQualities.Select(i => KeyValuePair.Create(i, new SearchToken(SearchTokenKind.ItemQuality, i, quality: QualityColorConverter.QualityNameToColor(i)))),
|
||||
.. IntrinsicFrozen.WeaponTypes.Select(w => KeyValuePair.Create(w, new SearchToken(SearchTokenKind.WeaponType, w, iconUri: WeaponTypeIconConverter.WeaponTypeNameToIconUri(w)))),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,20 +208,20 @@ internal sealed partial class WikiWeaponViewModel : Abstraction.ViewModel
|
||||
}
|
||||
|
||||
[Command("FilterCommand")]
|
||||
private void ApplyFilter(string? input)
|
||||
private void ApplyFilter()
|
||||
{
|
||||
if (Weapons is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrWhiteSpace(input))
|
||||
if (FilterTokens.IsNullOrEmpty())
|
||||
{
|
||||
Weapons.Filter = default!;
|
||||
return;
|
||||
}
|
||||
|
||||
Weapons.Filter = WeaponFilter.Compile(input);
|
||||
Weapons.Filter = WeaponFilter.Compile(FilterTokens);
|
||||
|
||||
if (Selected is not null && Weapons.Contains(Selected))
|
||||
{
|
||||
|
||||
@@ -47,21 +47,22 @@ internal static class HoyolabOptions
|
||||
/// <summary>
|
||||
/// 盐
|
||||
/// </summary>
|
||||
public static FrozenDictionary<SaltType, string> Salts { get; } = new Dictionary<SaltType, string>()
|
||||
{
|
||||
public static FrozenDictionary<SaltType, string> Salts { get; } = FrozenDictionary.ToFrozenDictionary(
|
||||
[
|
||||
|
||||
// Chinese
|
||||
[SaltType.K2] = SaltConstants.CNK2,
|
||||
[SaltType.LK2] = SaltConstants.CNLK2,
|
||||
[SaltType.X4] = "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs",
|
||||
[SaltType.X6] = "t0qEgfub6cvueAPgR5m9aQWWVciEer7v",
|
||||
[SaltType.PROD] = "JwYDpKvLj6MrMqqYU6jTKF17KNO2PXoS",
|
||||
KeyValuePair.Create(SaltType.K2, SaltConstants.CNK2),
|
||||
KeyValuePair.Create(SaltType.LK2, SaltConstants.CNLK2),
|
||||
KeyValuePair.Create(SaltType.X4, "xV8v4Qu54lUKrEYFZkJhB8cuOh9Asafs"),
|
||||
KeyValuePair.Create(SaltType.X6, "t0qEgfub6cvueAPgR5m9aQWWVciEer7v"),
|
||||
KeyValuePair.Create(SaltType.PROD, "JwYDpKvLj6MrMqqYU6jTKF17KNO2PXoS"),
|
||||
|
||||
// Oversea
|
||||
[SaltType.OSK2] = SaltConstants.OSK2,
|
||||
[SaltType.OSLK2] = SaltConstants.OSLK2,
|
||||
[SaltType.OSX4] = "h4c1d6ywfq5bsbnbhm1bzq7bxzzv6srt",
|
||||
[SaltType.OSX6] = "okr4obncj8bw5a65hbnn5oo6ixjc3l9w",
|
||||
}.ToFrozenDictionary();
|
||||
KeyValuePair.Create(SaltType.OSK2, SaltConstants.OSK2),
|
||||
KeyValuePair.Create(SaltType.OSLK2, SaltConstants.OSLK2),
|
||||
KeyValuePair.Create(SaltType.OSX4, "h4c1d6ywfq5bsbnbhm1bzq7bxzzv6srt"),
|
||||
KeyValuePair.Create(SaltType.OSX6, "okr4obncj8bw5a65hbnn5oo6ixjc3l9w"),
|
||||
]);
|
||||
|
||||
[SuppressMessage("", "CA1308")]
|
||||
private static string GenerateDeviceId40()
|
||||
|
||||
Reference in New Issue
Block a user