fix(tracker): mark_read шлётся на КАЖДЫЙ клик пилюли (идемпотентно)
Старый syncPending-баг успел залить локальный localState.read данными, которых нет на сервере. После фиксов firstTime=false для всех ключей в localState.read, и mark_read иначе никогда не уходил → каталог показывал 0 даже после реальных кликов. Решение: убрать оптимизацию firstTime. Слать mark_read КАЖДЫЙ раз — серверный код if(!arr.includes(mark_read)) arr.push(...) не добавит дубликат. Лишний POST стоит копейки, зато система самовосстанавливается без зависимости от загрузочного backfill.
This commit is contained in:
@@ -214,23 +214,24 @@
|
|||||||
localState.read.forEach(k => { refreshPillUI(k); refreshCheckUI(k); });
|
localState.read.forEach(k => { refreshPillUI(k); refreshCheckUI(k); });
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ── 7. Pill click → last_para + (первый раз) mark_read ────────
|
/* ── 7. Pill click → ВСЕГДА шлём last_para + mark_read одним POST
|
||||||
Объединяем оба обновления в один POST, чтобы syncPending-guard
|
Идемпотентно: на сервере `if (!arr.includes(mark_read)) arr.push(...)`
|
||||||
в syncToServer не дропнул второй вызов в том же тике. */
|
не добавит дубликат. Эта «избыточность» лечит самовосстановлением
|
||||||
|
ситуации, когда localState.read был засорён старым syncPending-багом
|
||||||
|
(есть ключ локально, нет на сервере, mark_read иначе никогда не уйдёт). */
|
||||||
function wirePillTracking() {
|
function wirePillTracking() {
|
||||||
document.body.addEventListener('click', e => {
|
document.body.addEventListener('click', e => {
|
||||||
const pill = e.target.closest('.para-pill[data-para]');
|
const pill = e.target.closest('.para-pill[data-para]');
|
||||||
if (!pill) return;
|
if (!pill) return;
|
||||||
const key = pill.dataset.para;
|
const key = pill.dataset.para;
|
||||||
localState.last = key;
|
localState.last = key;
|
||||||
const firstTime = !localState.read.includes(key);
|
if (!localState.read.includes(key)) {
|
||||||
if (firstTime) {
|
|
||||||
localState.read.push(key);
|
localState.read.push(key);
|
||||||
refreshPillUI(key);
|
|
||||||
refreshCheckUI(key);
|
|
||||||
}
|
}
|
||||||
|
refreshPillUI(key);
|
||||||
|
refreshCheckUI(key);
|
||||||
persist();
|
persist();
|
||||||
syncToServer(firstTime ? { mark_read: key } : {});
|
syncToServer({ mark_read: key });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user