Merge pull request #15

feat: add database details section to settings
This commit is contained in:
Infi
2024-04-11 15:40:13 +02:00
committed by GitHub
7 changed files with 265 additions and 15 deletions
+90
View File
@@ -1634,6 +1634,33 @@ namespace ChatTwo.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Clear the message history database.
/// </summary>
internal static string Options_ClearDatabase_Button {
get {
return ResourceManager.GetString("Options_ClearDatabase_Button", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Successfully cleared the chat database.
/// </summary>
internal static string Options_ClearDatabase_Success {
get {
return ResourceManager.GetString("Options_ClearDatabase_Success", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Removes all message history. Cannot be restored. Hold Ctrl+Shift to click..
/// </summary>
internal static string Options_ClearDatabase_Tooltip {
get {
return ResourceManager.GetString("Options_ClearDatabase_Tooltip", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Replace consecutive duplicate messages with a counter appended to the first instance of the message..
/// </summary>
@@ -1688,6 +1715,69 @@ namespace ChatTwo.Resources {
}
}
/// <summary>
/// Looks up a localized string similar to Click to copy database directory path.
/// </summary>
internal static string Options_Database_Metadata_CopyConfigPath {
get {
return ResourceManager.GetString("Options_Database_Metadata_CopyConfigPath", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Copied database directory path to clipboard.
/// </summary>
internal static string Options_Database_Metadata_CopyConfigPathNotification {
get {
return ResourceManager.GetString("Options_Database_Metadata_CopyConfigPathNotification", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Database details:.
/// </summary>
internal static string Options_Database_Metadata_Heading {
get {
return ResourceManager.GetString("Options_Database_Metadata_Heading", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Log size: {0}.
/// </summary>
internal static string Options_Database_Metadata_LogSize {
get {
return ResourceManager.GetString("Options_Database_Metadata_LogSize", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Stored messages: {0:N0}/{1:N0}.
/// </summary>
internal static string Options_Database_Metadata_MessageCount {
get {
return ResourceManager.GetString("Options_Database_Metadata_MessageCount", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Path: {0}.
/// </summary>
internal static string Options_Database_Metadata_Path {
get {
return ResourceManager.GetString("Options_Database_Metadata_Path", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Size: {0}.
/// </summary>
internal static string Options_Database_Metadata_Size {
get {
return ResourceManager.GetString("Options_Database_Metadata_Size", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Database.
/// </summary>
+30
View File
@@ -952,4 +952,34 @@
<data name="Options_HideInLoadingScreens_Description" xml:space="preserve">
<value>Hide {0} during loading screens.</value>
</data>
<data name="Options_ClearDatabase_Button">
<value>Clear the message history database</value>
</data>
<data name="Options_ClearDatabase_Success">
<value>Successfully cleared the chat database</value>
</data>
<data name="Options_ClearDatabase_Tooltip">
<value>Removes all message history. Cannot be restored. Hold Ctrl+Shift to click.</value>
</data>
<data name="Options_Database_Metadata_CopyConfigPath">
<value>Click to copy database directory path</value>
</data>
<data name="Options_Database_Metadata_CopyConfigPathNotification">
<value>Copied database directory path to clipboard</value>
</data>
<data name="Options_Database_Metadata_Heading">
<value>Database details:</value>
</data>
<data name="Options_Database_Metadata_LogSize">
<value>Log size: {0}</value>
</data>
<data name="Options_Database_Metadata_MessageCount">
<value>Stored messages: {0:N0}/{1:N0}</value>
</data>
<data name="Options_Database_Metadata_Path">
<value>Path: {0}</value>
</data>
<data name="Options_Database_Metadata_Size">
<value>Size: {0}</value>
</data>
</root>
+32 -6
View File
@@ -140,9 +140,6 @@ internal class Store : IDisposable {
bson => DateTime.UnixEpoch.AddMilliseconds(bson.AsInt64)
);
Database = Connect();
Messages.EnsureIndex(msg => msg.Date);
Messages.EnsureIndex(msg => msg.SortCode);
Messages.EnsureIndex(msg => msg.ExtraChatChannel);
Plugin.ChatGui.ChatMessageUnhandled += ChatMessage;
Plugin.Framework.Update += GetMessageInfo;
@@ -159,17 +156,26 @@ internal class Store : IDisposable {
Database.Dispose();
}
private ILiteDatabase Connect() {
internal static string DatabasePath()
{
var dir = Plugin.Interface.ConfigDirectory;
dir.Create();
return Path.Join(dir.FullName, "chat.db");
}
var dbPath = Path.Join(dir.FullName, "chat.db");
private LiteDatabase Connect() {
var dbPath = DatabasePath();
var connection = Plugin.Config.SharedMode ? "shared" : "direct";
var connString = $"Filename='{dbPath}';Connection={connection}";
return new LiteDatabase(connString, BsonMapper.Global) {
var conn = new LiteDatabase(connString, BsonMapper.Global) {
CheckpointSize = 1_000,
Timeout = TimeSpan.FromSeconds(1),
};
var messages = conn.GetCollection<Message>("messages");
messages.EnsureIndex(msg => msg.Date);
messages.EnsureIndex(msg => msg.SortCode);
messages.EnsureIndex(msg => msg.ExtraChatChannel);
return conn;
}
internal void Reconnect() {
@@ -177,6 +183,26 @@ internal class Store : IDisposable {
Database = Connect();
}
internal void ClearDatabase()
{
Messages.DeleteAll();
Database.Rebuild();
}
internal static long DatabaseSize()
{
var dbPath = DatabasePath();
return !File.Exists(dbPath) ? 0 : new FileInfo(dbPath).Length;
}
internal static long DatabaseLogSize()
{
var dbLogPath = Path.Join(Plugin.Interface.ConfigDirectory.FullName, "chat-log.db");
return !File.Exists(dbLogPath) ? 0 : new FileInfo(dbLogPath).Length;
}
internal int MessageCount() => Messages.Count();
private void Logout() {
LastContentId = 0;
}
+1 -1
View File
@@ -35,7 +35,7 @@ public sealed class SettingsWindow : Window, IUiComponent
new Ui.SettingsTabs.Fonts(Mutable),
new ChatColours(Mutable, Plugin),
new Tabs(Plugin, Mutable),
new Database(Mutable, Plugin.Store),
new Database(Mutable, Plugin),
new Miscellaneous(Mutable),
new About(),
};
+84 -8
View File
@@ -1,22 +1,28 @@
using ChatTwo.Resources;
using ChatTwo.Util;
using Dalamud.Interface.Internal.Notifications;
using ImGuiNET;
namespace ChatTwo.Ui.SettingsTabs;
internal sealed class Database : ISettingsTab {
private Configuration Mutable { get; }
private Store Store { get; }
private Plugin Plugin { get; }
public string Name => Language.Options_Database_Tab + "###tabs-database";
internal Database(Configuration mutable, Store store) {
Store = store;
internal Database(Configuration mutable, Plugin plugin) {
Plugin = plugin;
Mutable = mutable;
}
private bool _showAdvanced;
private long _databaseLastRefreshTicks;
private long _databaseSize;
private long _databaseLogSize;
private int _databaseMessageCount;
public void Draw(bool changed) {
if (changed) {
_showAdvanced = ImGui.GetIO().KeyShift;
@@ -46,18 +52,88 @@ internal sealed class Database : ISettingsTab {
);
ImGuiUtil.WarningText(string.Format(Language.Options_SharedMode_Warning, Plugin.PluginName));
ImGui.Spacing();
ImGui.Separator();
ImGui.Spacing();
if (_showAdvanced && ImGui.TreeNodeEx(Language.Options_Database_Advanced)) {
ImGui.Text(Language.Options_Database_Metadata_Heading);
var style = ImGui.GetStyle();
ImGui.Indent(style.IndentSpacing);
// Refresh the database size and message count every 5 seconds to avoid
// constant stat calls and spamming the database.
if (_databaseLastRefreshTicks + 5 * 1000 < Environment.TickCount64)
{
_databaseSize = Store.DatabaseSize();
_databaseLogSize = Store.DatabaseLogSize();
_databaseMessageCount = Plugin.Store.MessageCount();
_databaseLastRefreshTicks = Environment.TickCount64;
}
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_Path, Store.DatabasePath()));
if (ImGui.IsItemClicked(ImGuiMouseButton.Left))
{
// Copy the directory path instead of the file path so people can
// paste it into their file explorer.
var path = Path.GetDirectoryName(Store.DatabasePath());
ImGui.SetClipboardText(path);
WrapperUtil.AddNotification(Language.Options_Database_Metadata_CopyConfigPathNotification, NotificationType.Info);
}
if (ImGui.IsItemHovered())
{
ImGui.SetMouseCursor(ImGuiMouseCursor.Hand);
ImGui.BeginTooltip();
ImGui.Text(Language.Options_Database_Metadata_CopyConfigPath);
ImGui.EndTooltip();
}
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_Size, StringUtil.BytesToString(_databaseSize)));
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text(_databaseSize.ToString("N0") + "B");
ImGui.EndTooltip();
}
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_LogSize, StringUtil.BytesToString(_databaseLogSize)));
if (ImGui.IsItemHovered())
{
ImGui.BeginTooltip();
ImGui.Text(_databaseLogSize.ToString("N0") + "B");
ImGui.EndTooltip();
}
ImGuiUtil.HelpText(string.Format(Language.Options_Database_Metadata_MessageCount, _databaseMessageCount, Store.MessagesLimit));
if (ImGuiUtil.CtrlShiftButton(Language.Options_ClearDatabase_Button, Language.Options_ClearDatabase_Tooltip))
{
Plugin.Log.Warning("Clearing database");
Plugin.Store.ClearDatabase();
foreach (var tab in Plugin.Config.Tabs)
{
tab.Clear();
}
// Refresh on next draw
_databaseLastRefreshTicks = 0;
WrapperUtil.AddNotification(Language.Options_ClearDatabase_Success, NotificationType.Info);
}
ImGui.Unindent(style.IndentSpacing);
ImGui.Spacing();
if (_showAdvanced && ImGui.TreeNodeEx(Language.Options_Database_Advanced))
{
ImGui.PushTextWrapPos();
ImGuiUtil.WarningText(Language.Options_Database_Advanced_Warning);
if (ImGui.Button("Checkpoint")) {
Store.Database.Checkpoint();
if (ImGuiUtil.CtrlShiftButton("Checkpoint", "Ctrl+Shift: Database.Checkpoint()"))
{
Plugin.Store.Database.Checkpoint();
}
if (ImGui.Button("Rebuild")) {
Store.Database.Rebuild();
if (ImGuiUtil.CtrlShiftButton("Rebuild", "Ctrl+Shift: Database.Rebuild()"))
{
Plugin.Store.Database.Rebuild();
}
ImGui.PopTextWrapPos();
+16
View File
@@ -234,6 +234,22 @@ internal static class ImGuiUtil {
return r;
}
internal static bool CtrlShiftButton(string label, string tooltip = "")
{
var io = ImGui.GetIO();
var ctrlShiftHeld = io.KeyCtrl && io.KeyShift;
if (!ctrlShiftHeld) ImGui.BeginDisabled();
var ret = ImGui.Button(label) && ctrlShiftHeld;
if (!ctrlShiftHeld) ImGui.EndDisabled();
if (!string.IsNullOrEmpty(tooltip) && ImGui.IsItemHovered(ImGuiHoveredFlags.AllowWhenDisabled)) {
ImGui.BeginTooltip();
ImGui.TextUnformatted(tooltip);
ImGui.EndTooltip();
}
return ret;
}
internal static bool TryToImGui(this VirtualKey key, out ImGuiKey result) {
result = key switch {
VirtualKey.NO_KEY => ImGuiKey.None,
+12
View File
@@ -10,4 +10,16 @@ internal static class StringUtil {
bytes[^1] = 0;
return bytes;
}
// Taken from https://stackoverflow.com/a/4975942
internal static String BytesToString(long byteCount) {
string[] suf = ["B", "KB", "MB", "GB", "TB", "PB", "EB"]; // Longs run out around EB
if (byteCount == 0)
return "0" + suf[0];
var bytes = Math.Abs(byteCount);
var place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
var num = Math.Round(bytes / Math.Pow(1024, place), 1);
return (Math.Sign(byteCount) * num).ToString("N0") + suf[place];
}
}