Skip to content

Commit

Permalink
chore: update Emote-only expressions
Browse files Browse the repository at this point in the history
- update the emote base regex
- use calcUnlocalizedBody for emote computation
- update documentation about emote computation
- add source for the emote regex

Signed-off-by: The one with the braid <[email protected]>
  • Loading branch information
TheOneWithTheBraid committed Sep 21, 2024
1 parent 71180de commit 5dbe64b
Showing 1 changed file with 8 additions and 16 deletions.
24 changes: 8 additions & 16 deletions lib/src/event.dart
Original file line number Diff line number Diff line change
Expand Up @@ -988,29 +988,27 @@ class Event extends MatrixEvent {
content['formatted_body'] is String;

// regexes to fetch the number of emotes, including emoji, and if the message consists of only those
// to match an emoji we can use the following regex:
// (?:\x{00a9}|\x{00ae}|[\x{2600}-\x{27bf}]|[\x{2b00}-\x{2bff}]|\x{d83c}[\x{d000}-\x{dfff}]|\x{d83d}[\x{d000}-\x{dfff}]|\x{d83e}[\x{d000}-\x{dfff}])[\x{fe00}-\x{fe0f}]?
// we need to replace \x{0000} with \u0000, the comment is left in the other format to be able to paste into regex101.com
// to match an emoji we can use the following regularly updated regex : https://stackoverflow.com/a/67705964
// to see if there is a custom emote, we use the following regex: <img[^>]+data-mx-(?:emote|emoticon)(?==|>|\s)[^>]*>
// now we combind the two to have four regexes:
// now we combined the two to have four regexes:
// 1. are there only emoji, or whitespace
// 2. are there only emoji, emotes, or whitespace
// 3. count number of emoji
// 4- count number of emoji or emotes
static final RegExp _onlyEmojiRegex = RegExp(
r'^((?:\u00a9|\u00ae|[\u2600-\u27bf]|[\u2b00-\u2bff]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])[\ufe00-\ufe0f]?|\s)*$',
r'^((?:\x{00a9}|\x{00ae}|\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])?|\s)*$',
caseSensitive: false,
multiLine: false);
static final RegExp _onlyEmojiEmoteRegex = RegExp(
r'^((?:\u00a9|\u00ae|[\u2600-\u27bf]|[\u2b00-\u2bff]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])[\ufe00-\ufe0f]?|<img[^>]+data-mx-(?:emote|emoticon)(?==|>|\s)[^>]*>|\s)*$',
r'^((?:\x{00a9}|\x{00ae}|\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])?|<img[^>]+data-mx-(?:emote|emoticon)(?==|>|\s)[^>]*>|\s)*$',
caseSensitive: false,
multiLine: false);
static final RegExp _countEmojiRegex = RegExp(
r'((?:\u00a9|\u00ae|[\u2600-\u27bf]|[\u2b00-\u2bff]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])[\ufe00-\ufe0f]?)',
r'((?:\x{00a9}|\x{00ae}|\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])?)',
caseSensitive: false,
multiLine: false);
static final RegExp _countEmojiEmoteRegex = RegExp(
r'((?:\u00a9|\u00ae|[\u2600-\u27bf]|[\u2b00-\u2bff]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])[\ufe00-\ufe0f]?|<img[^>]+data-mx-(?:emote|emoticon)(?==|>|\s)[^>]*>)',
r'((?:\x{00a9}|\x{00ae}|\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff])?|<img[^>]+data-mx-(?:emote|emoticon)(?==|>|\s)[^>]*>)',
caseSensitive: false,
multiLine: false);

Expand All @@ -1019,10 +1017,7 @@ class Event extends MatrixEvent {
/// This is useful to determine if stand-alone emotes should be displayed bigger.
bool get onlyEmotes {
if (isRichMessage) {
final formattedTextStripped = formattedText.replaceAll(
RegExp('<mx-reply>.*</mx-reply>',
caseSensitive: false, multiLine: false, dotAll: true),
'');
final formattedTextStripped = calcUnlocalizedBody(hideReply: true);
return _onlyEmojiEmoteRegex.hasMatch(formattedTextStripped);
} else {
return _onlyEmojiRegex.hasMatch(plaintextBody);
Expand All @@ -1035,10 +1030,7 @@ class Event extends MatrixEvent {
/// WARNING: This does **not** test if there are only emotes. Use `event.onlyEmotes` for that!
int get numberEmotes {
if (isRichMessage) {
final formattedTextStripped = formattedText.replaceAll(
RegExp('<mx-reply>.*</mx-reply>',
caseSensitive: false, multiLine: false, dotAll: true),
'');
final formattedTextStripped = calcUnlocalizedBody(hideReply: true);
return _countEmojiEmoteRegex.allMatches(formattedTextStripped).length;
} else {
return _countEmojiRegex.allMatches(plaintextBody).length;
Expand Down

0 comments on commit 5dbe64b

Please sign in to comment.