/// Utility functions for text processing class TextUtils { /// Convert Vietnamese characters to English (non-accented) characters /// Example: "Tuấn" -> "tuan", "Hồ Chí Minh" -> "ho chi minh" static String removeVietnameseAccents(String text) { if (text.isEmpty) return text; // Convert to lowercase for consistent comparison String result = text.toLowerCase(); // Map of Vietnamese characters to their non-accented equivalents const vietnameseMap = { // a with accents 'á': 'a', 'à': 'a', 'ả': 'a', 'ã': 'a', 'ạ': 'a', 'ă': 'a', 'ắ': 'a', 'ằ': 'a', 'ẳ': 'a', 'ẵ': 'a', 'ặ': 'a', 'â': 'a', 'ấ': 'a', 'ầ': 'a', 'ẩ': 'a', 'ẫ': 'a', 'ậ': 'a', // e with accents 'é': 'e', 'è': 'e', 'ẻ': 'e', 'ẽ': 'e', 'ẹ': 'e', 'ê': 'e', 'ế': 'e', 'ề': 'e', 'ể': 'e', 'ễ': 'e', 'ệ': 'e', // i with accents 'í': 'i', 'ì': 'i', 'ỉ': 'i', 'ĩ': 'i', 'ị': 'i', // o with accents 'ó': 'o', 'ò': 'o', 'ỏ': 'o', 'õ': 'o', 'ọ': 'o', 'ô': 'o', 'ố': 'o', 'ồ': 'o', 'ổ': 'o', 'ỗ': 'o', 'ộ': 'o', 'ơ': 'o', 'ớ': 'o', 'ờ': 'o', 'ở': 'o', 'ỡ': 'o', 'ợ': 'o', // u with accents 'ú': 'u', 'ù': 'u', 'ủ': 'u', 'ũ': 'u', 'ụ': 'u', 'ư': 'u', 'ứ': 'u', 'ừ': 'u', 'ử': 'u', 'ữ': 'u', 'ự': 'u', // y with accents 'ý': 'y', 'ỳ': 'y', 'ỷ': 'y', 'ỹ': 'y', 'ỵ': 'y', // d with stroke 'đ': 'd', }; // Replace each Vietnamese character with its non-accented equivalent vietnameseMap.forEach((vietnamese, english) { result = result.replaceAll(vietnamese, english); }); return result; } /// Normalize text for search (lowercase + remove accents) static String normalizeForSearch(String text) { return removeVietnameseAccents(text.toLowerCase().trim()); } /// Check if a text contains a search term (Vietnamese-aware, case-insensitive) /// /// Example: /// ```dart /// containsVietnameseSearch("Nguyễn Văn Tuấn", "tuan") // returns true /// containsVietnameseSearch("tuan@example.com", "TUAN") // returns true /// ``` static bool containsVietnameseSearch(String text, String searchTerm) { if (searchTerm.isEmpty) return true; if (text.isEmpty) return false; final normalizedText = normalizeForSearch(text); final normalizedSearch = normalizeForSearch(searchTerm); return normalizedText.contains(normalizedSearch); } /// Check if any of the provided texts contains the search term static bool containsVietnameseSearchInAny( List texts, String searchTerm, ) { if (searchTerm.isEmpty) return true; for (final text in texts) { if (containsVietnameseSearch(text, searchTerm)) { return true; } } return false; } }