From edeb4428466b859720826f006b8da01cc3dbd11e Mon Sep 17 00:00:00 2001 From: Maxim Dolgolyov Date: Wed, 27 May 2026 17:33:54 +0300 Subject: [PATCH] =?UTF-8?q?fix(tracker):=20hash-=D0=B2=D1=85=D0=BE=D0=B4?= =?UTF-8?q?=20(chemistry-9#p6)=20=D1=82=D0=BE=D0=B6=D0=B5=20=D1=88=D0=BB?= =?UTF-8?q?=D1=91=D1=82=20mark=5Fread?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Из каталога кнопка 'Продолжить' ведёт на /textbook/#. handleHashNav при загрузке делала setLastPara(p6) — POST с last_para БЕЗ mark_read. Поэтому каталог менял last_para, но 'прочитано' оставалось без изменений. Сейчас handleHashNav объединяет оба обновления (как wirePillTracking) в один POST с mark_read=key. Из лога user 2: '[tracker] chemistry-9 → POST {"last_para":"p6"}' теперь будет '...{"last_para":"p6","mark_read":"p6"}'. --- frontend/js/textbook-tracker.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/frontend/js/textbook-tracker.js b/frontend/js/textbook-tracker.js index a144bdb..134ee9f 100644 --- a/frontend/js/textbook-tracker.js +++ b/frontend/js/textbook-tracker.js @@ -455,8 +455,18 @@ function handleHashNav() { const m = (location.hash || '').match(/^#(p\d+)$/); if (m) { - openParaByKey(m[1]); - setLastPara(m[1]); + const key = m[1]; + openParaByKey(key); + localState.last = key; + if (!localState.read.includes(key)) { + localState.read.push(key); + refreshPillUI(key); + refreshCheckUI(key); + } + persist(); + // Hash-вход (например, «Продолжить» из каталога) считается просмотром + // параграфа — шлём last_para + mark_read одним POST. + syncToServer({ mark_read: key }); return true; } return false;