feat: add unread modes
This commit is contained in:
parent
388973a5b6
commit
756e984cf7
|
@ -5,7 +5,7 @@ namespace ChatTwo;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
internal class Configuration : IPluginConfiguration {
|
internal class Configuration : IPluginConfiguration {
|
||||||
public int Version { get; set; } = 1;
|
public int Version { get; set; } = 2;
|
||||||
|
|
||||||
public bool HideChat = true;
|
public bool HideChat = true;
|
||||||
public bool HideDuringCutscenes = true;
|
public bool HideDuringCutscenes = true;
|
||||||
|
@ -36,13 +36,45 @@ internal class Configuration : IPluginConfiguration {
|
||||||
this.ChatColours = other.ChatColours.ToDictionary(entry => entry.Key, entry => entry.Value);
|
this.ChatColours = other.ChatColours.ToDictionary(entry => entry.Key, entry => entry.Value);
|
||||||
this.Tabs = other.Tabs.Select(t => t.Clone()).ToList();
|
this.Tabs = other.Tabs.Select(t => t.Clone()).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Migrate() {
|
||||||
|
if (this.Version == 1) {
|
||||||
|
this.Version = 2;
|
||||||
|
|
||||||
|
foreach (var tab in this.Tabs) {
|
||||||
|
#pragma warning disable CS0618
|
||||||
|
tab.UnreadMode = tab.DisplayUnread ? UnreadMode.Unseen : UnreadMode.None;
|
||||||
|
#pragma warning restore CS0618
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Serializable]
|
||||||
|
internal enum UnreadMode {
|
||||||
|
All,
|
||||||
|
Unseen,
|
||||||
|
None,
|
||||||
|
}
|
||||||
|
|
||||||
|
internal static class UnreadModeExt {
|
||||||
|
internal static string? Tooltip(this UnreadMode mode) => mode switch {
|
||||||
|
UnreadMode.All => "Always show unread indicators.",
|
||||||
|
UnreadMode.Unseen => "Only show unread indicators for messages you haven't seen.",
|
||||||
|
UnreadMode.None => "Never show unread indicators.",
|
||||||
|
_ => null,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
internal class Tab {
|
internal class Tab {
|
||||||
public string Name = "New tab";
|
public string Name = "New tab";
|
||||||
public Dictionary<ChatType, ChatSource> ChatCodes = new();
|
public Dictionary<ChatType, ChatSource> ChatCodes = new();
|
||||||
|
|
||||||
|
[Obsolete("Use UnreadMode instead")]
|
||||||
public bool DisplayUnread = true;
|
public bool DisplayUnread = true;
|
||||||
|
|
||||||
|
public UnreadMode UnreadMode = UnreadMode.Unseen;
|
||||||
public bool DisplayTimestamp = true;
|
public bool DisplayTimestamp = true;
|
||||||
public InputChannel? Channel;
|
public InputChannel? Channel;
|
||||||
|
|
||||||
|
@ -87,7 +119,10 @@ internal class Tab {
|
||||||
return new Tab {
|
return new Tab {
|
||||||
Name = this.Name,
|
Name = this.Name,
|
||||||
ChatCodes = this.ChatCodes.ToDictionary(entry => entry.Key, entry => entry.Value),
|
ChatCodes = this.ChatCodes.ToDictionary(entry => entry.Key, entry => entry.Value),
|
||||||
|
#pragma warning disable CS0618
|
||||||
DisplayUnread = this.DisplayUnread,
|
DisplayUnread = this.DisplayUnread,
|
||||||
|
#pragma warning restore CS0618
|
||||||
|
UnreadMode = this.UnreadMode,
|
||||||
DisplayTimestamp = this.DisplayTimestamp,
|
DisplayTimestamp = this.DisplayTimestamp,
|
||||||
Channel = this.Channel,
|
Channel = this.Channel,
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,6 +66,7 @@ public sealed class Plugin : IDalamudPlugin {
|
||||||
#pragma warning disable CS8618
|
#pragma warning disable CS8618
|
||||||
public Plugin() {
|
public Plugin() {
|
||||||
this.Config = this.Interface!.GetPluginConfig() as Configuration ?? new Configuration();
|
this.Config = this.Interface!.GetPluginConfig() as Configuration ?? new Configuration();
|
||||||
|
this.Config.Migrate();
|
||||||
this.Common = new XivCommonBase();
|
this.Common = new XivCommonBase();
|
||||||
this.TextureCache = new TextureCache(this.DataManager!);
|
this.TextureCache = new TextureCache(this.DataManager!);
|
||||||
this.Functions = new GameFunctions.GameFunctions(this);
|
this.Functions = new GameFunctions.GameFunctions(this);
|
||||||
|
|
|
@ -18,6 +18,17 @@ internal sealed class PluginUi : IDisposable {
|
||||||
internal ImFontPtr? ItalicFont { get; private set; }
|
internal ImFontPtr? ItalicFont { get; private set; }
|
||||||
internal Vector4 DefaultText { get; private set; }
|
internal Vector4 DefaultText { get; private set; }
|
||||||
|
|
||||||
|
internal Tab? CurrentTab {
|
||||||
|
get {
|
||||||
|
var i = this._chatLog.LastTab;
|
||||||
|
if (i > -1 && i < this.Plugin.Config.Tabs.Count) {
|
||||||
|
return this.Plugin.Config.Tabs[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private List<IUiComponent> Components { get; }
|
private List<IUiComponent> Components { get; }
|
||||||
private ImFontConfigPtr _fontCfg;
|
private ImFontConfigPtr _fontCfg;
|
||||||
private ImFontConfigPtr _fontCfgMerge;
|
private ImFontConfigPtr _fontCfgMerge;
|
||||||
|
@ -42,12 +53,16 @@ internal sealed class PluginUi : IDisposable {
|
||||||
GCHandleType.Pinned
|
GCHandleType.Pinned
|
||||||
);
|
);
|
||||||
|
|
||||||
|
private readonly ChatLog _chatLog;
|
||||||
|
|
||||||
internal unsafe PluginUi(Plugin plugin) {
|
internal unsafe PluginUi(Plugin plugin) {
|
||||||
this.Plugin = plugin;
|
this.Plugin = plugin;
|
||||||
this.Salt = new Random().Next().ToString();
|
this.Salt = new Random().Next().ToString();
|
||||||
|
|
||||||
|
this._chatLog = new ChatLog(this);
|
||||||
this.Components = new List<IUiComponent> {
|
this.Components = new List<IUiComponent> {
|
||||||
new Settings(this),
|
new Settings(this),
|
||||||
new ChatLog(this),
|
this._chatLog,
|
||||||
};
|
};
|
||||||
|
|
||||||
this._fontCfg = new ImFontConfigPtr(ImGuiNative.ImFontConfig_ImFontConfig()) {
|
this._fontCfg = new ImFontConfigPtr(ImGuiNative.ImFontConfig_ImFontConfig()) {
|
||||||
|
|
|
@ -62,7 +62,7 @@ internal class Store : IDisposable {
|
||||||
return new MessagesLock(this.Messages, this.MessagesMutex);
|
return new MessagesLock(this.Messages, this.MessagesMutex);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void AddMessage(Message message) {
|
internal void AddMessage(Message message, Tab? currentTab) {
|
||||||
using var messages = this.GetMessages();
|
using var messages = this.GetMessages();
|
||||||
messages.Messages.Add(message);
|
messages.Messages.Add(message);
|
||||||
|
|
||||||
|
@ -70,9 +70,13 @@ internal class Store : IDisposable {
|
||||||
messages.Messages.RemoveAt(0);
|
messages.Messages.RemoveAt(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var currentMatches = currentTab?.Matches(message) ?? false;
|
||||||
|
|
||||||
foreach (var tab in this.Plugin.Config.Tabs) {
|
foreach (var tab in this.Plugin.Config.Tabs) {
|
||||||
|
var unread = !(tab.UnreadMode == UnreadMode.Unseen && currentTab != tab && currentMatches);
|
||||||
|
|
||||||
if (tab.Matches(message)) {
|
if (tab.Matches(message)) {
|
||||||
tab.AddMessage(message);
|
tab.AddMessage(message, unread);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -114,7 +118,7 @@ internal class Store : IDisposable {
|
||||||
var messageChunks = ChunkUtil.ToChunks(message, chatCode.Type).ToList();
|
var messageChunks = ChunkUtil.ToChunks(message, chatCode.Type).ToList();
|
||||||
|
|
||||||
var msg = new Message(chatCode, senderChunks, messageChunks);
|
var msg = new Message(chatCode, senderChunks, messageChunks);
|
||||||
this.AddMessage(msg);
|
this.AddMessage(msg, this.Plugin.Ui.CurrentTab);
|
||||||
|
|
||||||
var idx = this.Plugin.Functions.GetCurrentChatLogEntryIndex();
|
var idx = this.Plugin.Functions.GetCurrentChatLogEntryIndex();
|
||||||
if (idx != null) {
|
if (idx != null) {
|
||||||
|
|
|
@ -26,7 +26,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
private readonly TextureWrap? _fontIcon;
|
private readonly TextureWrap? _fontIcon;
|
||||||
private readonly List<string> _inputBacklog = new();
|
private readonly List<string> _inputBacklog = new();
|
||||||
private int _inputBacklogIdx = -1;
|
private int _inputBacklogIdx = -1;
|
||||||
private int _lastTab;
|
internal int LastTab { get; private set; }
|
||||||
private InputChannel? _tempChannel;
|
private InputChannel? _tempChannel;
|
||||||
private TellTarget? _tellTarget;
|
private TellTarget? _tellTarget;
|
||||||
private Vector2 _lastWindowSize = Vector2.Zero;
|
private Vector2 _lastWindowSize = Vector2.Zero;
|
||||||
|
@ -137,8 +137,8 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (this._lastTab > -1 && this._lastTab < this.Ui.Plugin.Config.Tabs.Count) {
|
if (this.LastTab > -1 && this.LastTab < this.Ui.Plugin.Config.Tabs.Count) {
|
||||||
this.Ui.Plugin.Config.Tabs[this._lastTab].Clear();
|
this.Ui.Plugin.Config.Tabs[this.LastTab].Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -645,7 +645,7 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
for (var tabI = 0; tabI < this.Ui.Plugin.Config.Tabs.Count; tabI++) {
|
for (var tabI = 0; tabI < this.Ui.Plugin.Config.Tabs.Count; tabI++) {
|
||||||
var tab = this.Ui.Plugin.Config.Tabs[tabI];
|
var tab = this.Ui.Plugin.Config.Tabs[tabI];
|
||||||
|
|
||||||
var unread = tabI == this._lastTab || !tab.DisplayUnread || tab.Unread == 0 ? "" : $" ({tab.Unread})";
|
var unread = tabI == this.LastTab || tab.UnreadMode == UnreadMode.None || tab.Unread == 0 ? "" : $" ({tab.Unread})";
|
||||||
var draw = ImGui.BeginTabItem($"{tab.Name}{unread}###log-tab-{tabI}");
|
var draw = ImGui.BeginTabItem($"{tab.Name}{unread}###log-tab-{tabI}");
|
||||||
this.DrawTabContextMenu(tab, tabI);
|
this.DrawTabContextMenu(tab, tabI);
|
||||||
|
|
||||||
|
@ -654,8 +654,8 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTab = tabI;
|
currentTab = tabI;
|
||||||
var switchedTab = this._lastTab != tabI;
|
var switchedTab = this.LastTab != tabI;
|
||||||
this._lastTab = tabI;
|
this.LastTab = tabI;
|
||||||
tab.Unread = 0;
|
tab.Unread = 0;
|
||||||
|
|
||||||
this.DrawMessageLog(tab, GetRemainingHeightForMessageLog(), switchedTab);
|
this.DrawMessageLog(tab, GetRemainingHeightForMessageLog(), switchedTab);
|
||||||
|
@ -686,8 +686,8 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
for (var tabI = 0; tabI < this.Ui.Plugin.Config.Tabs.Count; tabI++) {
|
for (var tabI = 0; tabI < this.Ui.Plugin.Config.Tabs.Count; tabI++) {
|
||||||
var tab = this.Ui.Plugin.Config.Tabs[tabI];
|
var tab = this.Ui.Plugin.Config.Tabs[tabI];
|
||||||
|
|
||||||
var unread = tabI == this._lastTab || !tab.DisplayUnread || tab.Unread == 0 ? "" : $" ({tab.Unread})";
|
var unread = tabI == this.LastTab || tab.UnreadMode == UnreadMode.None || tab.Unread == 0 ? "" : $" ({tab.Unread})";
|
||||||
var clicked = ImGui.Selectable($"{tab.Name}{unread}###log-tab-{tabI}", this._lastTab == tabI);
|
var clicked = ImGui.Selectable($"{tab.Name}{unread}###log-tab-{tabI}", this.LastTab == tabI);
|
||||||
this.DrawTabContextMenu(tab, tabI);
|
this.DrawTabContextMenu(tab, tabI);
|
||||||
|
|
||||||
if (!clicked) {
|
if (!clicked) {
|
||||||
|
@ -695,8 +695,8 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
currentTab = tabI;
|
currentTab = tabI;
|
||||||
switchedTab = this._lastTab != tabI;
|
switchedTab = this.LastTab != tabI;
|
||||||
this._lastTab = tabI;
|
this.LastTab = tabI;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -704,8 +704,8 @@ internal sealed class ChatLog : IUiComponent {
|
||||||
|
|
||||||
ImGui.TableNextColumn();
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
if (currentTab == -1 && this._lastTab < this.Ui.Plugin.Config.Tabs.Count) {
|
if (currentTab == -1 && this.LastTab < this.Ui.Plugin.Config.Tabs.Count) {
|
||||||
currentTab = this._lastTab;
|
currentTab = this.LastTab;
|
||||||
this.Ui.Plugin.Config.Tabs[currentTab].Unread = 0;
|
this.Ui.Plugin.Config.Tabs[currentTab].Unread = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,24 @@ internal sealed class Tabs : ISettingsTab {
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.InputText("Name", ref tab.Name, 512, ImGuiInputTextFlags.EnterReturnsTrue);
|
ImGui.InputText("Name", ref tab.Name, 512, ImGuiInputTextFlags.EnterReturnsTrue);
|
||||||
ImGui.Checkbox("Show unread count", ref tab.DisplayUnread);
|
|
||||||
ImGui.Checkbox("Show timestamps", ref tab.DisplayTimestamp);
|
ImGui.Checkbox("Show timestamps", ref tab.DisplayTimestamp);
|
||||||
|
|
||||||
|
if (ImGui.BeginCombo("Unread mode", tab.UnreadMode.ToString())) {
|
||||||
|
foreach (var mode in Enum.GetValues<UnreadMode>()) {
|
||||||
|
if (ImGui.Selectable(mode.ToString(), tab.UnreadMode == mode)) {
|
||||||
|
tab.UnreadMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mode.Tooltip() is { } tooltip && ImGui.IsItemHovered()) {
|
||||||
|
ImGui.BeginTooltip();
|
||||||
|
ImGui.TextUnformatted(tooltip);
|
||||||
|
ImGui.EndTooltip();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
|
||||||
var input = tab.Channel?.ToChatType().Name() ?? "<None>";
|
var input = tab.Channel?.ToChatType().Name() ?? "<None>";
|
||||||
if (ImGui.BeginCombo("Input channel", input)) {
|
if (ImGui.BeginCombo("Input channel", input)) {
|
||||||
if (ImGui.Selectable("<None>", tab.Channel == null)) {
|
if (ImGui.Selectable("<None>", tab.Channel == null)) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user