feat(ui): add Integrations settings tab
This commit is contained in:
@@ -0,0 +1,185 @@
|
|||||||
|
using Dalamud.Bindings.ImGui;
|
||||||
|
using Dalamud.Interface.Utility.Raii;
|
||||||
|
using HellionChat.Branding;
|
||||||
|
using HellionChat.Resources;
|
||||||
|
using HellionChat.Util;
|
||||||
|
|
||||||
|
namespace HellionChat.Ui.SettingsTabs;
|
||||||
|
|
||||||
|
// First settings tab introduced in v1.3.0 (Plugin Integrations Cycle 1).
|
||||||
|
// Designed to grow organically: each future cycle adds a new section above
|
||||||
|
// the "Coming soon" block and removes the corresponding stub item.
|
||||||
|
internal sealed class Integrations : ISettingsTab
|
||||||
|
{
|
||||||
|
private Plugin Plugin { get; }
|
||||||
|
private Configuration Mutable { get; }
|
||||||
|
|
||||||
|
public string Name => HellionStrings.Settings_Tab_Integrations + "###tabs-integrations";
|
||||||
|
|
||||||
|
internal Integrations(Plugin plugin, Configuration mutable)
|
||||||
|
{
|
||||||
|
Plugin = plugin;
|
||||||
|
Mutable = mutable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw(bool changed)
|
||||||
|
{
|
||||||
|
ImGui.TextWrapped(HellionStrings.Settings_Integrations_Intro);
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
DrawHonorificSection();
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
DrawComingSoonSection();
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
DrawGotAnIdeaSection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawHonorificSection()
|
||||||
|
{
|
||||||
|
DrawSectionHeader(HellionStrings.Settings_Integrations_Honorific_SectionHeader);
|
||||||
|
|
||||||
|
DrawHonorificStatus();
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
// The toggle is enabled regardless of detection state — leaving it
|
||||||
|
// on means "render when available, hide otherwise". Disabling the
|
||||||
|
// toggle when Honorific is missing would force the user to retoggle
|
||||||
|
// it every time Honorific is reloaded, which is worse UX than the
|
||||||
|
// silent auto-hide.
|
||||||
|
if (ImGui.Checkbox(
|
||||||
|
HellionStrings.Settings_Integrations_Honorific_Toggle,
|
||||||
|
ref Mutable.ShowHonorificTitleInHeader))
|
||||||
|
{
|
||||||
|
Plugin.SaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
using (ImRaii.PushIndent())
|
||||||
|
{
|
||||||
|
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(Plugin.ThemeRegistry.Active.Colors.TextMuted)))
|
||||||
|
{
|
||||||
|
ImGui.TextWrapped(HellionStrings.Settings_Integrations_Honorific_ToggleHint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawHonorificStatus()
|
||||||
|
{
|
||||||
|
var theme = Plugin.ThemeRegistry.Active;
|
||||||
|
var service = Plugin.HonorificService;
|
||||||
|
|
||||||
|
if (service.IsAvailable && service.DetectedApiVersion is { } version)
|
||||||
|
{
|
||||||
|
DrawStatusGlyph('●', theme.Colors.StatusSuccess);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(string.Format(
|
||||||
|
HellionStrings.Settings_Integrations_Honorific_Status_Detected,
|
||||||
|
version.Major, version.Minor));
|
||||||
|
}
|
||||||
|
else if (service.DetectedApiVersion is { } incompatibleVersion)
|
||||||
|
{
|
||||||
|
DrawStatusGlyph('⚠', theme.Colors.StatusWarning);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(string.Format(
|
||||||
|
HellionStrings.Settings_Integrations_Honorific_Status_Incompatible,
|
||||||
|
3, incompatibleVersion.Major, incompatibleVersion.Minor));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
DrawStatusGlyph('○', theme.Colors.TextMuted);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(HellionStrings.Settings_Integrations_Honorific_Status_NotInstalled);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawStatusGlyph(char glyph, uint rgba)
|
||||||
|
{
|
||||||
|
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(rgba)))
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted(glyph.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawComingSoonSection()
|
||||||
|
{
|
||||||
|
DrawSectionHeader(HellionStrings.Settings_Integrations_ComingSoon_SectionHeader);
|
||||||
|
ImGui.TextWrapped(HellionStrings.Settings_Integrations_ComingSoon_Intro);
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
// Static list maintained in code (not Configuration). Each cycle
|
||||||
|
// that lands a real integration removes its stub here and adds a
|
||||||
|
// full section above the Coming Soon block.
|
||||||
|
DrawComingSoonItem(
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_ContextMenu_Title,
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_ContextMenu_Description);
|
||||||
|
DrawComingSoonItem(
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_Notifications_Title,
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_Notifications_Description);
|
||||||
|
DrawComingSoonItem(
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_RPStatus_Title,
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_RPStatus_Description);
|
||||||
|
DrawComingSoonItem(
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_ExtraChat_Title,
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_ExtraChat_Description);
|
||||||
|
DrawComingSoonItem(
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_QuickDM_Title,
|
||||||
|
HellionStrings.Settings_Integrations_ComingSoon_QuickDM_Description);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawComingSoonItem(string title, string description)
|
||||||
|
{
|
||||||
|
var theme = Plugin.ThemeRegistry.Active;
|
||||||
|
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(theme.Colors.TextMuted)))
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("◌");
|
||||||
|
}
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted(title);
|
||||||
|
using (ImRaii.PushIndent())
|
||||||
|
{
|
||||||
|
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(theme.Colors.TextMuted)))
|
||||||
|
{
|
||||||
|
ImGui.TextWrapped(description);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.Spacing();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawGotAnIdeaSection()
|
||||||
|
{
|
||||||
|
DrawSectionHeader(HellionStrings.Settings_Integrations_GotAnIdea_SectionHeader);
|
||||||
|
ImGui.TextWrapped(HellionStrings.Settings_Integrations_GotAnIdea_Body);
|
||||||
|
ImGui.Spacing();
|
||||||
|
|
||||||
|
var theme = Plugin.ThemeRegistry.Active;
|
||||||
|
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(theme.Colors.Primary)))
|
||||||
|
{
|
||||||
|
// Selectable so the whole "→ link label" line is clickable and
|
||||||
|
// shows a hover state, matching the affordance users expect from
|
||||||
|
// hyperlinks in ImGui-driven plugins. Fully-qualified
|
||||||
|
// Dalamud.Utility.Util.OpenLink because HellionChat.Util is in
|
||||||
|
// scope here and an unqualified Util would clash.
|
||||||
|
if (ImGui.Selectable("→ " + HellionStrings.Settings_Integrations_GotAnIdea_LinkLabel))
|
||||||
|
{
|
||||||
|
Dalamud.Utility.Util.OpenLink(BrandingLinks.HellionForgeDiscordInvite);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (ImGui.IsItemHovered())
|
||||||
|
{
|
||||||
|
ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawSectionHeader(string label)
|
||||||
|
{
|
||||||
|
var theme = Plugin.ThemeRegistry.Active;
|
||||||
|
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(theme.Colors.Primary)))
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("── " + label + " ──");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user