From 0f6a1aedd6cca023f994572f925e4db07bec5b88 Mon Sep 17 00:00:00 2001 From: Greg Price Date: Sat, 7 Dec 2024 01:09:03 -0800 Subject: [PATCH] wip emoji: Recognize word-aligned matches in ranking; TODO test --- lib/model/emoji.dart | 50 +++++++++++++++++++++----------------------- 1 file changed, 24 insertions(+), 26 deletions(-) diff --git a/lib/model/emoji.dart b/lib/model/emoji.dart index 03b3d36241..966d76c999 100644 --- a/lib/model/emoji.dart +++ b/lib/model/emoji.dart @@ -342,7 +342,15 @@ enum EmojiMatchQuality { /// The query matches a prefix of the emoji name, but not the whole name. prefix, - /// The query matches somewhere in the emoji name, but not at the start. + /// The query matches starting at the start of a word in the emoji name, + /// but not the start of the whole name. + /// + /// For example a name "ab_cd_ef" would match queries "c" or "cd_e" + /// at this level, but not a query "b_cd_ef". + wordAligned, + + /// The query matches somewhere in the emoji name, + /// but not at the start of any word. other; /// The best possible quality of match. @@ -395,11 +403,9 @@ class EmojiAutocompleteView extends AutocompleteView false, }; return switch (matchQuality) { - EmojiMatchQuality.exact => 0, - EmojiMatchQuality.prefix => isPopular ? 1 : isCustomEmoji ? 3 : 4, - // TODO word-boundary vs. not - EmojiMatchQuality.other => isPopular ? 2 : isCustomEmoji ? 5 : 6, + EmojiMatchQuality.exact => 0, + EmojiMatchQuality.prefix => isPopular ? 1 : isCustomEmoji ? 3 : 5, + EmojiMatchQuality.wordAligned => isPopular ? 2 : isCustomEmoji ? 4 : 6, + EmojiMatchQuality.other => isCustomEmoji ? 7 : 8, }; } /// The number of possible values returned by [_rankResult]. - static const _numResultRanks = 7; + static const _numResultRanks = 9; } class EmojiAutocompleteQuery extends ComposeAutocompleteQuery { @@ -493,25 +499,17 @@ class EmojiAutocompleteQuery extends ComposeAutocompleteQuery { // See also commentary in [_rankResult] above. // TODO(#1067) this assumes emojiName is already lower-case (and no diacritics) - if (emojiName == _adjusted) return EmojiMatchQuality.exact; - if (emojiName.startsWith(_adjusted)) return EmojiMatchQuality.prefix; - if (_nameMatches(emojiName)) return EmojiMatchQuality.other; - return null; - } - - bool _nameMatches(String emojiName) { + if (emojiName == _adjusted) return EmojiMatchQuality.exact; + if (emojiName.startsWith(_adjusted)) return EmojiMatchQuality.prefix; + if (emojiName.contains(_sepAdjusted)) return EmojiMatchQuality.wordAligned; if (!_adjusted.contains(_separator)) { // If the query is a single token (doesn't contain a separator), - // the match can be anywhere in the string. - return emojiName.contains(_adjusted); + // allow a match anywhere in the string, too. + if (emojiName.contains(_adjusted)) return EmojiMatchQuality.other; + } else { + // Otherwise, require at least a word-aligned match. } - - // If there is a separator in the query, then we - // require the match to start at the start of a token. - // (E.g. for 'ab_cd_ef', query could be 'ab_c' or 'cd_ef', - // but not 'b_cd_ef'.) - assert(!emojiName.startsWith(_adjusted)); // checked before calling this method - return emojiName.contains(_sepAdjusted); + return null; } @override