feat: add duplicate message collapsing
This commit is contained in:
parent
771e7d787b
commit
02118163ac
|
@ -22,6 +22,20 @@ internal abstract class Chunk {
|
|||
ChunkSource.Content => this.Message?.ContentSource,
|
||||
_ => null,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Get some basic text for use in generating hashes.
|
||||
/// </summary>
|
||||
internal string StringValue() {
|
||||
switch (this) {
|
||||
case TextChunk text:
|
||||
return text.Content;
|
||||
case IconChunk icon:
|
||||
return icon.Icon.ToString();
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal enum ChunkSource {
|
||||
|
|
|
@ -35,6 +35,7 @@ internal class Configuration : IPluginConfiguration {
|
|||
public bool FilterIncludePreviousSessions;
|
||||
public bool SharedMode;
|
||||
public bool SortAutoTranslate;
|
||||
public bool CollapseDuplicateMessages;
|
||||
|
||||
public bool FontsEnabled = true;
|
||||
public ExtraGlyphRanges ExtraGlyphRanges = 0;
|
||||
|
@ -71,6 +72,7 @@ internal class Configuration : IPluginConfiguration {
|
|||
this.FilterIncludePreviousSessions = other.FilterIncludePreviousSessions;
|
||||
this.SharedMode = other.SharedMode;
|
||||
this.SortAutoTranslate = other.SortAutoTranslate;
|
||||
this.CollapseDuplicateMessages = other.CollapseDuplicateMessages;
|
||||
this.FontsEnabled = other.FontsEnabled;
|
||||
this.ExtraGlyphRanges = other.ExtraGlyphRanges;
|
||||
this.FontSize = other.FontSize;
|
||||
|
|
|
@ -15,6 +15,28 @@ internal class SortCode {
|
|||
|
||||
public SortCode() {
|
||||
}
|
||||
|
||||
private bool Equals(SortCode other) {
|
||||
return this.Type == other.Type && this.Source == other.Source;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj) {
|
||||
if (ReferenceEquals(null, obj)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ReferenceEquals(this, obj)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return obj.GetType() == this.GetType() && this.Equals((SortCode) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
unchecked {
|
||||
return ((int) this.Type * 397) ^ (int) this.Source;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class Message {
|
||||
|
@ -38,6 +60,8 @@ internal class Message {
|
|||
internal SeString ContentSource { get; }
|
||||
|
||||
internal SortCode SortCode { get; }
|
||||
|
||||
internal int Hash { get; }
|
||||
|
||||
internal Message(ulong receiver, ChatCode code, List<Chunk> sender, List<Chunk> content, SeString senderSource, SeString contentSource) {
|
||||
this.Receiver = receiver;
|
||||
|
@ -48,6 +72,7 @@ internal class Message {
|
|||
this.SenderSource = senderSource;
|
||||
this.ContentSource = contentSource;
|
||||
this.SortCode = new SortCode(this.Code.Type, this.Code.Source);
|
||||
this.Hash = this.GenerateHash();
|
||||
|
||||
foreach (var chunk in sender.Concat(content)) {
|
||||
chunk.Message = this;
|
||||
|
@ -65,9 +90,16 @@ internal class Message {
|
|||
this.SenderSource = BsonMapper.Global.Deserialize<SeString>(senderSource);
|
||||
this.ContentSource = BsonMapper.Global.Deserialize<SeString>(contentSource);
|
||||
this.SortCode = BsonMapper.Global.ToObject<SortCode>(sortCode);
|
||||
this.Hash = this.GenerateHash();
|
||||
|
||||
foreach (var chunk in this.Sender.Concat(this.Content)) {
|
||||
chunk.Message = this;
|
||||
}
|
||||
}
|
||||
|
||||
private int GenerateHash() {
|
||||
return this.SortCode.GetHashCode()
|
||||
^ string.Join("", this.Sender.Select(c => c.StringValue())).GetHashCode()
|
||||
^ string.Join("", this.Content.Select(c => c.StringValue())).GetHashCode();
|
||||
}
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -839,4 +839,10 @@
|
|||
<data name="ChatType_GmNoviceNetwork" xml:space="preserve">
|
||||
<value>Novice Network (GM)</value>
|
||||
</data>
|
||||
<data name="Options_CollapseDuplicateMessages_Name" xml:space="preserve">
|
||||
<value>Collapse duplicate messages</value>
|
||||
</data>
|
||||
<data name="Options_CollapseDuplicateMessages_Description" xml:space="preserve">
|
||||
<value>Only show the first message and show a counter at the end of messages that have been repeated.</value>
|
||||
</data>
|
||||
</root>
|
||||
|
|
|
@ -671,12 +671,50 @@ internal sealed class ChatLog : IUiComponent {
|
|||
|
||||
var lastPos = ImGui.GetCursorPosY();
|
||||
var lastTimestamp = string.Empty;
|
||||
foreach (var message in tab.Messages) {
|
||||
int? lastMessageHash = null;
|
||||
var sameCount = 0;
|
||||
for (var i = 0; i < tab.Messages.Count; i++) {
|
||||
var message = tab.Messages[i];
|
||||
|
||||
if (reset) {
|
||||
message.Height = null;
|
||||
message.IsVisible = false;
|
||||
}
|
||||
|
||||
if (this.Ui.Plugin.Config.CollapseDuplicateMessages) {
|
||||
var messageHash = message.Hash;
|
||||
var same = lastMessageHash == messageHash;
|
||||
if (same) {
|
||||
sameCount += 1;
|
||||
|
||||
if (i != tab.Messages.Count - 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (sameCount > 0) {
|
||||
ImGui.SameLine();
|
||||
this.DrawChunks(
|
||||
new[] {
|
||||
new TextChunk(ChunkSource.None, null, $" ({sameCount + 1}x)") {
|
||||
FallbackColour = ChatType.System,
|
||||
Italic = true,
|
||||
},
|
||||
},
|
||||
true,
|
||||
handler,
|
||||
ImGui.GetContentRegionAvail().X
|
||||
);
|
||||
sameCount = 0;
|
||||
}
|
||||
|
||||
lastMessageHash = messageHash;
|
||||
|
||||
if (same && i == tab.Messages.Count - 1) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// go to next row
|
||||
if (table) {
|
||||
ImGui.TableNextColumn();
|
||||
|
@ -924,13 +962,13 @@ internal sealed class ChatLog : IUiComponent {
|
|||
this._popOutDocked.Clear();
|
||||
this._popOutDocked.AddRange(Enumerable.Repeat(false, this.Ui.Plugin.Config.Tabs.Count));
|
||||
}
|
||||
|
||||
|
||||
for (var i = 0; i < this.Ui.Plugin.Config.Tabs.Count; i++) {
|
||||
var tab = this.Ui.Plugin.Config.Tabs[i];
|
||||
if (!tab.PopOut) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
this.DrawPopOut(tab, i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,6 +65,9 @@ internal sealed class Display : ISettingsTab {
|
|||
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.OptionCheckbox(ref this.Mutable.CollapseDuplicateMessages, Language.Options_CollapseDuplicateMessages_Name, Language.Options_CollapseDuplicateMessages_Description);
|
||||
ImGui.Spacing();
|
||||
|
||||
ImGuiUtil.OptionCheckbox(ref this.Mutable.ShowNoviceNetwork, Language.Options_ShowNoviceNetwork_Name, Language.Options_ShowNoviceNetwork_Description);
|
||||
ImGui.Spacing();
|
||||
|
||||
|
|
Loading…
Reference in New Issue