mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
daily note card
This commit is contained in:
@@ -50,6 +50,7 @@ internal sealed class UniversalAnalyzer : DiagnosticAnalyzer
|
||||
context.RegisterSyntaxNodeAction(HandleTypeDeclaration, types);
|
||||
|
||||
context.RegisterSyntaxNodeAction(HandleMethodDeclaration, SyntaxKind.MethodDeclaration);
|
||||
context.RegisterSyntaxNodeAction(HandleConstructorDeclaration, SyntaxKind.ConstructorDeclaration);
|
||||
}
|
||||
|
||||
private void HandleTypeDeclaration(SyntaxNodeAnalysisContext context)
|
||||
@@ -133,6 +134,35 @@ internal sealed class UniversalAnalyzer : DiagnosticAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleConstructorDeclaration(SyntaxNodeAnalysisContext context)
|
||||
{
|
||||
ConstructorDeclarationSyntax constructorSyntax = (ConstructorDeclarationSyntax)context.Node;
|
||||
|
||||
foreach (ParameterSyntax parameter in constructorSyntax.ParameterList.Parameters)
|
||||
{
|
||||
if (context.SemanticModel.GetDeclaredSymbol(parameter) is IParameterSymbol symbol)
|
||||
{
|
||||
if (IsBuiltInType(symbol.Type))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// 跳过 CancellationToken
|
||||
if (symbol.Type.ToDisplayString() == "System.Threading.CancellationToken")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (symbol.Type.IsReadOnly && symbol.RefKind == RefKind.None)
|
||||
{
|
||||
Location location = parameter.GetLocation();
|
||||
Diagnostic diagnostic = Diagnostic.Create(readOnlyStructRefDescriptor, location, symbol.Type);
|
||||
context.ReportDiagnostic(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsBuiltInType(ITypeSymbol symbol)
|
||||
{
|
||||
return symbol.SpecialType switch
|
||||
|
||||
@@ -53,7 +53,9 @@
|
||||
<SolidColorBrush x:Key="AvatarPropertyAddValueBrush" Color="{ThemeResource AvatarPropertyAddValueColor}"/>
|
||||
<!-- Settings -->
|
||||
<x:Double x:Key="SettingsCardSpacing">3</x:Double>
|
||||
|
||||
<x:Double x:Key="SettingsCardMinHeight">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapNoIconThreshold">0</x:Double>
|
||||
<Style
|
||||
x:Key="SettingsSectionHeaderTextBlockStyle"
|
||||
BasedOn="{StaticResource BodyStrongTextBlockStyle}"
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Buffers.Binary;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Windows.UI;
|
||||
|
||||
namespace Snap.Hutao.Control.Media;
|
||||
@@ -10,70 +11,37 @@ namespace Snap.Hutao.Control.Media;
|
||||
/// BGRA8 结构
|
||||
/// </summary>
|
||||
[HighQuality]
|
||||
[StructLayout(LayoutKind.Explicit)]
|
||||
internal struct Bgra8
|
||||
{
|
||||
/// <summary>
|
||||
/// B
|
||||
/// </summary>
|
||||
[FieldOffset(0)]
|
||||
public byte B;
|
||||
|
||||
/// <summary>
|
||||
/// G
|
||||
/// </summary>
|
||||
[FieldOffset(1)]
|
||||
public byte G;
|
||||
|
||||
/// <summary>
|
||||
/// R
|
||||
/// </summary>
|
||||
[FieldOffset(2)]
|
||||
public byte R;
|
||||
|
||||
/// <summary>
|
||||
/// A
|
||||
/// </summary>
|
||||
[FieldOffset(3)]
|
||||
public byte A;
|
||||
|
||||
[FieldOffset(0)]
|
||||
private readonly uint data;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的 BGRA8 结构
|
||||
/// </summary>
|
||||
/// <param name="b">B</param>
|
||||
/// <param name="g">G</param>
|
||||
/// <param name="r">R</param>
|
||||
/// <param name="a">A</param>
|
||||
public Bgra8(byte b, byte g, byte r, byte a)
|
||||
{
|
||||
B = b;
|
||||
G = g;
|
||||
R = r;
|
||||
A = a;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从Color值转换
|
||||
/// 从 Color 转换
|
||||
/// </summary>
|
||||
/// <param name="color">颜色</param>
|
||||
/// <returns>新的 BGRA8 结构</returns>
|
||||
public static Bgra8 FromColor(Color color)
|
||||
public static unsafe Bgra8 FromColor(Color color)
|
||||
{
|
||||
return new(color.B, color.G, color.R, color.A);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 从RGB值转换
|
||||
/// </summary>
|
||||
/// <param name="r">R</param>
|
||||
/// <param name="g">G</param>
|
||||
/// <param name="b">B</param>
|
||||
/// <returns>新的 BGRA8 结构</returns>
|
||||
public static Bgra8 FromRgb(byte r, byte g, byte b)
|
||||
{
|
||||
return new(b, g, r, 0xFF);
|
||||
Unsafe.SkipInit(out Bgra8 bgra8);
|
||||
*(uint*)&bgra8 = BinaryPrimitives.ReverseEndianness(*(uint*)&color);
|
||||
return bgra8;
|
||||
}
|
||||
}
|
||||
@@ -47,7 +47,7 @@ internal struct Rgba8
|
||||
/// 构造一个新的 RGBA8 颜色
|
||||
/// </summary>
|
||||
/// <param name="hex">色值字符串</param>
|
||||
public Rgba8(ReadOnlySpan<char> hex)
|
||||
public Rgba8(in ReadOnlySpan<char> hex)
|
||||
{
|
||||
R = 0;
|
||||
G = 0;
|
||||
|
||||
@@ -85,7 +85,7 @@ file readonly struct MeasureExecutionDisposable : IDisposable
|
||||
private readonly ILogger logger;
|
||||
private readonly string callerName;
|
||||
|
||||
public MeasureExecutionDisposable(ValueStopwatch stopwatch, ILogger logger, string callerName)
|
||||
public MeasureExecutionDisposable(in ValueStopwatch stopwatch, ILogger logger, string callerName)
|
||||
{
|
||||
this.stopwatch = stopwatch;
|
||||
this.logger = logger;
|
||||
|
||||
@@ -30,7 +30,7 @@ internal sealed class WindowSubclass<TWindow> : IDisposable
|
||||
/// 构造一个新的窗体子类管理器
|
||||
/// </summary>
|
||||
/// <param name="options">选项</param>
|
||||
public WindowSubclass(WindowOptions<TWindow> options)
|
||||
public WindowSubclass(in WindowOptions<TWindow> options)
|
||||
{
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ internal sealed class HistoryWishBuilder
|
||||
/// </summary>
|
||||
/// <param name="gachaEvent">卡池配置</param>
|
||||
/// <param name="context">祈愿记录上下文</param>
|
||||
[SuppressMessage("", "SH002")]
|
||||
public HistoryWishBuilder(GachaEvent gachaEvent, GachaLogServiceContext context)
|
||||
{
|
||||
this.gachaEvent = gachaEvent;
|
||||
|
||||
@@ -24,7 +24,7 @@ internal sealed class GameFpsUnlocker : IGameFpsUnlocker
|
||||
private bool isValid = true;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的 <see cref="Unlocker"/> 对象,
|
||||
/// 构造一个新的 <see cref="GameFpsUnlocker"/> 对象,
|
||||
/// 每个解锁器只能解锁一次原神的进程,
|
||||
/// 再次解锁需要重新创建对象
|
||||
/// <para/>
|
||||
@@ -62,43 +62,16 @@ internal sealed class GameFpsUnlocker : IGameFpsUnlocker
|
||||
private static unsafe bool UnsafeReadModuleMemory(Process process, MODULEENTRY32 entry, out Span<byte> memory)
|
||||
{
|
||||
memory = new byte[entry.modBaseSize];
|
||||
|
||||
fixed (byte* lpBuffer = memory)
|
||||
{
|
||||
bool hProcessAddRef = false;
|
||||
try
|
||||
{
|
||||
process.SafeHandle.DangerousAddRef(ref hProcessAddRef);
|
||||
HANDLE hProcessLocal = (HANDLE)process.SafeHandle.DangerousGetHandle();
|
||||
return ReadProcessMemory(hProcessLocal, entry.modBaseAddr, lpBuffer, entry.modBaseSize, null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (hProcessAddRef)
|
||||
{
|
||||
process.SafeHandle.DangerousRelease();
|
||||
}
|
||||
}
|
||||
return ReadProcessMemory((HANDLE)process.Handle, entry.modBaseAddr, lpBuffer, entry.modBaseSize, null);
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe bool UnsafeWriteModuleMemory(Process process, nuint baseAddress, int write)
|
||||
{
|
||||
int* lpBuffer = &write;
|
||||
|
||||
bool hProcessAddRef = false;
|
||||
try
|
||||
{
|
||||
process.SafeHandle.DangerousAddRef(ref hProcessAddRef);
|
||||
HANDLE hProcessLocal = (HANDLE)process.SafeHandle.DangerousGetHandle();
|
||||
return WriteProcessMemory(hProcessLocal, (void*)baseAddress, lpBuffer, sizeof(int), null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (hProcessAddRef)
|
||||
{
|
||||
process.SafeHandle.DangerousRelease();
|
||||
}
|
||||
}
|
||||
return WriteProcessMemory((HANDLE)process.Handle, (void*)baseAddress, &write, sizeof(int), null);
|
||||
}
|
||||
|
||||
private static unsafe MODULEENTRY32 UnsafeFindModule(int processId, in ReadOnlySpan<byte> moduleName)
|
||||
@@ -109,8 +82,7 @@ internal sealed class GameFpsUnlocker : IGameFpsUnlocker
|
||||
Marshal.ThrowExceptionForHR(Marshal.GetLastPInvokeError());
|
||||
foreach (MODULEENTRY32 entry in StructMarshal.EnumerateModuleEntry32(snapshot))
|
||||
{
|
||||
__CHAR_256* pszModule = &entry.szModule;
|
||||
ReadOnlySpan<byte> szModuleLocal = MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte*)pszModule);
|
||||
ReadOnlySpan<byte> szModuleLocal = MemoryMarshal.CreateReadOnlySpanFromNullTerminated((byte*)&entry.szModule);
|
||||
if (entry.th32ProcessID == processId && szModuleLocal.SequenceEqual(moduleName))
|
||||
{
|
||||
return entry;
|
||||
|
||||
@@ -108,6 +108,7 @@
|
||||
<None Remove="Resource\WelcomeView_Background.png" />
|
||||
<None Remove="stylecop.json" />
|
||||
<None Remove="View\Card\AchievementCard.xaml" />
|
||||
<None Remove="View\Card\DailyNoteCard.xaml" />
|
||||
<None Remove="View\Card\GachaStatisticsCard.xaml" />
|
||||
<None Remove="View\Card\LaunchGameCard.xaml" />
|
||||
<None Remove="View\Control\BaseValueSlider.xaml" />
|
||||
@@ -299,6 +300,12 @@
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Card\DailyNoteCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Page Update="View\Card\AchievementCard.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
</mxi:Interaction.Behaviors>
|
||||
<Grid>
|
||||
<FlipView
|
||||
x:Name="RootFlipView"
|
||||
Background="{x:Null}"
|
||||
ItemsSource="{Binding StatisticsList}"
|
||||
Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
@@ -64,8 +65,14 @@
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</FlipView.ItemTemplate>
|
||||
|
||||
</FlipView>
|
||||
<PipsPager
|
||||
Height="16"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Bottom"
|
||||
NumberOfPages="{Binding StatisticsList.Count}"
|
||||
SelectedPageIndex="{x:Bind Path=RootFlipView.SelectedIndex, Mode=TwoWay}"
|
||||
Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
<shvc:LoadingViewSlim IsLoading="{Binding IsInitialized, Converter={StaticResource BoolNegationConverter}}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
@@ -15,6 +15,7 @@ internal sealed partial class AchievementCard : Button
|
||||
/// </summary>
|
||||
public AchievementCard()
|
||||
{
|
||||
DataContext = Ioc.Default.GetRequiredService<ViewModel.Achievement.AchievementViewModelSlim>();
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
164
src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml
Normal file
164
src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml
Normal file
@@ -0,0 +1,164 @@
|
||||
<Button
|
||||
x:Class="Snap.Hutao.View.Card.DailyNoteCard"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
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:shcb="using:Snap.Hutao.Control.Behavior"
|
||||
xmlns:shvc="using:Snap.Hutao.View.Control"
|
||||
xmlns:shvd="using:Snap.Hutao.ViewModel.DailyNote"
|
||||
Padding="0"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Stretch"
|
||||
HorizontalContentAlignment="Stretch"
|
||||
d:DataContext="{d:DesignInstance shvd:DailyNoteViewModelSlim}"
|
||||
Command="{Binding NavigateCommand}"
|
||||
Style="{ThemeResource DefaultButtonStyle}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
<mxi:Interaction.Behaviors>
|
||||
<shcb:InvokeCommandOnLoadedBehavior Command="{Binding OpenUICommand}"/>
|
||||
</mxi:Interaction.Behaviors>
|
||||
<Grid>
|
||||
<FlipView
|
||||
x:Name="RootFlipView"
|
||||
Background="{x:Null}"
|
||||
ItemsSource="{Binding DailyNoteEntries}"
|
||||
Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
<FlipView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid
|
||||
Margin="12"
|
||||
ColumnSpacing="6"
|
||||
RowSpacing="6">
|
||||
<Grid.Resources>
|
||||
<x:Double x:Key="ProgressBarOpacity">0.2</x:Double>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid Grid.Column="0" RowSpacing="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="auto"/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<TextBlock HorizontalAlignment="Center" Text="{Binding Uid}"/>
|
||||
<Border Grid.Row="1" Style="{StaticResource BorderCardStyle}">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<Image Width="64" Source="ms-appx:///Resource/Icon/UI_ItemIcon_210_256.png"/>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding DailyNote.ResinFormatted}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<InfoBadge
|
||||
Grid.Row="1"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Margin="8"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Style="{ThemeResource AttentionDotInfoBadgeStyle}"
|
||||
Visibility="{Binding ResinNotifySuppressed, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Column="1" RowSpacing="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Border Style="{StaticResource BorderCardStyle}">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<Image Width="32" Source="ms-appx:///Resource/Icon/UI_ItemIcon_204.png"/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding DailyNote.HomeCoinFormatted}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<InfoBadge
|
||||
Width="8"
|
||||
Height="8"
|
||||
Margin="8"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Style="{ThemeResource AttentionDotInfoBadgeStyle}"
|
||||
Visibility="{Binding HomeCoinNotifySuppressed, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
<Border Grid.Row="1" Style="{StaticResource BorderCardStyle}">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<Image Width="32" Source="ms-appx:///Resource/Icon/UI_MarkQuest_Events_Proce.png"/>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding DailyNote.TaskFormatted}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<InfoBadge
|
||||
Grid.Row="1"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Margin="8"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Style="{ThemeResource AttentionDotInfoBadgeStyle}"
|
||||
Visibility="{Binding DailyTaskNotifySuppressed, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
<Grid Grid.Column="2" RowSpacing="6">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition/>
|
||||
<RowDefinition/>
|
||||
</Grid.RowDefinitions>
|
||||
<Border Style="{StaticResource BorderCardStyle}">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<Image Width="32" Source="ms-appx:///Resource/Icon/UI_MarkTower.png"/>
|
||||
<TextBlock
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding DailyNote.ResinDiscountFormatted}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<Border Grid.Row="1" Style="{StaticResource BorderCardStyle}">
|
||||
<StackPanel VerticalAlignment="Center">
|
||||
<Image Width="32" Source="ms-appx:///Resource/Icon/UI_ItemIcon_220021.png"/>
|
||||
<TextBlock
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
Style="{StaticResource CaptionTextBlockStyle}"
|
||||
Text="{Binding DailyNote.Transformer.RecoveryTime.TimeLeftFormatted}"/>
|
||||
</StackPanel>
|
||||
</Border>
|
||||
<InfoBadge
|
||||
Grid.Row="1"
|
||||
Width="8"
|
||||
Height="8"
|
||||
Margin="8"
|
||||
HorizontalAlignment="Right"
|
||||
VerticalAlignment="Top"
|
||||
Style="{ThemeResource AttentionDotInfoBadgeStyle}"
|
||||
Visibility="{Binding TransformerNotifySuppressed, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</FlipView.ItemTemplate>
|
||||
</FlipView>
|
||||
<PipsPager
|
||||
Height="16"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Bottom"
|
||||
NumberOfPages="{Binding DailyNoteEntries.Count}"
|
||||
SelectedPageIndex="{x:Bind Path=RootFlipView.SelectedIndex, Mode=TwoWay}"
|
||||
Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
<shvc:LoadingViewSlim IsLoading="{Binding IsInitialized, Converter={StaticResource BoolNegationConverter}}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
21
src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml.cs
Normal file
21
src/Snap.Hutao/Snap.Hutao/View/Card/DailyNoteCard.xaml.cs
Normal file
@@ -0,0 +1,21 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
|
||||
namespace Snap.Hutao.View.Card;
|
||||
|
||||
/// <summary>
|
||||
/// 实时便笺卡片
|
||||
/// </summary>
|
||||
internal sealed partial class DailyNoteCard : Button
|
||||
{
|
||||
/// <summary>
|
||||
/// 构造一个新的实时便笺卡片
|
||||
/// </summary>
|
||||
public DailyNoteCard()
|
||||
{
|
||||
DataContext = Ioc.Default.GetRequiredService<ViewModel.DailyNote.DailyNoteViewModelSlim>();
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
@@ -23,6 +23,7 @@
|
||||
</mxi:Interaction.Behaviors>
|
||||
<Grid>
|
||||
<FlipView
|
||||
x:Name="RootFlipView"
|
||||
Background="{x:Null}"
|
||||
ItemsSource="{Binding StatisticsList}"
|
||||
Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}">
|
||||
@@ -32,6 +33,7 @@
|
||||
<Grid.Resources>
|
||||
<SolidColorBrush x:Key="PurpleBrush" Color="#FFA156E0"/>
|
||||
<SolidColorBrush x:Key="OrangeBrush" Color="#FFBC6932"/>
|
||||
<x:Double x:Key="PullProgressOpacity">0.2</x:Double>
|
||||
</Grid.Resources>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
@@ -81,7 +83,7 @@
|
||||
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||
Foreground="{StaticResource OrangeBrush}"
|
||||
Maximum="{Binding GuaranteeOrangeThreshold}"
|
||||
Opacity="0.15"
|
||||
Opacity="{StaticResource PullProgressOpacity}"
|
||||
Style="{StaticResource DefaultProgressBarStyle}"
|
||||
Value="{Binding LastOrangePull}"/>
|
||||
<TextBlock
|
||||
@@ -114,7 +116,7 @@
|
||||
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||
Foreground="{StaticResource PurpleBrush}"
|
||||
Maximum="{Binding GuaranteePurpleThreshold}"
|
||||
Opacity="0.15"
|
||||
Opacity="{StaticResource PullProgressOpacity}"
|
||||
Style="{StaticResource DefaultProgressBarStyle}"
|
||||
Value="{Binding LastPurplePull}"/>
|
||||
<TextBlock
|
||||
@@ -161,7 +163,7 @@
|
||||
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||
Foreground="{StaticResource OrangeBrush}"
|
||||
Maximum="{Binding GuaranteeOrangeThreshold}"
|
||||
Opacity="0.15"
|
||||
Opacity="{StaticResource PullProgressOpacity}"
|
||||
Style="{StaticResource DefaultProgressBarStyle}"
|
||||
Value="{Binding LastOrangePull}"/>
|
||||
<TextBlock
|
||||
@@ -194,7 +196,7 @@
|
||||
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||
Foreground="{StaticResource PurpleBrush}"
|
||||
Maximum="{Binding GuaranteePurpleThreshold}"
|
||||
Opacity="0.15"
|
||||
Opacity="{StaticResource PullProgressOpacity}"
|
||||
Style="{StaticResource DefaultProgressBarStyle}"
|
||||
Value="{Binding LastPurplePull}"/>
|
||||
<TextBlock
|
||||
@@ -241,7 +243,7 @@
|
||||
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||
Foreground="{StaticResource OrangeBrush}"
|
||||
Maximum="{Binding GuaranteeOrangeThreshold}"
|
||||
Opacity="0.15"
|
||||
Opacity="{StaticResource PullProgressOpacity}"
|
||||
Style="{StaticResource DefaultProgressBarStyle}"
|
||||
Value="{Binding LastOrangePull}"/>
|
||||
<TextBlock
|
||||
@@ -274,7 +276,7 @@
|
||||
CornerRadius="{StaticResource CompatCornerRadius}"
|
||||
Foreground="{StaticResource PurpleBrush}"
|
||||
Maximum="{Binding GuaranteePurpleThreshold}"
|
||||
Opacity="0.15"
|
||||
Opacity="{StaticResource PullProgressOpacity}"
|
||||
Style="{StaticResource DefaultProgressBarStyle}"
|
||||
Value="{Binding LastPurplePull}"/>
|
||||
<TextBlock
|
||||
@@ -299,6 +301,13 @@
|
||||
</DataTemplate>
|
||||
</FlipView.ItemTemplate>
|
||||
</FlipView>
|
||||
<PipsPager
|
||||
Height="16"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Bottom"
|
||||
NumberOfPages="{Binding StatisticsList.Count}"
|
||||
SelectedPageIndex="{x:Bind Path=RootFlipView.SelectedIndex, Mode=TwoWay}"
|
||||
Visibility="{Binding IsInitialized, Converter={StaticResource BoolToVisibilityConverter}}"/>
|
||||
<shvc:LoadingViewSlim IsLoading="{Binding IsInitialized, Converter={StaticResource BoolNegationConverter}}"/>
|
||||
</Grid>
|
||||
</Button>
|
||||
|
||||
@@ -15,6 +15,7 @@ internal sealed partial class GachaStatisticsCard : Button
|
||||
/// </summary>
|
||||
public GachaStatisticsCard()
|
||||
{
|
||||
DataContext = Ioc.Default.GetRequiredService<ViewModel.GachaLog.GachaLogViewModelSlim>();
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ internal sealed partial class LaunchGameCard : Button
|
||||
/// </summary>
|
||||
public LaunchGameCard()
|
||||
{
|
||||
DataContext = Ioc.Default.GetRequiredService<ViewModel.Game.LaunchGameViewModelSlim>();
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,9 +14,20 @@
|
||||
Style="{StaticResource DefaultContentDialogStyle}"
|
||||
mc:Ignorable="d">
|
||||
<ScrollViewer>
|
||||
<StackPanel>
|
||||
<TextBlock Style="{StaticResource BaseTextBlockStyle}" Text="{Binding UserGameRole}"/>
|
||||
<clw:SettingsCard Padding="16,8" Header="{shcm:ResourceString Name=ViewDialogDailyNoteNotificationResinNotifyThreshold}">
|
||||
<StackPanel Spacing="{StaticResource SettingsCardSpacing}">
|
||||
<StackPanel.Resources>
|
||||
<x:Double x:Key="SettingsCardMinHeight">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapThreshold">0</x:Double>
|
||||
<x:Double x:Key="SettingsCardWrapNoIconThreshold">0</x:Double>
|
||||
</StackPanel.Resources>
|
||||
<TextBlock
|
||||
Margin="0,3,0,3"
|
||||
Style="{StaticResource SettingsSectionHeaderTextBlockStyle}"
|
||||
Text="{Binding UserGameRole}"/>
|
||||
<clw:SettingsCard
|
||||
Width="480"
|
||||
Padding="16,8"
|
||||
Header="{shcm:ResourceString Name=ViewDialogDailyNoteNotificationResinNotifyThreshold}">
|
||||
<Slider
|
||||
MinWidth="160"
|
||||
Margin="32,0,0,0"
|
||||
|
||||
@@ -169,13 +169,11 @@
|
||||
DesiredWidth="300"
|
||||
ItemContainerStyle="{StaticResource LargeGridViewItemStyle}"
|
||||
SelectionMode="None">
|
||||
<shvca:LaunchGameCard Height="{StaticResource HomeAdaptiveCardHeight}" DataContext="{Binding LaunchGameViewModelSlim}"/>
|
||||
<shvca:GachaStatisticsCard DataContext="{Binding GachaLogViewModelSlim}"/>
|
||||
<shvca:AchievementCard DataContext="{Binding AchievementViewModelSlim}"/>
|
||||
<shvca:LaunchGameCard Height="{StaticResource HomeAdaptiveCardHeight}"/>
|
||||
<shvca:GachaStatisticsCard/>
|
||||
<shvca:AchievementCard/>
|
||||
<shvca:DailyNoteCard/>
|
||||
|
||||
<Border Style="{StaticResource BorderCardStyle}">
|
||||
<TextBlock Text="实时便笺"/>
|
||||
</Border>
|
||||
<Border Style="{StaticResource BorderCardStyle}">
|
||||
<TextBlock Text="养成计划"/>
|
||||
</Border>
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
xmlns:shcb="using:Snap.Hutao.Control.Behavior"
|
||||
xmlns:shci="using:Snap.Hutao.Control.Image"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
xmlns:shv="using:Snap.Hutao.ViewModel"
|
||||
d:DataContext="{d:DesignInstance shv:DailyNoteViewModel}"
|
||||
xmlns:shvd="using:Snap.Hutao.ViewModel.DailyNote"
|
||||
d:DataContext="{d:DesignInstance shvd:DailyNoteViewModel}"
|
||||
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
|
||||
mc:Ignorable="d">
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Control;
|
||||
using Snap.Hutao.ViewModel;
|
||||
using Snap.Hutao.ViewModel.DailyNote;
|
||||
|
||||
namespace Snap.Hutao.View.Page;
|
||||
|
||||
@@ -20,4 +20,4 @@ internal sealed partial class DailyNotePage : ScopedPage
|
||||
InitializeWith<DailyNoteViewModel>();
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@
|
||||
xmlns:mxim="using:Microsoft.Xaml.Interactions.Media"
|
||||
xmlns:shc="using:Snap.Hutao.Control"
|
||||
xmlns:shcm="using:Snap.Hutao.Control.Markup"
|
||||
xmlns:shvm="using:Snap.Hutao.ViewModel"
|
||||
d:DataContext="{d:DesignInstance shvm:UserViewModel}"
|
||||
xmlns:shvu="using:Snap.Hutao.ViewModel.User"
|
||||
d:DataContext="{d:DesignInstance shvu:UserViewModel}"
|
||||
mc:Ignorable="d">
|
||||
<mxi:Interaction.Behaviors>
|
||||
<mxic:EventTriggerBehavior EventName="Loaded">
|
||||
@@ -121,6 +121,7 @@
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
<ColumnDefinition Width="auto"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<PersonPicture
|
||||
Height="32"
|
||||
@@ -132,10 +133,14 @@
|
||||
Margin="12,0,0,0"
|
||||
VerticalAlignment="Center"
|
||||
Text="{Binding UserInfo.Nickname}"/>
|
||||
|
||||
<TextBlock
|
||||
Grid.Column="2"
|
||||
VerticalAlignment="Center"
|
||||
Text="HoYoLAB"
|
||||
Visibility="{Binding IsOversea}"/>
|
||||
<StackPanel
|
||||
x:Name="ButtonPanel"
|
||||
Grid.Column="2"
|
||||
Grid.Column="3"
|
||||
Orientation="Horizontal"
|
||||
Visibility="Collapsed">
|
||||
<Button
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Snap.Hutao.ViewModel.Achievement;
|
||||
/// <summary>
|
||||
/// 简化的成就视图模型
|
||||
/// </summary>
|
||||
[Injection(InjectAs.Scoped)]
|
||||
[Injection(InjectAs.Transient)]
|
||||
internal sealed class AchievementViewModelSlim : Abstraction.ViewModelSlim<View.Page.AchievementPage>
|
||||
{
|
||||
private List<AchievementStatistics>? statisticsList;
|
||||
|
||||
@@ -24,10 +24,6 @@ internal sealed class AnnouncementViewModel : Abstraction.ViewModel
|
||||
public AnnouncementViewModel(IServiceProvider serviceProvider)
|
||||
{
|
||||
announcementService = serviceProvider.GetRequiredService<IAnnouncementService>();
|
||||
|
||||
LaunchGameViewModelSlim = serviceProvider.GetRequiredService<Game.LaunchGameViewModelSlim>();
|
||||
GachaLogViewModelSlim = serviceProvider.GetRequiredService<GachaLog.GachaLogViewModelSlim>();
|
||||
AchievementViewModelSlim = serviceProvider.GetRequiredService<Achievement.AchievementViewModelSlim>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -35,21 +31,6 @@ internal sealed class AnnouncementViewModel : Abstraction.ViewModel
|
||||
/// </summary>
|
||||
public AnnouncementWrapper? Announcement { get => announcement; set => SetProperty(ref announcement, value); }
|
||||
|
||||
/// <summary>
|
||||
/// 启动游戏视图模型
|
||||
/// </summary>
|
||||
public Game.LaunchGameViewModelSlim LaunchGameViewModelSlim { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 祈愿记录视图模型
|
||||
/// </summary>
|
||||
public GachaLog.GachaLogViewModelSlim GachaLogViewModelSlim { get; }
|
||||
|
||||
/// <summary>
|
||||
/// 成就统计视图模型
|
||||
/// </summary>
|
||||
public Achievement.AchievementViewModelSlim AchievementViewModelSlim { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OpenUIAsync()
|
||||
{
|
||||
|
||||
@@ -14,7 +14,7 @@ using Snap.Hutao.View.Dialog;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Snap.Hutao.ViewModel;
|
||||
namespace Snap.Hutao.ViewModel.DailyNote;
|
||||
|
||||
/// <summary>
|
||||
/// 实时便笺视图模型
|
||||
@@ -0,0 +1,64 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Snap.Hutao.Model.Entity;
|
||||
using Snap.Hutao.Service.Abstraction;
|
||||
using Snap.Hutao.Service.DailyNote;
|
||||
using Snap.Hutao.Service.User;
|
||||
using Snap.Hutao.ViewModel.User;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
namespace Snap.Hutao.ViewModel.DailyNote;
|
||||
|
||||
/// <summary>
|
||||
/// 简化的实时便笺视图模型
|
||||
/// </summary>
|
||||
[Injection(InjectAs.Transient)]
|
||||
internal sealed class DailyNoteViewModelSlim : Abstraction.ViewModelSlim<View.Page.DailyNotePage>
|
||||
{
|
||||
private List<DailyNoteEntry>? dailyNoteEntries;
|
||||
|
||||
/// <summary>
|
||||
/// 构造一个新的简化的实时便笺视图模型
|
||||
/// </summary>
|
||||
/// <param name="serviceProvider">服务提供器</param>
|
||||
public DailyNoteViewModelSlim(IServiceProvider serviceProvider)
|
||||
: base(serviceProvider)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 实时便笺集合
|
||||
/// </summary>
|
||||
public List<DailyNoteEntry>? DailyNoteEntries { get => dailyNoteEntries; set => SetProperty(ref dailyNoteEntries, value); }
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OpenUIAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
await ThreadHelper.SwitchToBackgroundAsync();
|
||||
_ = await ServiceProvider
|
||||
.GetRequiredService<IUserService>()
|
||||
.GetRoleCollectionAsync()
|
||||
.ConfigureAwait(false);
|
||||
ObservableCollection<DailyNoteEntry> entries = await ServiceProvider
|
||||
.GetRequiredService<IDailyNoteService>()
|
||||
.GetDailyNoteEntriesAsync()
|
||||
.ConfigureAwait(false);
|
||||
|
||||
// We have to create a copy here,
|
||||
// to prevent page add/remove failure.
|
||||
List<DailyNoteEntry> entryList = entries.ToList();
|
||||
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
DailyNoteEntries = entryList;
|
||||
IsInitialized = true;
|
||||
}
|
||||
catch (Core.ExceptionService.UserdataCorruptedException ex)
|
||||
{
|
||||
ServiceProvider.GetRequiredService<IInfoBarService>().Error(ex);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,7 @@ namespace Snap.Hutao.ViewModel.GachaLog;
|
||||
/// <summary>
|
||||
/// 简化的祈愿记录视图模型
|
||||
/// </summary>
|
||||
[Injection(InjectAs.Scoped)]
|
||||
[Injection(InjectAs.Transient)]
|
||||
internal sealed class GachaLogViewModelSlim : Abstraction.ViewModelSlim<View.Page.GachaLogPage>
|
||||
{
|
||||
private List<GachaStatisticsSlim>? statisticsList;
|
||||
@@ -30,14 +30,17 @@ internal sealed class GachaLogViewModelSlim : Abstraction.ViewModelSlim<View.Pag
|
||||
/// <inheritdoc/>
|
||||
protected override async Task OpenUIAsync()
|
||||
{
|
||||
IGachaLogService gachaLogService = ServiceProvider.GetRequiredService<IGachaLogService>();
|
||||
|
||||
if (await gachaLogService.InitializeAsync(default).ConfigureAwait(false))
|
||||
using (IServiceScope scope = ServiceProvider.CreateScope())
|
||||
{
|
||||
List<GachaStatisticsSlim> list = await gachaLogService.GetStatisticsSlimsAsync().ConfigureAwait(false);
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
StatisticsList = list;
|
||||
IsInitialized = true;
|
||||
IGachaLogService gachaLogService = scope.ServiceProvider.GetRequiredService<IGachaLogService>();
|
||||
|
||||
if (await gachaLogService.InitializeAsync(default).ConfigureAwait(false))
|
||||
{
|
||||
List<GachaStatisticsSlim> list = await gachaLogService.GetStatisticsSlimsAsync().ConfigureAwait(false);
|
||||
await ThreadHelper.SwitchToMainThreadAsync();
|
||||
StatisticsList = list;
|
||||
IsInitialized = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace Snap.Hutao.ViewModel.Game;
|
||||
/// <summary>
|
||||
/// 简化的启动游戏视图模型
|
||||
/// </summary>
|
||||
[Injection(InjectAs.Scoped)]
|
||||
[Injection(InjectAs.Transient)]
|
||||
internal sealed class LaunchGameViewModelSlim : Abstraction.ViewModelSlim<View.Page.LaunchGamePage>
|
||||
{
|
||||
private readonly IGameService gameService;
|
||||
|
||||
@@ -30,7 +30,7 @@ internal class AvatarView : INameIconSide
|
||||
/// </summary>
|
||||
/// <param name="avatarId">角色Id</param>
|
||||
/// <param name="idAvatarMap">Id角色映射</param>
|
||||
public AvatarView(AvatarId avatarId, Dictionary<AvatarId, Model.Metadata.Avatar.Avatar> idAvatarMap)
|
||||
public AvatarView(in AvatarId avatarId, Dictionary<AvatarId, Model.Metadata.Avatar.Avatar> idAvatarMap)
|
||||
: this(idAvatarMap[avatarId])
|
||||
{
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ internal sealed class RankAvatar : AvatarView
|
||||
/// <param name="value">值</param>
|
||||
/// <param name="avatarId">角色Id</param>
|
||||
/// <param name="idAvatarMap">Id角色映射</param>
|
||||
public RankAvatar(int value, AvatarId avatarId, Dictionary<AvatarId, Model.Metadata.Avatar.Avatar> idAvatarMap)
|
||||
public RankAvatar(int value, in AvatarId avatarId, Dictionary<AvatarId, Model.Metadata.Avatar.Avatar> idAvatarMap)
|
||||
: base(avatarId, idAvatarMap)
|
||||
{
|
||||
Value = value;
|
||||
|
||||
@@ -87,6 +87,11 @@ internal sealed class User : ObservableObject
|
||||
set => inner.SToken = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为国际服
|
||||
/// </summary>
|
||||
public bool IsOversea { get => Entity.IsOversea; }
|
||||
|
||||
/// <summary>
|
||||
/// 内部的用户实体
|
||||
/// </summary>
|
||||
|
||||
@@ -19,7 +19,7 @@ internal sealed class UserAndUid
|
||||
/// </summary>
|
||||
/// <param name="user">实体用户</param>
|
||||
/// <param name="role">角色</param>
|
||||
public UserAndUid(EntityUser user, PlayerUid role)
|
||||
public UserAndUid(EntityUser user, in PlayerUid role)
|
||||
{
|
||||
User = user;
|
||||
Uid = role;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Web.WebView2.Core;
|
||||
using Snap.Hutao.Web.Bridge.Model;
|
||||
|
||||
namespace Snap.Hutao.Web.Bridge;
|
||||
|
||||
@@ -51,7 +51,7 @@ internal struct GachaLogQueryOptions
|
||||
/// <param name="query">原始查询字符串</param>
|
||||
/// <param name="type">祈愿类型</param>
|
||||
/// <param name="endId">终止Id</param>
|
||||
public GachaLogQueryOptions(GachaLogQuery query, GachaConfigType type, long endId = 0L)
|
||||
public GachaLogQueryOptions(in GachaLogQuery query, GachaConfigType type, long endId = 0L)
|
||||
{
|
||||
IsOversea = query.IsOversea;
|
||||
innerQuery = QueryString.Parse(query.Query);
|
||||
|
||||
@@ -17,7 +17,7 @@ internal sealed class GenAuthKeyData
|
||||
/// <param name="authAppId">AppId</param>
|
||||
/// <param name="gameBiz">游戏代号</param>
|
||||
/// <param name="uid">uid</param>
|
||||
public GenAuthKeyData(string authAppId, string gameBiz, PlayerUid uid)
|
||||
public GenAuthKeyData(string authAppId, string gameBiz, in PlayerUid uid)
|
||||
{
|
||||
AuthAppId = authAppId;
|
||||
GameBiz = gameBiz;
|
||||
|
||||
@@ -15,7 +15,7 @@ internal sealed class CharacterData
|
||||
/// </summary>
|
||||
/// <param name="uid">uid</param>
|
||||
/// <param name="characterIds">角色id</param>
|
||||
public CharacterData(PlayerUid uid, IEnumerable<AvatarId> characterIds)
|
||||
public CharacterData(in PlayerUid uid, IEnumerable<AvatarId> characterIds)
|
||||
{
|
||||
CharacterIds = characterIds;
|
||||
Uid = uid.Value;
|
||||
|
||||
@@ -77,6 +77,30 @@ internal sealed class RecoveryTime
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化的剩余时间
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public string TimeLeftFormatted
|
||||
{
|
||||
get
|
||||
{
|
||||
if (Reached)
|
||||
{
|
||||
return SH.WebDailyNoteTransformerReady;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new StringBuilder()
|
||||
.AppendIf(Day > 0, string.Format(SH.WebDailyNoteTransformerDaysFormat, Day))
|
||||
.AppendIf(Hour > 0, string.Format(SH.WebDailyNoteTransformerHoursFormat, Hour))
|
||||
.AppendIf(Minute > 0, string.Format(SH.WebDailyNoteTransformerMinutesFormat, Minute))
|
||||
.AppendIf(Second > 0, string.Format(SH.WebDailyNoteTransformerSecondsFormat, Second))
|
||||
.ToString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取格式化的状态
|
||||
/// </summary>
|
||||
|
||||
@@ -44,7 +44,7 @@ internal static class StructMarshal
|
||||
public static unsafe Windows.UI.Color Color(uint value)
|
||||
{
|
||||
Unsafe.SkipInit(out Windows.UI.Color color);
|
||||
*(uint*)&color = BinaryPrimitives.ReverseEndianness(value); // Unsafe.WriteUnaligned(&color, reversed);
|
||||
*(uint*)&color = BinaryPrimitives.ReverseEndianness(value);
|
||||
return color;
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ internal static class StructMarshal
|
||||
{
|
||||
MODULEENTRY32 entry = MODULEENTRY32();
|
||||
|
||||
if (!UnsafeModule32First(snapshot, ref entry))
|
||||
if (!Module32First(snapshot, ref entry))
|
||||
{
|
||||
yield break;
|
||||
}
|
||||
@@ -99,7 +99,7 @@ internal static class StructMarshal
|
||||
{
|
||||
yield return entry;
|
||||
}
|
||||
while (UnsafeModule32Next(snapshot, ref entry));
|
||||
while (Module32Next(snapshot, ref entry));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -111,20 +111,4 @@ internal static class StructMarshal
|
||||
{
|
||||
return moduleEntry32.dwSize == 0;
|
||||
}
|
||||
|
||||
private static unsafe BOOL UnsafeModule32First(in HANDLE snapshot, ref MODULEENTRY32 lpme)
|
||||
{
|
||||
fixed (MODULEENTRY32* lpmeLocal = &lpme)
|
||||
{
|
||||
return Module32First(snapshot, lpmeLocal);
|
||||
}
|
||||
}
|
||||
|
||||
private static unsafe BOOL UnsafeModule32Next(in HANDLE snapshot, ref MODULEENTRY32 lpme)
|
||||
{
|
||||
fixed (MODULEENTRY32* lpmeLocal = &lpme)
|
||||
{
|
||||
return Module32Next(snapshot, lpmeLocal);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user