more to notification system with new settings tab

This commit is contained in:
choco
2025-10-08 23:20:58 +02:00
parent 17f4ddad89
commit 27e7fb7ed9
8 changed files with 963 additions and 150 deletions

View File

@@ -1,4 +1,4 @@
using Dalamud.Bindings.ImGui;
using Dalamud.Bindings.ImGui;
using Dalamud.Game.Text;
using Dalamud.Interface;
using Dalamud.Interface.Colors;
@@ -61,6 +61,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
private readonly IProgress<(int, int, FileCacheEntity)> _validationProgress;
private readonly NameplateService _nameplateService;
private readonly NameplateHandler _nameplateHandler;
private readonly LightlessNotificationService _lightlessNotificationService;
private (int, int, FileCacheEntity) _currentProgress;
private bool _deleteAccountPopupModalShown = false;
private bool _deleteFilesPopupModalShown = false;
@@ -105,7 +106,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
IpcManager ipcManager, CacheMonitor cacheMonitor,
DalamudUtilService dalamudUtilService, HttpClient httpClient,
NameplateService nameplateService,
NameplateHandler nameplateHandler) : base(logger, mediator, "Lightless Sync Settings", performanceCollector)
NameplateHandler nameplateHandler,
LightlessNotificationService lightlessNotificationService) : base(logger, mediator, "Lightless Sync Settings", performanceCollector)
{
_configService = configService;
_pairManager = pairManager;
@@ -125,6 +127,7 @@ public class SettingsUi : WindowMediatorSubscriberBase
_uiShared = uiShared;
_nameplateService = nameplateService;
_nameplateHandler = nameplateHandler;
_lightlessNotificationService = lightlessNotificationService;
AllowClickthrough = false;
AllowPinning = true;
_validationProgress = new Progress<(int, int, FileCacheEntity)>(v => _currentProgress = v);
@@ -351,13 +354,8 @@ public class SettingsUi : WindowMediatorSubscriberBase
_uiShared.UnderlinedBigText("Transfer UI", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
bool useNotificationsForDownloads = _configService.Current.UseNotificationsForDownloads;
if (ImGui.Checkbox("Use notifications for download progress", ref useNotificationsForDownloads))
{
_configService.Current.UseNotificationsForDownloads = useNotificationsForDownloads;
_configService.Save();
}
_uiShared.DrawHelpText("Show download progress as clean notifications instead of overlay text. Notifications update in real-time.");
_uiShared.DrawHelpText("Download progress notification settings have been moved to the 'Enhanced Notifications' tab for better organization.");
ImGuiHelpers.ScaledDummy(5);
bool showTransferWindow = _configService.Current.ShowTransferWindow;
if (ImGui.Checkbox("Show separate transfer window", ref showTransferWindow))
@@ -1645,48 +1643,10 @@ public class SettingsUi : WindowMediatorSubscriberBase
ImGui.Dummy(new Vector2(10));
_uiShared.BigText("Notifications");
var disableOptionalPluginWarnings = _configService.Current.DisableOptionalPluginWarnings;
var onlineNotifs = _configService.Current.ShowOnlineNotifications;
var onlineNotifsPairsOnly = _configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs;
var onlineNotifsNamedOnly = _configService.Current.ShowOnlineNotificationsOnlyForNamedPairs;
if (_uiShared.MediumTreeNode("Display", UIColors.Get("LightlessPurple")))
{
_uiShared.DrawCombo("Info Notification Display##settingsUi", (NotificationLocation[])Enum.GetValues(typeof(NotificationLocation)), (i) => i.ToString(),
(i) =>
{
_configService.Current.InfoNotification = i;
_configService.Save();
}, _configService.Current.InfoNotification);
_uiShared.DrawHelpText("The location where \"Info\" notifications will display."
+ Environment.NewLine + "'Nowhere' will not show any Info notifications"
+ Environment.NewLine + "'Chat' will print Info notifications in chat"
+ Environment.NewLine + "'Toast' will show Warning toast notifications in the bottom right corner"
+ Environment.NewLine + "'Both' will show chat as well as the toast notification");
_uiShared.DrawCombo("Warning Notification Display##settingsUi", (NotificationLocation[])Enum.GetValues(typeof(NotificationLocation)), (i) => i.ToString(),
(i) =>
{
_configService.Current.WarningNotification = i;
_configService.Save();
}, _configService.Current.WarningNotification);
_uiShared.DrawHelpText("The location where \"Warning\" notifications will display."
+ Environment.NewLine + "'Nowhere' will not show any Warning notifications"
+ Environment.NewLine + "'Chat' will print Warning notifications in chat"
+ Environment.NewLine + "'Toast' will show Warning toast notifications in the bottom right corner"
+ Environment.NewLine + "'Both' will show chat as well as the toast notification");
_uiShared.DrawCombo("Error Notification Display##settingsUi", (NotificationLocation[])Enum.GetValues(typeof(NotificationLocation)), (i) => i.ToString(),
(i) =>
{
_configService.Current.ErrorNotification = i;
_configService.Save();
}, _configService.Current.ErrorNotification);
_uiShared.DrawHelpText("The location where \"Error\" notifications will display."
+ Environment.NewLine + "'Nowhere' will not show any Error notifications"
+ Environment.NewLine + "'Chat' will print Error notifications in chat"
+ Environment.NewLine + "'Toast' will show Error toast notifications in the bottom right corner"
+ Environment.NewLine + "'Both' will show chat as well as the toast notification");
_uiShared.DrawHelpText("Notification settings have been moved to the 'Enhanced Notifications' tab for better organization. You can configure where all notifications appear from there.");
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
ImGui.TreePop();
@@ -1694,38 +1654,6 @@ public class SettingsUi : WindowMediatorSubscriberBase
ImGui.Separator();
if (_uiShared.MediumTreeNode("Toggles", UIColors.Get("LightlessPurple")))
{
if (ImGui.Checkbox("Disable optional plugin warnings", ref disableOptionalPluginWarnings))
{
_configService.Current.DisableOptionalPluginWarnings = disableOptionalPluginWarnings;
_configService.Save();
}
_uiShared.DrawHelpText("Enabling this will not show any \"Warning\" labeled messages for missing optional plugins.");
if (ImGui.Checkbox("Enable online notifications", ref onlineNotifs))
{
_configService.Current.ShowOnlineNotifications = onlineNotifs;
_configService.Save();
}
_uiShared.DrawHelpText("Enabling this will show a small notification (type: Info) in the bottom right corner when pairs go online.");
using var disabled = ImRaii.Disabled(!onlineNotifs);
if (ImGui.Checkbox("Notify only for individual pairs", ref onlineNotifsPairsOnly))
{
_configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs = onlineNotifsPairsOnly;
_configService.Save();
}
_uiShared.DrawHelpText("Enabling this will only show online notifications (type: Info) for individual pairs.");
if (ImGui.Checkbox("Notify only for named pairs", ref onlineNotifsNamedOnly))
{
_configService.Current.ShowOnlineNotificationsOnlyForNamedPairs = onlineNotifsNamedOnly;
_configService.Save();
}
_uiShared.DrawHelpText("Enabling this will only show online notifications (type: Info) for pairs where you have set an individual note.");
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
ImGui.TreePop();
}
}
private void DrawPerformance()
@@ -2661,6 +2589,12 @@ public class SettingsUi : WindowMediatorSubscriberBase
ImGui.EndTabItem();
}
if (ImGui.BeginTabItem("Notifications"))
{
DrawNotificationSettings();
ImGui.EndTabItem();
}
if (ImGui.BeginTabItem("Debug"))
{
DrawDebug();
@@ -2681,4 +2615,568 @@ public class SettingsUi : WindowMediatorSubscriberBase
_wasOpen = IsOpen;
IsOpen = false;
}
private void DrawNotificationSettings()
{
_lastTab = "Notifications";
_uiShared.UnderlinedBigText("Notification System", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
bool useLightlessNotifications = _configService.Current.UseLightlessNotifications;
if (ImGui.Checkbox("Use Enhanced Lightless Notifications", ref useLightlessNotifications))
{
_configService.Current.UseLightlessNotifications = useLightlessNotifications;
_configService.Save();
}
_uiShared.DrawHelpText("Enable the new enhanced notification system with interactive buttons, animations, and better visual design.");
ImGui.Separator();
_uiShared.UnderlinedBigText("Notification Locations", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
UiSharedService.ColorTextWrapped("Configure where different types of notifications appear. Enhanced notifications provide modern interactive notifications with backwards compatibility support for classic toast/chat notifications.", ImGuiColors.DalamudGrey);
ImGuiHelpers.ScaledDummy(5);
if (useLightlessNotifications)
{
// Enhanced notification locations (primary)
_uiShared.BigText("Enhanced Notification Locations");
ImGuiHelpers.ScaledDummy(3);
var lightlessLocations = GetLightlessNotificationLocations();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Info Notifications:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###enhanced_info", lightlessLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.LightlessInfoNotification = location;
_configService.Save();
}, _configService.Current.LightlessInfoNotification);
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Warning Notifications:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###enhanced_warning", lightlessLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.LightlessWarningNotification = location;
_configService.Save();
}, _configService.Current.LightlessWarningNotification);
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Error Notifications:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###enhanced_error", lightlessLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.LightlessErrorNotification = location;
_configService.Save();
}, _configService.Current.LightlessErrorNotification);
ImGuiHelpers.ScaledDummy(5);
// Classic notification locations (backwards compatibility)
if (ImGui.CollapsingHeader("Classic Notification Settings (Backwards Compatibility)"))
{
_uiShared.DrawHelpText("These settings provide backwards compatibility. They will also be used if they're different from the enhanced settings above and don't conflict.");
ImGuiHelpers.ScaledDummy(3);
var classicLocations = GetClassicNotificationLocations();
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Info Fallback:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###classic_info", classicLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.InfoNotification = location;
_configService.Save();
}, _configService.Current.InfoNotification);
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Warning Fallback:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###classic_warning", classicLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.WarningNotification = location;
_configService.Save();
}, _configService.Current.WarningNotification);
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Error Fallback:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###classic_error", classicLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.ErrorNotification = location;
_configService.Save();
}, _configService.Current.ErrorNotification);
}
}
else
{
// Only classic notifications when enhanced is disabled
var classicLocations = GetClassicNotificationLocations();
_uiShared.BigText("Classic Notification Locations");
ImGuiHelpers.ScaledDummy(3);
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Info Notifications:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###info", classicLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.InfoNotification = location;
_configService.Save();
}, _configService.Current.InfoNotification);
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Warning Notifications:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###warning", classicLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.WarningNotification = location;
_configService.Save();
}, _configService.Current.WarningNotification);
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Error Notifications:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
_uiShared.DrawCombo("###error", classicLocations, GetNotificationLocationLabel, (location) =>
{
_configService.Current.ErrorNotification = location;
_configService.Save();
}, _configService.Current.ErrorNotification);
}
ImGui.Separator();
if (useLightlessNotifications)
{
UiSharedService.ColorTextWrapped("• Lightless Notifications: Modern animated notifications with interactive buttons", ImGuiColors.DalamudGrey);
UiSharedService.ColorTextWrapped("• Chat: Traditional chat messages with colored text", ImGuiColors.DalamudGrey);
UiSharedService.ColorTextWrapped("• Combined options: Show in multiple locations simultaneously", ImGuiColors.DalamudGrey);
}
else
{
UiSharedService.ColorTextWrapped("• Toast: Dalamud's built-in notification toasts", ImGuiColors.DalamudGrey);
UiSharedService.ColorTextWrapped("• Chat: Traditional chat messages with colored text", ImGuiColors.DalamudGrey);
UiSharedService.ColorTextWrapped("• Both: Show in both toast and chat", ImGuiColors.DalamudGrey);
}
ImGui.Separator();
if (useLightlessNotifications)
{
ImGui.Indent();
// Test notification buttons
if (_uiShared.IconTextButton(FontAwesomeIcon.Bell, "Test Info"))
{
Mediator.Publish(new NotificationMessage("Test Info", "This is a test info notification with the current settings!", NotificationType.Info));
}
ImGui.SameLine();
if (_uiShared.IconTextButton(FontAwesomeIcon.ExclamationTriangle, "Test Warning"))
{
Mediator.Publish(new NotificationMessage("Test Warning", "This is a test warning notification!", NotificationType.Warning));
}
ImGui.SameLine();
if (_uiShared.IconTextButton(FontAwesomeIcon.ExclamationCircle, "Test Error"))
{
Mediator.Publish(new NotificationMessage("Test Error", "This is a test error notification!", NotificationType.Error));
}
_uiShared.DrawHelpText("Click to preview different notification types with your current settings.");
ImGui.Unindent();
ImGui.Separator();
_uiShared.UnderlinedBigText("Basic Settings", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
int defaultDuration = _configService.Current.DefaultNotificationDurationSeconds;
if (ImGui.SliderInt("Default Duration (seconds)", ref defaultDuration, 3, 60))
{
_configService.Current.DefaultNotificationDurationSeconds = defaultDuration;
_configService.Save();
}
_uiShared.DrawHelpText("How long notifications stay visible by default.");
bool showProgress = _configService.Current.ShowNotificationProgress;
if (ImGui.Checkbox("Show Progress Bars", ref showProgress))
{
_configService.Current.ShowNotificationProgress = showProgress;
_configService.Save();
}
_uiShared.DrawHelpText("Display progress bars for download and other progress-based notifications.");
bool showTimestamp = _configService.Current.ShowNotificationTimestamp;
if (ImGui.Checkbox("Show Timestamps", ref showTimestamp))
{
_configService.Current.ShowNotificationTimestamp = showTimestamp;
_configService.Save();
}
_uiShared.DrawHelpText("Display the time when each notification was created.");
bool autoDismiss = _configService.Current.AutoDismissOnAction;
if (ImGui.Checkbox("Auto-dismiss on Action", ref autoDismiss))
{
_configService.Current.AutoDismissOnAction = autoDismiss;
_configService.Save();
}
_uiShared.DrawHelpText("Automatically close notifications when you click an action button.");
if (useLightlessNotifications)
{
ImGui.Separator();
_uiShared.UnderlinedBigText("Appearance & Animation", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
float opacity = _configService.Current.NotificationOpacity;
if (ImGui.SliderFloat("Notification Opacity", ref opacity, 0.1f, 1.0f, "%.2f"))
{
_configService.Current.NotificationOpacity = opacity;
_configService.Save();
}
_uiShared.DrawHelpText("Transparency level of notification windows.");
bool enableAnimations = _configService.Current.EnableNotificationAnimations;
if (ImGui.Checkbox("Enable Animations", ref enableAnimations))
{
_configService.Current.EnableNotificationAnimations = enableAnimations;
_configService.Save();
}
_uiShared.DrawHelpText("Enable slide-in/out animations for notifications.");
int maxNotifications = _configService.Current.MaxSimultaneousNotifications;
if (ImGui.SliderInt("Max Simultaneous Notifications", ref maxNotifications, 1, 10))
{
_configService.Current.MaxSimultaneousNotifications = maxNotifications;
_configService.Save();
}
_uiShared.DrawHelpText("Maximum number of notifications that can be shown at once.");
bool enableHistory = _configService.Current.EnableNotificationHistory;
if (ImGui.Checkbox("Enable Notification History", ref enableHistory))
{
_configService.Current.EnableNotificationHistory = enableHistory;
_configService.Save();
}
_uiShared.DrawHelpText("Keep a history of recent notifications that you can review.");
if (enableHistory)
{
ImGui.Indent();
int historySize = _configService.Current.NotificationHistorySize;
if (ImGui.SliderInt("History Size", ref historySize, 10, 200))
{
_configService.Current.NotificationHistorySize = historySize;
_configService.Save();
}
_uiShared.DrawHelpText("Number of notifications to keep in history.");
ImGui.Unindent();
}
}
ImGui.Separator();
_uiShared.UnderlinedBigText("Sound Settings", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
bool enableSounds = _configService.Current.EnableNotificationSounds;
if (ImGui.Checkbox("Enable Notification Sounds", ref enableSounds))
{
_configService.Current.EnableNotificationSounds = enableSounds;
_configService.Save();
}
_uiShared.DrawHelpText("Play FFXIV sound effects when notifications appear.");
if (enableSounds)
{
ImGui.Indent();
// float soundVolume = _configService.Current.NotificationSoundVolume;
// if (ImGui.SliderFloat("Sound Volume", ref soundVolume, 0.0f, 1.0f, "%.2f"))
// {
// _configService.Current.NotificationSoundVolume = soundVolume;
// _configService.Save();
// }
// _uiShared.DrawHelpText("Volume level for notification sounds (Note: FFXIV doesn't support volume control for SE sounds).");
// bool useCustomSounds = _configService.Current.UseCustomSounds;
// if (ImGui.Checkbox("Use Custom Sound Effects", ref useCustomSounds))
// {
// _configService.Current.UseCustomSounds = useCustomSounds;
// _configService.Save();
// }
// _uiShared.DrawHelpText("Override default sounds with custom FFXIV sound effects.");
DrawSoundCustomization();
// if (useCustomSounds)
// {
// ImGui.Indent();
// DrawSoundCustomization();
// ImGui.Unindent();
// }
ImGui.Unindent();
}
ImGui.Separator();
_uiShared.UnderlinedBigText("Specific Notification Types", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
UiSharedService.ColorTextWrapped("Configure specific types of notifications and their behavior.", ImGuiColors.DalamudGrey);
ImGuiHelpers.ScaledDummy(3);
// Online Notifications Section
if (_uiShared.MediumTreeNode("Online Status Notifications", UIColors.Get("LightlessGreen")))
{
var onlineNotifs = _configService.Current.ShowOnlineNotifications;
var onlineNotifsPairsOnly = _configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs;
var onlineNotifsNamedOnly = _configService.Current.ShowOnlineNotificationsOnlyForNamedPairs;
if (ImGui.Checkbox("Enable online notifications", ref onlineNotifs))
{
_configService.Current.ShowOnlineNotifications = onlineNotifs;
_configService.Save();
}
_uiShared.DrawHelpText("Show notifications when pairs come online. These will use the Info notification location settings above.");
using var disabled = ImRaii.Disabled(!onlineNotifs);
ImGui.Indent();
if (ImGui.Checkbox("Notify only for individual pairs", ref onlineNotifsPairsOnly))
{
_configService.Current.ShowOnlineNotificationsOnlyForIndividualPairs = onlineNotifsPairsOnly;
_configService.Save();
}
_uiShared.DrawHelpText("Only show online notifications for individual pairs (not syncshell members).");
if (ImGui.Checkbox("Notify only for named pairs", ref onlineNotifsNamedOnly))
{
_configService.Current.ShowOnlineNotificationsOnlyForNamedPairs = onlineNotifsNamedOnly;
_configService.Save();
}
_uiShared.DrawHelpText("Only show online notifications for pairs where you have set an individual note.");
ImGui.Unindent();
_uiShared.ColoredSeparator(UIColors.Get("LightlessGreen"), 1.5f);
ImGui.TreePop();
}
// Pairing Request Notifications Section
if (_uiShared.MediumTreeNode("Pairing Request Notifications", UIColors.Get("LightlessBlue")))
{
UiSharedService.ColorTextWrapped("Pairing requests always show as interactive notifications with Accept/Decline buttons. These settings control additional behavior.", ImGuiColors.DalamudGrey);
ImGuiHelpers.ScaledDummy(3);
// Note: Pairing requests are always shown as interactive notifications
// This section can be expanded later with additional pairing notification settings
_uiShared.ColoredSeparator(UIColors.Get("LightlessBlue"), 1.5f);
ImGui.TreePop();
}
// Download Progress Notifications Section
if (_uiShared.MediumTreeNode("Download Progress Notifications", UIColors.Get("LightlessPurple")))
{
var useNotificationsForDownloads = _configService.Current.UseNotificationsForDownloads;
if (ImGui.Checkbox("Show download progress as notifications", ref useNotificationsForDownloads))
{
_configService.Current.UseNotificationsForDownloads = useNotificationsForDownloads;
_configService.Save();
}
_uiShared.DrawHelpText("Show download progress as clean notifications instead of overlay text. Notifications update in real-time and use the Info notification location settings above.");
_uiShared.ColoredSeparator(UIColors.Get("LightlessPurple"), 1.5f);
ImGui.TreePop();
}
// System Notifications Section
if (_uiShared.MediumTreeNode("System Notifications", UIColors.Get("LightlessYellow")))
{
var disableOptionalPluginWarnings = _configService.Current.DisableOptionalPluginWarnings;
if (ImGui.Checkbox("Disable optional plugin warnings", ref disableOptionalPluginWarnings))
{
_configService.Current.DisableOptionalPluginWarnings = disableOptionalPluginWarnings;
_configService.Save();
}
_uiShared.DrawHelpText("Disable warning notifications for missing optional plugins.");
_uiShared.ColoredSeparator(UIColors.Get("LightlessYellow"), 1.5f);
ImGui.TreePop();
}
ImGui.Separator();
_uiShared.UnderlinedBigText("Location Descriptions", UIColors.Get("LightlessBlue"));
ImGuiHelpers.ScaledDummy(5);
}
}
private NotificationLocation[] GetLightlessNotificationLocations()
{
return new[]
{
NotificationLocation.LightlessUI,
NotificationLocation.ChatAndLightlessUI,
NotificationLocation.Nowhere
};
}
private NotificationLocation[] GetClassicNotificationLocations()
{
return new[]
{
NotificationLocation.Toast,
NotificationLocation.Chat,
NotificationLocation.Both,
NotificationLocation.Nowhere
};
}
private string GetNotificationLocationLabel(NotificationLocation location)
{
return location switch
{
NotificationLocation.Nowhere => "Nowhere",
NotificationLocation.Chat => "Chat",
NotificationLocation.Toast => "Toast",
NotificationLocation.Both => "Toast + Chat",
NotificationLocation.LightlessUI => "Lightless Notifications",
NotificationLocation.ChatAndLightlessUI => "Chat + Lightless Notifications",
_ => location.ToString()
};
}
private void DrawSoundCustomization()
{
var soundEffects = new[]
{
(1u, "Se1 - Soft chime"),
(2u, "Se2 - Higher chime"),
(3u, "Se3 - Bell tone"),
(4u, "Se4 - Harp tone"),
(5u, "Se5 - Drum/percussion"),
(6u, "Se6 - Mechanical click"),
(7u, "Se7 - Metallic chime"),
(8u, "Se8 - Wooden tone"),
(9u, "Se9 - Wind/flute tone"),
(10u, "Se10 - Magical sparkle"),
(11u, "Se11 - Metallic ring"),
(12u, "Se12 - Deep thud"),
(13u, "Se13 - Tell received ping"),
(14u, "Se14 - Success fanfare"),
(15u, "Se15 - System warning"),
(16u, "Se16 - Error/failure")
};
// Info Sound
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Info Sound:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
var currentInfoSound = _configService.Current.CustomInfoSoundId;
var currentInfoIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentInfoSound);
if (currentInfoIndex == -1) currentInfoIndex = 1; // Default to Se2
if (ImGui.Combo("###info_sound", ref currentInfoIndex, soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
{
_configService.Current.CustomInfoSoundId = soundEffects[currentInfoIndex].Item1;
_configService.Save();
}
ImGui.SameLine();
ImGui.PushID("test_info");
if (_uiShared.IconButton(FontAwesomeIcon.Play))
{
try
{
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomInfoSoundId);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to play test sound");
}
}
ImGui.PopID();
UiSharedService.AttachToolTip("Test this sound");
// Warning Sound
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Warning Sound:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
var currentWarningSound = _configService.Current.CustomWarningSoundId;
var currentWarningIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentWarningSound);
if (currentWarningIndex == -1) currentWarningIndex = 14; // Default to Se15
if (ImGui.Combo("###warning_sound", ref currentWarningIndex, soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
{
_configService.Current.CustomWarningSoundId = soundEffects[currentWarningIndex].Item1;
_configService.Save();
}
ImGui.SameLine();
ImGui.PushID("test_warning");
if (_uiShared.IconButton(FontAwesomeIcon.Play))
{
try
{
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomWarningSoundId);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to play test sound");
}
}
ImGui.PopID();
UiSharedService.AttachToolTip("Test this sound");
// Error Sound
ImGui.AlignTextToFramePadding();
ImGui.TextUnformatted("Error Sound:");
ImGui.SameLine();
ImGui.SetNextItemWidth(200 * ImGuiHelpers.GlobalScale);
var currentErrorSound = _configService.Current.CustomErrorSoundId;
var currentErrorIndex = Array.FindIndex(soundEffects, s => s.Item1 == currentErrorSound);
if (currentErrorIndex == -1) currentErrorIndex = 15; // Default to Se16
if (ImGui.Combo("###error_sound", ref currentErrorIndex, soundEffects.Select(s => s.Item2).ToArray(), soundEffects.Length))
{
_configService.Current.CustomErrorSoundId = soundEffects[currentErrorIndex].Item1;
_configService.Save();
}
ImGui.SameLine();
ImGui.PushID("test_error");
if (_uiShared.IconButton(FontAwesomeIcon.Play))
{
try
{
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomErrorSoundId);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to play test sound");
}
}
ImGui.PopID();
UiSharedService.AttachToolTip("Test this sound");
ImGuiHelpers.ScaledDummy(5);
if (_uiShared.IconTextButton(FontAwesomeIcon.VolumeUp, "Test All Sounds"))
{
Task.Run(async () =>
{
try
{
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomInfoSoundId);
await Task.Delay(800);
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomWarningSoundId);
await Task.Delay(800);
FFXIVClientStructs.FFXIV.Client.UI.UIGlobals.PlayChatSoundEffect(_configService.Current.CustomErrorSoundId);
}
catch (Exception ex)
{
_logger.LogWarning(ex, "Failed to play test sounds");
}
});
}
_uiShared.DrawHelpText("Play all custom sounds in sequence: Info → Warning → Error");
}
}