2026-01-22 01:19:24 +02:00
|
|
|
import type { PushAPI, PushSubscribePayload, PushUnsubscribePayload } from '@openchamber/ui/lib/api/types';
|
2026-06-02 00:43:05 +03:00
|
|
|
import { runtimeFetch } from '@openchamber/ui/lib/runtime-fetch';
|
2026-01-22 01:19:24 +02:00
|
|
|
|
2026-06-02 00:43:05 +03:00
|
|
|
const fetchJson = async <T>(input: string | URL | Request, init?: RequestInit): Promise<T | null> => {
|
2026-01-22 01:19:24 +02:00
|
|
|
try {
|
2026-06-02 00:43:05 +03:00
|
|
|
const res = await runtimeFetch(input, {
|
2026-01-22 01:19:24 +02:00
|
|
|
...init,
|
|
|
|
|
credentials: 'include',
|
|
|
|
|
headers: {
|
|
|
|
|
Accept: 'application/json',
|
|
|
|
|
...(init?.headers ?? {}),
|
|
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
if (!res.ok) {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return (await res.json()) as T;
|
|
|
|
|
} catch {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
export const createWebPushAPI = (): PushAPI => ({
|
|
|
|
|
async getVapidPublicKey() {
|
|
|
|
|
return fetchJson<{ publicKey: string }>('/api/push/vapid-public-key');
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async subscribe(payload: PushSubscribePayload) {
|
|
|
|
|
return fetchJson<{ ok: true }>('/api/push/subscribe', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async unsubscribe(payload: PushUnsubscribePayload) {
|
|
|
|
|
return fetchJson<{ ok: true }>('/api/push/subscribe', {
|
|
|
|
|
method: 'DELETE',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
async setVisibility(payload: { visible: boolean }) {
|
|
|
|
|
return fetchJson<{ ok: true }>('/api/push/visibility', {
|
|
|
|
|
method: 'POST',
|
|
|
|
|
headers: {
|
|
|
|
|
'Content-Type': 'application/json',
|
|
|
|
|
},
|
|
|
|
|
body: JSON.stringify(payload),
|
|
|
|
|
keepalive: true,
|
|
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
});
|