feat(settings): add About tab with brand, links, credits
This commit is contained in:
@@ -10,6 +10,8 @@ internal static class BrandingLinks
|
|||||||
public const string HellionForgeGitea = "https://gitea.hellion-forge.cloud/Hellion-Forge";
|
public const string HellionForgeGitea = "https://gitea.hellion-forge.cloud/Hellion-Forge";
|
||||||
public const string HellionChatRepo =
|
public const string HellionChatRepo =
|
||||||
"https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat";
|
"https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat";
|
||||||
|
public const string HellionChatCustomRepoManifest =
|
||||||
|
"https://gitea.hellion-forge.cloud/JonKazama-Hellion/HellionChat/raw/branch/main/repo.json";
|
||||||
public const string HellionForgeWebsite = "https://hellion-forge.cloud";
|
public const string HellionForgeWebsite = "https://hellion-forge.cloud";
|
||||||
public const string HellionMediaWebsite = "https://hellion-media.de/de";
|
public const string HellionMediaWebsite = "https://hellion-media.de/de";
|
||||||
|
|
||||||
@@ -26,6 +28,7 @@ internal static class BrandingLinks
|
|||||||
HellionForgeDiscordInvite,
|
HellionForgeDiscordInvite,
|
||||||
HellionForgeGitea,
|
HellionForgeGitea,
|
||||||
HellionChatRepo,
|
HellionChatRepo,
|
||||||
|
HellionChatCustomRepoManifest,
|
||||||
HellionForgeWebsite,
|
HellionForgeWebsite,
|
||||||
HellionMediaWebsite
|
HellionMediaWebsite
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ public class ConfigKeyBind
|
|||||||
[Serializable]
|
[Serializable]
|
||||||
public class Configuration : IPluginConfiguration
|
public class Configuration : IPluginConfiguration
|
||||||
{
|
{
|
||||||
private const int LatestVersion = 20;
|
internal const int LatestVersion = 20;
|
||||||
|
|
||||||
public int Version { get; set; } = LatestVersion;
|
public int Version { get; set; } = LatestVersion;
|
||||||
|
|
||||||
|
|||||||
@@ -183,6 +183,10 @@ internal static class PluginHostFactory
|
|||||||
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.DataPrivacyTab(
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.DataPrivacyTab(
|
||||||
sp.GetRequiredService<Plugin>()
|
sp.GetRequiredService<Plugin>()
|
||||||
));
|
));
|
||||||
|
services.AddSingleton(sp => new Ui.Components.Settings.Tabs.AboutTab(
|
||||||
|
sp.GetRequiredService<FontManager>(),
|
||||||
|
sp.GetRequiredService<ILogger<Ui.Components.Settings.Tabs.AboutTab>>()
|
||||||
|
));
|
||||||
services.AddSingleton(sp => new Ui.Components.StatusBar(
|
services.AddSingleton(sp => new Ui.Components.StatusBar(
|
||||||
sp.GetRequiredService<ThemeRegistry>(),
|
sp.GetRequiredService<ThemeRegistry>(),
|
||||||
sp.GetRequiredService<FontManager>()
|
sp.GetRequiredService<FontManager>()
|
||||||
|
|||||||
@@ -0,0 +1,117 @@
|
|||||||
|
using System.Diagnostics;
|
||||||
|
using System.Reflection;
|
||||||
|
using Dalamud.Bindings.ImGui;
|
||||||
|
using Dalamud.Interface;
|
||||||
|
using HellionChat.Branding;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
|
namespace HellionChat.Ui.Components.Settings.Tabs;
|
||||||
|
|
||||||
|
internal sealed class AboutTab
|
||||||
|
{
|
||||||
|
private readonly FontManager _fonts;
|
||||||
|
private readonly ILogger<AboutTab> _logger;
|
||||||
|
|
||||||
|
public AboutTab(FontManager fonts, ILogger<AboutTab> logger)
|
||||||
|
{
|
||||||
|
_fonts = fonts;
|
||||||
|
_logger = logger;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Draw()
|
||||||
|
{
|
||||||
|
DrawPluginInfo();
|
||||||
|
DrawSectionHeader("Brand");
|
||||||
|
DrawBrand();
|
||||||
|
DrawSectionHeader("Links");
|
||||||
|
DrawLinks();
|
||||||
|
DrawSectionHeader("Credits");
|
||||||
|
DrawCredits();
|
||||||
|
DrawSectionHeader("License");
|
||||||
|
DrawLicense();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dalamud.Bindings.ImGui does not expose ImGui.SeparatorText, so we use
|
||||||
|
// the Separator + TextUnformatted idiom the rest of the codebase uses.
|
||||||
|
private static void DrawSectionHeader(string title)
|
||||||
|
{
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.Separator();
|
||||||
|
ImGui.Spacing();
|
||||||
|
ImGui.TextUnformatted(title);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawPluginInfo()
|
||||||
|
{
|
||||||
|
var version = Assembly.GetExecutingAssembly().GetName().Version?.ToString() ?? "unknown";
|
||||||
|
ImGui.TextUnformatted("HellionChat");
|
||||||
|
// Schema version pulled from Configuration.LatestVersion (single source of
|
||||||
|
// truth) so future schema bumps don't have to touch this string.
|
||||||
|
ImGui.TextDisabled($"Version {version} · Schema v{Configuration.LatestVersion}");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawBrand()
|
||||||
|
{
|
||||||
|
using (_fonts.FontAwesome.Push())
|
||||||
|
{
|
||||||
|
// ImGui's PushStyleColor uint API is ABGR-native. 0xFF0C41C2u packs
|
||||||
|
// as A=FF B=0C G=41 R=C2 → RGB #C2410C (Forge-Bronze). No swap needed
|
||||||
|
// because the literal is already ABGR; theme-sourced uints from
|
||||||
|
// ThemeColors.* (RGBA) would need ColourUtil.RgbaToAbgr first.
|
||||||
|
ImGui.PushStyleColor(ImGuiCol.Text, 0xFF0C41C2u);
|
||||||
|
ImGui.TextUnformatted(FontAwesomeIcon.Hammer.ToIconString());
|
||||||
|
ImGui.PopStyleColor();
|
||||||
|
}
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.TextUnformatted("by Hellion Online Media");
|
||||||
|
ImGui.TextDisabled("Hellion Forge — Modding Division");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawLinks()
|
||||||
|
{
|
||||||
|
DrawLinkButton("Discord (Hellion Forge)", BrandingLinks.HellionForgeDiscordInvite);
|
||||||
|
DrawLinkButton("Gitea repository", BrandingLinks.HellionChatRepo);
|
||||||
|
DrawLinkButton("Custom repo manifest", BrandingLinks.HellionChatCustomRepoManifest);
|
||||||
|
}
|
||||||
|
|
||||||
|
// URLs in v1.7.0 are exclusively hardcoded BrandingLinks.* constants —
|
||||||
|
// Process.Start with UseShellExecute=true is safe under that constraint.
|
||||||
|
// If a future cycle ever feeds user-supplied URLs here, add an https/http
|
||||||
|
// allow-list filter via Uri.TryCreate before Process.Start; without it
|
||||||
|
// UseShellExecute would happily launch file:// or shell-protocol handlers.
|
||||||
|
private void DrawLinkButton(string label, string url)
|
||||||
|
{
|
||||||
|
if (ImGui.Button(label))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Process.Start(new ProcessStartInfo(url) { UseShellExecute = true });
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogWarning(ex, "Could not open {Url}, copying to clipboard instead", url);
|
||||||
|
ImGui.SetClipboardText(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.SmallButton($"Copy##{url}"))
|
||||||
|
{
|
||||||
|
ImGui.SetClipboardText(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawCredits()
|
||||||
|
{
|
||||||
|
ImGui.BulletText("ChatTwo — original maintainer Anna Clemens, GPL-3.0");
|
||||||
|
ImGui.BulletText("Dalamud — goatcorp, AGPL-3.0");
|
||||||
|
ImGui.BulletText("ImGui — Omar Cornut, MIT");
|
||||||
|
ImGui.BulletText("FontAwesome — Fonticons, OFL-1.1");
|
||||||
|
ImGui.BulletText("Inter — rsms, OFL-1.1");
|
||||||
|
ImGui.BulletText("NotoSansCJK — Google, OFL-1.1");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void DrawLicense()
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("GPL-3.0-or-later");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ internal sealed class SettingsWindow : Window
|
|||||||
private readonly WindowTab _window;
|
private readonly WindowTab _window;
|
||||||
private readonly ChannelsTab _channels;
|
private readonly ChannelsTab _channels;
|
||||||
private readonly DataPrivacyTab _dataPrivacy;
|
private readonly DataPrivacyTab _dataPrivacy;
|
||||||
|
private readonly AboutTab _about;
|
||||||
|
|
||||||
public SettingsWindow(
|
public SettingsWindow(
|
||||||
Plugin plugin,
|
Plugin plugin,
|
||||||
@@ -39,6 +40,7 @@ internal sealed class SettingsWindow : Window
|
|||||||
WindowTab window,
|
WindowTab window,
|
||||||
ChannelsTab channels,
|
ChannelsTab channels,
|
||||||
DataPrivacyTab dataPrivacy,
|
DataPrivacyTab dataPrivacy,
|
||||||
|
AboutTab about,
|
||||||
ILoggerFactory loggerFactory
|
ILoggerFactory loggerFactory
|
||||||
)
|
)
|
||||||
: base($"{Language.Settings_Title.Format(Plugin.PluginName)}###chat2-settings")
|
: base($"{Language.Settings_Title.Format(Plugin.PluginName)}###chat2-settings")
|
||||||
@@ -55,6 +57,7 @@ internal sealed class SettingsWindow : Window
|
|||||||
_window = window;
|
_window = window;
|
||||||
_channels = channels;
|
_channels = channels;
|
||||||
_dataPrivacy = dataPrivacy;
|
_dataPrivacy = dataPrivacy;
|
||||||
|
_about = about;
|
||||||
_ = loggerFactory;
|
_ = loggerFactory;
|
||||||
|
|
||||||
Size = new Vector2(720, 540);
|
Size = new Vector2(720, 540);
|
||||||
@@ -98,6 +101,9 @@ internal sealed class SettingsWindow : Window
|
|||||||
case "data-privacy":
|
case "data-privacy":
|
||||||
_dataPrivacy.Draw();
|
_dataPrivacy.Draw();
|
||||||
break;
|
break;
|
||||||
|
case "about":
|
||||||
|
_about.Draw();
|
||||||
|
break;
|
||||||
case "appearance":
|
case "appearance":
|
||||||
_appearance.Draw();
|
_appearance.Draw();
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user