From 3af3cce60612f14fc019c173ad6f7038daf79b43 Mon Sep 17 00:00:00 2001 From: ZIER Date: Wed, 29 Apr 2026 11:04:36 +0200 Subject: [PATCH 1/2] latin languages heuristics --- lib/services/translation_service.dart | 49 ++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/lib/services/translation_service.dart b/lib/services/translation_service.dart index 7d76efab..f0f37fb6 100644 --- a/lib/services/translation_service.dart +++ b/lib/services/translation_service.dart @@ -519,12 +519,11 @@ class TranslationService extends ChangeNotifier { } String? _heuristicLanguageCode(String text) { - if (RegExp(r'[іїєґІЇЄҐ]').hasMatch(text)) { - return 'uk'; - } - if (RegExp(r'[а-яёА-ЯЁ]').hasMatch(text)) { - return 'ru'; + final trimmed = text.trim(); + if (trimmed.isEmpty) { + return null; } + if (RegExp(r'[ぁ-んァ-ン]').hasMatch(text)) { return 'ja'; } @@ -534,9 +533,43 @@ class TranslationService extends ChangeNotifier { if (RegExp(r'[\u4e00-\u9fff]').hasMatch(text)) { return 'zh'; } - // Latin-script languages can't be reliably distinguished by characters - // alone — return null so the translator always attempts translation. - return null; + + final lower = trimmed.toLowerCase(); + final patterns = { + 'uk': r'\b(привіт|дякую|будь|ласка|як|де|не|так|це|є|най|ще|може|для)\b', + 'ru': r'\b(что|это|как|не|да|нет|он|она|они|быть|есть|для|сегодня|если|уже|может)\b', + 'bg': r'\b(ще|няма|благодаря|моля|това|какво|тук|ние|вие|не|със|за)\b', + 'de': r'\b(der|die|das|und|ist|nicht|ein|eine|ich|für|mit|auf|zu|auch|als|an|im|am|es|dem|den|sich|von)\b', + 'en': r'\b(the|and|is|you|for|with|from|not|that|this|have|be|are|was|were|but|can|will|your|what|when|how|they)\b', + 'es': r'\b(el|la|los|las|es|que|de|en|con|por|para|no|un|una|se|como|su|al|del|está)\b', + 'fr': r'\b(le|la|les|un|une|et|est|que|qui|pour|dans|pas|avec|sur|ne|vous|il|elle|des|ce|cette|je|tu|nous|vous)\b', + 'it': r'\b(il|la|lo|un|una|che|di|da|in|per|con|non|si|mi|ti|noi|voi|lui|lei)\b', + 'pt': r'\b(os|as|que|de|do|da|em|para|com|por|não|uma|um|se|você|também)\b', + 'nl': r'\b(de|het|een|en|is|niet|dat|wat|je|ik|op|aan|voor|met|als|nog|zijn)\b', + 'sv': r'\b(och|är|det|att|som|en|på|inte|har|var|men|du|jag|vi|ni|den|detta)\b', + 'pl': r'\b(na|się|nie|jest|to|że|do|od|dla|czy|tak|ale|ma|jak|on|ona|my)\b', + 'sk': r'\b(je|na|so|že|do|od|za|si|to|ten|tá|tí|ako|má|nie|som|sa)\b', + 'sl': r'\b(in|je|na|se|da|za|od|ne|to|ta|so|kako|bo|sem|si)\b', + 'hu': r'\b(az|és|nem|van|volt|hogy|mit|mire|ki|mi|ez|azért|is|de|ha|te|ő|mi|itt)\b', + }; + + final scores = {}; + for (final entry in patterns.entries) { + scores[entry.key] = RegExp(entry.value, caseSensitive: false) + .allMatches(lower) + .length; + } + + final sorted = scores.entries.toList() + ..sort((a, b) => b.value.compareTo(a.value)); + if (sorted.isEmpty || sorted.first.value == 0) { + return null; + } + if (sorted.length > 1 && sorted.first.value == sorted[1].value) { + return null; + } + + return sorted.first.key; } String _languageLabel(String code) { From 38fece33131217efb88bd9ba19bc177bf187dbe6 Mon Sep 17 00:00:00 2001 From: ZIER Date: Wed, 29 Apr 2026 11:51:50 +0200 Subject: [PATCH 2/2] replace pattern with String. --- lib/services/translation_service.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/services/translation_service.dart b/lib/services/translation_service.dart index f0f37fb6..46cf7ea8 100644 --- a/lib/services/translation_service.dart +++ b/lib/services/translation_service.dart @@ -535,7 +535,7 @@ class TranslationService extends ChangeNotifier { } final lower = trimmed.toLowerCase(); - final patterns = { + final patterns = { 'uk': r'\b(привіт|дякую|будь|ласка|як|де|не|так|це|є|най|ще|може|для)\b', 'ru': r'\b(что|это|как|не|да|нет|он|она|они|быть|есть|для|сегодня|если|уже|может)\b', 'bg': r'\b(ще|няма|благодаря|моля|това|какво|тук|ние|вие|не|със|за)\b',