feat(notify): web push as a notification channel
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m15s
MindSift CI & Docker Release / Build, Test in Container & Push (push) Successful in 2m15s
- VAPID keys from VAPID_* or generated once (push_keys, migration 9); devices in push_subscriptions, forgotten on 404/410 from the push service - push column for every event (also due tasks) and the daily summary, bundles as one notification; /push/key, /devices, /subscribe, /unsubscribe, /test - settings: switch push on per device, test it, see the devices; the service worker shows notifications and focuses MindSift on click - tests decrypt a sent push like a browser (RFC 8291) and check VAPID Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
1a49e6b304
commit
38b8c92899
27 files changed
+918
-27
No files matched your search
@@ -5,6 +5,7 @@ import {
|
||||
Document,
|
||||
TrashedDocument,
|
||||
JournalDay,
|
||||
PushDevice,
|
||||
BackupFile,
|
||||
DataSection,
|
||||
ApiKeyScope,
|
||||
@@ -724,6 +725,27 @@ export const api = {
|
||||
return request<TrashedDocument[]>('/api/v1/documents/trash');
|
||||
},
|
||||
|
||||
async getPushKey(): Promise<{ enabled: boolean; publicKey?: string }> {
|
||||
return request('/api/v1/push/key');
|
||||
},
|
||||
|
||||
async getPushDevices(): Promise<PushDevice[]> {
|
||||
const res = await request<{ devices: PushDevice[] }>('/api/v1/push/devices');
|
||||
return res.devices || [];
|
||||
},
|
||||
|
||||
async subscribePush(sub: PushSubscriptionJSON, device: string): Promise<void> {
|
||||
await request('/api/v1/push/subscribe', { method: 'POST', body: JSON.stringify({ ...sub, device }) });
|
||||
},
|
||||
|
||||
async unsubscribePush(endpoint: string): Promise<void> {
|
||||
await request('/api/v1/push/unsubscribe', { method: 'POST', body: JSON.stringify({ endpoint }) });
|
||||
},
|
||||
|
||||
async testPush(): Promise<{ devices: number }> {
|
||||
return request('/api/v1/push/test', { method: 'POST' });
|
||||
},
|
||||
|
||||
/** Days of the own journal (newest first) with their notes. */
|
||||
async getJournal(): Promise<JournalDay[]> {
|
||||
const res = await request<{ days: JournalDay[] }>('/api/v1/journal');
|
||||
|
||||
Reference in new issue
Block a user