feat: add vehicle customization, Arabic search normalization, and smooth movement interpolation
This commit is contained in:
@@ -0,0 +1,51 @@
|
||||
class ArabicSearchNormalizer {
|
||||
ArabicSearchNormalizer._();
|
||||
|
||||
static final RegExp _diacriticsRegExp = RegExp(
|
||||
r'[\u064B-\u065F\u0670\u0640]', // Harakat, Tanween, Shadda, Sukoon, Tatweel
|
||||
);
|
||||
|
||||
/// Normalizes Arabic text for flexible, fuzzy searching:
|
||||
/// - Strips diacritics / tashkeel
|
||||
/// - Normalizes all Alef forms (أ, إ, آ, ٱ) -> ا
|
||||
/// - Normalizes Alef Maksura (ى) -> ي
|
||||
/// - Normalizes Teh Marbuta (ة) -> ه
|
||||
/// - Normalizes Hamza on Waw (ؤ) -> و and Hamza on Yaa (ئ) -> ي
|
||||
/// - Lowercases English characters and trims spaces
|
||||
static String normalize(String text) {
|
||||
if (text.isEmpty) return '';
|
||||
|
||||
String cleaned = text
|
||||
.replaceAll(_diacriticsRegExp, '')
|
||||
.replaceAll(RegExp(r'[أإآٱ]'), 'ا')
|
||||
.replaceAll('ى', 'ي')
|
||||
.replaceAll('ة', 'ه')
|
||||
.replaceAll('ؤ', 'و')
|
||||
.replaceAll('ئ', 'ي')
|
||||
.toLowerCase()
|
||||
.trim();
|
||||
|
||||
// Collapse multiple whitespaces into a single space
|
||||
cleaned = cleaned.replaceAll(RegExp(r'\s+'), ' ');
|
||||
return cleaned;
|
||||
}
|
||||
|
||||
/// Checks if [target] contains [query], normalizing both in Arabic and English.
|
||||
static bool matches(String target, String query) {
|
||||
final normTarget = normalize(target);
|
||||
final normQuery = normalize(query);
|
||||
|
||||
if (normQuery.isEmpty) return true;
|
||||
if (normTarget.isEmpty) return false;
|
||||
|
||||
if (normTarget.contains(normQuery)) return true;
|
||||
|
||||
// Split words in query and verify each token is present
|
||||
final queryWords = normQuery.split(' ').where((w) => w.isNotEmpty);
|
||||
if (queryWords.length > 1) {
|
||||
return queryWords.every((word) => normTarget.contains(word));
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user