feat: add duplicate message collapsing

This commit is contained in:
Anna 2022-06-14 12:33:06 -04:00
parent 771e7d787b
commit 02118163ac
7 changed files with 2084 additions and 1239 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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();
}
}

3222
ChatTwo/Resources/Language.Designer.cs generated Normal file → Executable file

File diff suppressed because it is too large Load Diff

View File

@ -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>

View File

@ -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);
}
}

View File

@ -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();