494 lines
18 KiB
C#
494 lines
18 KiB
C#
using System.Numerics;
|
|
using Dalamud.Bindings.ImGui;
|
|
using Dalamud.Interface;
|
|
using Dalamud.Interface.Colors;
|
|
using Dalamud.Interface.Utility;
|
|
using Dalamud.Interface.Utility.Raii;
|
|
using HellionChat.Branding;
|
|
using HellionChat.Integrations;
|
|
using HellionChat.Resources;
|
|
using HellionChat.Util;
|
|
|
|
namespace HellionChat.Ui.SettingsTabs;
|
|
|
|
// The About tab absorbs the former Integrations tab (now the first section)
|
|
// and organises its remaining content into four thematic sections.
|
|
internal sealed class About : ISettingsTab
|
|
{
|
|
private Plugin Plugin { get; }
|
|
private Configuration Mutable { get; }
|
|
|
|
public string Name => HellionStrings.Settings_Tab_Information + "###tabs-information";
|
|
|
|
private readonly List<string> Translators =
|
|
[
|
|
"q673135110",
|
|
"Akizem",
|
|
"d0tiKs",
|
|
"Moonlight_Everlit",
|
|
"Dark32",
|
|
"andreycout",
|
|
"Button_",
|
|
"Cali666",
|
|
"cassandra308",
|
|
"lokinmodar",
|
|
"jtabox",
|
|
"AkiraYorumoto",
|
|
"MKhayle",
|
|
"elena.space",
|
|
"imlisa",
|
|
"andrei5125",
|
|
"ShivaMaheshvara",
|
|
"aislinn87",
|
|
"nishinatsu051",
|
|
"lichuyuan",
|
|
"Risu64",
|
|
"yummypillow",
|
|
"witchymary",
|
|
"Yuzumi",
|
|
"zomsakura",
|
|
"Sirayuki",
|
|
];
|
|
|
|
internal About(Plugin plugin, Configuration mutable)
|
|
{
|
|
Plugin = plugin;
|
|
Mutable = mutable;
|
|
Translators.Sort(
|
|
(a, b) =>
|
|
string.Compare(a.ToLowerInvariant(), b.ToLowerInvariant(), StringComparison.Ordinal)
|
|
);
|
|
}
|
|
|
|
public void Draw(bool sectionJustEntered)
|
|
{
|
|
using var wrap = ImRaii.TextWrapPos(0.0f);
|
|
|
|
DrawExtensionsSection(sectionJustEntered);
|
|
ImGui.Spacing();
|
|
DrawPluginInfoSection(sectionJustEntered);
|
|
ImGui.Spacing();
|
|
DrawProjectSection(sectionJustEntered);
|
|
ImGui.Spacing();
|
|
DrawTranslatorsSection(sectionJustEntered);
|
|
ImGui.Spacing();
|
|
DrawChangelogSection(sectionJustEntered);
|
|
}
|
|
|
|
// ── Extensions ──────────────────────────────────────────────────────────
|
|
|
|
private void DrawExtensionsSection(bool sectionJustEntered)
|
|
{
|
|
if (sectionJustEntered)
|
|
ImGui.SetNextItemOpen(false);
|
|
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Extensions);
|
|
if (!tree.Success)
|
|
return;
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
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();
|
|
|
|
// Toggle works regardless of detection state: "show when available,
|
|
// hide otherwise". Disabling it when Honorific is missing would force
|
|
// the user to retoggle on every reload.
|
|
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);
|
|
}
|
|
|
|
if (
|
|
ImGui.Checkbox(
|
|
HellionStrings.Settings_Integrations_Honorific_Glow_Toggle,
|
|
ref Mutable.ShowHonorificGlow
|
|
)
|
|
)
|
|
{
|
|
Plugin.SaveConfig();
|
|
}
|
|
ImGuiUtil.HelpMarker(HellionStrings.Settings_Integrations_Honorific_Glow_Hint);
|
|
}
|
|
|
|
// Honorific has no LICENSE in its repo so we link upstream and author
|
|
// instead of bundling assets. Text labels because FA Brands isn't
|
|
// guaranteed in Dalamud's font set.
|
|
ImGui.Spacing();
|
|
if (ImGui.Button(HellionStrings.Settings_Integrations_Honorific_LinkRepo))
|
|
{
|
|
Plugin.PlatformUtil.OpenLink(IntegrationLinks.HonorificRepo);
|
|
}
|
|
ImGui.SameLine();
|
|
if (ImGui.Button(HellionStrings.Settings_Integrations_Honorific_LinkAuthor))
|
|
{
|
|
Plugin.PlatformUtil.OpenLink(IntegrationLinks.HonorificAuthor);
|
|
}
|
|
}
|
|
|
|
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,
|
|
HonorificService.ExpectedApiMajor,
|
|
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();
|
|
|
|
// Each integration cycle removes its stub here and adds a full section above.
|
|
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)))
|
|
using (Plugin.FontManager.FontAwesome.Push())
|
|
{
|
|
ImGui.TextUnformatted(FontAwesomeIcon.Hourglass.ToIconString());
|
|
}
|
|
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();
|
|
|
|
if (ImGui.Button(HellionStrings.Settings_Integrations_GotAnIdea_LinkLabel))
|
|
{
|
|
Plugin.PlatformUtil.OpenLink(BrandingLinks.HellionForgeDiscordInvite);
|
|
}
|
|
}
|
|
|
|
private void DrawSectionHeader(string label)
|
|
{
|
|
var theme = Plugin.ThemeRegistry.Active;
|
|
using (ImRaii.PushColor(ImGuiCol.Text, ColourUtil.RgbaToAbgr(theme.Colors.Primary)))
|
|
{
|
|
ImGui.TextUnformatted("── " + label + " ──");
|
|
}
|
|
}
|
|
|
|
// ── Plugin info ──────────────────────────────────────────────────────────
|
|
|
|
private void DrawPluginInfoSection(bool sectionJustEntered)
|
|
{
|
|
if (sectionJustEntered)
|
|
ImGui.SetNextItemOpen(false);
|
|
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_PluginInfo);
|
|
if (!tree.Success)
|
|
return;
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
DrawFoxBanner();
|
|
ImGuiHelpers.ScaledDummy(6.0f);
|
|
|
|
ImGui.TextUnformatted(string.Format(Language.Options_About_Opening, Plugin.PluginName));
|
|
|
|
ImGuiHelpers.ScaledDummy(10.0f);
|
|
|
|
ImGui.TextUnformatted(Language.Options_About_Authors);
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(ImGuiColors.ParsedGold, Plugin.Interface.Manifest.Author);
|
|
|
|
ImGui.TextUnformatted(Language.Options_About_Discord);
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(ImGuiColors.ParsedGold, "@j.j_kazama");
|
|
|
|
ImGui.TextUnformatted(Language.Options_About_Version);
|
|
ImGui.SameLine();
|
|
ImGui.TextColored(
|
|
ImGuiColors.ParsedOrange,
|
|
Plugin.Interface.Manifest.AssemblyVersion.ToString(3)
|
|
);
|
|
|
|
ImGuiHelpers.ScaledDummy(10.0f);
|
|
|
|
ImGui.TextUnformatted(Language.Options_About_Github_Issues);
|
|
ImGui.SameLine();
|
|
if (ImGuiUtil.IconButton(FontAwesomeIcon.ExternalLinkAlt, "githubIssues"))
|
|
Plugin.PlatformUtil.OpenLink(
|
|
"https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/issues"
|
|
);
|
|
}
|
|
}
|
|
|
|
private void DrawFoxBanner()
|
|
{
|
|
var banner = FoxBannerTexture.Shared.GetWrapOrDefault();
|
|
if (banner is null)
|
|
return;
|
|
|
|
const uint CardColor = 0xFFE8E8E8; // off-white fill so the dark fox pops
|
|
var imgHeight = 170f * ImGuiHelpers.GlobalScale;
|
|
var imgWidth = imgHeight * banner.Size.X / banner.Size.Y;
|
|
var pad = 14f * ImGuiHelpers.GlobalScale;
|
|
var cardWidth = imgWidth + pad * 2f;
|
|
var cardHeight = imgHeight + pad * 2f;
|
|
var rounding = 8f * ImGuiHelpers.GlobalScale;
|
|
|
|
// Left-aligned: card origin stays at the current layout cursor position.
|
|
var cardOrigin = ImGui.GetCursorScreenPos();
|
|
|
|
// Draw the rounded card behind the image, then place the image on top.
|
|
ImGui
|
|
.GetWindowDrawList()
|
|
.AddRectFilled(
|
|
cardOrigin,
|
|
cardOrigin + new Vector2(cardWidth, cardHeight),
|
|
CardColor,
|
|
rounding
|
|
);
|
|
ImGui.SetCursorScreenPos(cardOrigin + new Vector2(pad, pad));
|
|
ImGui.Image(banner.Handle, new Vector2(imgWidth, imgHeight));
|
|
|
|
// Advance the layout cursor past the full card so content below does not overlap.
|
|
ImGui.SetCursorScreenPos(cardOrigin);
|
|
ImGui.Dummy(new Vector2(cardWidth, cardHeight));
|
|
}
|
|
|
|
// ── The Project ──────────────────────────────────────────────────────────
|
|
|
|
private void DrawProjectSection(bool sectionJustEntered)
|
|
{
|
|
if (sectionJustEntered)
|
|
ImGui.SetNextItemOpen(false);
|
|
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Project);
|
|
if (!tree.Success)
|
|
return;
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
ImGui.TextColored(ImGuiColors.ParsedGold, HellionStrings.About_Maintainer_Heading);
|
|
ImGui.TextUnformatted(HellionStrings.About_Maintainer_Body);
|
|
ImGui.TextUnformatted(HellionStrings.About_Maintainer_Website_Label);
|
|
ImGui.SameLine();
|
|
if (ImGuiUtil.IconButton(FontAwesomeIcon.ExternalLinkAlt, "hellionMedia"))
|
|
Plugin.PlatformUtil.OpenLink("https://hellion-media.de");
|
|
|
|
ImGuiHelpers.ScaledDummy(10.0f);
|
|
|
|
ImGui.TextColored(ImGuiColors.ParsedGold, HellionStrings.About_Mission_Heading);
|
|
ImGui.TextUnformatted(HellionStrings.About_Mission_P1);
|
|
ImGui.Spacing();
|
|
ImGui.TextUnformatted(HellionStrings.About_Mission_P2);
|
|
ImGui.Spacing();
|
|
ImGui.TextUnformatted(HellionStrings.About_Mission_P3);
|
|
|
|
ImGuiHelpers.ScaledDummy(10.0f);
|
|
|
|
ImGui.TextColored(ImGuiColors.ParsedGold, HellionStrings.About_BuiltOn_Heading);
|
|
ImGui.TextUnformatted(HellionStrings.About_BuiltOn_P1);
|
|
ImGui.Spacing();
|
|
ImGui.TextUnformatted(HellionStrings.About_BuiltOn_P2);
|
|
ImGui.Spacing();
|
|
ImGui.TextUnformatted(HellionStrings.About_BuiltOn_Upstream_Label);
|
|
ImGui.SameLine();
|
|
if (ImGuiUtil.IconButton(FontAwesomeIcon.ExternalLinkAlt, "chatTwoUpstream"))
|
|
Plugin.PlatformUtil.OpenLink("https://github.com/Infiziert90/ChatTwo");
|
|
|
|
ImGuiHelpers.ScaledDummy(10.0f);
|
|
|
|
ImGui.TextColored(ImGuiColors.ParsedGold, HellionStrings.About_License_Heading);
|
|
ImGui.TextUnformatted(HellionStrings.About_License_P1);
|
|
ImGui.TextUnformatted(HellionStrings.About_License_P2);
|
|
ImGui.TextUnformatted(HellionStrings.About_License_P3);
|
|
|
|
ImGuiHelpers.ScaledDummy(10.0f);
|
|
|
|
ImGui.TextColored(ImGuiColors.DalamudOrange, HellionStrings.About_SE_Heading);
|
|
ImGui.TextUnformatted(HellionStrings.About_SE_P1);
|
|
ImGui.TextUnformatted(HellionStrings.About_SE_P2);
|
|
|
|
ImGui.Spacing();
|
|
|
|
ImGui.TextColored(ImGuiColors.ParsedGold, HellionStrings.About_Localization_Heading);
|
|
ImGui.TextUnformatted(HellionStrings.About_Localization_P1);
|
|
ImGui.TextUnformatted(HellionStrings.About_Localization_P2);
|
|
}
|
|
}
|
|
|
|
// ── Translators ──────────────────────────────────────────────────────────
|
|
|
|
private void DrawTranslatorsSection(bool sectionJustEntered)
|
|
{
|
|
if (sectionJustEntered)
|
|
ImGui.SetNextItemOpen(false);
|
|
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Translators);
|
|
if (!tree.Success)
|
|
return;
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
// The translator list belongs to the Chat 2 upstream Crowdin project.
|
|
using var translatorTree = ImRaii.TreeNode(HellionStrings.About_Translators_TreeNode);
|
|
if (translatorTree)
|
|
{
|
|
using var indent = ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false);
|
|
foreach (var translator in Translators)
|
|
ImGui.TextUnformatted(translator);
|
|
}
|
|
}
|
|
}
|
|
|
|
// ── Changelog ────────────────────────────────────────────────────────────
|
|
|
|
private void DrawChangelogSection(bool sectionJustEntered)
|
|
{
|
|
if (sectionJustEntered)
|
|
ImGui.SetNextItemOpen(false);
|
|
|
|
using var tree = ImRaii.TreeNode(HellionStrings.Settings_Section_Changelog);
|
|
if (!tree.Success)
|
|
return;
|
|
|
|
using (ImRaii.PushIndent(ImGui.GetStyle().IndentSpacing, false))
|
|
{
|
|
ImGui.Checkbox(Language.Options_PrintChangelog_Name, ref Mutable.PrintChangelog);
|
|
ImGuiUtil.HelpMarker(Language.Options_PrintChangelog_Description);
|
|
|
|
ImGui.Spacing();
|
|
ImGui.Separator();
|
|
ImGui.Spacing();
|
|
|
|
var changelog = Plugin.Interface.Manifest.Changelog;
|
|
if (changelog == null)
|
|
return;
|
|
|
|
ImGui.TextUnformatted(Language.Options_Changelog_Header);
|
|
ImGui.TextUnformatted(
|
|
$"Version {Plugin.Interface.Manifest.AssemblyVersion.ToString(3)}"
|
|
);
|
|
ImGui.Spacing();
|
|
foreach (var sentence in changelog.Split("\n"))
|
|
{
|
|
if (sentence == string.Empty)
|
|
{
|
|
ImGui.NewLine();
|
|
continue;
|
|
}
|
|
|
|
var indented = sentence.StartsWith('-') || sentence.StartsWith(" -");
|
|
using var indent = ImRaii.PushIndent(10.0f, true, indented);
|
|
ImGui.TextUnformatted(sentence);
|
|
}
|
|
}
|
|
}
|
|
}
|