using System; using System.Globalization; using System.Linq; using System.Numerics; using Dalamud.Bindings.ImGui; using Dalamud.Interface; using Dalamud.Interface.Utility.Raii; using Questionable.Data; using Questionable.Model.Changelog; namespace Questionable.Windows.ChangelogComponents; internal sealed class ChangelogEntryComponent { private readonly Configuration _configuration; private readonly int _windowOpenCount; private readonly float _animationTime; public ChangelogEntryComponent(Configuration configuration, int windowOpenCount, float animationTime) { _configuration = configuration; _windowOpenCount = windowOpenCount; _animationTime = animationTime; } public void Draw(ChangelogEntry changelog, bool isLatest, bool hasSetInitialState) { bool isNew = changelog.IsNewVersion(_configuration.LastViewedChangelogVersion, ChangelogData.Changelogs); ImGui.GetWindowDrawList(); string text = changelog.ReleaseDate.ToString("MMMM dd, yyyy", CultureInfo.InvariantCulture); if (!hasSetInitialState) { ImGui.SetNextItemOpen(isLatest, ImGuiCond.Always); } string text2 = "v" + changelog.Version; float fontSize = ImGui.GetFontSize(); float num = fontSize; Vector2 versionSize; using (ImRaii.PushFont(UiBuilder.MonoFont)) { versionSize = ImGui.CalcTextSize(text2); } Vector2 dateSize = ImGui.CalcTextSize(text); float scaledIconFontSize = fontSize * 0.85f; float x = ImGui.GetContentRegionAvail().X; Vector2 cursorPos = ImGui.GetCursorPos(); Vector2 cursorScreenPos = ImGui.GetCursorScreenPos(); ImU8String label = new ImU8String(19, 2); label.AppendLiteral("###header_"); label.AppendFormatted(changelog.Version); label.AppendLiteral("_changes_"); label.AppendFormatted(_windowOpenCount); bool num2 = ImGui.CollapsingHeader(label); Vector2 cursorPos2 = ImGui.GetCursorPos(); float verticalOffset = (cursorPos2.Y - cursorPos.Y - num) * 0.5f - 1f; DrawVersionText(text2, versionSize, cursorPos, verticalOffset); DrawNewBadge(isNew, cursorScreenPos, x); DrawDateWithIcon(text, dateSize, scaledIconFontSize, cursorScreenPos, cursorPos, x, verticalOffset, fontSize); ImGui.SetCursorPos(cursorPos2); if (num2) { DrawChangelogContent(changelog); } } private static void DrawVersionText(string versionText, Vector2 versionSize, Vector2 headerStartPos, float verticalOffset) { float x = headerStartPos.X + ImGui.GetStyle().FramePadding.X * 2f + 20f; using (ImRaii.PushFont(UiBuilder.MonoFont)) { ImGui.SetCursorPos(new Vector2(x, headerStartPos.Y + verticalOffset)); ImGui.TextColored(in UiThemeUtils.PrimaryTextColor, versionText); } } private void DrawNewBadge(bool isNew, Vector2 headerStartScreenPos, float availableWidth) { if (isNew) { float num = 2.5f; float w = (MathF.Sin(_animationTime * num) + 1f) * 0.5f * 0.15f; float frameHeight = ImGui.GetFrameHeight(); float frameRounding = ImGui.GetStyle().FrameRounding; ImGui.GetWindowDrawList().AddRectFilled(headerStartScreenPos, headerStartScreenPos + new Vector2(availableWidth, frameHeight), ImGui.ColorConvertFloat4ToU32(new Vector4(0.5f, 1f, 0.6f, w)), frameRounding); } } private static void DrawDateWithIcon(string dateText, Vector2 dateSize, float scaledIconFontSize, Vector2 headerStartScreenPos, Vector2 headerStartPos, float availableWidth, float verticalOffset, float defaultFontSize) { string text = FontAwesomeIcon.Calendar.ToIconString(); Vector2 vector; using (ImRaii.PushFont(UiBuilder.IconFont)) { vector = ImGui.CalcTextSize(text); } float num = vector.X * (scaledIconFontSize / defaultFontSize); float num2 = num + 4f + dateSize.X; float num3 = availableWidth - num2 - 12f; Vector2 pos = headerStartScreenPos + new Vector2(num3, verticalOffset); ImGui.GetWindowDrawList().AddText(UiBuilder.IconFont, scaledIconFontSize, pos, ImGui.ColorConvertFloat4ToU32(UiThemeUtils.DimTextColor), text); ImGui.SetCursorPos(new Vector2(num3 + num + 4f, headerStartPos.Y + verticalOffset)); ImGui.TextColored(in UiThemeUtils.PrimaryTextColor, dateText); } private static void DrawChangelogContent(ChangelogEntry changelog) { IOrderedEnumerable> orderedEnumerable = from x in changelog.Changes group x by x.Category into g orderby g.Key select g; (Vector2 ContentStartPos, float AvailableWidth, ImDrawListPtr DrawList) tuple = UiThemeUtils.BeginCard(); Vector2 item = tuple.ContentStartPos; float item2 = tuple.AvailableWidth; ImDrawListPtr item3 = tuple.DrawList; float cursorPosX = ImGui.GetCursorPosX(); bool flag = true; foreach (IGrouping item4 in orderedEnumerable) { if (!flag) { ImGui.Spacing(); } ChangelogCategoryComponent.DrawCategoryGroup(item4.Key, item4.ToList(), cursorPosX); flag = false; } UiThemeUtils.EndCard(item, item2, item3); } }