Клиент: устойчивость к отсутствию POST /read, оптимистичное снятие непрочитанного

This commit is contained in:
root
2026-05-14 10:26:58 +00:00
parent c5b300ffa2
commit 2facc3d0d2
+26 -2
View File
@@ -51,6 +51,9 @@
setTimeout(() => URL.revokeObjectURL(url), 120000); setTimeout(() => URL.revokeObjectURL(url), 120000);
} }
/** Сервер без маршрута `POST .../read` (404) — не дёргать повторно, меньше шума в консоли. */
let skipClientReadReceiptPost = false;
const state = { const state = {
tickets: [], tickets: [],
currentTicket: null, currentTicket: null,
@@ -261,14 +264,31 @@
} }
async function markClientTicketRead(ticketNumber) { async function markClientTicketRead(ticketNumber) {
const res = await fetch(`${apiBase}/api/client/tickets/${encodeURIComponent(ticketNumber)}/read`, { if (skipClientReadReceiptPost || !ticketNumber) return;
let res;
try {
res = await fetch(`${apiBase}/api/client/tickets/${encodeURIComponent(ticketNumber)}/read`, {
method: "POST", method: "POST",
headers: clientIdentityHeaders(), headers: clientIdentityHeaders(),
}); });
} catch {
return;
}
if (res.status === 404) {
skipClientReadReceiptPost = true;
return;
}
if (!res.ok) return; if (!res.ok) return;
const row = state.tickets.find((x) => x.ticket_number === ticketNumber); const row = state.tickets.find((x) => x.ticket_number === ticketNumber);
if (row) row.has_unread = false; if (row) row.has_unread = false;
renderTickets(); renderTickets();
reapplyActiveTicketCard(ticketNumber);
}
function reapplyActiveTicketCard(ticketNumber) {
const tnSel = String(ticketNumber).replace(/\\/g, "\\\\").replace(/"/g, '\\"');
const card = document.querySelector(`.f7-ticket-card[data-ticket-number="${tnSel}"]`);
if (card) card.classList.add("f7-ticket-card--active");
} }
root.innerHTML = ` root.innerHTML = `
@@ -825,7 +845,11 @@
openChatModal(ticket); openChatModal(ticket);
try { try {
await fetchMessages(); await fetchMessages();
await markClientTicketRead(ticket.ticket_number); const row = state.tickets.find((x) => x.ticket_number === ticketNumber);
if (row) row.has_unread = false;
renderTickets();
reapplyActiveTicketCard(ticketNumber);
void markClientTicketRead(ticket.ticket_number);
connectTicketSocket(ticket.ticket_number); connectTicketSocket(ticket.ticket_number);
} catch (e) { } catch (e) {
showError(e.message || "Не удалось загрузить сообщения"); showError(e.message || "Не удалось загрузить сообщения");