@@ -18,28 +18,7 @@ async function sendPushNotification({title = APP_NAME, body = "", icon = "/image
1818 } ) ;
1919}
2020
21- async function handlePush ( event ) {
22- const clientList = await clients . matchAll ( { type : 'window' , includeUncontrolled : true } ) ;
23-
24- const isInsideChat = clientList . some ( client => {
25- const url = new URL ( client . url ) ;
26- return url . pathname . startsWith ( '/chat' ) && client . visibilityState === 'visible' ;
27- } ) ;
28-
29- var origin = "" + self . location . origin ;
30- origin = origin . trim ( ) ;
31- if ( origin . endsWith ( "/" ) ) {
32- origin = origin . slice ( 0 , origin . length - 1 ) ; //remove the ending slash.
33- }
34-
35- // Parse the data sent from your Node.js server
36- var json = null ;
37- if ( event . data ) {
38- json = event . data . json ( ) ;
39- } else {
40- return ;
41- }
42-
21+ async function handleNotification ( json ) {
4322 if ( json . type == "test" ) {
4423 sendPushNotification ( {
4524 body : "This is test notification"
@@ -65,6 +44,37 @@ async function handlePush(event) {
6544 }
6645}
6746
47+ async function handlePush ( event ) {
48+ const clientList = await clients . matchAll ( { type : 'window' , includeUncontrolled : true } ) ;
49+
50+ const isInsideChat = clientList . some ( client => {
51+ const url = new URL ( client . url ) ;
52+ return url . pathname . startsWith ( '/chat' ) && client . visibilityState === 'visible' ;
53+ } ) ;
54+
55+ var origin = "" + self . location . origin ;
56+ origin = origin . trim ( ) ;
57+ if ( origin . endsWith ( "/" ) ) {
58+ origin = origin . slice ( 0 , origin . length - 1 ) ; //remove the ending slash.
59+ }
60+
61+ // Parse the data sent from your Node.js server
62+ var json = null ;
63+ if ( event . data ) {
64+ json = event . data . json ( ) ;
65+ } else {
66+ return ;
67+ }
68+
69+ await handleNotification ( json ) ;
70+ }
71+
72+ function buildWsNotifyURL ( ) {
73+ var protocol = self . location . protocol === "https:" ? "wss://" : "ws://" ;
74+ var wsUrl = `${ protocol } ${ self . location . host } /notifications` ;
75+ return wsUrl ;
76+ }
77+
6878// 2. Handle Notification Clicks
6979self . addEventListener ( 'notificationclick' , ( event ) => {
7080 event . notification . close ( ) ;
@@ -98,4 +108,71 @@ self.addEventListener('install', (event) => {
98108
99109self . addEventListener ( 'activate' , ( event ) => {
100110 event . waitUntil ( clients . claim ( ) ) ;
111+ } ) ;
112+
113+ async function sendInitialNotifcations ( ) {
114+ var ws = new WebSocket ( wsUrl ) ;
115+
116+ setTimeout ( ( ) => {
117+ try {
118+
119+ } catch ( e ) {
120+ ws . close ( ) ;
121+ }
122+ } , 2000 ) ;
123+
124+ ws . onmessage = async function ( event ) {
125+ var json = JSON . parse ( event . data ) ;
126+
127+ if ( json . type == "current" ) {
128+ for ( const notif of json . notifications ) {
129+ await handleNotification ( notif ) ;
130+ }
131+ }
132+ } ;
133+ }
134+
135+ self . addEventListener ( 'message' , async ( event ) => {
136+ if ( event . data && event . data . type === 'HEARTBEAT' ) {
137+ var cache = await caches . open ( 'rr-meta' ) ;
138+ // Save the current timestamp
139+ await cache . put ( 'last-seen-online' , new Response ( Date . now ( ) . toString ( ) ) ) ;
140+ }
141+ } ) ;
142+
143+ async function checkReEngagement ( ) {
144+ var THREE_DAYS = 3 * 24 * 60 * 60 * 1000 ;
145+ var now = Date . now ( ) ;
146+
147+ var cache = await caches . open ( 'rr-meta' ) ;
148+ var lastSeenResponse = await cache . match ( 'last-seen-online' ) ;
149+
150+ if ( lastSeenResponse ) {
151+ var lastSeen = parseInt ( await lastSeenResponse . text ( ) ) ;
152+
153+ // If it's been more than 3 days since the last HEARTBEAT
154+ if ( now - lastSeen > THREE_DAYS ) {
155+ await sendPushNotification ( {
156+ title : "Missing the chaos?" ,
157+ body : "Your friends haven't seen you in a while! Jump back into the rants." ,
158+ tag : "re-engage" ,
159+ data : { targetURL : "/chat" }
160+ } ) ;
161+
162+ // Update timestamp so we don't nag them again for another 3 days
163+ await cache . put ( 'last-seen-online' , new Response ( now . toString ( ) ) ) ;
164+ }
165+ }
166+ }
167+
168+ var hasRunStartupCheck = false ;
169+
170+ self . addEventListener ( 'activate' , ( event ) => {
171+ event . waitUntil ( ( async ( ) => {
172+ if ( hasRunStartupCheck ) return ; // Skip if already done this session
173+ hasRunStartupCheck = true ;
174+
175+ await sendInitialNotifcations ( ) ;
176+ await checkReEngagement ( ) ;
177+ } ) ) ;
101178} ) ;
0 commit comments