mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
Merge branch 'main' of https://github.com/DGP-Studio/Snap.Hutao
This commit is contained in:
@@ -3,6 +3,8 @@
|
|||||||
|
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
|
using Snap.Hutao.Core;
|
||||||
|
using Snap.Hutao.Web.Request;
|
||||||
|
|
||||||
namespace Snap.Hutao;
|
namespace Snap.Hutao;
|
||||||
|
|
||||||
|
|||||||
39
src/Snap.Hutao/Snap.Hutao/Core/HttpJson.cs
Normal file
39
src/Snap.Hutao/Snap.Hutao/Core/HttpJson.cs
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using System.Net.Http;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Http Json 处理
|
||||||
|
/// </summary>
|
||||||
|
public class HttpJson
|
||||||
|
{
|
||||||
|
private readonly Json json;
|
||||||
|
private readonly HttpClient httpClient;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化一个新的 Http Json 处理 实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="json">Json 处理器</param>
|
||||||
|
/// <param name="httpClient">http 客户端</param>
|
||||||
|
public HttpJson(Json json, HttpClient httpClient)
|
||||||
|
{
|
||||||
|
this.json = json;
|
||||||
|
this.httpClient = httpClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从网站上下载json并转换为对象
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">对象的类型</typeparam>
|
||||||
|
/// <param name="url">链接</param>
|
||||||
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
|
/// <returns>Json字符串中的反序列化对象, 如果反序列化失败会抛出异常</returns>
|
||||||
|
public async Task<T?> FromWebsiteAsync<T>(string url, CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
string response = await httpClient.GetStringAsync(url, cancellationToken);
|
||||||
|
return json.ToObject<T>(response);
|
||||||
|
}
|
||||||
|
}
|
||||||
133
src/Snap.Hutao/Snap.Hutao/Core/Json.cs
Normal file
133
src/Snap.Hutao/Snap.Hutao/Core/Json.cs
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Json操作
|
||||||
|
/// </summary>
|
||||||
|
[Injection(InjectAs.Transient)]
|
||||||
|
public class Json
|
||||||
|
{
|
||||||
|
private readonly ILogger logger;
|
||||||
|
|
||||||
|
private readonly JsonSerializerSettings jsonSerializerSettings = new()
|
||||||
|
{
|
||||||
|
DateFormatString = "yyyy'-'MM'-'dd' 'HH':'mm':'ss.FFFFFFFK",
|
||||||
|
Formatting = Formatting.Indented,
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 初始化一个新的 Json操作 实例
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logger">日志器</param>
|
||||||
|
public Json(ILogger<Json> logger)
|
||||||
|
{
|
||||||
|
this.logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将JSON反序列化为指定的.NET类型
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要反序列化的对象的类型</typeparam>
|
||||||
|
/// <param name="value">要反序列化的JSON</param>
|
||||||
|
/// <returns>Json字符串中的反序列化对象, 如果反序列化失败会抛出异常</returns>
|
||||||
|
public T? ToObject<T>(string value)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return JsonConvert.DeserializeObject<T>(value);
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
logger.LogError("反序列化Json时遇到问题:{ex}", ex);
|
||||||
|
}
|
||||||
|
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将JSON反序列化为指定的.NET类型
|
||||||
|
/// 若为null则返回一个新建的实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">指定的类型</typeparam>
|
||||||
|
/// <param name="value">字符串</param>
|
||||||
|
/// <returns>Json字符串中的反序列化对象, 如果反序列化失败会抛出异常</returns>
|
||||||
|
public T ToObjectOrNew<T>(string value)
|
||||||
|
where T : new()
|
||||||
|
{
|
||||||
|
return ToObject<T>(value) ?? new T();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将指定的对象序列化为JSON字符串
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">要序列化的对象</param>
|
||||||
|
/// <returns>对象的JSON字符串表示形式</returns>
|
||||||
|
public string Stringify(object? value)
|
||||||
|
{
|
||||||
|
return JsonConvert.SerializeObject(value, jsonSerializerSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用 <see cref="FileMode.Open"/>, <see cref="FileAccess.Read"/> 和 <see cref="FileShare.Read"/> 从文件中读取后转化为实体类
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要反序列化的对象的类型</typeparam>
|
||||||
|
/// <param name="fileName">存放JSON数据的文件路径</param>
|
||||||
|
/// <returns>JSON字符串中的反序列化对象, 如果反序列化失败则抛出异常,若文件不存在则返回 <see langword="null"/></returns>
|
||||||
|
public T? FromFile<T>(string fileName)
|
||||||
|
{
|
||||||
|
if (File.Exists(fileName))
|
||||||
|
{
|
||||||
|
// FileShare.Read is important to read some file
|
||||||
|
using (StreamReader sr = new(new FileStream(fileName, FileMode.Open, FileAccess.Read, FileShare.Read)))
|
||||||
|
{
|
||||||
|
return ToObject<T>(sr.ReadToEnd());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return default;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 使用 <see cref="FileMode.Open"/>, <see cref="FileAccess.Read"/> 和 <see cref="FileShare.Read"/> 从文件中读取后转化为实体类
|
||||||
|
/// 若为null则返回一个新建的实例
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要反序列化的对象的类型</typeparam>
|
||||||
|
/// <param name="fileName">存放JSON数据的文件路径</param>
|
||||||
|
/// <returns>JSON字符串中的反序列化对象</returns>
|
||||||
|
public T FromFileOrNew<T>(string fileName)
|
||||||
|
where T : new()
|
||||||
|
{
|
||||||
|
return FromFile<T>(fileName) ?? new T();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 从文件中读取后转化为实体类
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">要反序列化的对象的类型</typeparam>
|
||||||
|
/// <param name="file">存放JSON数据的文件</param>
|
||||||
|
/// <returns>JSON字符串中的反序列化对象</returns>
|
||||||
|
public T? FromFile<T>(FileInfo file)
|
||||||
|
{
|
||||||
|
using (StreamReader sr = file.OpenText())
|
||||||
|
{
|
||||||
|
return ToObject<T>(sr.ReadToEnd());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 将对象保存到文件
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="fileName">文件名称</param>
|
||||||
|
/// <param name="value">对象</param>
|
||||||
|
public void ToFile(string fileName, object? value)
|
||||||
|
{
|
||||||
|
File.WriteAllText(fileName, Stringify(value));
|
||||||
|
}
|
||||||
|
}
|
||||||
43
src/Snap.Hutao/Snap.Hutao/Core/Observable.cs
Normal file
43
src/Snap.Hutao/Snap.Hutao/Core/Observable.cs
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Core;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 简单的实现了 <see cref="INotifyPropertyChanged"/> 接口
|
||||||
|
/// </summary>
|
||||||
|
public class Observable : INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public event PropertyChangedEventHandler? PropertyChanged;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 设置字段的值
|
||||||
|
/// </summary>
|
||||||
|
/// <typeparam name="T">字段类型</typeparam>
|
||||||
|
/// <param name="storage">现有值</param>
|
||||||
|
/// <param name="value">新的值</param>
|
||||||
|
/// <param name="propertyName">属性名称</param>
|
||||||
|
protected void Set<T>([NotNullIfNotNull("value")] ref T storage, T value, [CallerMemberName] string propertyName = default!)
|
||||||
|
{
|
||||||
|
if (Equals(storage, value))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
storage = value;
|
||||||
|
OnPropertyChanged(propertyName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 触发 <see cref="PropertyChanged"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="propertyName">属性名称</param>
|
||||||
|
protected void OnPropertyChanged(string propertyName)
|
||||||
|
{
|
||||||
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,6 @@ namespace Snap.Hutao.Core.Threading;
|
|||||||
public class Watcher : Observable
|
public class Watcher : Observable
|
||||||
{
|
{
|
||||||
private readonly bool isReusable;
|
private readonly bool isReusable;
|
||||||
|
|
||||||
private bool hasUsed;
|
private bool hasUsed;
|
||||||
private bool isWorking;
|
private bool isWorking;
|
||||||
private bool isCompleted;
|
private bool isCompleted;
|
||||||
|
|||||||
@@ -95,6 +95,16 @@
|
|||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="View\Page\AnnouncementContentPage.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Page Update="View\Page\AnnouncementPage.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Page Update="View\Page\SettingPage.xaml">
|
<Page Update="View\Page\SettingPage.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
|||||||
@@ -0,0 +1,86 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
using Microsoft.UI.Xaml.Data;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.View.Converter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class converts a boolean value into an other object.
|
||||||
|
/// Can be used to convert true/false to visibility, a couple of colors, couple of images, etc.
|
||||||
|
/// </summary>
|
||||||
|
public class BoolToObjectConverter : DependencyObject, IValueConverter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies the <see cref="TrueValue"/> property.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty TrueValueProperty =
|
||||||
|
DependencyProperty.Register(nameof(TrueValue), typeof(object), typeof(BoolToObjectConverter), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Identifies the <see cref="FalseValue"/> property.
|
||||||
|
/// </summary>
|
||||||
|
public static readonly DependencyProperty FalseValueProperty =
|
||||||
|
DependencyProperty.Register(nameof(FalseValue), typeof(object), typeof(BoolToObjectConverter), new PropertyMetadata(null));
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the value to be returned when the boolean is true
|
||||||
|
/// </summary>
|
||||||
|
public object TrueValue
|
||||||
|
{
|
||||||
|
get => GetValue(TrueValueProperty);
|
||||||
|
set => SetValue(TrueValueProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets the value to be returned when the boolean is false
|
||||||
|
/// </summary>
|
||||||
|
public object FalseValue
|
||||||
|
{
|
||||||
|
get => GetValue(FalseValueProperty);
|
||||||
|
set => SetValue(FalseValueProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert a boolean value to an other object.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="value">The source data being passed to the target.</param>
|
||||||
|
/// <param name="targetType">The type of the target property, as a type reference.</param>
|
||||||
|
/// <param name="parameter">An optional parameter to be used to invert the converter logic.</param>
|
||||||
|
/// <param name="language">The language of the conversion.</param>
|
||||||
|
/// <returns>The value to be passed to the target dependency property.</returns>
|
||||||
|
public object Convert(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
bool boolValue = value is bool valid && valid;
|
||||||
|
|
||||||
|
// Negate if needed
|
||||||
|
if (ConvertHelper.TryParseBool(parameter))
|
||||||
|
{
|
||||||
|
boolValue = !boolValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return ConvertHelper.Convert(boolValue ? TrueValue : FalseValue, targetType);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Convert back the value to a boolean
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>If the <paramref name="value"/> parameter is a reference type, <see cref="TrueValue"/> must match its reference to return true.</remarks>
|
||||||
|
/// <param name="value">The target data being passed to the source.</param>
|
||||||
|
/// <param name="targetType">The type of the target property, as a type reference (System.Type for Microsoft .NET, a TypeName helper struct for Visual C++ component extensions (C++/CX)).</param>
|
||||||
|
/// <param name="parameter">An optional parameter to be used to invert the converter logic.</param>
|
||||||
|
/// <param name="language">The language of the conversion.</param>
|
||||||
|
/// <returns>The value to be passed to the source object.</returns>
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||||
|
{
|
||||||
|
bool result = Equals(value, ConvertHelper.Convert(TrueValue, value.GetType()));
|
||||||
|
|
||||||
|
if (ConvertHelper.TryParseBool(parameter))
|
||||||
|
{
|
||||||
|
result = !result;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Microsoft.UI.Xaml;
|
||||||
|
|
||||||
|
namespace Snap.Hutao.View.Converter;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This class converts a boolean value into a Visibility enumeration.
|
||||||
|
/// </summary>
|
||||||
|
public class BoolToVisibilityConverter : BoolToObjectConverter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="BoolToVisibilityConverter"/> class.
|
||||||
|
/// </summary>
|
||||||
|
public BoolToVisibilityConverter()
|
||||||
|
{
|
||||||
|
TrueValue = Visibility.Visible;
|
||||||
|
FalseValue = Visibility.Collapsed;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -29,9 +29,11 @@
|
|||||||
|
|
||||||
<Frame x:Name="ContentFrame">
|
<Frame x:Name="ContentFrame">
|
||||||
<Frame.ContentTransitions>
|
<Frame.ContentTransitions>
|
||||||
<NavigationThemeTransition>
|
<TransitionCollection>
|
||||||
<DrillInNavigationTransitionInfo/>
|
<NavigationThemeTransition>
|
||||||
</NavigationThemeTransition>
|
<DrillInNavigationTransitionInfo/>
|
||||||
|
</NavigationThemeTransition>
|
||||||
|
</TransitionCollection>
|
||||||
</Frame.ContentTransitions>
|
</Frame.ContentTransitions>
|
||||||
</Frame>
|
</Frame>
|
||||||
</NavigationView>
|
</NavigationView>
|
||||||
|
|||||||
Reference in New Issue
Block a user