Implement some todos from #27
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
using System.Numerics;
|
||||
using ChatTwo.Util;
|
||||
using Dalamud.Interface.Colors;
|
||||
using Dalamud.Interface.Components;
|
||||
using Dalamud.Interface.ImGuiNotification;
|
||||
using Dalamud.Interface.ImGuiNotification.EventArgs;
|
||||
using Dalamud.Interface.Internal.Notifications;
|
||||
using Dalamud.Interface.Utility;
|
||||
using Dalamud.Interface.Utility.Raii;
|
||||
using Dalamud.Interface.Windowing;
|
||||
using ImGuiNET;
|
||||
|
||||
namespace ChatTwo.Ui;
|
||||
|
||||
internal class LegacyMessageImporterWindow : Window
|
||||
{
|
||||
private readonly Plugin Plugin;
|
||||
private readonly MessageStore _store;
|
||||
|
||||
private LegacyMessageImporterEligibility Eligibility { get; set; }
|
||||
private LegacyMessageImporter? Importer { get; set; }
|
||||
|
||||
internal LegacyMessageImporterWindow(Plugin plugin) : base("Chat 2 Legacy Importer###chat2-legacy-importer")
|
||||
{
|
||||
Plugin = plugin;
|
||||
|
||||
Flags = ImGuiWindowFlags.NoResize;
|
||||
Size = new Vector2(500, 400);
|
||||
|
||||
_store = plugin.MessageManager.Store;
|
||||
Eligibility = LegacyMessageImporterEligibility.CheckEligibility();
|
||||
LogAndNotify();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Importer?.Dispose();
|
||||
}
|
||||
|
||||
private void NotificationClicked(INotificationClickArgs args)
|
||||
{
|
||||
IsOpen = true;
|
||||
args.Notification.DismissNow();
|
||||
}
|
||||
|
||||
private void LogAndNotify()
|
||||
{
|
||||
Plugin.Log.Info($"[Migration] Checked migration eligibility: {Eligibility.Status} - '{Eligibility.AdditionalIneligibilityInfo}'");
|
||||
|
||||
switch (Eligibility.Status)
|
||||
{
|
||||
case LegacyMessageImporterEligibilityStatus.Eligible:
|
||||
{
|
||||
var notification = Plugin.Notification.AddNotification(new Notification
|
||||
{
|
||||
// The user needs to dismiss this for it to go away.
|
||||
Type = NotificationType.Info,
|
||||
InitialDuration = TimeSpan.FromHours(24),
|
||||
Title = "Chat2 Migration",
|
||||
Content = "Import messages from old database into new database?\nClick for more information.",
|
||||
Minimized = false,
|
||||
});
|
||||
|
||||
notification.Click += NotificationClicked;
|
||||
break;
|
||||
}
|
||||
|
||||
case LegacyMessageImporterEligibilityStatus.IneligibleLiteDbFailed:
|
||||
{
|
||||
var notification = Plugin.Notification.AddNotification(new Notification
|
||||
{
|
||||
Type = NotificationType.Warning,
|
||||
InitialDuration = TimeSpan.FromMinutes(1),
|
||||
Title = "Chat2 Migration",
|
||||
Content = "Migration is not possible because the old database could not be opened.\nClick for more information.",
|
||||
Minimized = false,
|
||||
});
|
||||
|
||||
notification.Click += NotificationClicked;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override void Draw()
|
||||
{
|
||||
if (Importer != null)
|
||||
{
|
||||
DrawImportStatus();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Eligibility.Status == LegacyMessageImporterEligibilityStatus.Eligible)
|
||||
DrawEligible();
|
||||
else
|
||||
DrawIneligible();
|
||||
}
|
||||
|
||||
private void DrawEligible()
|
||||
{
|
||||
ImGui.TextWrapped("Import database messages from legacy LiteDB database to SQLite database?");
|
||||
ImGui.Text($"Message count: {Eligibility.MessageCount:N0}");
|
||||
ImGui.Text($"Database size: {StringUtil.BytesToString(Eligibility.DatabaseSizeBytes)}");
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
var colorNormal = new Vector4(0.0f, 0.70f, 0.0f, 1.0f);
|
||||
var colorHovered = new Vector4(0.059f, 0.49f, 0.0f, 1.0f);
|
||||
using (ImRaii.PushColor(ImGuiCol.Button, colorNormal))
|
||||
using (ImRaii.PushColor(ImGuiCol.ButtonHovered, colorHovered))
|
||||
{
|
||||
if (ImGui.Button("Yes, import messages"))
|
||||
{
|
||||
// Next draw call will run DrawImportStatus().
|
||||
Importer = Eligibility.StartImport(_store, plugin: Plugin);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ImGui.SameLine();
|
||||
|
||||
if (ImGuiUtil.CtrlShiftButtonColored("No, do not import messages", "Ctrl+Shift: renames old database to avoid prompting again"))
|
||||
{
|
||||
Eligibility.RenameOldDatabase();
|
||||
IsOpen = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawIneligible()
|
||||
{
|
||||
ImGui.Text("Your legacy LiteDB database is not eligible for import:");
|
||||
switch (Eligibility.Status)
|
||||
{
|
||||
case LegacyMessageImporterEligibilityStatus.IneligibleOriginalDbNotExists:
|
||||
ImGui.Text("The old database could not be found.");
|
||||
break;
|
||||
case LegacyMessageImporterEligibilityStatus.IneligibleMigrationDbExists:
|
||||
ImGui.Text("The migration process was already started.");
|
||||
break;
|
||||
case LegacyMessageImporterEligibilityStatus.IneligibleLiteDbFailed:
|
||||
ImGui.Text("The old database could not be opened.");
|
||||
break;
|
||||
case LegacyMessageImporterEligibilityStatus.IneligibleNoMessages:
|
||||
ImGui.Text("The old database contains no messages.");
|
||||
break;
|
||||
case LegacyMessageImporterEligibilityStatus.Eligible:
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
}
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(Eligibility.AdditionalIneligibilityInfo))
|
||||
ImGui.Text(Eligibility.AdditionalIneligibilityInfo);
|
||||
|
||||
// LiteDB failures notify the user, so give them a chance to rename the
|
||||
// database to avoid prompting again.
|
||||
if (Eligibility.Status == LegacyMessageImporterEligibilityStatus.IneligibleLiteDbFailed)
|
||||
{
|
||||
if (ImGuiUtil.CtrlShiftButton("Rename old database", "Ctrl+Shift: rename old database to avoid import prompt in the future"))
|
||||
{
|
||||
if (Eligibility.RenameOldDatabase())
|
||||
WrapperUtil.AddNotification("Successfully renamed the old database.", NotificationType.Success);
|
||||
else
|
||||
WrapperUtil.AddNotification("Rename failed, please check /xllog for more information.", NotificationType.Error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawImportStatus()
|
||||
{
|
||||
if (Importer == null)
|
||||
return;
|
||||
|
||||
if (Importer.ImportComplete != null)
|
||||
{
|
||||
ImGui.TextUnformatted($"Completed migration in {Duration(Importer.ImportStart, Importer.ImportComplete.Value):g}");
|
||||
ImGui.TextUnformatted($"Successfully imported: {Importer.SuccessfulMessages} messages");
|
||||
ImGui.TextUnformatted($"Failed to import: {Importer.FailedMessages} messages");
|
||||
ImGui.TextUnformatted($"Unaccounted for: {Importer.RemainingMessages}");
|
||||
ImGui.TextUnformatted("See logs for more details: /xllog");
|
||||
|
||||
ImGui.Spacing();
|
||||
|
||||
if (ImGui.Button("Finish"))
|
||||
IsOpen = false;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
ImGui.TextUnformatted($"Importing messages ... {Importer.Progress:P}");
|
||||
ImGuiHelpers.ScaledDummy(10.0f);
|
||||
|
||||
ImGui.TextUnformatted($"Duration: {Duration(Importer.ImportStart, Environment.TickCount64):g}");
|
||||
ImGui.TextUnformatted($"Progress: {Importer.ProcessedMessages}/{Importer.ImportCount} messages ({Importer.FailedMessages} failed)");
|
||||
ImGuiHelpers.ScaledDummy(10.0f);
|
||||
|
||||
var width = ImGui.GetContentRegionAvail().X / 2;
|
||||
ImGui.AlignTextToFramePadding();
|
||||
ImGui.TextUnformatted("Import speed:");
|
||||
ImGui.SameLine();
|
||||
ImGui.SetNextItemWidth(width);
|
||||
ImGui.SliderInt("##speedSlider", ref Importer.MaxMessageRate, 1, 10000, "%d m/sec", ImGuiSliderFlags.AlwaysClamp);
|
||||
ImGui.TextUnformatted($"Current speed: {Importer.CurrentMessageRate:N0} m/sec");
|
||||
ImGui.TextUnformatted($"Estimated time remaining: {Importer.EstimatedTimeRemaining:g}");
|
||||
ImGui.TextUnformatted("See logs for more details: /xllog");
|
||||
ImGuiHelpers.ScaledDummy(10.0f);
|
||||
|
||||
ImGui.ProgressBar(Importer.Progress, new Vector2(-1, 0), $"{Importer.Progress:P}");
|
||||
ImGui.Spacing();
|
||||
|
||||
if (ImGuiUtil.CtrlShiftButton("Cancel import", "Ctrl+Shift: cancel import and close window"))
|
||||
{
|
||||
Task.Run(async () =>
|
||||
{
|
||||
await Importer.DisposeAsync();
|
||||
Importer = null;
|
||||
Eligibility = LegacyMessageImporterEligibility.CheckEligibility();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static TimeSpan Duration(long startTicks, long endTicks)
|
||||
{
|
||||
return endTicks < startTicks ? TimeSpan.Zero : TimeSpan.FromMilliseconds(endTicks - startTicks);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user