diff --git a/backend/extension-src/background.js b/backend/extension-src/background.js index 6c872fd..6859212 100644 --- a/backend/extension-src/background.js +++ b/backend/extension-src/background.js @@ -107,7 +107,12 @@ async function pushBooking(bookingId, deviceId) { // from other failures — used by content-script.js's default-tablet // fast-path to decide whether to fall back to the device picker. if (!res.ok) return { ok: false, status: res.status, error: body.error || `HTTP ${res.status}` }; - return { ok: true, status: res.status }; + // delivered: false means the push landed server-side (a session was + // created, the tablet will pick it up if it reconnects) but there's no + // live SSE connection for that device right now — e.g. its kiosk tab + // isn't open, or its WiFi dropped. Passed through so callers can warn + // honestly instead of claiming success a disconnected tablet never saw. + return { ok: true, status: res.status, delivered: body.delivered }; } catch (err) { return { ok: false, error: err.message }; } diff --git a/backend/extension-src/content-script.js b/backend/extension-src/content-script.js index bde89ed..c13cfb0 100644 --- a/backend/extension-src/content-script.js +++ b/backend/extension-src/content-script.js @@ -131,8 +131,13 @@ async function handleSendClick(anchorBtn, bookingId, guestName, variant) { return; } if (result?.ok) { - status.textContent = 'Sent — the tablet should navigate now.'; - status.style.color = '#166534'; + if (result.delivered === false) { + status.textContent = 'Sent, but that tablet isn’t connected right now — it’ll pick this up if it reconnects.'; + status.style.color = '#b45309'; + } else { + status.textContent = 'Sent — the tablet should navigate now.'; + status.style.color = '#166534'; + } return; } if (result?.status === 409) { @@ -256,7 +261,10 @@ async function togglePanel(anchorBtn, bookingId, guestName, variant = 'block', n action: 'tcpPush', bookingId, deviceId: select.value, }); if (result?.ok) { - panel.textContent = 'Sent — the tablet should navigate now.'; + panel.textContent = result.delivered === false + ? 'Sent, but that tablet isn’t connected right now — it’ll pick this up if it reconnects.' + : 'Sent — the tablet should navigate now.'; + panel.style.color = result.delivered === false ? '#b45309' : '#1e293b'; } else { panel.textContent = `Failed: ${result?.error || 'unknown error'}`; } diff --git a/backend/extension-src/popup/popup.js b/backend/extension-src/popup/popup.js index 1f7f68d..5fd398a 100644 --- a/backend/extension-src/popup/popup.js +++ b/backend/extension-src/popup/popup.js @@ -127,7 +127,11 @@ function renderBooking(el, bookingId, devices, defaultDeviceId, baseUrl, apiKey) if (!msgEl) return; // "Send to a different tablet" was clicked before this resolved if (result.ok) { - setMsg(msgEl, 'Sent — the tablet should navigate now.', 'ok'); + if (result.delivered === false) { + setMsg(msgEl, 'Sent, but that tablet isn’t connected right now — it’ll pick this up if it reconnects.', 'warn'); + } else { + setMsg(msgEl, 'Sent — the tablet should navigate now.', 'ok'); + } } else if (result.status === 409) { // Default went busy in the moment between loading the popup and // sending — fall back to the manual picker rather than leaving the @@ -172,7 +176,11 @@ function renderPicker(el, bookingId, devices, defaultDeviceId, baseUrl, apiKey, setMsg(msgEl, 'Sending…', 'warn'); const result = await sendPush(bookingId, deviceSelect.value, baseUrl, apiKey); if (result.ok) { - setMsg(msgEl, 'Sent — the tablet should navigate now.', 'ok'); + if (result.delivered === false) { + setMsg(msgEl, 'Sent, but that tablet isn’t connected right now — it’ll pick this up if it reconnects.', 'warn'); + } else { + setMsg(msgEl, 'Sent — the tablet should navigate now.', 'ok'); + } } else if (result.status === 409) { setMsg(msgEl, result.error || 'That tablet is busy with another guest right now.', 'warn'); } else { @@ -191,7 +199,7 @@ async function sendPush(bookingId, deviceId, baseUrl, apiKey) { }); const body = await res.json().catch(() => ({})); if (!res.ok) return { ok: false, status: res.status, error: body.error || `HTTP ${res.status}` }; - return { ok: true }; + return { ok: true, delivered: body.delivered }; } catch (err) { return { ok: false, status: 0, error: err.message }; }