diff --git a/PrivaPub.Tests/Federation/ReactionTests.cs b/PrivaPub.Tests/Federation/ReactionTests.cs index db10383..835f589 100644 --- a/PrivaPub.Tests/Federation/ReactionTests.cs +++ b/PrivaPub.Tests/Federation/ReactionTests.cs @@ -17,6 +17,9 @@ namespace PrivaPub.Tests.Federation [InlineData(":blobcat@k.example:", "blobcat")] [InlineData("👍🏽", "👍🏽")] [InlineData("❤️", "❤️")] + [InlineData("❤", "❤️")] + [InlineData("✌", "✌️")] + [InlineData("🔥\uFE0F", "🔥")] [InlineData("nope", null)] [InlineData("👍👍", null)] [InlineData(":unknown:", null)] diff --git a/PrivaPub/Domain/Social/Reactions.cs b/PrivaPub/Domain/Social/Reactions.cs index 05b750b..d1253b8 100644 --- a/PrivaPub/Domain/Social/Reactions.cs +++ b/PrivaPub/Domain/Social/Reactions.cs @@ -178,6 +178,11 @@ namespace PrivaPub.Domain.Social return requireKnownCustom ? default : new Picked(bare, default); return new Picked(bare, emoji.URL); } + // one emoji, one name: ❤ and ❤️ (with the emoji variation selector) were two reactions, counted apart. The selector + // is dropped, then put back on a symbol that shows as text without it (U+2000 to U+2BFF: ❤, ☺, ✌...) + text = text.Replace("\uFE0F", ""); + if (text.Length == 1 && text[0] is >= '\u2000' and <= '\u2BFF') + text += "\uFE0F"; if (text.Any(c => c < 128 || char.IsWhiteSpace(c)) || new StringInfo(text).LengthInTextElements != 1) return default; return new Picked(text, default);