mirror of
https://jihulab.com/DGP-Studio/Snap.Hutao.git
synced 2025-11-19 21:02:53 +08:00
Compare commits
49 Commits
1.7.13
...
winappsdk-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
957b63ac32 | ||
|
|
3af8f356cc | ||
|
|
05608cee30 | ||
|
|
f8d7f72679 | ||
|
|
1564f2a97e | ||
|
|
1f5619baa0 | ||
|
|
7406f5822f | ||
|
|
38cffe4dc3 | ||
|
|
ba4a7c1447 | ||
|
|
a03edeef3f | ||
|
|
981d2d74ee | ||
|
|
27aa404e52 | ||
|
|
78a56ec912 | ||
|
|
8f25769527 | ||
|
|
85e31d122d | ||
|
|
65191d91bd | ||
|
|
c885a6f220 | ||
|
|
3d0ea2dd4e | ||
|
|
9d2e5896e6 | ||
|
|
d376d9b3f6 | ||
|
|
449ae4499b | ||
|
|
2d59fcfb21 | ||
|
|
5600d1fe9e | ||
|
|
02ee082bd0 | ||
|
|
f4a1914735 | ||
|
|
df8f317020 | ||
|
|
d09e4c3035 | ||
|
|
e0d43b0dfb | ||
|
|
805d8ed87d | ||
|
|
bbbe2eeb79 | ||
|
|
7b8cc1b4c3 | ||
|
|
7c357d3a1c | ||
|
|
7fc4e1a0a3 | ||
|
|
f29fa1e8a0 | ||
|
|
9a54463d7d | ||
|
|
ababf74473 | ||
|
|
ba7ba3af44 | ||
|
|
91f6665849 | ||
|
|
154f6a1bb6 | ||
|
|
45cca2185e | ||
|
|
95631df4fa | ||
|
|
d8186082bf | ||
|
|
18d6ee214c | ||
|
|
bfc967d244 | ||
|
|
0c8f757d69 | ||
|
|
dda4e60813 | ||
|
|
cc01269d9a | ||
|
|
b5706c316f | ||
|
|
bc0e2bd717 |
@@ -52,8 +52,8 @@ public sealed partial class App : Application
|
||||
if (firstInstance.IsCurrent)
|
||||
{
|
||||
// manually invoke
|
||||
activation.NonRedirectToActivate(firstInstance, activatedEventArgs);
|
||||
activation.InitializeWith(firstInstance);
|
||||
activation.NonRedirectToActivate(firstInstance, activatedEventArgs);
|
||||
|
||||
LogDiagnosticInformation();
|
||||
serviceProvider.GetRequiredService<IJumpListInterop>().ConfigureAsync().SafeForget();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.WinUI.Notifications;
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Microsoft.Windows.AppNotifications;
|
||||
using Snap.Hutao.Core.Setting;
|
||||
using Snap.Hutao.Service.DailyNote;
|
||||
using Snap.Hutao.Service.Hutao;
|
||||
@@ -23,24 +23,9 @@ namespace Snap.Hutao.Core.LifeCycle;
|
||||
[SuppressMessage("", "CA1001")]
|
||||
internal sealed partial class Activation : IActivation
|
||||
{
|
||||
/// <summary>
|
||||
/// 操作
|
||||
/// </summary>
|
||||
public const string Action = nameof(Action);
|
||||
|
||||
/// <summary>
|
||||
/// Uid
|
||||
/// </summary>
|
||||
public const string Uid = nameof(Uid);
|
||||
|
||||
/// <summary>
|
||||
/// 启动游戏启动参数
|
||||
/// </summary>
|
||||
public const string LaunchGame = nameof(LaunchGame);
|
||||
|
||||
/// <summary>
|
||||
/// 从剪贴板导入成就
|
||||
/// </summary>
|
||||
public const string ImportUIAFFromClipboard = nameof(ImportUIAFFromClipboard);
|
||||
|
||||
private const string CategoryAchievement = "ACHIEVEMENT";
|
||||
@@ -52,50 +37,50 @@ internal sealed partial class Activation : IActivation
|
||||
private readonly ICurrentWindowReference currentWindowReference;
|
||||
private readonly ITaskContext taskContext;
|
||||
private readonly SemaphoreSlim activateSemaphore = new(1);
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Activate(object? sender, AppActivationArguments args)
|
||||
{
|
||||
_ = sender;
|
||||
if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated())
|
||||
{
|
||||
HandleActivationAsync(args, true).SafeForget();
|
||||
}
|
||||
}
|
||||
private readonly AppNotificationManager appNotificationManager = AppNotificationManager.Default;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void NonRedirectToActivate(object? sender, AppActivationArguments args)
|
||||
{
|
||||
_ = sender;
|
||||
if (!ToastNotificationManagerCompat.WasCurrentProcessToastActivated())
|
||||
{
|
||||
HandleActivationAsync(args, false).SafeForget();
|
||||
}
|
||||
HandleActivationAsync(args, false).SafeForget();
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void InitializeWith(AppInstance appInstance)
|
||||
{
|
||||
appInstance.Activated += Activate;
|
||||
ToastNotificationManagerCompat.OnActivated += NotificationActivate;
|
||||
appInstance.Activated += OnAppInstanceActivate;
|
||||
appNotificationManager.NotificationInvoked += OnAppNotificationManagerNotificationInvoked;
|
||||
appNotificationManager.Register();
|
||||
}
|
||||
|
||||
private void NotificationActivate(ToastNotificationActivatedEventArgsCompat args)
|
||||
private void OnAppInstanceActivate(object? sender, AppActivationArguments args)
|
||||
{
|
||||
ToastArguments toastArgs = ToastArguments.Parse(args.Argument);
|
||||
HandleActivationAsync(args, true).SafeForget();
|
||||
}
|
||||
|
||||
if (toastArgs.TryGetValue(Action, out string? action))
|
||||
private void OnAppNotificationManagerNotificationInvoked(AppNotificationManager manager, AppNotificationActivatedEventArgs args)
|
||||
{
|
||||
IDictionary<string, string> arguments = args.Arguments;
|
||||
HandleAppNotificationActivationAsync(arguments).SafeForget();
|
||||
}
|
||||
|
||||
private async ValueTask HandleAppNotificationActivationAsync(IDictionary<string, string> arguments)
|
||||
{
|
||||
if (arguments.TryGetValue(Action, out string? action))
|
||||
{
|
||||
if (action == LaunchGame)
|
||||
{
|
||||
_ = toastArgs.TryGetValue(Uid, out string? uid);
|
||||
HandleLaunchGameActionAsync(uid).SafeForget();
|
||||
if (arguments.TryGetValue(Uid, out string? uid))
|
||||
{
|
||||
await HandleLaunchGameActionAsync(uid).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async ValueTask HandleActivationAsync(AppActivationArguments args, bool isRedirected)
|
||||
{
|
||||
// Refuse other activations
|
||||
if (activateSemaphore.CurrentCount > 0)
|
||||
{
|
||||
using (await activateSemaphore.EnterAsync().ConfigureAwait(false))
|
||||
@@ -107,32 +92,42 @@ internal sealed partial class Activation : IActivation
|
||||
|
||||
private async ValueTask HandleActivationCoreAsync(AppActivationArguments args, bool isRedirected)
|
||||
{
|
||||
if (args.Kind == ExtendedActivationKind.Protocol)
|
||||
switch (args.Kind)
|
||||
{
|
||||
if (args.TryGetProtocolActivatedUri(out Uri? uri))
|
||||
{
|
||||
await HandleUrlActivationAsync(uri, isRedirected).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
else if (args.Kind == ExtendedActivationKind.Launch)
|
||||
{
|
||||
if (args.TryGetLaunchActivatedArgument(out string? arguments))
|
||||
{
|
||||
switch (arguments)
|
||||
case ExtendedActivationKind.Launch:
|
||||
if (args.TryGetLaunchActivatedArgument(out string? command))
|
||||
{
|
||||
case LaunchGame:
|
||||
{
|
||||
await HandleLaunchGameActionAsync().ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
switch (command)
|
||||
{
|
||||
case LaunchGame:
|
||||
{
|
||||
await HandleLaunchGameActionAsync().ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
await HandleNormalLaunchActionAsync().ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
await HandleNormalLaunchActionAsync().ConfigureAwait(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
case ExtendedActivationKind.AppNotification:
|
||||
if (args.TryGetAppNotificationActivatedArgument(out IDictionary<string, string>? arguments))
|
||||
{
|
||||
await HandleAppNotificationActivationAsync(arguments).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
break;
|
||||
case ExtendedActivationKind.Protocol:
|
||||
if (args.TryGetProtocolActivatedUri(out Uri? uri))
|
||||
{
|
||||
await HandleUrlActivationAsync(uri, isRedirected).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -212,8 +207,6 @@ internal sealed partial class Activation : IActivation
|
||||
|
||||
private async ValueTask HandleAchievementActionAsync(string action, string parameter, bool isRedirected)
|
||||
{
|
||||
_ = parameter;
|
||||
_ = isRedirected;
|
||||
switch (action)
|
||||
{
|
||||
case UrlActionImport:
|
||||
@@ -232,7 +225,6 @@ internal sealed partial class Activation : IActivation
|
||||
|
||||
private async ValueTask HandleDailyNoteActionAsync(string action, string parameter, bool isRedirected)
|
||||
{
|
||||
_ = parameter;
|
||||
switch (action)
|
||||
{
|
||||
case UrlActionRefresh:
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using Microsoft.Windows.AppLifecycle;
|
||||
using Microsoft.Windows.AppNotifications;
|
||||
using Windows.ApplicationModel.Activation;
|
||||
|
||||
namespace Snap.Hutao.Core.LifeCycle;
|
||||
@@ -47,4 +48,16 @@ internal static class AppActivationArgumentsExtensions
|
||||
arguments = launchArgs.Arguments.Trim();
|
||||
return true;
|
||||
}
|
||||
|
||||
public static bool TryGetAppNotificationActivatedArgument(this AppActivationArguments activatedEventArgs, [NotNullWhen(true)] out IDictionary<string, string>? arguments)
|
||||
{
|
||||
arguments = null;
|
||||
if (activatedEventArgs.Data is not AppNotificationActivatedEventArgs launchArgs)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
arguments = launchArgs.Arguments;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -10,14 +10,6 @@ namespace Snap.Hutao.Core.LifeCycle;
|
||||
/// </summary>
|
||||
internal interface IActivation
|
||||
{
|
||||
/// <summary>
|
||||
/// 响应激活事件
|
||||
/// 激活事件一般不会在UI线程上触发
|
||||
/// </summary>
|
||||
/// <param name="sender">发送方</param>
|
||||
/// <param name="args">激活参数</param>
|
||||
void Activate(object? sender, AppActivationArguments args);
|
||||
|
||||
/// <summary>
|
||||
/// 使用当前 App 实例初始化激活
|
||||
/// </summary>
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
</desktop:Extension>
|
||||
<com:Extension Category="windows.comServer">
|
||||
<com:ComServer>
|
||||
<com:ExeServer Executable="Snap.Hutao.exe" Arguments="-ToastActivated" DisplayName="Snap Hutao Toast Activator">
|
||||
<com:ExeServer Executable="Snap.Hutao.exe" Arguments="----AppNotificationActivated:" DisplayName="Snap Hutao Toast Activator">
|
||||
<com:Class Id="5760ec4d-f7e8-4666-a965-9886d7dffe7d" DisplayName="Snap Hutao Toast Activator"/>
|
||||
</com:ExeServer>
|
||||
</com:ComServer>
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
// Copyright (c) DGP Studio. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
using CommunityToolkit.WinUI.Notifications;
|
||||
using Microsoft.Windows.AppNotifications;
|
||||
using Microsoft.Windows.AppNotifications.Builder;
|
||||
using Snap.Hutao.Core;
|
||||
using Snap.Hutao.Core.LifeCycle;
|
||||
using Snap.Hutao.Model.Entity;
|
||||
@@ -63,18 +64,16 @@ internal sealed partial class DailyNoteNotificationOperation
|
||||
}
|
||||
}
|
||||
|
||||
ToastContentBuilder builder = new ToastContentBuilder()
|
||||
.AddHeader(ToastHeaderIdArgument, SH.ServiceDailyNoteNotifierTitle, ToastHeaderIdArgument)
|
||||
.AddAttributionText(attribution)
|
||||
.AddButton(new ToastButton()
|
||||
.SetContent(SH.ServiceDailyNoteNotifierActionLaunchGameButton)
|
||||
AppNotificationBuilder builder = new AppNotificationBuilder()
|
||||
.AddText(SH.ServiceDailyNoteNotifierTitle, new AppNotificationTextProperties().SetMaxLines(1))
|
||||
.SetAttributionText(attribution)
|
||||
.AddButton(new AppNotificationButton(SH.ServiceDailyNoteNotifierActionLaunchGameButton)
|
||||
.AddArgument(Activation.Action, Activation.LaunchGame)
|
||||
.AddArgument(Activation.Uid, entry.Uid))
|
||||
.AddButton(new ToastButtonDismiss(SH.ServiceDailyNoteNotifierActionLaunchGameDismiss));
|
||||
.AddArgument(Activation.Uid, entry.Uid));
|
||||
|
||||
if (options.IsReminderNotification)
|
||||
{
|
||||
builder.SetToastScenario(ToastScenario.Reminder);
|
||||
builder.SetScenario(AppNotificationScenario.Reminder);
|
||||
}
|
||||
|
||||
if (notifyInfos.Count > 2)
|
||||
@@ -101,7 +100,7 @@ internal sealed partial class DailyNoteNotificationOperation
|
||||
group.Children.Add(subgroup);
|
||||
}
|
||||
|
||||
builder.AddVisualChild(group);
|
||||
builder.SetGroup(group);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -121,14 +120,14 @@ internal sealed partial class DailyNoteNotificationOperation
|
||||
// Image limitation.
|
||||
// https://learn.microsoft.com/en-us/windows/apps/design/shell/tiles-and-notifications/send-local-toast?tabs=uwp#adding-images
|
||||
// NotifySuppressed judge
|
||||
ChcekResinNotifySuppressed(entry, notifyInfos);
|
||||
CheckResinNotifySuppressed(entry, notifyInfos);
|
||||
CheckHomeCoinNotifySuppressed(entry, notifyInfos);
|
||||
CheckDailyTaskNotifySuppressed(entry, notifyInfos);
|
||||
CheckTransformerNotifySuppressed(entry, notifyInfos);
|
||||
CheckExpeditionNotifySuppressed(entry, notifyInfos);
|
||||
}
|
||||
|
||||
private static void ChcekResinNotifySuppressed(DailyNoteEntry entry, List<DailyNoteNotifyInfo> notifyInfos)
|
||||
private static void CheckResinNotifySuppressed(DailyNoteEntry entry, List<DailyNoteNotifyInfo> notifyInfos)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(entry.DailyNote);
|
||||
if (entry.DailyNote.CurrentResin >= entry.ResinNotifyThreshold)
|
||||
|
||||
@@ -267,9 +267,8 @@
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.Segmented" Version="8.0.230907" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Controls.SettingsControls" Version="8.0.230907" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Media" Version="8.0.230907" />
|
||||
<PackageReference Include="CommunityToolkit.WinUI.Notifications" Version="7.1.2" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.13" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.13">
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="7.0.12" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="7.0.12">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
Reference in New Issue
Block a user