@@ -11,52 +11,34 @@ import LocalStorage from '../utils/LocalStorage';
1111import { CustomLinkManager } from '../managers/CustomLinkManager' ;
1212
1313export default class EventHelper {
14- static _mutexPromise : Promise < void > = Promise . resolve ( ) ;
15- static _mutexLocked = false ;
16-
17- static async onNotificationPermissionChange ( ) {
18- await EventHelper . checkAndTriggerSubscriptionChanged ( ) ;
14+ static onNotificationPermissionChange ( ) {
15+ EventHelper . checkAndTriggerSubscriptionChanged ( ) ;
1916 }
2017
2118 static async onInternalSubscriptionSet ( optedOut : boolean ) {
2219 LimitStore . put ( 'subscription.optedOut' , optedOut ) ;
2320 }
2421
2522 static async checkAndTriggerSubscriptionChanged ( ) {
26- if ( EventHelper . _mutexLocked ) {
27- await EventHelper . _mutexPromise ;
28- }
29-
30- EventHelper . _mutexLocked = true ;
31- // eslint-disable-next-line no-async-promise-executor
32- EventHelper . _mutexPromise = new Promise ( async ( resolve , reject ) => {
33- try {
34- OneSignalUtils . logMethodCall ( 'checkAndTriggerSubscriptionChanged' ) ;
35- const context : ContextSWInterface = OneSignal . context ;
36- const subscriptionState = await context . subscriptionManager . getSubscriptionState ( ) ;
37- const isPushEnabled = await OneSignal . privateIsPushNotificationsEnabled ( ) ;
38- const appState = await Database . getAppState ( ) ;
39- const { lastKnownPushEnabled } = appState ;
40- const didStateChange = (
41- lastKnownPushEnabled === null ||
42- isPushEnabled !== lastKnownPushEnabled
43- ) ;
44- if ( ! didStateChange ) return ;
45- Log . info (
46- `The user's subscription state changed from ` +
47- `${ lastKnownPushEnabled === null ? '(not stored)' : lastKnownPushEnabled } ⟶ ${ subscriptionState . subscribed } `
48- ) ;
49- LocalStorage . setIsPushNotificationsEnabled ( isPushEnabled ) ;
50- appState . lastKnownPushEnabled = isPushEnabled ;
51- await Database . setAppState ( appState ) ;
52- EventHelper . triggerSubscriptionChanged ( isPushEnabled ) ;
53- EventHelper . _mutexLocked = false ;
54- resolve ( ) ;
55- } catch ( e ) {
56- EventHelper . _mutexLocked = false ;
57- reject ( `checkAndTriggerSubscriptionChanged error: ${ e } ` ) ;
58- }
59- } ) ;
23+ OneSignalUtils . logMethodCall ( 'checkAndTriggerSubscriptionChanged' ) ;
24+ const context : ContextSWInterface = OneSignal . context ;
25+ const subscriptionState = await context . subscriptionManager . getSubscriptionState ( ) ;
26+ const isPushEnabled = await OneSignal . privateIsPushNotificationsEnabled ( ) ;
27+ const appState = await Database . getAppState ( ) ;
28+ const { lastKnownPushEnabled } = appState ;
29+ const didStateChange = (
30+ lastKnownPushEnabled === null ||
31+ isPushEnabled !== lastKnownPushEnabled
32+ ) ;
33+ if ( ! didStateChange ) return ;
34+ Log . info (
35+ `The user's subscription state changed from ` +
36+ `${ lastKnownPushEnabled === null ? '(not stored)' : lastKnownPushEnabled } ⟶ ${ subscriptionState . subscribed } `
37+ ) ;
38+ LocalStorage . setIsPushNotificationsEnabled ( isPushEnabled ) ;
39+ appState . lastKnownPushEnabled = isPushEnabled ;
40+ await Database . setAppState ( appState ) ;
41+ EventHelper . triggerSubscriptionChanged ( isPushEnabled ) ;
6042 }
6143
6244 static async _onSubscriptionChanged ( newSubscriptionState : boolean | undefined ) {
@@ -77,58 +59,70 @@ export default class EventHelper {
7759 }
7860 }
7961
62+ private static sendingOrSentWelcomeNotification = false ;
8063 private static async onSubscriptionChanged_showWelcomeNotification ( isSubscribed : boolean | undefined ) {
8164 if ( OneSignal . __doNotShowWelcomeNotification ) {
8265 Log . debug ( 'Not showing welcome notification because user has previously subscribed.' ) ;
8366 return ;
8467 }
85- if ( isSubscribed === true ) {
86- const { deviceId } = await Database . getSubscription ( ) ;
87- const { appId } = await Database . getAppConfig ( ) ;
88-
89- const welcome_notification_opts = OneSignal . config . userConfig . welcomeNotification ;
90- const welcome_notification_disabled =
91- welcome_notification_opts !== undefined && welcome_notification_opts [ 'disable' ] === true ;
92- let title =
93- welcome_notification_opts !== undefined &&
94- welcome_notification_opts [ 'title' ] !== undefined &&
95- welcome_notification_opts [ 'title' ] !== null
96- ? welcome_notification_opts [ 'title' ]
97- : '' ;
98- let message =
99- welcome_notification_opts !== undefined &&
100- welcome_notification_opts [ 'message' ] !== undefined &&
101- welcome_notification_opts [ 'message' ] !== null &&
102- welcome_notification_opts [ 'message' ] . length > 0
103- ? welcome_notification_opts [ 'message' ]
104- : 'Thanks for subscribing!' ;
105- const unopenableWelcomeNotificationUrl = new URL ( location . href ) . origin + '?_osp=do_not_open' ;
106- const url =
107- welcome_notification_opts && welcome_notification_opts [ 'url' ] && welcome_notification_opts [ 'url' ] . length > 0
108- ? welcome_notification_opts [ 'url' ]
109- : unopenableWelcomeNotificationUrl ;
110- title = BrowserUtils . decodeHtmlEntities ( title ) ;
111- message = BrowserUtils . decodeHtmlEntities ( message ) ;
112-
113- if ( ! welcome_notification_disabled ) {
114- Log . debug ( 'Sending welcome notification.' ) ;
115- OneSignalApiShared . sendNotification (
116- appId ,
117- [ deviceId ] ,
118- { en : title } ,
119- { en : message } ,
120- url ,
121- null ,
122- { __isOneSignalWelcomeNotification : true } ,
123- undefined
124- ) ;
125- Event . trigger ( OneSignal . EVENTS . WELCOME_NOTIFICATION_SENT , {
126- title : title ,
127- message : message ,
128- url : url
129- } ) ;
130- }
68+ const welcome_notification_opts = OneSignal . config . userConfig . welcomeNotification ;
69+ const welcome_notification_disabled =
70+ welcome_notification_opts !== undefined && welcome_notification_opts [ 'disable' ] === true ;
71+
72+ if ( welcome_notification_disabled ) {
73+ return ;
13174 }
75+
76+ if ( isSubscribed !== true ) {
77+ return ;
78+ }
79+
80+ // Workaround only for this v15 branch; There are race conditions in the SDK
81+ // that result in the onSubscriptionChanged firing more than once sometimes.
82+ if ( EventHelper . sendingOrSentWelcomeNotification ) {
83+ return ;
84+ }
85+ EventHelper . sendingOrSentWelcomeNotification = true ;
86+
87+ const { deviceId } = await Database . getSubscription ( ) ;
88+ const { appId } = await Database . getAppConfig ( ) ;
89+ let title =
90+ welcome_notification_opts !== undefined &&
91+ welcome_notification_opts [ 'title' ] !== undefined &&
92+ welcome_notification_opts [ 'title' ] !== null
93+ ? welcome_notification_opts [ 'title' ]
94+ : '' ;
95+ let message =
96+ welcome_notification_opts !== undefined &&
97+ welcome_notification_opts [ 'message' ] !== undefined &&
98+ welcome_notification_opts [ 'message' ] !== null &&
99+ welcome_notification_opts [ 'message' ] . length > 0
100+ ? welcome_notification_opts [ 'message' ]
101+ : 'Thanks for subscribing!' ;
102+ const unopenableWelcomeNotificationUrl = new URL ( location . href ) . origin + '?_osp=do_not_open' ;
103+ const url =
104+ welcome_notification_opts && welcome_notification_opts [ 'url' ] && welcome_notification_opts [ 'url' ] . length > 0
105+ ? welcome_notification_opts [ 'url' ]
106+ : unopenableWelcomeNotificationUrl ;
107+ title = BrowserUtils . decodeHtmlEntities ( title ) ;
108+ message = BrowserUtils . decodeHtmlEntities ( message ) ;
109+
110+ Log . debug ( 'Sending welcome notification.' ) ;
111+ OneSignalApiShared . sendNotification (
112+ appId ,
113+ [ deviceId ] ,
114+ { en : title } ,
115+ { en : message } ,
116+ url ,
117+ null ,
118+ { __isOneSignalWelcomeNotification : true } ,
119+ undefined
120+ ) ;
121+ Event . trigger ( OneSignal . EVENTS . WELCOME_NOTIFICATION_SENT , {
122+ title : title ,
123+ message : message ,
124+ url : url
125+ } ) ;
132126 }
133127
134128 private static async onSubscriptionChanged_evaluateNotifyButtonDisplayPredicate ( ) {
0 commit comments