@@ -58,6 +58,7 @@ import { extractGDevelopApiErrorStatusAndCode } from '../Utils/GDevelopServices/
5858import { showErrorBox } from '../UI/Messages/MessageBox' ;
5959import { userCancellationErrorName } from '../LoginProvider/Utils' ;
6060import { listUserPurchases } from '../Utils/GDevelopServices/Shop' ;
61+ import { listNotifications } from '../Utils/GDevelopServices/Notification' ;
6162
6263type Props = { |
6364 authentication : Authentication ,
@@ -94,6 +95,7 @@ const cleanUserTracesOnDevice = async () => {
9495} ;
9596
9697const TEN_SECONDS = 10 * 1000 ;
98+ const ONE_MINUTE = 6 * TEN_SECONDS ;
9799
98100export default class AuthenticatedUserProvider extends React . Component <
99101 Props ,
@@ -123,6 +125,7 @@ export default class AuthenticatedUserProvider extends React.Component<
123125 _automaticallyUpdateUserProfile = true ;
124126 _hasNotifiedUserAboutEmailVerification = false ;
125127 _abortController : ?AbortController = null ;
128+ _notificationPollingIntervalId : ?IntervalID = null ;
126129
127130 // Cloud projects are requested in 2 different places at app opening.
128131 // - First one comes from user authenticating and automatically fetching
@@ -212,6 +215,7 @@ export default class AuthenticatedUserProvider extends React.Component<
212215 onRefreshLimits : this . _fetchUserLimits ,
213216 onRefreshGameTemplatePurchases : this . _fetchUserGameTemplatePurchases ,
214217 onRefreshAssetPackPurchases : this . _fetchUserAssetPackPurchases ,
218+ onRefreshNotifications : this . _fetchUserNotifications ,
215219 onPurchaseSuccessful : this . _fetchUserProducts ,
216220 onSendEmailVerification : this . _doSendEmailVerification ,
217221 onOpenEmailVerificationDialog : ( {
@@ -239,6 +243,10 @@ export default class AuthenticatedUserProvider extends React.Component<
239243 // - When the user logs out.
240244 // - When the user deletes their account.
241245 _markAuthenticatedUserAsLoggedOut ( ) {
246+ if ( this . _notificationPollingIntervalId ) {
247+ clearInterval ( this . _notificationPollingIntervalId ) ;
248+ this . _notificationPollingIntervalId = null ;
249+ }
242250 this . setState ( ( { authenticatedUser } ) => ( {
243251 authenticatedUser : {
244252 ...authenticatedUser ,
@@ -267,6 +275,10 @@ export default class AuthenticatedUserProvider extends React.Component<
267275 try {
268276 const firebaseUser = await authentication . getFirebaseUser ( ) ;
269277 if ( ! firebaseUser ) {
278+ if ( this . _notificationPollingIntervalId ) {
279+ clearInterval ( this . _notificationPollingIntervalId ) ;
280+ this . _notificationPollingIntervalId = null ;
281+ }
270282 this . setState ( ( { authenticatedUser } ) => ( {
271283 authenticatedUser : {
272284 ...authenticatedUser ,
@@ -503,6 +515,7 @@ export default class AuthenticatedUserProvider extends React.Component<
503515 }
504516 ) ;
505517 this . _fetchUserBadges ( ) ;
518+ this . _fetchUserNotifications ( ) ;
506519
507520 // Load and wait for the user profile to be fetched.
508521 // (and let the error propagate if any).
@@ -523,6 +536,15 @@ export default class AuthenticatedUserProvider extends React.Component<
523536 }
524537 }
525538
539+ if ( ! this . _notificationPollingIntervalId ) {
540+ this . _notificationPollingIntervalId = setInterval ( ( ) => {
541+ // This property is correctly updated by Electron, browsers and capacitor.
542+ if ( document . visibilityState === 'visible' ) {
543+ this . _fetchUserNotifications ( ) ;
544+ }
545+ } , 10 * ONE_MINUTE ) ;
546+ }
547+
526548 this . setState (
527549 ( { authenticatedUser } ) => ( {
528550 authenticatedUser : {
@@ -561,6 +583,28 @@ export default class AuthenticatedUserProvider extends React.Component<
561583 }
562584 } ;
563585
586+ _fetchUserNotifications = async ( ) = > {
587+ const { authentication } = this . props ;
588+ const firebaseUser = this . state . authenticatedUser . firebaseUser ;
589+ if ( ! firebaseUser ) return ;
590+
591+ try {
592+ const notifications = await listNotifications (
593+ authentication . getAuthorizationHeader ,
594+ { userId : firebaseUser . uid }
595+ ) ;
596+
597+ this . setState ( ( { authenticatedUser } ) => ( {
598+ authenticatedUser : {
599+ ...authenticatedUser ,
600+ notifications,
601+ } ,
602+ } ) ) ;
603+ } catch ( error ) {
604+ console . error ( 'Error while loading user notifications:' , error ) ;
605+ }
606+ } ;
607+
564608 _fetchUserUsages = async ( ) = > {
565609 const { authentication } = this . props ;
566610 const firebaseUser = this . state . authenticatedUser . firebaseUser ;
0 commit comments