поиск стикеров

This commit is contained in:
Jganenokk
2026-07-05 20:50:26 +07:00
parent abf660e10c
commit 9fe9ea2d31
5 changed files with 311 additions and 31 deletions
+71
View File
@@ -0,0 +1,71 @@
import 'dart:convert';
import 'package:flutter/services.dart';
class _Entry {
final String emoji;
final List<String> tokens;
const _Entry(this.emoji, this.tokens);
}
class EmojiKeywordIndex {
EmojiKeywordIndex._();
static final EmojiKeywordIndex instance = EmojiKeywordIndex._();
static const _variationSelector = '';
static final _wordPattern = RegExp(r'[0-9a-zа-яё\-]{2,}', unicode: true);
final List<_Entry> _entries = [];
final Set<String> _emojiKeys = {};
Future<void>? _loading;
Future<void> ensureLoaded() => _loading ??= _load();
Future<void> _load() async {
final raw = await rootBundle.loadString('assets/emoji_keywords.json');
final map = json.decode(raw) as Map<String, dynamic>;
map.forEach((emoji, words) {
_entries.add(_Entry(emoji, (words as String).split(' ')));
_emojiKeys.add(emoji);
});
}
static String normalize(String emoji) =>
emoji.replaceAll(_variationSelector, '');
Set<String> resolve(String query) {
final q = query.trim().toLowerCase();
if (q.isEmpty) return const {};
final targets = <String>{};
final normalized = normalize(q);
for (final key in _emojiKeys) {
if (normalized.contains(key)) targets.add(key);
}
final words = _wordPattern
.allMatches(q)
.map((m) => m.group(0)!)
.toList(growable: false);
if (words.isEmpty) return targets;
for (final entry in _entries) {
for (final word in words) {
if (_hasPrefix(entry.tokens, word)) {
targets.add(entry.emoji);
break;
}
}
}
return targets;
}
static bool _hasPrefix(List<String> tokens, String prefix) {
for (final token in tokens) {
if (token.startsWith(prefix)) return true;
}
return false;
}
}