-
Notifications
You must be signed in to change notification settings - Fork 5
Notification done #36
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| import webpush, { PushSubscription } from 'web-push'; | ||
| import { env } from "../configs/env.config"; | ||
| import { scheduleJob } from 'node-schedule'; | ||
|
|
||
| // Configure web-push | ||
| webpush.setVapidDetails( | ||
| 'mailto:mohit@teziapp.com', | ||
| env.VAPID_PUBLIC_KEY, | ||
| env.VAPID_PRIVATE_KEY | ||
| ); | ||
|
|
||
| // In-memory storage for subscriptions (replace with database in production) | ||
| const pushSubscriptions = new Set<PushSubscription>(); | ||
|
|
||
| export function addSubscription(subscription: PushSubscription) { | ||
| pushSubscriptions.add(subscription); | ||
| } | ||
|
|
||
| export function removeSubscription(subscription: PushSubscription) { | ||
| pushSubscriptions.delete(subscription); | ||
| } | ||
|
|
||
|
Comment on lines
+15
to
+22
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If multiple instances of backend are running in production, this will lead to same notification being sent to user multiple times. |
||
| export async function sendNotificationToAll(title: string, body: string) { | ||
| for (const subscription of pushSubscriptions) { | ||
| try { | ||
| await webpush.sendNotification(subscription, JSON.stringify({ title, body })); | ||
| } catch (error) { | ||
| console.error('Error sending notification:', error); | ||
| pushSubscriptions.delete(subscription); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| // Schedule a notification every 5 seconds | ||
| export function scheduleFrequentNotification() { | ||
| scheduleJob('*/5 * * * * *', async () => { | ||
| console.log('Sending notification'); | ||
| await sendNotificationToAll('Frequent Update', 'Here is your notification every 5 seconds!'); | ||
| }); | ||
| } | ||
|
Comment on lines
+34
to
+40
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand you needed this for dev, but then have guardrails to run only in |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,73 @@ | ||
| /// <reference types="vite-plugin-pwa/client" /> | ||
| import React, { useState, useCallback } from "react"; | ||
| import { Dialog, DialogTitle, DialogContent, DialogActions, Button, Typography, Box} from "@mui/material"; | ||
| import { registerSW } from "virtual:pwa-register"; | ||
| import { toast } from 'react-toastify'; | ||
| import { NotificationToggle } from "./settings/drawer/NotificationToggle"; | ||
|
|
||
| const ServiceWorkerUpdateDialog: React.FC = () => { | ||
| const [updateAvailable, setUpdateAvailable] = useState(false); | ||
|
|
||
| // // Static update function | ||
| const updateSWFunction = registerSW({ | ||
| onNeedRefresh() { | ||
| setUpdateAvailable(true); | ||
| }, | ||
| onOfflineReady() { | ||
| toast.success('App is ready for offline use'); | ||
| }, | ||
| }); | ||
|
|
||
| const handleUpdate = () => { | ||
| updateSWFunction(true); // This triggers the installation of the new SW | ||
|
|
||
| navigator.serviceWorker.getRegistration().then((registration) => { | ||
| if (registration?.waiting) { | ||
| // Tell the service worker to skip the waiting phase and activate | ||
| registration.waiting.postMessage({ type: 'SKIP_WAITING' }); | ||
|
|
||
| // Reload the page when the new service worker takes control | ||
| registration.waiting.addEventListener('statechange', (event) => { | ||
| if ((event.target as ServiceWorker).state === 'activated') { | ||
| window.location.reload(); | ||
| } | ||
| }); | ||
| } | ||
| }); | ||
|
|
||
| setUpdateAvailable(false); // Close the modal | ||
| }; | ||
|
|
||
| const handleClose = useCallback(() => { | ||
| setUpdateAvailable(false); | ||
| }, []); | ||
|
|
||
| return ( | ||
| <Dialog | ||
| open={updateAvailable} | ||
| onClose={handleClose} | ||
| aria-labelledby="update-dialog-title" | ||
| > | ||
| <DialogTitle id="update-dialog-title">An update is available!</DialogTitle> | ||
| <DialogContent> | ||
| <Box sx={{ mb: 2 }}> | ||
| <Typography>Performance Improvement Update</Typography> | ||
| <Typography variant="h6">New Features:</Typography> | ||
| <ul> | ||
| <li>Customizations Added</li> | ||
| <li>Bug Fixes</li> | ||
| <li>Feature Improvements</li> | ||
| </ul> | ||
| </Box> | ||
| <NotificationToggle /> | ||
| </DialogContent> | ||
| <DialogActions> | ||
| <Button onClick={handleUpdate} variant="contained" color="primary"> | ||
| Update | ||
| </Button> | ||
| </DialogActions> | ||
| </Dialog> | ||
| ); | ||
| }; | ||
|
|
||
| export default ServiceWorkerUpdateDialog; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,14 @@ | ||
| import CustomToggleButton, { CustomToggleButtonProps } from '@/theme/CustomToggleButton'; | ||
| import { handleNotificationSubscription } from '@/utils/handleNotification'; | ||
|
|
||
| export const NotificationToggle = () => { | ||
|
|
||
| const property : CustomToggleButtonProps= { | ||
| initialState: false, | ||
| label: 'Enable Notifications', | ||
| direction: 'row' as const, | ||
| onToggleFunction: handleNotificationSubscription | ||
| }; | ||
|
|
||
| return <CustomToggleButton {...property} />; | ||
| }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This needs to be trpc routes.