feat(push): add phase7 offline push queue, worker, APIs, and simulator inbox
This commit is contained in:
@@ -134,6 +134,9 @@
|
||||
<option value="camera">camera</option>
|
||||
</select>
|
||||
|
||||
<label>Push Token (simulated)</label>
|
||||
<input id="pushToken" placeholder="optional push token for offline delivery" />
|
||||
|
||||
<div class="row">
|
||||
<button id="registerBtn">Register Device</button>
|
||||
<button id="loadSavedBtn" class="alt">Load Saved</button>
|
||||
@@ -189,6 +192,7 @@
|
||||
lastMotionEventId: null,
|
||||
lastStreamSessionId: null,
|
||||
lastRecordingId: null,
|
||||
latestPushNotificationId: null,
|
||||
};
|
||||
|
||||
const $ = (id) => document.getElementById(id);
|
||||
@@ -208,7 +212,11 @@
|
||||
$('deviceState').textContent = JSON.stringify({ device: state.device, hasToken: Boolean(state.deviceToken) }, null, 2);
|
||||
$('clientState').textContent = JSON.stringify({ lastStreamSessionId: state.lastStreamSessionId }, null, 2);
|
||||
$('cameraState').textContent = JSON.stringify(
|
||||
{ lastMotionEventId: state.lastMotionEventId, lastRecordingId: state.lastRecordingId },
|
||||
{
|
||||
lastMotionEventId: state.lastMotionEventId,
|
||||
lastRecordingId: state.lastRecordingId,
|
||||
latestPushNotificationId: state.latestPushNotificationId,
|
||||
},
|
||||
null,
|
||||
2,
|
||||
);
|
||||
@@ -338,6 +346,7 @@
|
||||
name: name || undefined,
|
||||
platform: 'web',
|
||||
appVersion: 'sim-1',
|
||||
pushToken: $('pushToken').value.trim() || undefined,
|
||||
}),
|
||||
});
|
||||
|
||||
@@ -361,6 +370,21 @@
|
||||
log('loaded saved device', parsed);
|
||||
});
|
||||
|
||||
$('loadSavedBtn').addEventListener('click', async () => {
|
||||
try {
|
||||
if (!state.device?.id) return;
|
||||
const token = $('pushToken').value.trim();
|
||||
if (!token) return;
|
||||
await authFetch(`/devices/${state.device.id}`, {
|
||||
method: 'PATCH',
|
||||
body: JSON.stringify({ pushToken: token }),
|
||||
});
|
||||
log('push token updated', { deviceId: state.device.id });
|
||||
} catch (error) {
|
||||
log('push token update failed', { error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
$('connectBtn').addEventListener('click', () => {
|
||||
try {
|
||||
connectSocket();
|
||||
@@ -534,6 +558,55 @@
|
||||
}
|
||||
});
|
||||
|
||||
const pushPanel = document.createElement('section');
|
||||
pushPanel.className = 'panel';
|
||||
pushPanel.style.marginTop = '16px';
|
||||
pushPanel.innerHTML = `
|
||||
<h2>Push Inbox (Offline Fallback)</h2>
|
||||
<div class="row">
|
||||
<button id="dispatchPushWorkerBtn" class="alt">Dispatch Push Worker</button>
|
||||
<button id="pollPushInboxBtn" class="alt">Poll Push Inbox</button>
|
||||
</div>
|
||||
<button id="markLatestPushReadBtn" class="alt">Mark Latest Push Read</button>
|
||||
`;
|
||||
document.querySelector('.page').appendChild(pushPanel);
|
||||
|
||||
$('dispatchPushWorkerBtn').addEventListener('click', async () => {
|
||||
try {
|
||||
const payload = await deviceFetch('/push-notifications/worker/dispatch', { method: 'POST', body: JSON.stringify({}) });
|
||||
log('push worker dispatch', payload);
|
||||
} catch (error) {
|
||||
log('push worker dispatch failed', { error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
$('pollPushInboxBtn').addEventListener('click', async () => {
|
||||
try {
|
||||
const payload = await deviceFetch('/push-notifications/me');
|
||||
const latest = payload.notifications?.[0];
|
||||
if (latest) {
|
||||
state.latestPushNotificationId = latest.id;
|
||||
}
|
||||
render();
|
||||
log('push inbox', payload);
|
||||
} catch (error) {
|
||||
log('poll push inbox failed', { error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
$('markLatestPushReadBtn').addEventListener('click', async () => {
|
||||
try {
|
||||
if (!state.latestPushNotificationId) throw new Error('No push notification selected');
|
||||
const payload = await deviceFetch(`/push-notifications/${state.latestPushNotificationId}/read`, {
|
||||
method: 'POST',
|
||||
body: JSON.stringify({}),
|
||||
});
|
||||
log('push marked read', payload);
|
||||
} catch (error) {
|
||||
log('mark push read failed', { error: error.message });
|
||||
}
|
||||
});
|
||||
|
||||
render();
|
||||
</script>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user