move extensions

This commit is contained in:
DismissedLight
2022-08-28 22:00:58 +08:00
parent 3046047f04
commit f84793b5c0
15 changed files with 79 additions and 115 deletions

View File

@@ -1,16 +1,19 @@
# Snap.Hutao
> 唷,找本堂主有何贵干呀?
![Alt](https://repobeats.axiom.co/api/embed/f029553fbe0c60689b1710476ec8512452163fc9.svg "Repobeats analytics image")
![Snap.Hutao](https://repobeats.axiom.co/api/embed/f029553fbe0c60689b1710476ec8512452163fc9.svg)
## 感谢以下项目或人员的帮助
## Special Thanks
* [biuuu/genshin-wish-export](https://github.com/biuuu/genshin-wish-export)
* [CommunityToolkit/dotnet](https://github.com/CommunityToolkit/dotnet)
* [CommunityToolkit/WindowsCommunityToolkit](https://github.com/CommunityToolkit/WindowsCommunityToolkit)
* [dotnet/efcore](https://github.com/dotnet/efcore)
* [dotnet/runtime](https://github.com/dotnet/runtime)
* [HolographicHat/YaeAchievement](https://github.com/HolographicHat/YaeAchievement)
* [DotNetAnalyzers/StyleCopAnalyzers](https://github.com/DotNetAnalyzers/StyleCopAnalyzers)
* [microsoft/vs-threading](https://github.com/microsoft/vs-threading)
* [microsoft/vs-validation](https://github.com/microsoft/vs-validation)
* [microsoft/WindowsAppSDK](https://github.com/microsoft/WindowsAppSDK)
* [microsoft/microsoft-ui-xaml](https://github.com/microsoft/microsoft-ui-xaml)
* [microsoft/microsoft-ui-xaml](https://github.com/microsoft/microsoft-ui-xaml)
* [YuehaiTeam/cocogoat](https://github.com/YuehaiTeam/cocogoat)

View File

@@ -5,7 +5,7 @@ using Microsoft.Graphics.Canvas.Effects;
using Microsoft.UI.Composition;
using System.Numerics;
namespace Snap.Hutao.Extension;
namespace Snap.Hutao.Control.Image;
/// <summary>
/// 合成扩展

View File

@@ -4,7 +4,6 @@
using Microsoft.UI;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml.Media;
using Snap.Hutao.Extension;
using System.Numerics;
using Windows.Graphics.Imaging;
using Windows.Storage;

View File

@@ -6,7 +6,6 @@ using Microsoft.UI;
using Microsoft.UI.Composition;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Media;
using Snap.Hutao.Extension;
namespace Snap.Hutao.Control.Image;

View File

@@ -4,7 +4,7 @@
using Microsoft.Windows.AppLifecycle;
using Windows.ApplicationModel.Activation;
namespace Snap.Hutao.Extension;
namespace Snap.Hutao.Core.LifeCycle;
/// <summary>
/// <see cref="AppActivationArguments"/> 扩展

View File

@@ -4,7 +4,7 @@
using Microsoft.UI.Windowing;
using Windows.Graphics;
namespace Snap.Hutao.Extension;
namespace Snap.Hutao.Core.Windowing;
/// <summary>
/// <see cref="AppWindow"/> 扩展

View File

@@ -4,7 +4,6 @@
using Microsoft.UI;
using Microsoft.UI.Windowing;
using Snap.Hutao.Core.Setting;
using Snap.Hutao.Extension;
using System.Runtime.InteropServices;
using Windows.Graphics;
using Windows.Win32.Foundation;

View File

@@ -1,75 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.Reflection;
namespace Snap.Hutao.Extension;
/// <summary>
/// 反射扩展
/// </summary>
internal static class ReflectionExtension
{
/// <summary>
/// 在指定的成员中尝试获取标记的特性
/// </summary>
/// <typeparam name="TAttribute">特性的类型</typeparam>
/// <param name="type">类型</param>
/// <param name="attribute">获取的特性</param>
/// <returns>是否获取成功</returns>
public static bool TryGetAttribute<TAttribute>(this Type type, [NotNullWhen(true)] out TAttribute? attribute)
where TAttribute : Attribute
{
attribute = type.GetCustomAttribute<TAttribute>();
return attribute != null;
}
/// <summary>
/// 检测类型是否实现接口
/// </summary>
/// <typeparam name="TInterface">被实现的类型</typeparam>
/// <param name="type">被检测的类型/param>
/// <returns>是否实现接口</returns>
[SuppressMessage("", "SA1615")]
public static bool Implement<TInterface>(this Type type)
{
return type.IsAssignableTo(typeof(TInterface));
}
/// <summary>
/// 检查程序集是否标记了指定的特性
/// </summary>
/// <typeparam name="TAttribute">特性类型</typeparam>
/// <param name="assembly">指定的程序集</param>
/// <returns>是否标记了指定的特性</returns>
public static bool HasAttribute<TAttribute>(this Assembly assembly)
where TAttribute : Attribute
{
return assembly.GetCustomAttribute<TAttribute>() is not null;
}
/// <summary>
/// 对程序集中的所有类型进行指定的操作
/// </summary>
/// <param name="assembly">指定的程序集</param>
/// <param name="action">进行的操作</param>
public static void ForEachType(this Assembly assembly, Action<Type> action)
{
foreach (Type type in assembly.GetTypes())
{
action.Invoke(type);
}
}
/// <summary>
/// 按字段名称设置值
/// </summary>
/// <param name="obj">对象</param>
/// <param name="fieldName">字段名称</param>
/// <param name="value">值</param>
public static void SetPrivateFieldValueByName(this object obj, string fieldName, object? value)
{
FieldInfo? fieldInfo = obj.GetType().GetField(fieldName, BindingFlags.Instance | BindingFlags.NonPublic);
fieldInfo?.SetValue(obj, value);
}
}

View File

@@ -1,25 +0,0 @@
// Copyright (c) DGP Studio. All rights reserved.
// Licensed under the MIT license.
using System.Collections.Generic;
namespace Snap.Hutao.Extension;
/// <summary>
/// 元组扩展
/// </summary>
public static class TupleExtensions
{
/// <summary>
/// 将二项元组转化为一个单项的字典
/// </summary>
/// <typeparam name="TKey">键类型</typeparam>
/// <typeparam name="TValue">值类型</typeparam>
/// <param name="tuple">元组</param>
/// <returns>仅包含一个项的字典</returns>
public static IDictionary<TKey, TValue> AsDictionary<TKey, TValue>(this (TKey Key, TValue Value) tuple)
where TKey : notnull
{
return new Dictionary<TKey, TValue>(1) { { tuple.Key, tuple.Value } };
}
}

View File

@@ -32,7 +32,7 @@ public sealed partial class MainWindow : Window
this.messenger = messenger;
InitializeComponent();
windowManager = new WindowManager(this, TitleBarView.DragableArea);
windowManager = new WindowManager(this, TitleBarView.DragArea);
initializaionCompletionSource.TrySetResult();
}

View File

@@ -57,7 +57,16 @@ public class Achievement : Observable
{
Entity.Status = Intrinsic.AchievementInfoStatus.ACHIEVEMENT_POINT_TAKEN;
Entity.Time = DateTimeOffset.Now;
OnPropertyChanged(nameof(Time));
}
}
}
/// <summary>
/// 格式化的时间
/// </summary>
public string Time
{
get => entity.Time.ToString("yyyy-MM-dd HH:mm:ss");
}
}

View File

@@ -10,12 +10,14 @@
xmlns:shci="using:Snap.Hutao.Control.Image"
xmlns:shmmc="using:Snap.Hutao.Model.Metadata.Converter"
xmlns:shv="using:Snap.Hutao.ViewModel"
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Converters"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
d:DataContext="{d:DesignInstance shv:AchievementViewModel}">
<shcc:CancellablePage.Resources>
<shmmc:AchievementIconConverter x:Key="AchievementIconConverter"/>
<cwuc:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
</shcc:CancellablePage.Resources>
<mxi:Interaction.Behaviors>
@@ -86,8 +88,11 @@
<FontIcon Glyph="&#xE8E5;"/>
</AppBarButton.Icon>
</AppBarButton>
<AppBarSeparator/>
<AppBarToggleButton
Label="优先未完成">
Label="优先未完成"
IsChecked="{Binding IsIncompletedItemsFirst}"
Command="{Binding SortIncompletedSwitchCommand}">
<AppBarToggleButton.Icon>
<FontIcon Glyph="&#xE8CB;"/>
</AppBarToggleButton.Icon>
@@ -163,7 +168,7 @@
<CheckBox
IsChecked="{Binding IsChecked,Mode=TwoWay}"
Margin="6,0,0,0"
Margin="6,0,12,0"
Style="{StaticResource DefaultCheckBoxStyle}"
Padding="16,0,0,0"
Grid.Column="1">
@@ -173,22 +178,32 @@
<TextBlock
Margin="0,2,0,0"
Style="{StaticResource SecondaryTextStyle}"
TextTrimming="CharacterEllipsis"
Text="{Binding Inner.Description}"/>
</StackPanel>
</CheckBox.Content>
</CheckBox>
<Grid Grid.Column="3">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition Width="32"/>
</Grid.ColumnDefinitions>
<TextBlock
Margin="12,0,12,0"
VerticalAlignment="Center"
Grid.Column="0"
Text="{Binding Time}"
Visibility="{Binding IsChecked,Converter={StaticResource BoolToVisibilityConverter}}"
/>
<Image
Grid.Column="1"
Height="32"
Source="ms-appx:///Resource/Icon/UI_ItemIcon_201.png"/>
<TextBlock
Margin="12,0,0,0"
VerticalAlignment="Center"
Grid.Column="1"
Grid.Column="2"
Text="{Binding Inner.FinishReward.Count}"/>
</Grid>
</Grid>

View File

@@ -9,7 +9,7 @@
Height="44">
<Grid x:Name="DragableGrid">
<TextBlock
Text="胡桃"
Text="{x:Bind Title}"
TextWrapping="NoWrap"
Style="{StaticResource CaptionTextBlockStyle}"
VerticalAlignment="Center"

View File

@@ -22,8 +22,13 @@ public sealed partial class TitleView : UserControl
/// <summary>
/// 获取可拖动区域
/// </summary>
public FrameworkElement DragableArea
public FrameworkElement DragArea
{
get => DragableGrid;
}
public string Title
{
get => $"胡桃 {Core.CoreEnvironment.Version}";
}
}

View File

@@ -2,6 +2,7 @@
// Licensed under the MIT license.
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using CommunityToolkit.Mvvm.Messaging;
using CommunityToolkit.WinUI.UI;
using Microsoft.UI.Xaml.Controls;
@@ -41,6 +42,8 @@ internal class AchievementViewModel
IRecipient<AchievementArchiveChangedMessage>,
IRecipient<MainWindowClosedMessage>
{
private static readonly SortDescription IncompletedItemsFirstSortDescription = new(nameof(Model.Binding.Achievement.IsChecked), SortDirection.Ascending);
private readonly IMetadataService metadataService;
private readonly IAchievementService achievementService;
private readonly IInfoBarService infoBarService;
@@ -54,6 +57,7 @@ internal class AchievementViewModel
private AchievementGoal? selectedAchievementGoal;
private ObservableCollection<Model.Entity.AchievementArchive>? archives;
private Model.Entity.AchievementArchive? selectedArchive;
private bool isIncompletedItemsFirst = true;
/// <summary>
/// 构造一个新的成就视图模型
@@ -85,6 +89,7 @@ internal class AchievementViewModel
ImportUIAFFromFileCommand = asyncRelayCommandFactory.Create(ImportUIAFFromFileAsync);
AddArchiveCommand = asyncRelayCommandFactory.Create(AddArchiveAsync);
RemoveArchiveCommand = asyncRelayCommandFactory.Create(RemoveArchiveAsync);
SortIncompletedSwitchCommand = new RelayCommand(UpdateAchievementsSort);
messenger.Register<AchievementArchiveChangedMessage>(this);
messenger.Register<MainWindowClosedMessage>(this);
@@ -148,6 +153,15 @@ internal class AchievementViewModel
}
}
/// <summary>
/// 未完成优先
/// </summary>
public bool IsIncompletedItemsFirst
{
get => isIncompletedItemsFirst;
set => SetProperty(ref isIncompletedItemsFirst, value);
}
/// <summary>
/// 打开页面命令
/// </summary>
@@ -173,6 +187,11 @@ internal class AchievementViewModel
/// </summary>
public ICommand ImportUIAFFromFileCommand { get; }
/// <summary>
/// 筛选未完成项开关命令
/// </summary>
public ICommand SortIncompletedSwitchCommand { get; }
/// <inheritdoc/>
public void Receive(MainWindowClosedMessage message)
{
@@ -264,6 +283,7 @@ internal class AchievementViewModel
Achievements = new(combined, true);
UpdateAchievementFilter(SelectedAchievementGoal);
UpdateAchievementsSort();
}
private async Task AddArchiveAsync()
@@ -443,6 +463,21 @@ internal class AchievementViewModel
return false;
}
private void UpdateAchievementsSort()
{
if (Achievements != null)
{
if (IsIncompletedItemsFirst)
{
Achievements.SortDescriptions.Add(IncompletedItemsFirstSortDescription);
}
else
{
Achievements.SortDescriptions.Clear();
}
}
}
private void UpdateAchievementFilter(AchievementGoal? goal)
{
if (Achievements != null)