feat(PluginInstaller): add Dalamud core changelogs

This commit is contained in:
goaaats 2022-02-03 21:52:28 +01:00
parent cf9e6d3969
commit 2dd7e73bae
No known key found for this signature in database
GPG key ID: 49E2AA8C6A76498B
9 changed files with 275 additions and 27 deletions

View file

@ -14,6 +14,7 @@ using Dalamud.Game.Gui;
using Dalamud.Game.Internal; using Dalamud.Game.Internal;
using Dalamud.Interface.Internal.ManagedAsserts; using Dalamud.Interface.Internal.ManagedAsserts;
using Dalamud.Interface.Internal.Windows; using Dalamud.Interface.Internal.Windows;
using Dalamud.Interface.Internal.Windows.PluginInstaller;
using Dalamud.Interface.Internal.Windows.SelfTest; using Dalamud.Interface.Internal.Windows.SelfTest;
using Dalamud.Interface.Internal.Windows.StyleEditor; using Dalamud.Interface.Internal.Windows.StyleEditor;
using Dalamud.Interface.Style; using Dalamud.Interface.Style;

View file

@ -64,9 +64,10 @@ namespace Dalamud.Interface.Internal.Windows
this.InstalledIcon = interfaceManager.LoadImage(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "installedIcon.png"))!; this.InstalledIcon = interfaceManager.LoadImage(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "installedIcon.png"))!;
this.ThirdIcon = interfaceManager.LoadImage(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "thirdIcon.png"))!; this.ThirdIcon = interfaceManager.LoadImage(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "thirdIcon.png"))!;
this.ThirdInstalledIcon = interfaceManager.LoadImage(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "thirdInstalledIcon.png"))!; this.ThirdInstalledIcon = interfaceManager.LoadImage(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "thirdInstalledIcon.png"))!;
this.CorePluginIcon = interfaceManager.LoadImage(Path.Combine(dalamud.AssetDirectory.FullName, "UIRes", "tsmLogo.png"))!;
if (this.DefaultIcon == null || this.TroubleIcon == null || this.UpdateIcon == null || this.InstalledIcon == null || if (this.DefaultIcon == null || this.TroubleIcon == null || this.UpdateIcon == null || this.InstalledIcon == null ||
this.ThirdIcon == null || this.ThirdInstalledIcon == null) this.ThirdIcon == null || this.ThirdInstalledIcon == null || this.CorePluginIcon == null)
{ {
throw new Exception("Plugin overlay images could not be loaded."); throw new Exception("Plugin overlay images could not be loaded.");
} }
@ -105,6 +106,11 @@ namespace Dalamud.Interface.Internal.Windows
/// </summary> /// </summary>
public TextureWrap ThirdInstalledIcon { get; } public TextureWrap ThirdInstalledIcon { get; }
/// <summary>
/// Gets the core plugin icon.
/// </summary>
public TextureWrap CorePluginIcon { get; }
/// <inheritdoc/> /// <inheritdoc/>
public void Dispose() public void Dispose()
{ {
@ -114,6 +120,7 @@ namespace Dalamud.Interface.Internal.Windows
this.InstalledIcon?.Dispose(); this.InstalledIcon?.Dispose();
this.ThirdIcon?.Dispose(); this.ThirdIcon?.Dispose();
this.ThirdInstalledIcon?.Dispose(); this.ThirdInstalledIcon?.Dispose();
this.CorePluginIcon?.Dispose();
this.downloadToken?.Cancel(); this.downloadToken?.Cancel();

View file

@ -0,0 +1,52 @@
using System;
using System.Collections.Generic;
namespace Dalamud.Interface.Internal.Windows.PluginInstaller
{
/// <summary>
/// Class representing a Dalamud changelog.
/// </summary>
internal class DalamudChangelog
{
/// <summary>
/// Gets the date of the version.
/// </summary>
public DateTime Date { get; init; }
/// <summary>
/// Gets the relevant version number.
/// </summary>
public string Version { get; init; }
/// <summary>
/// Gets the list of changes.
/// </summary>
public List<DalamudChangelogChange> Changes { get; init; }
/// <summary>
/// Class representing the relevant changes.
/// </summary>
public class DalamudChangelogChange
{
/// <summary>
/// Gets the commit message.
/// </summary>
public string Message { get; init; }
/// <summary>
/// Gets the commit author.
/// </summary>
public string Author { get; init; }
/// <summary>
/// Gets the commit reference SHA.
/// </summary>
public string Sha { get; init; }
/// <summary>
/// Gets the commit datetime.
/// </summary>
public DateTime Date { get; init; }
}
}
}

View file

@ -0,0 +1,54 @@
using System;
using ImGuiScene;
namespace Dalamud.Interface.Internal.Windows.PluginInstaller
{
/// <summary>
/// Class representing a Dalamud changelog.
/// </summary>
internal class DalamudChangelogEntry : IChangelogEntry
{
private readonly DalamudChangelog changelog;
/// <summary>
/// Initializes a new instance of the <see cref="DalamudChangelogEntry"/> class.
/// </summary>
/// <param name="changelog">The changelog.</param>
/// <param name="icon">The icon.</param>
public DalamudChangelogEntry(DalamudChangelog changelog, TextureWrap icon)
{
this.changelog = changelog;
this.Icon = icon;
var changelogText = string.Empty;
for (var i = 0; i < changelog.Changes.Count; i++)
{
var change = changelog.Changes[i];
changelogText += $"{change.Message} (by {change.Author})";
if (i < changelog.Changes.Count - 1)
{
changelogText += Environment.NewLine;
}
}
this.Text = changelogText;
}
/// <inheritdoc/>
public string Title => "Dalamud Core";
/// <inheritdoc/>
public string Version => this.changelog.Version;
/// <inheritdoc/>
public string Text { get; init; }
/// <inheritdoc/>
public TextureWrap Icon { get; init; }
/// <inheritdoc/>
public DateTime Date => this.changelog.Date;
}
}

View file

@ -0,0 +1,38 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
namespace Dalamud.Interface.Internal.Windows.PluginInstaller
{
/// <summary>
/// Class responsible for managing Dalamud changelogs.
/// </summary>
internal class DalamudChangelogManager : IDisposable
{
private const string ChangelogUrl = "https://kamori.goats.dev/Plugin/CoreChangelog";
private readonly HttpClient client = new();
/// <summary>
/// Gets a list of all available changelogs.
/// </summary>
public IReadOnlyList<DalamudChangelog>? Changelogs { get; private set; }
/// <summary>
/// Reload the changelog list.
/// </summary>
/// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
public async Task ReloadChangelogAsync()
{
this.Changelogs = await this.client.GetFromJsonAsync<List<DalamudChangelog>>(ChangelogUrl);
}
/// <inheritdoc/>
public void Dispose()
{
this.client.Dispose();
}
}
}

View file

@ -0,0 +1,37 @@
using System;
using ImGuiScene;
namespace Dalamud.Interface.Internal.Windows.PluginInstaller
{
/// <summary>
/// Class representing a changelog entry.
/// </summary>
internal interface IChangelogEntry
{
/// <summary>
/// Gets the title of the entry.
/// </summary>
string Title { get; }
/// <summary>
/// Gets the version this entry applies to.
/// </summary>
string Version { get; }
/// <summary>
/// Gets the text of the entry.
/// </summary>
string Text { get; }
/// <summary>
/// Gets the icon of the entry.
/// </summary>
TextureWrap Icon { get; }
/// <summary>
/// Gets the date of the entry.
/// </summary>
DateTime Date { get; }
}
}

View file

@ -0,0 +1,52 @@
using System;
using Dalamud.Plugin.Internal;
using Dalamud.Utility;
using ImGuiScene;
namespace Dalamud.Interface.Internal.Windows.PluginInstaller
{
/// <summary>
/// Class representing a plugin changelog.
/// </summary>
internal class PluginChangelogEntry : IChangelogEntry
{
private readonly LocalPlugin plugin;
/// <summary>
/// Initializes a new instance of the <see cref="PluginChangelogEntry"/> class.
/// </summary>
/// <param name="plugin">The plugin manifest.</param>
/// <param name="icon">The icon.</param>
public PluginChangelogEntry(LocalPlugin plugin, TextureWrap icon)
{
this.plugin = plugin;
this.Icon = icon;
if (plugin.Manifest.Changelog.IsNullOrEmpty())
throw new ArgumentException("Manifest has no changelog.");
var version = plugin.AssemblyName?.Version;
version ??= plugin.Manifest.Testing
? plugin.Manifest.TestingAssemblyVersion
: plugin.Manifest.AssemblyVersion;
this.Version = version!.ToString();
}
/// <inheritdoc/>
public string Title => this.plugin.Manifest.Name;
/// <inheritdoc/>
public string Version { get; init; }
/// <inheritdoc/>
public string Text => this.plugin.Manifest.Changelog!;
/// <inheritdoc/>
public TextureWrap Icon { get; init; }
/// <inheritdoc/>
public DateTime Date => DateTimeOffset.FromUnixTimeSeconds(this.plugin.Manifest.LastUpdate).DateTime;
}
}

View file

@ -5,6 +5,7 @@ using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Net.Http;
using System.Numerics; using System.Numerics;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -25,7 +26,7 @@ using Dalamud.Utility;
using ImGuiNET; using ImGuiNET;
using ImGuiScene; using ImGuiScene;
namespace Dalamud.Interface.Internal.Windows namespace Dalamud.Interface.Internal.Windows.PluginInstaller
{ {
/// <summary> /// <summary>
/// Class responsible for drawing the plugin installer. /// Class responsible for drawing the plugin installer.
@ -39,6 +40,9 @@ namespace Dalamud.Interface.Internal.Windows
private readonly PluginCategoryManager categoryManager = new(); private readonly PluginCategoryManager categoryManager = new();
private readonly PluginImageCache imageCache = new(); private readonly PluginImageCache imageCache = new();
private readonly DalamudChangelogManager dalamudChangelogManager = new();
private readonly List<int> openPluginCollapsibles = new();
#region Image Tester State #region Image Tester State
@ -81,8 +85,6 @@ namespace Dalamud.Interface.Internal.Windows
private OperationStatus installStatus = OperationStatus.Idle; private OperationStatus installStatus = OperationStatus.Idle;
private OperationStatus updateStatus = OperationStatus.Idle; private OperationStatus updateStatus = OperationStatus.Idle;
private List<int> openPluginCollapsibles = new();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PluginInstallerWindow"/> class. /// Initializes a new instance of the <see cref="PluginInstallerWindow"/> class.
/// </summary> /// </summary>
@ -150,6 +152,7 @@ namespace Dalamud.Interface.Internal.Windows
var pluginManager = Service<PluginManager>.Get(); var pluginManager = Service<PluginManager>.Get();
_ = pluginManager.ReloadPluginMastersAsync(); _ = pluginManager.ReloadPluginMastersAsync();
_ = this.dalamudChangelogManager.ReloadChangelogAsync();
this.searchText = string.Empty; this.searchText = string.Empty;
this.sortKind = PluginSortKind.Alphabetical; this.sortKind = PluginSortKind.Alphabetical;
@ -518,13 +521,28 @@ namespace Dalamud.Interface.Internal.Windows
return; return;
} }
var filteredList = this.pluginListInstalled var pluginChangelogs = this.pluginListInstalled
.Where(plugin => !this.IsManifestFiltered(plugin.Manifest) .Where(plugin => !this.IsManifestFiltered(plugin.Manifest)
&& !plugin.Manifest.Changelog.IsNullOrEmpty()) && !plugin.Manifest.Changelog.IsNullOrEmpty())
.OrderByDescending(plugin => plugin.Manifest.LastUpdate) .Select(x =>
.ToList(); {
var iconTex = this.imageCache.DefaultIcon;
var hasIcon = this.imageCache.TryGetIcon(x, x.Manifest, x.Manifest.IsThirdParty, out var cachedIconTex);
if (hasIcon && cachedIconTex != null)
{
iconTex = cachedIconTex;
}
if (!filteredList.Any()) var changelog = new PluginChangelogEntry(x, iconTex);
return (IChangelogEntry)changelog;
});
var changelogs = (this.dalamudChangelogManager.Changelogs != null
? pluginChangelogs
.Concat(this.dalamudChangelogManager.Changelogs.Select(x => new DalamudChangelogEntry(x, this.imageCache.CorePluginIcon)))
: pluginChangelogs).OrderByDescending(x => x.Date).ToList();
if (!changelogs.Any())
{ {
ImGui.TextColored( ImGui.TextColored(
ImGuiColors.DalamudGrey2, ImGuiColors.DalamudGrey2,
@ -535,9 +553,9 @@ namespace Dalamud.Interface.Internal.Windows
return; return;
} }
foreach (var plugin in filteredList) foreach (var logEntry in changelogs)
{ {
this.DrawChangelog(plugin); this.DrawChangelog(logEntry);
} }
} }
@ -1202,41 +1220,30 @@ namespace Dalamud.Interface.Internal.Windows
return isOpen; return isOpen;
} }
private void DrawChangelog(LocalPlugin plugin) private void DrawChangelog(IChangelogEntry log)
{ {
ImGui.Separator(); ImGui.Separator();
var startCursor = ImGui.GetCursorPos(); var startCursor = ImGui.GetCursorPos();
var iconTex = this.imageCache.DefaultIcon;
var hasIcon = this.imageCache.TryGetIcon(plugin, plugin.Manifest, plugin.Manifest.IsThirdParty, out var cachedIconTex);
if (hasIcon && cachedIconTex != null)
{
iconTex = cachedIconTex;
}
var iconSize = ImGuiHelpers.ScaledVector2(64, 64); var iconSize = ImGuiHelpers.ScaledVector2(64, 64);
ImGui.Image(iconTex.ImGuiHandle, iconSize); ImGui.Image(log.Icon.ImGuiHandle, iconSize);
ImGui.SameLine(); ImGui.SameLine();
ImGuiHelpers.ScaledDummy(5); ImGuiHelpers.ScaledDummy(5);
ImGui.SameLine(); ImGui.SameLine();
var cursor = ImGui.GetCursorPos(); var cursor = ImGui.GetCursorPos();
ImGui.Text(plugin.Name); ImGui.Text(log.Title);
ImGui.SameLine(); ImGui.SameLine();
var version = plugin.AssemblyName?.Version; ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{log.Version}");
version ??= plugin.Manifest.Testing
? plugin.Manifest.TestingAssemblyVersion
: plugin.Manifest.AssemblyVersion;
ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{version}");
cursor.Y += ImGui.GetTextLineHeightWithSpacing(); cursor.Y += ImGui.GetTextLineHeightWithSpacing();
ImGui.SetCursorPos(cursor); ImGui.SetCursorPos(cursor);
ImGui.TextWrapped(plugin.Manifest.Changelog); ImGui.TextWrapped(log.Text);
var endCursor = ImGui.GetCursorPos(); var endCursor = ImGui.GetCursorPos();

View file

@ -15,7 +15,7 @@ namespace Dalamud.Plugin.Internal
/// </summary> /// </summary>
internal class PluginRepository internal class PluginRepository
{ {
private const string DalamudPluginsMasterUrl = "https://kamori.goats.dev/Plugin/GetPluginMaster"; private const string DalamudPluginsMasterUrl = "https://kamori.goats.dev/Plugin/PluginMaster";
private static readonly ModuleLog Log = new("PLUGINR"); private static readonly ModuleLog Log = new("PLUGINR");