2022-01-28 13:00:11 -08:00
import $ from 'jquery' ;
2020-04-24 04:57:38 +01:00
2022-01-28 13:00:11 -08:00
const { appSubUrl , csrfToken , notificationSettings } = window . config ;
2021-07-17 17:18:10 +01:00
let notificationSequenceNumber = 0 ;
2020-04-24 04:57:38 +01:00
export function initNotificationsTable ( ) {
2021-11-12 20:37:45 +08:00
$ ( '#notification_table .button' ) . on ( 'click' , function ( ) {
( async ( ) => {
const data = await updateNotification (
$ ( this ) . data ( 'url' ) ,
$ ( this ) . data ( 'status' ) ,
$ ( this ) . data ( 'page' ) ,
$ ( this ) . data ( 'q' ) ,
$ ( this ) . data ( 'notification-id' ) ,
) ;
2020-04-24 04:57:38 +01:00
2021-11-12 20:37:45 +08:00
if ( $ ( data ) . data ( 'sequence-number' ) === notificationSequenceNumber ) {
$ ( '#notification_div' ) . replaceWith ( data ) ;
initNotificationsTable ( ) ;
}
await updateNotificationCount ( ) ;
} ) ( ) ;
2020-04-24 04:57:38 +01:00
return false ;
} ) ;
}
2020-07-03 10:55:36 +01:00
async function receiveUpdateCount ( event ) {
try {
const data = JSON . parse ( event . data ) ;
const notificationCount = document . querySelector ( '.notification_count' ) ;
if ( data . Count > 0 ) {
notificationCount . classList . remove ( 'hidden' ) ;
} else {
notificationCount . classList . add ( 'hidden' ) ;
}
2020-07-04 23:04:00 +01:00
notificationCount . textContent = ` ${ data . Count } ` ;
2020-07-03 10:55:36 +01:00
await updateNotificationTable ( ) ;
} catch ( error ) {
console . error ( error , event ) ;
}
}
2021-11-09 17:27:25 +08:00
export function initNotificationCount ( ) {
2020-05-07 22:49:00 +01:00
const notificationCount = $ ( '.notification_count' ) ;
if ( ! notificationCount . length ) {
2020-04-24 04:57:38 +01:00
return ;
}
2021-10-21 15:37:43 +08:00
if ( notificationSettings . EventSourceUpdateTime > 0 && ! ! window . EventSource && window . SharedWorker ) {
2020-07-03 10:55:36 +01:00
// Try to connect to the event source via the shared worker first
2020-12-27 15:24:27 +01:00
const worker = new SharedWorker ( ` ${ _ _webpack _public _path _ _ } js/eventsource.sharedworker.js ` , 'notification-worker' ) ;
worker . addEventListener ( 'error' , ( event ) => {
console . error ( event ) ;
} ) ;
2021-08-17 07:32:48 +02:00
worker . port . addEventListener ( 'messageerror' , ( ) => {
2020-12-27 15:24:27 +01:00
console . error ( 'Unable to deserialize message' ) ;
2021-08-17 07:32:48 +02:00
} ) ;
2020-12-27 15:24:27 +01:00
worker . port . postMessage ( {
type : 'start' ,
2021-10-21 15:37:43 +08:00
url : ` ${ window . location . origin } ${ appSubUrl } /user/events ` ,
2020-12-27 15:24:27 +01:00
} ) ;
worker . port . addEventListener ( 'message' , ( event ) => {
if ( ! event . data || ! event . data . type ) {
2020-07-03 10:55:36 +01:00
console . error ( event ) ;
2020-12-27 15:24:27 +01:00
return ;
}
if ( event . data . type === 'notification-count' ) {
2021-11-09 17:27:25 +08:00
const _promise = receiveUpdateCount ( event . data ) ;
2020-12-27 15:24:27 +01:00
} else if ( event . data . type === 'error' ) {
console . error ( event . data ) ;
} else if ( event . data . type === 'logout' ) {
2021-04-08 00:48:13 +01:00
if ( event . data . data !== 'here' ) {
2020-07-03 10:55:36 +01:00
return ;
}
worker . port . postMessage ( {
type : 'close' ,
} ) ;
worker . port . close ( ) ;
2021-10-21 15:37:43 +08:00
window . location . href = appSubUrl ;
2021-04-04 22:37:50 +01:00
} else if ( event . data . type === 'close' ) {
worker . port . postMessage ( {
type : 'close' ,
} ) ;
worker . port . close ( ) ;
2020-12-27 15:24:27 +01:00
}
} ) ;
worker . port . addEventListener ( 'error' , ( e ) => {
console . error ( e ) ;
} ) ;
worker . port . start ( ) ;
window . addEventListener ( 'beforeunload' , ( ) => {
worker . port . postMessage ( {
type : 'close' ,
2020-07-03 10:55:36 +01:00
} ) ;
2020-12-27 15:24:27 +01:00
worker . port . close ( ) ;
} ) ;
2020-04-24 04:57:38 +01:00
2020-12-27 15:24:27 +01:00
return ;
2020-04-24 04:57:38 +01:00
}
2020-05-07 22:49:00 +01:00
2021-10-21 15:37:43 +08:00
if ( notificationSettings . MinTimeout <= 0 ) {
2020-05-07 22:49:00 +01:00
return ;
}
const fn = ( timeout , lastCount ) => {
2021-11-12 20:37:45 +08:00
setTimeout ( ( ) => {
const _promise = updateNotificationCountWithCallback ( fn , timeout , lastCount ) ;
2020-05-07 22:49:00 +01:00
} , timeout ) ;
} ;
2021-10-21 15:37:43 +08:00
fn ( notificationSettings . MinTimeout , notificationCount . text ( ) ) ;
2020-04-24 04:57:38 +01:00
}
async function updateNotificationCountWithCallback ( callback , timeout , lastCount ) {
const currentCount = $ ( '.notification_count' ) . text ( ) ;
if ( lastCount !== currentCount ) {
2021-10-21 15:37:43 +08:00
callback ( notificationSettings . MinTimeout , currentCount ) ;
2020-04-24 04:57:38 +01:00
return ;
}
const newCount = await updateNotificationCount ( ) ;
let needsUpdate = false ;
if ( lastCount !== newCount ) {
needsUpdate = true ;
2021-10-21 15:37:43 +08:00
timeout = notificationSettings . MinTimeout ;
} else if ( timeout < notificationSettings . MaxTimeout ) {
timeout += notificationSettings . TimeoutStep ;
2020-04-24 04:57:38 +01:00
}
callback ( timeout , newCount ) ;
2020-05-07 22:49:00 +01:00
if ( needsUpdate ) {
await updateNotificationTable ( ) ;
}
}
2020-04-24 04:57:38 +01:00
2020-05-07 22:49:00 +01:00
async function updateNotificationTable ( ) {
2020-04-24 04:57:38 +01:00
const notificationDiv = $ ( '#notification_div' ) ;
2020-05-07 22:49:00 +01:00
if ( notificationDiv . length > 0 ) {
2020-04-24 04:57:38 +01:00
const data = await $ . ajax ( {
type : 'GET' ,
2021-10-21 15:37:43 +08:00
url : ` ${ appSubUrl } /notifications? ${ notificationDiv . data ( 'params' ) } ` ,
2020-04-24 04:57:38 +01:00
data : {
'div-only' : true ,
2021-07-17 17:18:10 +01:00
'sequence-number' : ++ notificationSequenceNumber ,
2020-04-24 04:57:38 +01:00
}
} ) ;
2021-07-17 17:18:10 +01:00
if ( $ ( data ) . data ( 'sequence-number' ) === notificationSequenceNumber ) {
notificationDiv . replaceWith ( data ) ;
initNotificationsTable ( ) ;
}
2020-04-24 04:57:38 +01:00
}
}
async function updateNotificationCount ( ) {
const data = await $ . ajax ( {
type : 'GET' ,
2021-10-21 15:37:43 +08:00
url : ` ${ appSubUrl } /api/v1/notifications/new ` ,
2020-04-24 04:57:38 +01:00
headers : {
2021-10-21 15:37:43 +08:00
'X-Csrf-Token' : csrfToken ,
2020-04-24 04:57:38 +01:00
} ,
} ) ;
const notificationCount = $ ( '.notification_count' ) ;
if ( data . new === 0 ) {
notificationCount . addClass ( 'hidden' ) ;
} else {
notificationCount . removeClass ( 'hidden' ) ;
}
notificationCount . text ( ` ${ data . new } ` ) ;
return ` ${ data . new } ` ;
}
async function updateNotification ( url , status , page , q , notificationID ) {
if ( status !== 'pinned' ) {
$ ( ` #notification_ ${ notificationID } ` ) . remove ( ) ;
}
return $ . ajax ( {
type : 'POST' ,
url ,
data : {
2021-10-21 15:37:43 +08:00
_csrf : csrfToken ,
2020-04-24 04:57:38 +01:00
notification _id : notificationID ,
status ,
page ,
q ,
noredirect : true ,
2021-07-17 17:18:10 +01:00
'sequence-number' : ++ notificationSequenceNumber ,
2020-04-24 04:57:38 +01:00
} ,
} ) ;
}