mirror of
https://github.com/goatcorp/Dalamud.git
synced 2025-12-12 18:27:23 +01:00
feat(PluginInstaller): add Dalamud core changelogs
This commit is contained in:
parent
cf9e6d3969
commit
2dd7e73bae
9 changed files with 275 additions and 27 deletions
|
|
@ -14,6 +14,7 @@ using Dalamud.Game.Gui;
|
|||
using Dalamud.Game.Internal;
|
||||
using Dalamud.Interface.Internal.ManagedAsserts;
|
||||
using Dalamud.Interface.Internal.Windows;
|
||||
using Dalamud.Interface.Internal.Windows.PluginInstaller;
|
||||
using Dalamud.Interface.Internal.Windows.SelfTest;
|
||||
using Dalamud.Interface.Internal.Windows.StyleEditor;
|
||||
using Dalamud.Interface.Style;
|
||||
|
|
|
|||
|
|
@ -64,9 +64,10 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
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.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 ||
|
||||
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.");
|
||||
}
|
||||
|
|
@ -105,6 +106,11 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
/// </summary>
|
||||
public TextureWrap ThirdInstalledIcon { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the core plugin icon.
|
||||
/// </summary>
|
||||
public TextureWrap CorePluginIcon { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
@ -114,6 +120,7 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
this.InstalledIcon?.Dispose();
|
||||
this.ThirdIcon?.Dispose();
|
||||
this.ThirdInstalledIcon?.Dispose();
|
||||
this.CorePluginIcon?.Dispose();
|
||||
|
||||
this.downloadToken?.Cancel();
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
@ -5,6 +5,7 @@ using System.Diagnostics;
|
|||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Numerics;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
@ -25,7 +26,7 @@ using Dalamud.Utility;
|
|||
using ImGuiNET;
|
||||
using ImGuiScene;
|
||||
|
||||
namespace Dalamud.Interface.Internal.Windows
|
||||
namespace Dalamud.Interface.Internal.Windows.PluginInstaller
|
||||
{
|
||||
/// <summary>
|
||||
/// Class responsible for drawing the plugin installer.
|
||||
|
|
@ -39,6 +40,9 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
|
||||
private readonly PluginCategoryManager categoryManager = new();
|
||||
private readonly PluginImageCache imageCache = new();
|
||||
private readonly DalamudChangelogManager dalamudChangelogManager = new();
|
||||
|
||||
private readonly List<int> openPluginCollapsibles = new();
|
||||
|
||||
#region Image Tester State
|
||||
|
||||
|
|
@ -81,8 +85,6 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
private OperationStatus installStatus = OperationStatus.Idle;
|
||||
private OperationStatus updateStatus = OperationStatus.Idle;
|
||||
|
||||
private List<int> openPluginCollapsibles = new();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PluginInstallerWindow"/> class.
|
||||
/// </summary>
|
||||
|
|
@ -150,6 +152,7 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
var pluginManager = Service<PluginManager>.Get();
|
||||
|
||||
_ = pluginManager.ReloadPluginMastersAsync();
|
||||
_ = this.dalamudChangelogManager.ReloadChangelogAsync();
|
||||
|
||||
this.searchText = string.Empty;
|
||||
this.sortKind = PluginSortKind.Alphabetical;
|
||||
|
|
@ -518,13 +521,28 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
return;
|
||||
}
|
||||
|
||||
var filteredList = this.pluginListInstalled
|
||||
var pluginChangelogs = this.pluginListInstalled
|
||||
.Where(plugin => !this.IsManifestFiltered(plugin.Manifest)
|
||||
&& !plugin.Manifest.Changelog.IsNullOrEmpty())
|
||||
.OrderByDescending(plugin => plugin.Manifest.LastUpdate)
|
||||
.ToList();
|
||||
.Select(x =>
|
||||
{
|
||||
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(
|
||||
ImGuiColors.DalamudGrey2,
|
||||
|
|
@ -535,9 +553,9 @@ namespace Dalamud.Interface.Internal.Windows
|
|||
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;
|
||||
}
|
||||
|
||||
private void DrawChangelog(LocalPlugin plugin)
|
||||
private void DrawChangelog(IChangelogEntry log)
|
||||
{
|
||||
ImGui.Separator();
|
||||
|
||||
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);
|
||||
|
||||
ImGui.Image(iconTex.ImGuiHandle, iconSize);
|
||||
ImGui.Image(log.Icon.ImGuiHandle, iconSize);
|
||||
ImGui.SameLine();
|
||||
|
||||
ImGuiHelpers.ScaledDummy(5);
|
||||
|
||||
ImGui.SameLine();
|
||||
var cursor = ImGui.GetCursorPos();
|
||||
ImGui.Text(plugin.Name);
|
||||
ImGui.Text(log.Title);
|
||||
|
||||
ImGui.SameLine();
|
||||
var version = plugin.AssemblyName?.Version;
|
||||
version ??= plugin.Manifest.Testing
|
||||
? plugin.Manifest.TestingAssemblyVersion
|
||||
: plugin.Manifest.AssemblyVersion;
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{version}");
|
||||
ImGui.TextColored(ImGuiColors.DalamudGrey3, $" v{log.Version}");
|
||||
|
||||
cursor.Y += ImGui.GetTextLineHeightWithSpacing();
|
||||
ImGui.SetCursorPos(cursor);
|
||||
|
||||
ImGui.TextWrapped(plugin.Manifest.Changelog);
|
||||
ImGui.TextWrapped(log.Text);
|
||||
|
||||
var endCursor = ImGui.GetCursorPos();
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ namespace Dalamud.Plugin.Internal
|
|||
/// </summary>
|
||||
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");
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue