qstbak/Questionable/Questionable.Windows.ConfigComponents/NotificationConfigComponent.cs
2026-08-17 20:29:32 +10:00

182 lines
7.8 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Runtime.CompilerServices;
using Dalamud.Bindings.ImGui;
using Dalamud.Game.Text;
using Dalamud.Interface;
using Dalamud.Interface.Utility.Raii;
using Dalamud.Plugin;
using Dalamud.Utility;
using LLib.Notifications;
namespace Questionable.Windows.ConfigComponents;
internal sealed class NotificationConfigComponent : ConfigComponent
{
private static readonly string[] CuratedSoundNames;
private readonly OutOfGameNotifier _notifier;
private readonly string[] _soundFiles;
private readonly string[] _soundLabels;
private readonly XivChatType[] _xivChatTypes;
private readonly string[] _chatTypeNames;
private string _chatChannelSearchText = string.Empty;
private string _soundSearchText = string.Empty;
public NotificationConfigComponent(IDalamudPluginInterface pluginInterface, Configuration configuration, OutOfGameNotifier notifier)
: base(pluginInterface, configuration)
{
_notifier = notifier;
_soundFiles = CuratedSoundNames.Where((string n) => WindowsSounds.ResolvePath(n) != null).ToArray();
_soundLabels = _soundFiles.Select(SoundLabel).ToArray();
_xivChatTypes = (from x in Enum.GetValues<XivChatType>()
where x != XivChatType.StandardEmote
select x).ToArray();
_chatTypeNames = _xivChatTypes.Select((XivChatType t) => t.GetAttribute<XivChatTypeInfoAttribute>()?.FancyName ?? t.ToString()).ToArray();
}
private static string SoundLabel(string value)
{
if (!string.IsNullOrEmpty(value))
{
return Path.GetFileNameWithoutExtension(value);
}
return "(Default beep)";
}
public override void DrawTab()
{
UiThemeUtils.SectionHeader("Notifications");
(Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple = UiThemeUtils.BeginCard();
Vector2 item = tuple.ContentStartPos;
float item2 = tuple.AvailableWidth;
ImDrawListPtr item3 = tuple.DrawList;
bool value = base.Configuration.Notifications.Enabled;
if (UiThemeUtils.WrappedCheckbox("Enable notifications when manual interaction is required", ref value))
{
base.Configuration.Notifications.Enabled = value;
Save();
}
using (ImRaii.Disabled(!base.Configuration.Notifications.Enabled))
{
int currentItem = Array.IndexOf(_xivChatTypes, base.Configuration.Notifications.ChatType);
if (currentItem == -1)
{
currentItem = 0;
}
float width = MathF.Min(260f, ImGui.GetContentRegionAvail().X);
if (UiThemeUtils.SearchableCombo("Chat channel", ref currentItem, _chatTypeNames, ref _chatChannelSearchText, width))
{
base.Configuration.Notifications.ChatType = _xivChatTypes[currentItem];
Save();
}
}
UiThemeUtils.EndCard(item, item2, item3);
using (ImRaii.Disabled(!base.Configuration.Notifications.Enabled))
{
UiThemeUtils.SectionSpacing();
UiThemeUtils.SectionHeader("Out-of-game notifications");
(Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple2 = UiThemeUtils.BeginCard();
Vector2 item4 = tuple2.ContentStartPos;
float item5 = tuple2.AvailableWidth;
ImDrawListPtr item6 = tuple2.DrawList;
bool value2 = base.Configuration.Notifications.FlashTaskbar;
if (UiThemeUtils.WrappedCheckbox("Flash taskbar icon", ref value2))
{
base.Configuration.Notifications.FlashTaskbar = value2;
Save();
}
bool value3 = base.Configuration.Notifications.ShowTrayMessage;
if (UiThemeUtils.WrappedCheckbox("Show tray notification", ref value3))
{
base.Configuration.Notifications.ShowTrayMessage = value3;
Save();
}
bool value4 = base.Configuration.Notifications.PlaySound;
if (UiThemeUtils.WrappedCheckbox("Play a sound", ref value4))
{
base.Configuration.Notifications.PlaySound = value4;
Save();
}
using (ImRaii.Disabled(!base.Configuration.Notifications.PlaySound))
{
using (ImRaii.PushIndent())
{
int currentItem2 = Array.IndexOf(_soundFiles, base.Configuration.Notifications.SoundFile);
float width2 = MathF.Min(ImGui.GetContentRegionAvail().X * 0.6f, 260f);
string previewOverride = ((currentItem2 < 0) ? SoundLabel(base.Configuration.Notifications.SoundFile) : null);
if (UiThemeUtils.SearchableCombo("Sound", ref currentItem2, _soundLabels, ref _soundSearchText, width2, previewOverride))
{
base.Configuration.Notifications.SoundFile = _soundFiles[currentItem2];
Save();
}
ImGui.SameLine();
if (UiThemeUtils.IconTextButton(FontAwesomeIcon.Play, "Test"))
{
_notifier.PlayAlertSound(WindowsSounds.ResolvePath(base.Configuration.Notifications.SoundFile));
}
}
}
bool value5 = base.Configuration.Notifications.OnlyWhenUnfocused;
if (UiThemeUtils.WrappedCheckbox("Only when the game is not focused", ref value5, "Tray notification and sound are suppressed while the game window is focused. Taskbar flashing already stops when you focus the game."))
{
base.Configuration.Notifications.OnlyWhenUnfocused = value5;
Save();
}
UiThemeUtils.EndCard(item4, item5, item6);
UiThemeUtils.SectionSpacing();
UiThemeUtils.SectionHeader("Alert for");
ImGui.SameLine();
UiThemeUtils.InfoIcon("Which situations raise an out-of-game alert (taskbar / tray / sound): when a step needs you, when an auto-run duty / single-player duty finishes, and when a stop condition halts automation.");
(Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple3 = UiThemeUtils.BeginCard();
Vector2 item7 = tuple3.ContentStartPos;
float item8 = tuple3.AvailableWidth;
ImDrawListPtr item9 = tuple3.DrawList;
InlineArray4<UiThemeUtils.GridCheckbox> buffer = default(InlineArray4<UiThemeUtils.GridCheckbox>);
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray4<UiThemeUtils.GridCheckbox>, UiThemeUtils.GridCheckbox>(ref buffer, 0) = new UiThemeUtils.GridCheckbox("Duties", base.Configuration.Notifications.AlertForDuties);
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray4<UiThemeUtils.GridCheckbox>, UiThemeUtils.GridCheckbox>(ref buffer, 1) = new UiThemeUtils.GridCheckbox("Single-player duties", base.Configuration.Notifications.AlertForSinglePlayerDuties);
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray4<UiThemeUtils.GridCheckbox>, UiThemeUtils.GridCheckbox>(ref buffer, 2) = new UiThemeUtils.GridCheckbox("Snipe steps", base.Configuration.Notifications.AlertForSnipe);
global::_003CPrivateImplementationDetails_003E.InlineArrayElementRef<InlineArray4<UiThemeUtils.GridCheckbox>, UiThemeUtils.GridCheckbox>(ref buffer, 3) = new UiThemeUtils.GridCheckbox("Stop conditions", base.Configuration.Notifications.AlertForStopConditions);
ReadOnlySpan<UiThemeUtils.GridCheckbox> items = global::_003CPrivateImplementationDetails_003E.InlineArrayAsReadOnlySpan<InlineArray4<UiThemeUtils.GridCheckbox>, UiThemeUtils.GridCheckbox>(in buffer, 4);
switch (UiThemeUtils.CheckboxGrid("alertfor", items))
{
case 0:
base.Configuration.Notifications.AlertForDuties = !base.Configuration.Notifications.AlertForDuties;
Save();
break;
case 1:
base.Configuration.Notifications.AlertForSinglePlayerDuties = !base.Configuration.Notifications.AlertForSinglePlayerDuties;
Save();
break;
case 2:
base.Configuration.Notifications.AlertForSnipe = !base.Configuration.Notifications.AlertForSnipe;
Save();
break;
case 3:
base.Configuration.Notifications.AlertForStopConditions = !base.Configuration.Notifications.AlertForStopConditions;
Save();
break;
}
UiThemeUtils.EndCard(item7, item8, item9);
}
}
static NotificationConfigComponent()
{
List<string> list = new List<string>();
list.AddRange(from i in Enumerable.Range(1, 10)
select $"Alarm{i:D2}.wav");
list.AddRange(from i in Enumerable.Range(1, 10)
select $"Ring{i:D2}.wav");
CuratedSoundNames = list.ToArray();
}
}