sync last dev with cyr2lat

This commit is contained in:
HDDen
2026-05-01 01:38:31 +03:00
parent ca6058eccd
commit f63d50f0da
17 changed files with 528 additions and 66 deletions
+1 -2
View File
@@ -65,8 +65,7 @@ class BackgroundService {
return AppLocalizations.delegate.load(overrideLocale);
}
}
final preferred =
WidgetsBinding.instance.platformDispatcher.locales;
final preferred = WidgetsBinding.instance.platformDispatcher.locales;
final match = basicLocaleListResolution(preferred, supported);
return AppLocalizations.delegate.load(match);
}
+53 -8
View File
@@ -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,55 @@ 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 = <String, String>{
'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 = <String, int>{};
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) {