diff --git a/HellionChat/Configuration.cs b/HellionChat/Configuration.cs index ae2c356..9d2e649 100755 --- a/HellionChat/Configuration.cs +++ b/HellionChat/Configuration.cs @@ -187,6 +187,7 @@ public class Configuration : IPluginConfiguration public bool CollapseKeepUniqueLinks; public bool SymbolPickerEnabled = true; public bool PlaySounds = true; + // UI-2: toast when a tell the user sent could not be delivered. public bool NotifyFailedTell = true; public bool KeepInputFocus = true; diff --git a/HellionChat/Infrastructure/Hosting/InitHostedServices.cs b/HellionChat/Infrastructure/Hosting/InitHostedServices.cs index 6dfbe52..9ffb54f 100644 --- a/HellionChat/Infrastructure/Hosting/InitHostedServices.cs +++ b/HellionChat/Infrastructure/Hosting/InitHostedServices.cs @@ -89,8 +89,8 @@ internal sealed class AutoTellTabsServiceInitHostedService(AutoTellTabsService s // Eager-resolve trigger: resolving FailedTellNotifier in this adapter's ctor // enables its game hook during host startup. StartAsync itself is a no-op. -internal sealed class FailedTellNotifierInitHostedService( - FailedTellNotifier notifier) : IHostedService +internal sealed class FailedTellNotifierInitHostedService(FailedTellNotifier notifier) + : IHostedService { // No-op adapter: the ctor dependency above is the actual eager-resolve // trigger. Field kept to match the IpcManager/TypingIpc/ExtraChat no-op diff --git a/HellionChat/Integrations/FailedTellNotifier.cs b/HellionChat/Integrations/FailedTellNotifier.cs index 977137f..9817788 100644 --- a/HellionChat/Integrations/FailedTellNotifier.cs +++ b/HellionChat/Integrations/FailedTellNotifier.cs @@ -27,21 +27,29 @@ internal sealed class FailedTellNotifier : IDisposable // Creating/enabling a hook is safe off the framework thread (the // ctor runs during host startup on the framework thread, // eager-resolved via FailedTellNotifierInitHostedService). - _hook = Plugin.GameInteropProvider - .HookFromAddress( + _hook = + Plugin.GameInteropProvider.HookFromAddress( RaptureLogModule.MemberFunctionPointers.ShowLogMessageString, - ShowLogMessageStringDetour); + ShowLogMessageStringDetour + ); _hook.Enable(); } private unsafe void ShowLogMessageStringDetour( - RaptureLogModule* module, uint logMessageId, Utf8String* value) + RaptureLogModule* module, + uint logMessageId, + Utf8String* value + ) { try { - if (FailedTellMatcher.ShouldNotify( - logMessageId, Plugin.Config.NotifyFailedTell, - FailedTellMatcher.FailedTellLogMessageIds)) + if ( + FailedTellMatcher.ShouldNotify( + logMessageId, + Plugin.Config.NotifyFailedTell, + FailedTellMatcher.FailedTellLogMessageIds + ) + ) { var recipient = value is null ? string.Empty : value->ToString(); var content = string.IsNullOrEmpty(recipient) diff --git a/HellionChat/MessageManager.cs b/HellionChat/MessageManager.cs index 78620ab..cbdf3a5 100644 --- a/HellionChat/MessageManager.cs +++ b/HellionChat/MessageManager.cs @@ -347,11 +347,14 @@ internal class MessageManager : IAsyncDisposable // inactive tab that wants it, keeping a message matching several // background tabs from stacking sounds. // TEST-MIRROR: ../_Helpers/TabSoundDecision.cs - if (notificationSound is null + if ( + notificationSound is null && TabSoundDecision.ShouldPlay( Plugin.CurrentTab == tab, tab.EnableNotificationSound, - Plugin.Config.PlaySounds)) + Plugin.Config.PlaySounds + ) + ) { notificationSound = tab.NotificationSoundId; } @@ -363,8 +366,13 @@ internal class MessageManager : IAsyncDisposable // ProcessMessage runs on the PendingMessageThread worker; the native // UIGlobals.PlaySoundEffect must be marshalled onto the framework // thread (reference_dalamud_framework_thread). - Plugin.Framework.RunOnFrameworkThread( - () => { unsafe { UIGlobals.PlaySoundEffect(soundId); } }); + Plugin.Framework.RunOnFrameworkThread(() => + { + unsafe + { + UIGlobals.PlaySoundEffect(soundId); + } + }); } MessageProcessed?.Invoke(message); diff --git a/HellionChat/PluginHostFactory.cs b/HellionChat/PluginHostFactory.cs index c3656c6..1347b75 100644 --- a/HellionChat/PluginHostFactory.cs +++ b/HellionChat/PluginHostFactory.cs @@ -108,7 +108,8 @@ internal static class PluginHostFactory sp.GetRequiredService() )); services.AddSingleton(sp => new Integrations.FailedTellNotifier( - sp.GetRequiredService>())); + sp.GetRequiredService>() + )); services.AddSingleton(sp => new MessageManager( sp.GetRequiredService(), @@ -174,8 +175,11 @@ internal static class PluginHostFactory services.AddHostedService(sp => new AutoTellTabsServiceInitHostedService( sp.GetRequiredService() )); - services.AddHostedService(sp => new Infrastructure.Hosting.FailedTellNotifierInitHostedService( - sp.GetRequiredService())); + services.AddHostedService( + sp => new Infrastructure.Hosting.FailedTellNotifierInitHostedService( + sp.GetRequiredService() + ) + ); } } diff --git a/HellionChat/Ui/SettingsTabs/Tabs.cs b/HellionChat/Ui/SettingsTabs/Tabs.cs index 7f51c35..45e1f64 100755 --- a/HellionChat/Ui/SettingsTabs/Tabs.cs +++ b/HellionChat/Ui/SettingsTabs/Tabs.cs @@ -173,15 +173,19 @@ internal sealed class Tabs : ISettingsTab if (tab.EnableNotificationSound) { using var indent = ImRaii.PushIndent(10.0f); - var soundPreview = $"{HellionStrings.Tabs_NotificationSound_Option} {tab.NotificationSoundId}"; + var soundPreview = + $"{HellionStrings.Tabs_NotificationSound_Option} {tab.NotificationSoundId}"; using var combo = ImRaii.Combo($"##notif-sound-{i}", soundPreview); if (combo.Success) { for (uint s = 1; s <= 16; s++) { - if (ImGui.Selectable( + if ( + ImGui.Selectable( $"{HellionStrings.Tabs_NotificationSound_Option} {s}", - tab.NotificationSoundId == s)) + tab.NotificationSoundId == s + ) + ) tab.NotificationSoundId = s; } } diff --git a/HellionChat/_Helpers/FailedTellMatcher.cs b/HellionChat/_Helpers/FailedTellMatcher.cs index 5e628d8..66083bf 100644 --- a/HellionChat/_Helpers/FailedTellMatcher.cs +++ b/HellionChat/_Helpers/FailedTellMatcher.cs @@ -19,6 +19,9 @@ public static class FailedTellMatcher 3832u, }; - public static bool ShouldNotify(uint logMessageId, bool notifyEnabled, IReadOnlySet failedTellIds) - => notifyEnabled && failedTellIds.Contains(logMessageId); + public static bool ShouldNotify( + uint logMessageId, + bool notifyEnabled, + IReadOnlySet failedTellIds + ) => notifyEnabled && failedTellIds.Contains(logMessageId); } diff --git a/HellionChat/_Helpers/TabSoundDecision.cs b/HellionChat/_Helpers/TabSoundDecision.cs index ac46cb6..5d88f3e 100644 --- a/HellionChat/_Helpers/TabSoundDecision.cs +++ b/HellionChat/_Helpers/TabSoundDecision.cs @@ -9,6 +9,9 @@ public static class TabSoundDecision // True only when the message landed in a tab the user is not looking at, // that tab has its own sound switched on, and the global sound master is // not muted. - public static bool ShouldPlay(bool isActiveTab, bool tabSoundEnabled, bool globalSoundsEnabled) - => !isActiveTab && tabSoundEnabled && globalSoundsEnabled; + public static bool ShouldPlay( + bool isActiveTab, + bool tabSoundEnabled, + bool globalSoundsEnabled + ) => !isActiveTab && tabSoundEnabled && globalSoundsEnabled; }