feat: warn when enabling a plugin with a pending update

This commit is contained in:
goat 2022-08-21 18:05:40 +02:00
parent 3f76a70425
commit 4fd1f7a22f
No known key found for this signature in database
GPG key ID: 7773BB5B43BA52E5

View file

@ -45,7 +45,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
private readonly List<int> openPluginCollapsibles = new(); private readonly List<int> openPluginCollapsibles = new();
private readonly DateTime timeLoaded; private readonly DateTime timeLoaded;
#region Image Tester State #region Image Tester State
private string[] testerImagePaths = new string[5]; private string[] testerImagePaths = new string[5];
@ -64,6 +64,11 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
private string errorModalMessage = string.Empty; private string errorModalMessage = string.Empty;
private TaskCompletionSource? errorModalTaskCompletionSource; private TaskCompletionSource? errorModalTaskCompletionSource;
private bool updateModalDrawing = true;
private bool updateModalOnNextFrame = false;
private LocalPlugin? updateModalPlugin = null;
private TaskCompletionSource<bool>? updateModalTaskCompletionSource;
private bool feedbackModalDrawing = true; private bool feedbackModalDrawing = true;
private bool feedbackModalOnNextFrame = false; private bool feedbackModalOnNextFrame = false;
private bool feedbackModalOnNextFrameDontClear = false; private bool feedbackModalOnNextFrameDontClear = false;
@ -209,6 +214,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
this.DrawPluginCategories(); this.DrawPluginCategories();
this.DrawFooter(); this.DrawFooter();
this.DrawErrorModal(); this.DrawErrorModal();
this.DrawUpdateModal();
this.DrawFeedbackModal(); this.DrawFeedbackModal();
this.DrawProgressOverlay(); this.DrawProgressOverlay();
} }
@ -556,7 +562,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
if (ImGui.Button(Locs.ErrorModalButton_Ok, new Vector2(buttonWidth, 40))) if (ImGui.Button(Locs.ErrorModalButton_Ok, new Vector2(buttonWidth, 40)))
{ {
ImGui.CloseCurrentPopup(); ImGui.CloseCurrentPopup();
errorModalTaskCompletionSource?.SetResult(); this.errorModalTaskCompletionSource?.SetResult();
} }
ImGui.EndPopup(); ImGui.EndPopup();
@ -574,6 +580,50 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
} }
} }
private void DrawUpdateModal()
{
var modalTitle = Locs.UpdateModal_Title;
if (this.updateModalPlugin == null)
return;
if (ImGui.BeginPopupModal(modalTitle, ref this.updateModalDrawing, ImGuiWindowFlags.AlwaysAutoResize | ImGuiWindowFlags.NoScrollbar))
{
ImGui.Text(Locs.UpdateModal_UpdateAvailable(this.updateModalPlugin.Name));
ImGui.Spacing();
var buttonWidth = 120f;
ImGui.SetCursorPosX((ImGui.GetWindowWidth() - ((buttonWidth * 2) - (ImGui.GetStyle().ItemSpacing.Y * 2))) / 2);
if (ImGui.Button(Locs.UpdateModal_Yes, new Vector2(buttonWidth, 40)))
{
ImGui.CloseCurrentPopup();
this.updateModalTaskCompletionSource?.SetResult(true);
}
ImGui.SameLine();
if (ImGui.Button(Locs.UpdateModal_No, new Vector2(buttonWidth, 40)))
{
ImGui.CloseCurrentPopup();
this.updateModalTaskCompletionSource?.SetResult(false);
}
ImGui.EndPopup();
}
if (this.updateModalOnNextFrame)
{
// NOTE(goat): ImGui cannot open a modal if no window is focused, at the moment.
// If people click out of the installer into the game while a plugin is installing, we won't be able to show a modal if we don't grab focus.
ImGui.SetWindowFocus(this.WindowName);
ImGui.OpenPopup(modalTitle);
this.updateModalOnNextFrame = false;
this.updateModalDrawing = true;
}
}
private void DrawFeedbackModal() private void DrawFeedbackModal()
{ {
var modalTitle = Locs.FeedbackModal_Title; var modalTitle = Locs.FeedbackModal_Title;
@ -1879,7 +1929,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
} }
// Controls // Controls
this.DrawPluginControlButton(plugin); this.DrawPluginControlButton(plugin, availablePluginUpdate);
this.DrawDevPluginButtons(plugin); this.DrawDevPluginButtons(plugin);
this.DrawDeletePluginButton(plugin); this.DrawDeletePluginButton(plugin);
this.DrawVisitRepoUrlButton(plugin.Manifest.RepoUrl); this.DrawVisitRepoUrlButton(plugin.Manifest.RepoUrl);
@ -1966,7 +2016,7 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
} }
} }
private void DrawPluginControlButton(LocalPlugin plugin) private void DrawPluginControlButton(LocalPlugin plugin, AvailablePluginUpdate? availableUpdate)
{ {
var notifications = Service<NotificationManager>.Get(); var notifications = Service<NotificationManager>.Get();
var pluginManager = Service<PluginManager>.Get(); var pluginManager = Service<PluginManager>.Get();
@ -2038,13 +2088,14 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
} }
else else
{ {
this.enableDisableStatus = OperationStatus.InProgress; var enabler = new Task(() =>
this.loadingIndicatorKind = LoadingIndicatorKind.EnablingSingle;
Task.Run(() =>
{ {
this.enableDisableStatus = OperationStatus.InProgress;
this.loadingIndicatorKind = LoadingIndicatorKind.EnablingSingle;
var enableTask = Task.Run(() => plugin.Enable()) var enableTask = Task.Run(() => plugin.Enable())
.ContinueWith(this.DisplayErrorContinuation, Locs.ErrorModal_EnableFail(plugin.Name)); .ContinueWith(this.DisplayErrorContinuation,
Locs.ErrorModal_EnableFail(plugin.Name));
enableTask.Wait(); enableTask.Wait();
if (!enableTask.Result) if (!enableTask.Result)
@ -2054,7 +2105,8 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
} }
var loadTask = Task.Run(() => plugin.LoadAsync(PluginLoadReason.Installer)) var loadTask = Task.Run(() => plugin.LoadAsync(PluginLoadReason.Installer))
.ContinueWith(this.DisplayErrorContinuation, Locs.ErrorModal_LoadFail(plugin.Name)); .ContinueWith(this.DisplayErrorContinuation,
Locs.ErrorModal_LoadFail(plugin.Name));
loadTask.Wait(); loadTask.Wait();
this.enableDisableStatus = OperationStatus.Complete; this.enableDisableStatus = OperationStatus.Complete;
@ -2062,8 +2114,31 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
if (!loadTask.Result) if (!loadTask.Result)
return; return;
notifications.AddNotification(Locs.Notifications_PluginEnabled(plugin.Manifest.Name), Locs.Notifications_PluginEnabledTitle, NotificationType.Success); notifications.AddNotification(Locs.Notifications_PluginEnabled(plugin.Manifest.Name),
Locs.Notifications_PluginEnabledTitle,
NotificationType.Success);
}); });
if (availableUpdate != default)
{
this.ShowUpdateModal(plugin).ContinueWith(async t =>
{
var shouldUpdate = t.Result;
if (shouldUpdate)
{
await this.UpdateSinglePlugin(availableUpdate);
}
else
{
enabler.Start();
}
});
}
else
{
enabler.Start();
}
} }
} }
} }
@ -2080,31 +2155,31 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
} }
} }
private void DrawUpdateSinglePluginButton(AvailablePluginUpdate update) private async Task<bool> UpdateSinglePlugin(AvailablePluginUpdate update)
{ {
var pluginManager = Service<PluginManager>.Get(); var pluginManager = Service<PluginManager>.Get();
this.installStatus = OperationStatus.InProgress;
this.loadingIndicatorKind = LoadingIndicatorKind.UpdatingSingle;
return await Task.Run(async () => await pluginManager.UpdateSinglePluginAsync(update, true, false))
.ContinueWith(task =>
{
// There is no need to set as Complete for an individual plugin installation
this.installStatus = OperationStatus.Idle;
var errorMessage = Locs.ErrorModal_SingleUpdateFail(update.UpdateManifest.Name);
return this.DisplayErrorContinuation(task, errorMessage);
});
}
private void DrawUpdateSinglePluginButton(AvailablePluginUpdate update)
{
ImGui.SameLine(); ImGui.SameLine();
if (ImGuiComponents.IconButton(FontAwesomeIcon.Download)) if (ImGuiComponents.IconButton(FontAwesomeIcon.Download))
{ {
this.installStatus = OperationStatus.InProgress; Task.Run(() => this.UpdateSinglePlugin(update));
this.loadingIndicatorKind = LoadingIndicatorKind.UpdatingSingle;
Task.Run(async () => await pluginManager.UpdateSinglePluginAsync(update, true, false))
.ContinueWith(task =>
{
// There is no need to set as Complete for an individual plugin installation
this.installStatus = OperationStatus.Idle;
var errorMessage = Locs.ErrorModal_SingleUpdateFail(update.UpdateManifest.Name);
this.DisplayErrorContinuation(task, errorMessage);
if (!task.Result.WasUpdated)
{
this.ShowErrorModal(errorMessage);
}
});
} }
if (ImGui.IsItemHovered()) if (ImGui.IsItemHovered())
@ -2512,7 +2587,15 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
this.errorModalDrawing = true; this.errorModalDrawing = true;
this.errorModalOnNextFrame = true; this.errorModalOnNextFrame = true;
this.errorModalTaskCompletionSource = new TaskCompletionSource(); this.errorModalTaskCompletionSource = new TaskCompletionSource();
return this.errorModalTaskCompletionSource!.Task; return this.errorModalTaskCompletionSource.Task;
}
private Task<bool> ShowUpdateModal(LocalPlugin plugin)
{
this.updateModalOnNextFrame = true;
this.updateModalPlugin = plugin;
this.updateModalTaskCompletionSource = new TaskCompletionSource<bool>();
return this.updateModalTaskCompletionSource.Task;
} }
private void UpdateCategoriesOnSearchChange() private void UpdateCategoriesOnSearchChange()
@ -2755,6 +2838,18 @@ namespace Dalamud.Interface.Internal.Windows.PluginInstaller
#endregion #endregion
#region Update modal
public static string UpdateModal_Title => Loc.Localize("UpdateQuestionModal", "Update Available");
public static string UpdateModal_UpdateAvailable(string name) => Loc.Localize("UpdateModalUpdateAvailable", "An update for \"{0}\" is available.\nDo you want to update it before enabling?\nUpdates will fix bugs and incompatibilities, and may add new features.").Format(name);
public static string UpdateModal_Yes => Loc.Localize("UpdateModalYes", "Update plugin");
public static string UpdateModal_No => Loc.Localize("UpdateModalNo", "Just enable");
#endregion
#region Error modal #region Error modal
public static string ErrorModal_Title => Loc.Localize("InstallerError", "Installer Error"); public static string ErrorModal_Title => Loc.Localize("InstallerError", "Installer Error");