mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
use binding proxy to replace property
This commit is contained in:
@@ -13,8 +13,8 @@
|
|||||||
<!--Modify Window title bar color-->
|
<!--Modify Window title bar color-->
|
||||||
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush" />
|
<StaticResource x:Key="WindowCaptionBackground" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush" />
|
<StaticResource x:Key="WindowCaptionBackgroundDisabled" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
<StaticResource x:Key="WindowCaptionForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
<ThemeResource x:Key="WindowCaptionForeground" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||||
<StaticResource x:Key="WindowCaptionForegroundDisabled" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
<ThemeResource x:Key="WindowCaptionForegroundDisabled" ResourceKey="SystemControlForegroundBaseHighBrush" />
|
||||||
|
|
||||||
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
<StaticResource x:Key="ApplicationPageBackgroundThemeBrush" ResourceKey="ControlFillColorTransparentBrush" />
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
|
using CommunityToolkit.WinUI.UI;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.VisualStudio.Threading;
|
using Microsoft.VisualStudio.Threading;
|
||||||
@@ -31,6 +32,7 @@ public partial class App : Application
|
|||||||
// load app resource
|
// load app resource
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
InitializeDependencyInjection();
|
InitializeDependencyInjection();
|
||||||
|
InitializeImageCache();
|
||||||
|
|
||||||
logger = Ioc.Default.GetRequiredService<ILogger<App>>();
|
logger = Ioc.Default.GetRequiredService<ILogger<App>>();
|
||||||
UnhandledException += AppUnhandledException;
|
UnhandledException += AppUnhandledException;
|
||||||
@@ -69,10 +71,11 @@ public partial class App : Application
|
|||||||
Window = Ioc.Default.GetRequiredService<MainWindow>();
|
Window = Ioc.Default.GetRequiredService<MainWindow>();
|
||||||
Window.Activate();
|
Window.Activate();
|
||||||
|
|
||||||
logger.LogInformation("Image cache folder : {folder}", Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);
|
logger.LogInformation("Cache folder : {folder}", Windows.Storage.ApplicationData.Current.TemporaryFolder.Path);
|
||||||
|
|
||||||
if (Ioc.Default.GetRequiredService<IMetadataService>() is IMetadataInitializer initializer)
|
if (Ioc.Default.GetRequiredService<IMetadataService>() is IMetadataInitializer initializer)
|
||||||
{
|
{
|
||||||
initializer.InitializeInternalAsync().SafeForget();
|
initializer.InitializeInternalAsync().SafeForget(logger: logger);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (uri != null)
|
if (uri != null)
|
||||||
@@ -104,6 +107,12 @@ public partial class App : Application
|
|||||||
Ioc.Default.ConfigureServices(services);
|
Ioc.Default.ConfigureServices(services);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void InitializeImageCache()
|
||||||
|
{
|
||||||
|
ImageCache.Instance.CacheDuration = TimeSpan.FromDays(30);
|
||||||
|
ImageCache.Instance.RetryCount = 3;
|
||||||
|
}
|
||||||
|
|
||||||
private void AppUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
private void AppUnhandledException(object sender, Microsoft.UI.Xaml.UnhandledExceptionEventArgs e)
|
||||||
{
|
{
|
||||||
logger.LogError(EventIds.UnhandledException, e.Exception, "未经处理的异常");
|
logger.LogError(EventIds.UnhandledException, e.Exception, "未经处理的异常");
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ namespace Snap.Hutao.Control;
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 绑定探针
|
/// 绑定探针
|
||||||
|
/// 用于处理特定情况下需要穿透数据上下文的工作
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class BindingProxy : DependencyObject
|
public class BindingProxy : DependencyObject
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -14,12 +14,6 @@ namespace Snap.Hutao.Control.Image;
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class CachedImage : ImageEx
|
public class CachedImage : ImageEx
|
||||||
{
|
{
|
||||||
static CachedImage()
|
|
||||||
{
|
|
||||||
ImageCache.Instance.CacheDuration = TimeSpan.FromDays(30);
|
|
||||||
ImageCache.Instance.RetryCount = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造一个新的缓存图像
|
/// 构造一个新的缓存图像
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ public class DescriptionTextBlock : ContentControl
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public DescriptionTextBlock()
|
public DescriptionTextBlock()
|
||||||
{
|
{
|
||||||
|
IsTabStop = false;
|
||||||
Content = new TextBlock();
|
Content = new TextBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,5 +16,10 @@ internal static class EventIds
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 未处理的异常
|
/// 未处理的异常
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static readonly EventId UnhandledException = new(100000, nameof(UnhandledException));
|
public static readonly EventId UnhandledException = new(100001, nameof(UnhandledException));
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// Forget任务执行异常
|
||||||
|
/// </summary>
|
||||||
|
public static readonly EventId TaskException = new(100002, nameof(TaskException));
|
||||||
|
}
|
||||||
@@ -42,9 +42,12 @@ internal static class Property<TOwner>
|
|||||||
/// <param name="defaultValue">默认值</param>
|
/// <param name="defaultValue">默认值</param>
|
||||||
/// <param name="callback">属性更改回调</param>
|
/// <param name="callback">属性更改回调</param>
|
||||||
/// <returns>注册的依赖属性</returns>
|
/// <returns>注册的依赖属性</returns>
|
||||||
public static DependencyProperty Depend<TProperty>(string name, TProperty defaultValue, PropertyChangedCallback callback)
|
public static DependencyProperty Depend<TProperty>(
|
||||||
|
string name,
|
||||||
|
TProperty defaultValue,
|
||||||
|
Action<DependencyObject, DependencyPropertyChangedEventArgs> callback)
|
||||||
{
|
{
|
||||||
return DependencyProperty.Register(name, typeof(TProperty), typeof(TOwner), new(defaultValue, callback));
|
return DependencyProperty.Register(name, typeof(TProperty), typeof(TOwner), new(defaultValue, new(callback)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -75,10 +78,14 @@ internal static class Property<TOwner>
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="TProperty">属性的类型</typeparam>
|
/// <typeparam name="TProperty">属性的类型</typeparam>
|
||||||
/// <param name="name">属性名称</param>
|
/// <param name="name">属性名称</param>
|
||||||
|
/// <param name="defaultValue">默认值</param>
|
||||||
/// <param name="callback">属性更改回调</param>
|
/// <param name="callback">属性更改回调</param>
|
||||||
/// <returns>注册的附加属性</returns>
|
/// <returns>注册的附加属性</returns>
|
||||||
public static DependencyProperty Attach<TProperty>(string name, PropertyChangedCallback callback)
|
public static DependencyProperty Attach<TProperty>(
|
||||||
|
string name,
|
||||||
|
TProperty defaultValue,
|
||||||
|
Action<DependencyObject, DependencyPropertyChangedEventArgs> callback)
|
||||||
{
|
{
|
||||||
return DependencyProperty.RegisterAttached(name, typeof(TProperty), typeof(TOwner), new(callback));
|
return DependencyProperty.RegisterAttached(name, typeof(TProperty), typeof(TOwner), new(defaultValue, new(callback)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,14 +9,11 @@ namespace Snap.Hutao.Core;
|
|||||||
/// 检测 WebView2运行时 是否存在
|
/// 检测 WebView2运行时 是否存在
|
||||||
/// 不再使用注册表检查方式
|
/// 不再使用注册表检查方式
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class WebView2Helper
|
internal abstract class WebView2Helper
|
||||||
{
|
{
|
||||||
private static bool hasEverDetected = false;
|
private static bool hasEverDetected = false;
|
||||||
private static bool isSupported = false;
|
private static bool isSupported = false;
|
||||||
|
private static string version = "未检测到 WebView2 运行时";
|
||||||
private WebView2Helper()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 检测 WebView2 是否存在
|
/// 检测 WebView2 是否存在
|
||||||
@@ -35,7 +32,7 @@ internal class WebView2Helper
|
|||||||
isSupported = true;
|
isSupported = true;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
string version = CoreWebView2Environment.GetAvailableBrowserVersionString();
|
version = CoreWebView2Environment.GetAvailableBrowserVersionString();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
@@ -47,4 +44,9 @@ internal class WebView2Helper
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/// <summary>
|
||||||
|
/// WebView2的版本
|
||||||
|
/// </summary>
|
||||||
|
public static string Version => version;
|
||||||
|
}
|
||||||
21
src/Snap.Hutao/Snap.Hutao/Extension/MemoryCacheExtensions.cs
Normal file
21
src/Snap.Hutao/Snap.Hutao/Extension/MemoryCacheExtensions.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
namespace Snap.Hutao.Extension;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 内存缓存扩展
|
||||||
|
/// </summary>
|
||||||
|
public static class MemoryCacheExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 获取缓存键名称
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="className">类名</param>
|
||||||
|
/// <param name="propertyName">属性名</param>
|
||||||
|
/// <returns>缓存</returns>
|
||||||
|
public static string GetCacheKey(string className, string propertyName)
|
||||||
|
{
|
||||||
|
return $"{className}.Cache.{propertyName}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
// Copyright (c) DGP Studio. All rights reserved.
|
// Copyright (c) DGP Studio. All rights reserved.
|
||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
|
using Snap.Hutao.Core.Logging;
|
||||||
|
|
||||||
namespace Snap.Hutao.Extension;
|
namespace Snap.Hutao.Extension;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -12,18 +14,19 @@ public static class TaskExtensions
|
|||||||
/// 安全的触发任务
|
/// 安全的触发任务
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="task">任务</param>
|
/// <param name="task">任务</param>
|
||||||
|
/// <param name="continueOnCapturedContext">是否在捕获的上下文中继续执行</param>
|
||||||
/// <param name="logger">日志器</param>
|
/// <param name="logger">日志器</param>
|
||||||
[SuppressMessage("", "VSTHRD003")]
|
[SuppressMessage("", "VSTHRD003")]
|
||||||
[SuppressMessage("", "VSTHRD100")]
|
[SuppressMessage("", "VSTHRD100")]
|
||||||
public static async void SafeForget(this Task task, ILogger? logger = null)
|
public static async void SafeForget(this Task task, bool continueOnCapturedContext = true, ILogger? logger = null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await task;
|
await task.ConfigureAwait(continueOnCapturedContext);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
logger?.LogError(e, "{caller}:{exception}", nameof(SafeForget), e.GetBaseException());
|
logger?.LogError(EventIds.TaskException, e, "{caller}:{exception}", nameof(SafeForget), e.GetBaseException());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,17 +9,10 @@
|
|||||||
Closed="MainWindowClosed">
|
Closed="MainWindowClosed">
|
||||||
|
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="48.8"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
|
|
||||||
<view:TitleView
|
<view:TitleView
|
||||||
Margin="48,0,0,0"
|
Margin="48,0,0,0"
|
||||||
Grid.Row="0"
|
Height="44"
|
||||||
x:Name="TitleBarView"/>
|
x:Name="TitleBarView"/>
|
||||||
<view:MainView
|
<view:MainView/>
|
||||||
Grid.Row="0"
|
|
||||||
Grid.RowSpan="2"/>
|
|
||||||
</Grid>
|
</Grid>
|
||||||
</Window>
|
</Window>
|
||||||
|
|||||||
@@ -33,10 +33,6 @@ public sealed partial class MainWindow : Window
|
|||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
|
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
|
|
||||||
ExtendsContentIntoTitleBar = true;
|
|
||||||
SetTitleBar(TitleBarView.DragableArea);
|
|
||||||
|
|
||||||
handle = WindowNative.GetWindowHandle(this);
|
handle = WindowNative.GetWindowHandle(this);
|
||||||
InitializeWindow();
|
InitializeWindow();
|
||||||
}
|
}
|
||||||
@@ -53,6 +49,9 @@ public sealed partial class MainWindow : Window
|
|||||||
|
|
||||||
private void InitializeWindow()
|
private void InitializeWindow()
|
||||||
{
|
{
|
||||||
|
ExtendsContentIntoTitleBar = true;
|
||||||
|
SetTitleBar(TitleBarView.DragableArea);
|
||||||
|
|
||||||
RECT rect = RetriveWindowRect();
|
RECT rect = RetriveWindowRect();
|
||||||
if (!rect.Size.IsEmpty)
|
if (!rect.Size.IsEmpty)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,10 +45,7 @@ public class FetterInfo
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public string BirthFormatted
|
public string BirthFormatted
|
||||||
{
|
{
|
||||||
get
|
get => $"{BirthMonth} 月 {BirthDay} 日";
|
||||||
{
|
|
||||||
return $"{BirthMonth} 月 {BirthDay} 日";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -13,8 +13,7 @@ public interface IAnnouncementService
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 异步获取游戏公告与活动,通常会进行缓存
|
/// 异步获取游戏公告与活动,通常会进行缓存
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="openAnnouncementUICommand">打开公告时触发的命令</param>
|
|
||||||
/// <param name="cancellationToken">取消令牌</param>
|
/// <param name="cancellationToken">取消令牌</param>
|
||||||
/// <returns>公告包装器</returns>
|
/// <returns>公告包装器</returns>
|
||||||
ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(ICommand openAnnouncementUICommand, CancellationToken cancellationToken = default);
|
ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(CancellationToken cancellationToken = default);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
// Licensed under the MIT license.
|
// Licensed under the MIT license.
|
||||||
|
|
||||||
using Microsoft.Extensions.Caching.Memory;
|
using Microsoft.Extensions.Caching.Memory;
|
||||||
|
using Snap.Hutao.Extension;
|
||||||
using Snap.Hutao.Service.Abstraction;
|
using Snap.Hutao.Service.Abstraction;
|
||||||
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
|
using Snap.Hutao.Web.Hoyolab.Hk4e.Common.Announcement;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@@ -14,7 +15,7 @@ namespace Snap.Hutao.Service;
|
|||||||
[Injection(InjectAs.Transient, typeof(IAnnouncementService))]
|
[Injection(InjectAs.Transient, typeof(IAnnouncementService))]
|
||||||
internal class AnnouncementService : IAnnouncementService
|
internal class AnnouncementService : IAnnouncementService
|
||||||
{
|
{
|
||||||
private const string CacheKey = $"{nameof(AnnouncementService)}.Cache.{nameof(AnnouncementWrapper)}";
|
private static readonly string CacheKey = MemoryCacheExtensions.GetCacheKey(nameof(AnnouncementService), nameof(AnnouncementWrapper));
|
||||||
|
|
||||||
private readonly AnnouncementClient announcementClient;
|
private readonly AnnouncementClient announcementClient;
|
||||||
private readonly IMemoryCache memoryCache;
|
private readonly IMemoryCache memoryCache;
|
||||||
@@ -31,12 +32,12 @@ internal class AnnouncementService : IAnnouncementService
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public async ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(ICommand openAnnouncementUICommand, CancellationToken cancellationToken = default)
|
public async ValueTask<AnnouncementWrapper> GetAnnouncementsAsync(CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
// 缓存中存在记录,直接返回
|
// 缓存中存在记录,直接返回
|
||||||
if (memoryCache.TryGetValue(CacheKey, out object? cache))
|
if (memoryCache.TryGetValue(CacheKey, out object? cache))
|
||||||
{
|
{
|
||||||
return Must.NotNull((cache as AnnouncementWrapper)!);
|
return Must.NotNull((AnnouncementWrapper)cache);
|
||||||
}
|
}
|
||||||
|
|
||||||
AnnouncementWrapper? wrapper = await announcementClient
|
AnnouncementWrapper? wrapper = await announcementClient
|
||||||
@@ -55,30 +56,27 @@ internal class AnnouncementService : IAnnouncementService
|
|||||||
wrapper.List.Reverse();
|
wrapper.List.Reverse();
|
||||||
|
|
||||||
// 将公告内容联入公告列表
|
// 将公告内容联入公告列表
|
||||||
JoinAnnouncements(openAnnouncementUICommand, contentMap, wrapper.List);
|
JoinAnnouncements(contentMap, wrapper.List);
|
||||||
|
|
||||||
return memoryCache.Set(CacheKey, wrapper, TimeSpan.FromMinutes(30));
|
return memoryCache.Set(CacheKey, wrapper, TimeSpan.FromMinutes(30));
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void JoinAnnouncements(ICommand openAnnouncementUICommand, Dictionary<int, string> contentMap, List<AnnouncementListWrapper> announcementListWrappers)
|
private static void JoinAnnouncements(Dictionary<int, string> contentMap, List<AnnouncementListWrapper> announcementListWrappers)
|
||||||
{
|
{
|
||||||
// 匹配特殊的时间格式: <t>(.*?)</t>
|
// 匹配特殊的时间格式: <t>(.*?)</t>
|
||||||
Regex timeTagRegrex = new("<t.*?>(.*?)</t>", RegexOptions.Multiline);
|
Regex timeTagRegrex = new("<t.*?>(.*?)</t>", RegexOptions.Multiline);
|
||||||
|
|
||||||
Regex timeTagInnerRegex = new("(?<=<t.*?>)(.*?)(?=</t>)");
|
|
||||||
|
|
||||||
announcementListWrappers.ForEach(listWrapper =>
|
announcementListWrappers.ForEach(listWrapper =>
|
||||||
{
|
{
|
||||||
listWrapper.List?.ForEach(item =>
|
listWrapper.List.ForEach(item =>
|
||||||
{
|
{
|
||||||
if (contentMap.TryGetValue(item.AnnId, out string? rawContent))
|
if (contentMap.TryGetValue(item.AnnId, out string? rawContent))
|
||||||
{
|
{
|
||||||
// remove <t/> tag
|
// remove <t/> tag
|
||||||
rawContent = timeTagRegrex.Replace(rawContent!, x => timeTagInnerRegex.Match(x.Value).Value);
|
rawContent = timeTagRegrex.Replace(rawContent!, x => x.Groups[1].Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Content = rawContent ?? string.Empty;
|
item.Content = rawContent ?? string.Empty;
|
||||||
item.OpenAnnouncementUICommand = openAnnouncementUICommand;
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,6 +70,7 @@
|
|||||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Behaviors" Version="7.1.2" />
|
<PackageReference Include="CommunityToolkit.WinUI.UI.Behaviors" Version="7.1.2" />
|
||||||
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
|
<PackageReference Include="CommunityToolkit.WinUI.UI.Controls" Version="7.1.2" />
|
||||||
|
<PackageReference Include="CommunityToolkit.WinUI.UI.Media" Version="7.1.2" />
|
||||||
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.5.1" />
|
<PackageReference Include="Microsoft.AppCenter.Analytics" Version="4.5.1" />
|
||||||
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.5.1" />
|
<PackageReference Include="Microsoft.AppCenter.Crashes" Version="4.5.1" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="6.0.6" />
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
xmlns:view="using:Snap.Hutao.View"
|
xmlns:view="using:Snap.Hutao.View"
|
||||||
mc:Ignorable="d">
|
mc:Ignorable="d">
|
||||||
<UserControl.Resources>
|
<UserControl.Resources>
|
||||||
<Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>
|
<Thickness x:Key="NavigationViewContentMargin">0,44,0,0</Thickness>
|
||||||
</UserControl.Resources>
|
</UserControl.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<NavigationView
|
<NavigationView
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ public sealed partial class AnnouncementContentPage : Microsoft.UI.Xaml.Controls
|
|||||||
{
|
{
|
||||||
// support click open browser.
|
// support click open browser.
|
||||||
private const string MihoyoSDKDefinition =
|
private const string MihoyoSDKDefinition =
|
||||||
@"window.miHoYoGameJSSDK = {
|
@"window.miHoYoGameJSSDK = {
|
||||||
openInBrowser: function(url){ window.chrome.webview.postMessage(url); },
|
openInBrowser: function(url){ window.chrome.webview.postMessage(url); },
|
||||||
openInWebview: function(url){ location.href = url }}";
|
openInWebview: function(url){ location.href = url }}";
|
||||||
|
|
||||||
@@ -25,7 +25,6 @@ openInWebview: function(url){ location.href = url }}";
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 构造一个新的公告窗体
|
/// 构造一个新的公告窗体
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="content">要展示的内容</param>
|
|
||||||
public AnnouncementContentPage()
|
public AnnouncementContentPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
@@ -43,7 +42,7 @@ openInWebview: function(url){ location.href = url }}";
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadAnnouncementAsync(INavigationData extra)
|
private async Task LoadAnnouncementAsync(INavigationData data)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -54,11 +53,11 @@ openInWebview: function(url){ location.href = url }}";
|
|||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
extra.NotifyNavigationException(ex);
|
data.NotifyNavigationException(ex);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
WebView.NavigateToString(targetContent);
|
WebView.NavigateToString(targetContent);
|
||||||
extra.NotifyNavigationCompleted();
|
data.NotifyNavigationCompleted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -9,8 +9,9 @@
|
|||||||
xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors"
|
xmlns:cwub="using:CommunityToolkit.WinUI.UI.Behaviors"
|
||||||
xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls"
|
xmlns:cwucont="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
xmlns:cwuconv="using:CommunityToolkit.WinUI.UI.Converters"
|
xmlns:cwuconv="using:CommunityToolkit.WinUI.UI.Converters"
|
||||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
|
||||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
|
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||||
|
xmlns:shc="using:Snap.Hutao.Control"
|
||||||
xmlns:shca="using:Snap.Hutao.Control.Animation"
|
xmlns:shca="using:Snap.Hutao.Control.Animation"
|
||||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||||
xmlns:shcc="using:Snap.Hutao.Control.Cancellable"
|
xmlns:shcc="using:Snap.Hutao.Control.Cancellable"
|
||||||
@@ -25,6 +26,8 @@
|
|||||||
<shcc:CancellablePage.Resources>
|
<shcc:CancellablePage.Resources>
|
||||||
<cwuconv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
<cwuconv:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter"/>
|
||||||
<shvc:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/>
|
<shvc:BoolToVisibilityRevertConverter x:Key="BoolToVisibilityRevertConverter"/>
|
||||||
|
|
||||||
|
<shc:BindingProxy x:Key="BindingProxy" DataContext="{Binding}"/>
|
||||||
</shcc:CancellablePage.Resources>
|
</shcc:CancellablePage.Resources>
|
||||||
<Grid>
|
<Grid>
|
||||||
<ScrollViewer Padding="0,0,4,0">
|
<ScrollViewer Padding="0,0,4,0">
|
||||||
@@ -152,7 +155,7 @@
|
|||||||
<mxi:Interaction.Behaviors>
|
<mxi:Interaction.Behaviors>
|
||||||
<mxic:EventTriggerBehavior EventName="Tapped">
|
<mxic:EventTriggerBehavior EventName="Tapped">
|
||||||
<mxic:InvokeCommandAction
|
<mxic:InvokeCommandAction
|
||||||
Command="{Binding OpenAnnouncementUICommand}"
|
Command="{Binding DataContext.OpenAnnouncementUICommand,Source={StaticResource BindingProxy}}"
|
||||||
CommandParameter="{Binding Content}"/>
|
CommandParameter="{Binding Content}"/>
|
||||||
</mxic:EventTriggerBehavior>
|
</mxic:EventTriggerBehavior>
|
||||||
<mxic:EventTriggerBehavior EventName="PointerEntered">
|
<mxic:EventTriggerBehavior EventName="PointerEntered">
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ public sealed partial class AnnouncementPage : CancellablePage
|
|||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
|
|
||||||
if (e.Parameter is INavigationData extra)
|
if (e.Parameter is INavigationData data)
|
||||||
{
|
{
|
||||||
extra.NotifyNavigationCompleted();
|
data.NotifyNavigationCompleted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ public sealed partial class SettingPage : Microsoft.UI.Xaml.Controls.Page
|
|||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
|
|
||||||
if (e.Parameter is INavigationData extra)
|
if (e.Parameter is INavigationData data)
|
||||||
{
|
{
|
||||||
extra.NotifyNavigationCompleted();
|
data.NotifyNavigationCompleted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls"
|
xmlns:cwuc="using:CommunityToolkit.WinUI.UI.Controls"
|
||||||
|
xmlns:cwum="using:CommunityToolkit.WinUI.UI.Media"
|
||||||
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
xmlns:mxic="using:Microsoft.Xaml.Interactions.Core"
|
||||||
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
xmlns:mxi="using:Microsoft.Xaml.Interactivity"
|
||||||
xmlns:shc="using:Snap.Hutao.Control"
|
xmlns:shc="using:Snap.Hutao.Control"
|
||||||
@@ -43,12 +44,14 @@
|
|||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
HorizontalContentAlignment="Stretch">
|
HorizontalContentAlignment="Stretch">
|
||||||
<Grid>
|
<Grid>
|
||||||
<Grid.RowDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<RowDefinition Height="auto"/>
|
<ColumnDefinition Width="auto"/>
|
||||||
<RowDefinition/>
|
<ColumnDefinition/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<shct:DescriptionTextBlock
|
<shct:DescriptionTextBlock
|
||||||
Margin="16,16,16,0"
|
Grid.Column="0"
|
||||||
|
MaxWidth="280"
|
||||||
|
Margin="16"
|
||||||
Description="{Binding Description}">
|
Description="{Binding Description}">
|
||||||
<shct:DescriptionTextBlock.Resources>
|
<shct:DescriptionTextBlock.Resources>
|
||||||
<Style
|
<Style
|
||||||
@@ -59,7 +62,7 @@
|
|||||||
</shct:DescriptionTextBlock.Resources>
|
</shct:DescriptionTextBlock.Resources>
|
||||||
</shct:DescriptionTextBlock>
|
</shct:DescriptionTextBlock>
|
||||||
<ScrollViewer
|
<ScrollViewer
|
||||||
Grid.Row="1"
|
Grid.Column="1"
|
||||||
VerticalScrollMode="Disabled"
|
VerticalScrollMode="Disabled"
|
||||||
HorizontalScrollBarVisibility="Auto">
|
HorizontalScrollBarVisibility="Auto">
|
||||||
<Grid
|
<Grid
|
||||||
@@ -195,16 +198,16 @@
|
|||||||
<ColumnDefinition/>
|
<ColumnDefinition/>
|
||||||
<ColumnDefinition/>
|
<ColumnDefinition/>
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
<shci:CachedImage
|
<BitmapIcon
|
||||||
Grid.Column="0"
|
Grid.Column="0"
|
||||||
Width="27.2"
|
Width="27.2"
|
||||||
Height="27.2"
|
Height="27.2"
|
||||||
Source="{Binding Selected.FetterInfo.VisionBefore,Converter={StaticResource ElementNameIconConverter}}"/>
|
UriSource="{Binding Selected.FetterInfo.VisionBefore,Converter={StaticResource ElementNameIconConverter}}"/>
|
||||||
<shci:CachedImage
|
<BitmapIcon
|
||||||
Grid.Column="1"
|
Grid.Column="1"
|
||||||
Width="27.2"
|
Width="27.2"
|
||||||
Height="27.2"
|
Height="27.2"
|
||||||
Source="{Binding Selected.Weapon,Converter={StaticResource WeaponTypeIconConverter}}"/>
|
UriSource="{Binding Selected.Weapon,Converter={StaticResource WeaponTypeIconConverter}}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<shvc:ItemIcon
|
<shvc:ItemIcon
|
||||||
Height="100"
|
Height="100"
|
||||||
@@ -395,93 +398,11 @@
|
|||||||
ItemsSource="{Binding Selected.SkillDepot.Skills}"
|
ItemsSource="{Binding Selected.SkillDepot.Skills}"
|
||||||
ItemTemplate="{StaticResource SkillDataTemplate}"/>
|
ItemTemplate="{StaticResource SkillDataTemplate}"/>
|
||||||
|
|
||||||
<!--元素爆发-->
|
<ContentControl
|
||||||
<Expander
|
|
||||||
Margin="16,16,0,0"
|
|
||||||
Header="{Binding Name}"
|
|
||||||
DataContext="{Binding Selected.SkillDepot.EnergySkill}"
|
|
||||||
HorizontalAlignment="Stretch"
|
HorizontalAlignment="Stretch"
|
||||||
HorizontalContentAlignment="Stretch">
|
HorizontalContentAlignment="Stretch"
|
||||||
<Grid>
|
Content="{Binding Selected.SkillDepot.EnergySkill}"
|
||||||
<Grid.RowDefinitions>
|
ContentTemplate="{StaticResource SkillDataTemplate}"/>
|
||||||
<RowDefinition Height="auto"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<shct:DescriptionTextBlock
|
|
||||||
Margin="16,16,16,0"
|
|
||||||
Description="{Binding Description}">
|
|
||||||
<shct:DescriptionTextBlock.Resources>
|
|
||||||
<Style
|
|
||||||
TargetType="TextBlock"
|
|
||||||
BasedOn="{StaticResource BodyTextBlockStyle}">
|
|
||||||
<Setter Property="TextWrapping" Value="Wrap"/>
|
|
||||||
</Style>
|
|
||||||
</shct:DescriptionTextBlock.Resources>
|
|
||||||
</shct:DescriptionTextBlock>
|
|
||||||
<ScrollViewer
|
|
||||||
Grid.Row="1"
|
|
||||||
VerticalScrollMode="Disabled"
|
|
||||||
HorizontalScrollBarVisibility="Auto">
|
|
||||||
<Grid>
|
|
||||||
<Grid
|
|
||||||
Grid.Row="1"
|
|
||||||
Margin="16"
|
|
||||||
DataContext="{Binding Proud,Converter={StaticResource DescParamDescriptor}}">
|
|
||||||
<Grid.RowDefinitions>
|
|
||||||
<RowDefinition Height="auto"/>
|
|
||||||
<RowDefinition/>
|
|
||||||
</Grid.RowDefinitions>
|
|
||||||
<ItemsControl
|
|
||||||
Grid.Row="0"
|
|
||||||
ItemsSource="{Binding Descriptions}">
|
|
||||||
<ItemsControl.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<cwuc:UniformGrid
|
|
||||||
ColumnSpacing="16"
|
|
||||||
Columns="{Binding Descriptions.Count}"/>
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ItemsControl.ItemsPanel>
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<TextBlock
|
|
||||||
Text="{Binding}"
|
|
||||||
TextWrapping="NoWrap"
|
|
||||||
TextTrimming="CharacterEllipsis"
|
|
||||||
Style="{StaticResource BaseTextBlockStyle}"/>
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
|
|
||||||
<ItemsControl
|
|
||||||
Margin="0,6,0,0"
|
|
||||||
Grid.Row="2"
|
|
||||||
ItemsSource="{Binding Parameters}">
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<ItemsControl ItemsSource="{Binding}">
|
|
||||||
<ItemsControl.ItemsPanel>
|
|
||||||
<ItemsPanelTemplate>
|
|
||||||
<cwuc:UniformGrid
|
|
||||||
ColumnSpacing="16"
|
|
||||||
Columns="{Binding Count}"/>
|
|
||||||
</ItemsPanelTemplate>
|
|
||||||
</ItemsControl.ItemsPanel>
|
|
||||||
<ItemsControl.ItemTemplate>
|
|
||||||
<DataTemplate>
|
|
||||||
<TextBlock
|
|
||||||
Text="{Binding}"
|
|
||||||
TextTrimming="CharacterEllipsis"/>
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
</DataTemplate>
|
|
||||||
</ItemsControl.ItemTemplate>
|
|
||||||
</ItemsControl>
|
|
||||||
</Grid>
|
|
||||||
</Grid>
|
|
||||||
</ScrollViewer>
|
|
||||||
</Grid>
|
|
||||||
</Expander>
|
|
||||||
|
|
||||||
<ItemsControl
|
<ItemsControl
|
||||||
ItemsSource="{Binding Selected.SkillDepot.Inherents}"
|
ItemsSource="{Binding Selected.SkillDepot.Inherents}"
|
||||||
|
|||||||
@@ -26,9 +26,9 @@ public sealed partial class WikiAvatarPage : Microsoft.UI.Xaml.Controls.Page
|
|||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
|
|
||||||
if (e.Parameter is INavigationData extra)
|
if (e.Parameter is INavigationData data)
|
||||||
{
|
{
|
||||||
extra.NotifyNavigationCompleted();
|
data.NotifyNavigationCompleted();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Height="48.8">
|
VerticalAlignment="Top"
|
||||||
|
Height="44">
|
||||||
<Grid x:Name="DragableGrid">
|
<Grid x:Name="DragableGrid">
|
||||||
<TextBlock
|
<TextBlock
|
||||||
Text="胡桃"
|
Text="胡桃"
|
||||||
|
|||||||
@@ -59,7 +59,6 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation
|
|||||||
public AnnouncementWrapper? Announcement
|
public AnnouncementWrapper? Announcement
|
||||||
{
|
{
|
||||||
get => announcement;
|
get => announcement;
|
||||||
|
|
||||||
set => SetProperty(ref announcement, value);
|
set => SetProperty(ref announcement, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +76,7 @@ internal class AnnouncementViewModel : ObservableObject, ISupportCancellation
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Announcement = await announcementService.GetAnnouncementsAsync(OpenAnnouncementUICommand, CancellationToken);
|
Announcement = await announcementService.GetAnnouncementsAsync(CancellationToken);
|
||||||
}
|
}
|
||||||
catch (TaskCanceledException)
|
catch (TaskCanceledException)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -12,11 +12,6 @@ public class Announcement : AnnouncementContent
|
|||||||
{
|
{
|
||||||
private double timePercent;
|
private double timePercent;
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// 启动展示窗口的命令
|
|
||||||
/// </summary>
|
|
||||||
public ICommand? OpenAnnouncementUICommand { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 是否应展示时间
|
/// 是否应展示时间
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -38,8 +38,7 @@ public struct PlayerUid
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
region ??= EvaluateRegion(Value[0]);
|
return region ??= EvaluateRegion(Value[0]);
|
||||||
return region;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +52,7 @@ public struct PlayerUid
|
|||||||
'7' => "os_euro", // 欧服
|
'7' => "os_euro", // 欧服
|
||||||
'8' => "os_asia", // 亚服
|
'8' => "os_asia", // 亚服
|
||||||
'9' => "os_cht", // 台服
|
'9' => "os_cht", // 台服
|
||||||
_ => Must.NeverHappen<string>(),
|
_ => throw Must.NeverHappen(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user