fix(reader): preserve full context sentence with abbreviations (Mr., Mrs., etc.) and log bug fix
This commit is contained in:
@@ -369,6 +369,14 @@
|
||||
|
||||
---
|
||||
|
||||
### 🐛 Устранённые дефекты и хотфиксы (Bug Tracker & Hotfixes)
|
||||
- [x] **Баг читалки: Преждевременный обрыв контекстного предложения на точках сокращений (`Mr.`, `Mrs.`, `Dr.`, `Prof.`, `St.`, `etc.`, `e.g.`, `i.e.`, `1.5`)**:
|
||||
- **Симптом**: При клике на слово в предложении с обращением или сокращением (например, *«Mr. and Mrs. Dursley were proud...»*) кнопка перевода предложения («🌐 Перевести предложение») отправляла на перевод лишь обрезок до или после точки (*«Mr.»*, *«and Mrs.»* или *«Dursley were proud...»*). Если перед словом была точка в обращении, текст дальше не переводился.
|
||||
- **Причина**: В функции `extractContextSentence(fullText, word)` в [`app/static/js/modules/reader.js`](file:///home/ai-projects/services/study.qpid.pro/app/static/js/modules/reader.js) использовалось наивное регулярное выражение `[^.!?\n]*`, считавшее абсолютно любую точку концом предложения.
|
||||
- **Решение**: Реализована безопасная защита списка английских титулов и сокращений (`READER_HONORIFICS`) и дробных чисел перед сегментацией. Предложения корректно делятся по терминальным знакам препинания с закрывающими кавычками/скобками (`[.!?]['"”’»)]*`), гарантируя передачу полного, связного контекста в переводчик и словарь.
|
||||
|
||||
---
|
||||
|
||||
### 17. 🍔 Разгрузка хеддера и единая навигация через боковое меню / Drawer (Unified Navigation & Header Redesign)
|
||||
- [ ] **Проблема перегруженного хеддера**:
|
||||
- В шапке скопилось 8+ кнопок (`📚 Читалка`, `🎯 Тесты CEFR`, `📖 Грамматика`, `🎓 Тренажёр`, `📊 Статистика`, `📤 Экспорт`, тема, шестеренка, профиль), на экранах планшетов и ноутбуков возникает переполнение и визуальный шум.
|
||||
|
||||
@@ -1070,11 +1070,39 @@ export function renderInteractiveSpans(container, text, contextText, knownWordsM
|
||||
});
|
||||
}
|
||||
|
||||
const READER_HONORIFICS = [
|
||||
'Mr.', 'Mrs.', 'Ms.', 'Dr.', 'Prof.', 'St.', 'vs.', 'etc.', 'e.g.', 'i.e.', 'Jr.', 'Sr.',
|
||||
'Capt.', 'Col.', 'Gen.', 'Lt.', 'Sgt.', 'Rev.', 'Hon.'
|
||||
];
|
||||
|
||||
export function extractContextSentence(fullText, word) {
|
||||
if (!fullText) return '';
|
||||
const re = new RegExp(`([^.!?\\n]*?\\b${escapeRegex(word)}\\b[^.!?\\n]*[.!?]?)`, 'i');
|
||||
const m = fullText.match(re);
|
||||
if (m && m[1]) return m[1].trim();
|
||||
let protectedText = fullText;
|
||||
for (const h of READER_HONORIFICS) {
|
||||
if (protectedText.toLowerCase().includes(h.toLowerCase())) {
|
||||
const safe = h.replace(/\./g, '§DOT§');
|
||||
const reH = new RegExp(escapeRegex(h), 'gi');
|
||||
protectedText = protectedText.replace(reH, safe);
|
||||
}
|
||||
}
|
||||
// Protect decimal numbers (e.g. 3.14, 1.5)
|
||||
protectedText = protectedText.replace(/(\d+)\.(\d+)/g, '$1§DOT§$2');
|
||||
|
||||
// Split sentences on terminal punctuation (.!?) followed by optional quotes/brackets and whitespace
|
||||
const marked = protectedText.replace(/([.!?]['"”’»)]*)\s+/g, '$1§SEP§');
|
||||
const rawSentences = marked.split('§SEP§');
|
||||
|
||||
const cleanWord = (word || '').trim();
|
||||
if (cleanWord) {
|
||||
const escaped = escapeRegex(cleanWord);
|
||||
const wordRe = new RegExp(`(?:^|\\W)${escaped}(?:$|\\W)`, 'i');
|
||||
for (const s of rawSentences) {
|
||||
if (wordRe.test(s)) {
|
||||
return s.replace(/§DOT§/g, '.').trim();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return fullText.slice(0, 160).trim();
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
// Service Worker for Notes English PWA (Stage 2)
|
||||
// Strategy: Cache-first for static assets, Network-first for API calls.
|
||||
|
||||
const CACHE_NAME = 'notes-v5.5';
|
||||
const CACHE_NAME = 'notes-v5.6';
|
||||
const OFFLINE_URL = '/';
|
||||
|
||||
const PRECACHE_URLS = [
|
||||
|
||||
Reference in New Issue
Block a user