releasebird-javascript-sdk 1.0.38 → 1.0.40
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +9 -0
- package/.idea/inspectionProfiles/Project_Default.xml +6 -0
- package/build/index.js +1 -1
- package/package.json +1 -1
- package/published/1.0.39/index.js +1 -0
- package/published/1.0.40/index.js +1 -0
- package/published/latest/index.js +1 -1
- package/src/RbirdBannerManager.js +378 -0
- package/src/RbirdScreenshotManager.js +43 -23
- package/src/index.js +7 -0
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
import RbirdUtils from './RbirdUtils';
|
|
2
|
+
import RbirdSessionManager from './RbirdSessionManager';
|
|
3
|
+
|
|
4
|
+
const API = RbirdUtils.API;
|
|
5
|
+
|
|
6
|
+
export class RbirdBannerManager {
|
|
7
|
+
static instance;
|
|
8
|
+
|
|
9
|
+
constructor() {
|
|
10
|
+
this.banners = [];
|
|
11
|
+
this.displayedBanners = new Set();
|
|
12
|
+
this.apiKey = null;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
static getInstance() {
|
|
16
|
+
if (!RbirdBannerManager.instance) {
|
|
17
|
+
RbirdBannerManager.instance = new RbirdBannerManager();
|
|
18
|
+
}
|
|
19
|
+
return RbirdBannerManager.instance;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
init(apiKey) {
|
|
23
|
+
if (typeof window === 'undefined') return;
|
|
24
|
+
this.apiKey = apiKey;
|
|
25
|
+
this.fetchAndDisplayBanners();
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
fetchAndDisplayBanners() {
|
|
29
|
+
const sessionManager = RbirdSessionManager.getInstance();
|
|
30
|
+
const state = sessionManager.getState();
|
|
31
|
+
|
|
32
|
+
const http = new XMLHttpRequest();
|
|
33
|
+
http.open("GET", `${API}/ewidget/banners/active`);
|
|
34
|
+
http.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
35
|
+
http.setRequestHeader("apiKey", this.apiKey);
|
|
36
|
+
|
|
37
|
+
// Send user identification for filtering dismissed banners
|
|
38
|
+
if (state?.identify?.people) {
|
|
39
|
+
http.setRequestHeader("peopleId", state.identify.people);
|
|
40
|
+
}
|
|
41
|
+
if (sessionManager.anonymousIdentifier) {
|
|
42
|
+
http.setRequestHeader("anonymousId", sessionManager.anonymousIdentifier);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const self = this;
|
|
46
|
+
http.onreadystatechange = function () {
|
|
47
|
+
if (http.readyState === 4) {
|
|
48
|
+
if (http.status === 200) {
|
|
49
|
+
try {
|
|
50
|
+
const response = JSON.parse(http.responseText);
|
|
51
|
+
self.banners = response;
|
|
52
|
+
self.renderBanners();
|
|
53
|
+
} catch (exp) {
|
|
54
|
+
console.error('Error parsing banners response:', exp);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
http.send();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
renderBanners() {
|
|
63
|
+
if (!this.banners || this.banners.length === 0) return;
|
|
64
|
+
|
|
65
|
+
this.banners.forEach(banner => {
|
|
66
|
+
if (banner.type === 'INLINE') {
|
|
67
|
+
this.renderInlineBanner(banner);
|
|
68
|
+
} else if (banner.type === 'FLOATING') {
|
|
69
|
+
this.renderFloatingBanner(banner);
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
renderInlineBanner(banner) {
|
|
75
|
+
// Find all elements with data-rbird-banner attribute matching the banner's placement
|
|
76
|
+
const targetElements = document.querySelectorAll(`[data-rbird-banner="${banner.placement || 'default'}"]`);
|
|
77
|
+
|
|
78
|
+
targetElements.forEach(targetElement => {
|
|
79
|
+
const bannerElement = this.createBannerElement(banner, false);
|
|
80
|
+
targetElement.appendChild(bannerElement);
|
|
81
|
+
this.displayedBanners.add(banner.id);
|
|
82
|
+
this.trackImpression(banner.id);
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
renderFloatingBanner(banner) {
|
|
87
|
+
const bannerElement = this.createBannerElement(banner, true);
|
|
88
|
+
document.body.appendChild(bannerElement);
|
|
89
|
+
this.displayedBanners.add(banner.id);
|
|
90
|
+
this.trackImpression(banner.id);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
createBannerElement(banner, isFloating) {
|
|
94
|
+
const container = document.createElement('div');
|
|
95
|
+
container.className = isFloating ? 'rbird-banner-floating' : 'rbird-banner-inline';
|
|
96
|
+
container.id = `rbird-banner-${banner.id}`;
|
|
97
|
+
container.setAttribute('data-banner-id', banner.id);
|
|
98
|
+
|
|
99
|
+
// Get user language
|
|
100
|
+
const userLang = navigator.language?.split('-')[0] || 'de';
|
|
101
|
+
const title = banner.title?.[userLang] || banner.title?.['de'] || '';
|
|
102
|
+
const message = banner.message?.[userLang] || banner.message?.['de'] || '';
|
|
103
|
+
const buttonText = banner.buttonText?.[userLang] || banner.buttonText?.['de'] || '';
|
|
104
|
+
|
|
105
|
+
// Create banner HTML structure
|
|
106
|
+
const bannerHTML = `
|
|
107
|
+
<div class="rbird-banner-content" style="${this.getBannerStyles(banner, isFloating)}">
|
|
108
|
+
<button class="rbird-banner-close" data-banner-id="${banner.id}" style="${this.getCloseButtonStyles()}">
|
|
109
|
+
×
|
|
110
|
+
</button>
|
|
111
|
+
<div class="rbird-banner-body">
|
|
112
|
+
${title ? `<h3 class="rbird-banner-title" style="${this.getTitleStyles()}">${this.escapeHtml(title)}</h3>` : ''}
|
|
113
|
+
${message ? `<p class="rbird-banner-message" style="${this.getMessageStyles()}">${this.escapeHtml(message)}</p>` : ''}
|
|
114
|
+
${banner.showButton && buttonText ? `
|
|
115
|
+
<button class="rbird-banner-cta" data-banner-id="${banner.id}" style="${this.getCtaButtonStyles(banner)}">
|
|
116
|
+
${this.escapeHtml(buttonText)}
|
|
117
|
+
</button>
|
|
118
|
+
` : ''}
|
|
119
|
+
</div>
|
|
120
|
+
</div>
|
|
121
|
+
`;
|
|
122
|
+
|
|
123
|
+
container.innerHTML = bannerHTML;
|
|
124
|
+
|
|
125
|
+
// Add position styles for floating banners
|
|
126
|
+
if (isFloating) {
|
|
127
|
+
this.applyFloatingPosition(container, banner.position);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// Add event listeners
|
|
131
|
+
const closeButton = container.querySelector('.rbird-banner-close');
|
|
132
|
+
if (closeButton) {
|
|
133
|
+
closeButton.addEventListener('click', (e) => {
|
|
134
|
+
e.preventDefault();
|
|
135
|
+
this.closeBanner(banner.id);
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
const ctaButton = container.querySelector('.rbird-banner-cta');
|
|
140
|
+
if (ctaButton) {
|
|
141
|
+
ctaButton.addEventListener('click', (e) => {
|
|
142
|
+
e.preventDefault();
|
|
143
|
+
this.handleCtaClick(banner);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return container;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
getBannerStyles(banner, isFloating) {
|
|
151
|
+
const baseStyles = `
|
|
152
|
+
position: relative;
|
|
153
|
+
background-color: ${banner.backgroundColor || '#ffffff'};
|
|
154
|
+
color: ${banner.textColor || '#000000'};
|
|
155
|
+
padding: 20px;
|
|
156
|
+
border-radius: 8px;
|
|
157
|
+
box-shadow: 0 2px 8px rgba(0,0,0,0.15);
|
|
158
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
|
|
159
|
+
max-width: ${isFloating ? '400px' : '100%'};
|
|
160
|
+
box-sizing: border-box;
|
|
161
|
+
z-index: 10000;
|
|
162
|
+
`;
|
|
163
|
+
|
|
164
|
+
return baseStyles;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
getCloseButtonStyles() {
|
|
168
|
+
return `
|
|
169
|
+
position: absolute;
|
|
170
|
+
top: 10px;
|
|
171
|
+
right: 10px;
|
|
172
|
+
background: transparent;
|
|
173
|
+
border: none;
|
|
174
|
+
font-size: 24px;
|
|
175
|
+
line-height: 1;
|
|
176
|
+
cursor: pointer;
|
|
177
|
+
color: inherit;
|
|
178
|
+
opacity: 0.6;
|
|
179
|
+
padding: 0;
|
|
180
|
+
width: 24px;
|
|
181
|
+
height: 24px;
|
|
182
|
+
display: flex;
|
|
183
|
+
align-items: center;
|
|
184
|
+
justify-content: center;
|
|
185
|
+
transition: opacity 0.2s;
|
|
186
|
+
`;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
getTitleStyles() {
|
|
190
|
+
return `
|
|
191
|
+
margin: 0 0 10px 0;
|
|
192
|
+
font-size: 18px;
|
|
193
|
+
font-weight: 600;
|
|
194
|
+
line-height: 1.4;
|
|
195
|
+
`;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
getMessageStyles() {
|
|
199
|
+
return `
|
|
200
|
+
margin: 0 0 15px 0;
|
|
201
|
+
font-size: 14px;
|
|
202
|
+
line-height: 1.6;
|
|
203
|
+
`;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
getCtaButtonStyles(banner) {
|
|
207
|
+
return `
|
|
208
|
+
background-color: ${banner.buttonColor || '#667eea'};
|
|
209
|
+
color: ${banner.buttonTextColor || '#ffffff'};
|
|
210
|
+
border: none;
|
|
211
|
+
padding: 10px 20px;
|
|
212
|
+
border-radius: 6px;
|
|
213
|
+
font-size: 14px;
|
|
214
|
+
font-weight: 600;
|
|
215
|
+
cursor: pointer;
|
|
216
|
+
transition: opacity 0.2s;
|
|
217
|
+
display: inline-block;
|
|
218
|
+
`;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
applyFloatingPosition(element, position) {
|
|
222
|
+
element.style.position = 'fixed';
|
|
223
|
+
element.style.margin = '20px';
|
|
224
|
+
element.style.animation = 'rbirdBannerSlideIn 0.3s ease-out';
|
|
225
|
+
|
|
226
|
+
switch (position) {
|
|
227
|
+
case 'TOP':
|
|
228
|
+
element.style.top = '0';
|
|
229
|
+
element.style.left = '50%';
|
|
230
|
+
element.style.transform = 'translateX(-50%)';
|
|
231
|
+
break;
|
|
232
|
+
case 'BOTTOM':
|
|
233
|
+
element.style.bottom = '0';
|
|
234
|
+
element.style.left = '50%';
|
|
235
|
+
element.style.transform = 'translateX(-50%)';
|
|
236
|
+
break;
|
|
237
|
+
case 'TOP_LEFT':
|
|
238
|
+
element.style.top = '0';
|
|
239
|
+
element.style.left = '0';
|
|
240
|
+
break;
|
|
241
|
+
case 'TOP_RIGHT':
|
|
242
|
+
element.style.top = '0';
|
|
243
|
+
element.style.right = '0';
|
|
244
|
+
break;
|
|
245
|
+
case 'BOTTOM_LEFT':
|
|
246
|
+
element.style.bottom = '0';
|
|
247
|
+
element.style.left = '0';
|
|
248
|
+
break;
|
|
249
|
+
case 'BOTTOM_RIGHT':
|
|
250
|
+
element.style.bottom = '0';
|
|
251
|
+
element.style.right = '0';
|
|
252
|
+
break;
|
|
253
|
+
default:
|
|
254
|
+
element.style.bottom = '0';
|
|
255
|
+
element.style.right = '0';
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
handleCtaClick(banner) {
|
|
260
|
+
this.trackClick(banner.id);
|
|
261
|
+
|
|
262
|
+
if (banner.buttonAction === 'LINK' && banner.buttonLink) {
|
|
263
|
+
window.open(banner.buttonLink, '_blank');
|
|
264
|
+
} else if (banner.buttonAction === 'OPEN_WIDGET') {
|
|
265
|
+
// Open the Releasebird widget
|
|
266
|
+
if (window.Rbird && window.Rbird.showWidget) {
|
|
267
|
+
window.Rbird.showWidget();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// Close banner after CTA click if configured
|
|
272
|
+
if (banner.closeAfterAction) {
|
|
273
|
+
this.closeBanner(banner.id);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
closeBanner(bannerId) {
|
|
278
|
+
const bannerElement = document.getElementById(`rbird-banner-${bannerId}`);
|
|
279
|
+
if (bannerElement) {
|
|
280
|
+
bannerElement.style.animation = 'rbirdBannerSlideOut 0.3s ease-in';
|
|
281
|
+
setTimeout(() => {
|
|
282
|
+
bannerElement.remove();
|
|
283
|
+
}, 300);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Track dismiss in backend
|
|
287
|
+
this.trackDismiss(bannerId);
|
|
288
|
+
this.displayedBanners.delete(bannerId);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
trackDismiss(bannerId) {
|
|
292
|
+
this.trackInteraction(bannerId, 'DISMISS');
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
trackImpression(bannerId) {
|
|
296
|
+
this.trackInteraction(bannerId, 'IMPRESSION');
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
trackClick(bannerId) {
|
|
300
|
+
this.trackInteraction(bannerId, 'CLICK');
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
trackInteraction(bannerId, interactionType) {
|
|
304
|
+
const sessionManager = RbirdSessionManager.getInstance();
|
|
305
|
+
const state = sessionManager.getState();
|
|
306
|
+
|
|
307
|
+
const http = new XMLHttpRequest();
|
|
308
|
+
http.open("POST", `${API}/ewidget/banners/interaction`);
|
|
309
|
+
http.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
|
|
310
|
+
http.setRequestHeader("apiKey", this.apiKey);
|
|
311
|
+
|
|
312
|
+
// Send user identification
|
|
313
|
+
if (state?.identify?.people) {
|
|
314
|
+
http.setRequestHeader("peopleId", state.identify.people);
|
|
315
|
+
}
|
|
316
|
+
if (sessionManager.anonymousIdentifier) {
|
|
317
|
+
http.setRequestHeader("anonymousId", sessionManager.anonymousIdentifier);
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
const requestData = {
|
|
321
|
+
bannerId: bannerId,
|
|
322
|
+
type: interactionType
|
|
323
|
+
};
|
|
324
|
+
|
|
325
|
+
http.send(JSON.stringify(requestData));
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
escapeHtml(text) {
|
|
329
|
+
const div = document.createElement('div');
|
|
330
|
+
div.textContent = text;
|
|
331
|
+
return div.innerHTML;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// Add CSS animations
|
|
335
|
+
injectStyles() {
|
|
336
|
+
if (typeof window === 'undefined' || document.getElementById('rbird-banner-styles')) return;
|
|
337
|
+
|
|
338
|
+
const style = document.createElement('style');
|
|
339
|
+
style.id = 'rbird-banner-styles';
|
|
340
|
+
style.textContent = `
|
|
341
|
+
@keyframes rbirdBannerSlideIn {
|
|
342
|
+
from {
|
|
343
|
+
opacity: 0;
|
|
344
|
+
transform: translateY(-20px);
|
|
345
|
+
}
|
|
346
|
+
to {
|
|
347
|
+
opacity: 1;
|
|
348
|
+
transform: translateY(0);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
@keyframes rbirdBannerSlideOut {
|
|
353
|
+
from {
|
|
354
|
+
opacity: 1;
|
|
355
|
+
transform: translateY(0);
|
|
356
|
+
}
|
|
357
|
+
to {
|
|
358
|
+
opacity: 0;
|
|
359
|
+
transform: translateY(-20px);
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
.rbird-banner-close:hover {
|
|
364
|
+
opacity: 1 !important;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.rbird-banner-cta:hover {
|
|
368
|
+
opacity: 0.9 !important;
|
|
369
|
+
transform: translateY(-1px);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.rbird-banner-inline {
|
|
373
|
+
margin: 20px 0;
|
|
374
|
+
}
|
|
375
|
+
`;
|
|
376
|
+
document.head.appendChild(style);
|
|
377
|
+
}
|
|
378
|
+
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import RbirdWebsiteWidget from "./RbirdWebsiteWidget";
|
|
2
1
|
import SVGEditor from "./SVGEditor";
|
|
3
2
|
import html2canvas from "html2canvas";
|
|
4
3
|
|
|
@@ -15,9 +14,16 @@ export default class RbirdScreenshotManager {
|
|
|
15
14
|
return this.instance;
|
|
16
15
|
}
|
|
17
16
|
|
|
17
|
+
// Lazy load RbirdWebsiteWidget to avoid circular dependency
|
|
18
|
+
getRbirdWebsiteWidget() {
|
|
19
|
+
// Import at runtime to break circular dependency
|
|
20
|
+
const RbirdWebsiteWidget = require("./RbirdWebsiteWidget").default;
|
|
21
|
+
return RbirdWebsiteWidget;
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
activateMarker(allowPointerEvents) {
|
|
19
25
|
document.body.style.overflow = 'hidden';
|
|
20
|
-
|
|
26
|
+
this.getRbirdWebsiteWidget().getInstance().closeWebsiteWidget();
|
|
21
27
|
this.boundary = document.createElement('div');
|
|
22
28
|
this.boundary.id = "markerBoundary";
|
|
23
29
|
this.boundary.className = "markerBoundary";
|
|
@@ -51,7 +57,7 @@ export default class RbirdScreenshotManager {
|
|
|
51
57
|
deactivateMarker() {
|
|
52
58
|
document.body.style.overflow = 'auto';
|
|
53
59
|
document.body.removeChild(this.boundary);
|
|
54
|
-
|
|
60
|
+
this.getRbirdWebsiteWidget().getInstance().openWebsiteWidget();
|
|
55
61
|
}
|
|
56
62
|
|
|
57
63
|
showLoader() {
|
|
@@ -84,28 +90,42 @@ export default class RbirdScreenshotManager {
|
|
|
84
90
|
let that = this;
|
|
85
91
|
const loader = this.showLoader();
|
|
86
92
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
}).then(function (canvas) {
|
|
93
|
-
that.hideLoader();
|
|
94
|
-
|
|
95
|
-
if (RbirdWebsiteWidget.getInstance().iframe) {
|
|
96
|
-
RbirdWebsiteWidget.getInstance().iframe.contentWindow?.postMessage({
|
|
97
|
-
type: 'screenshot',
|
|
98
|
-
screenshot: canvas.toDataURL("image/jpeg")
|
|
99
|
-
}, '*');
|
|
93
|
+
// Hide the loader and marker boundary before taking the screenshot
|
|
94
|
+
setTimeout(() => {
|
|
95
|
+
loader.style.display = 'none';
|
|
96
|
+
if (that.boundary) {
|
|
97
|
+
that.boundary.style.display = 'none';
|
|
100
98
|
}
|
|
101
99
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
100
|
+
html2canvas(document.body, {
|
|
101
|
+
allowTaint: false,
|
|
102
|
+
useCORS: false,
|
|
103
|
+
logging: false,
|
|
104
|
+
foreignObjectRendering: false
|
|
105
|
+
}).then(function (canvas) {
|
|
106
|
+
that.hideLoader();
|
|
107
|
+
|
|
108
|
+
const widgetInstance = that.getRbirdWebsiteWidget().getInstance();
|
|
109
|
+
if (widgetInstance.iframe) {
|
|
110
|
+
widgetInstance.iframe.contentWindow?.postMessage({
|
|
111
|
+
type: 'screenshot',
|
|
112
|
+
screenshot: canvas.toDataURL("image/jpeg")
|
|
113
|
+
}, '*');
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
that.deactivateMarker();
|
|
117
|
+
|
|
118
|
+
//document.body.appendChild(canvas);
|
|
119
|
+
}).catch((e) => {
|
|
120
|
+
// Restore visibility in case of error
|
|
121
|
+
loader.style.display = 'flex';
|
|
122
|
+
if (that.boundary) {
|
|
123
|
+
that.boundary.style.display = 'block';
|
|
124
|
+
}
|
|
125
|
+
that.hideLoader();
|
|
126
|
+
console.error('Screenshot error:', e);
|
|
127
|
+
});
|
|
128
|
+
}, 100); // Small delay to ensure the loader is rendered before we hide it
|
|
109
129
|
}
|
|
110
130
|
|
|
111
131
|
}
|
package/src/index.js
CHANGED
|
@@ -2,6 +2,7 @@ import { injectStyledCSS } from "./Styles";
|
|
|
2
2
|
import RbirdSessionManager from "./RbirdSessionManager";
|
|
3
3
|
import RbirdWebsiteWidget from "./RbirdWebsiteWidget";
|
|
4
4
|
import { ReleasebirdConsoleLogger } from "./ReleasebirdConsoleLogger";
|
|
5
|
+
import { RbirdBannerManager } from "./RbirdBannerManager";
|
|
5
6
|
|
|
6
7
|
class Rbird {
|
|
7
8
|
|
|
@@ -81,6 +82,12 @@ class Rbird {
|
|
|
81
82
|
if (showButton) {
|
|
82
83
|
RbirdWebsiteWidget.getInstance().showButton(showButton);
|
|
83
84
|
}
|
|
85
|
+
// Initialize banner manager and display banners
|
|
86
|
+
runFunctionWhenDomIsReady(() => {
|
|
87
|
+
const bannerManager = RbirdBannerManager.getInstance();
|
|
88
|
+
bannerManager.injectStyles();
|
|
89
|
+
bannerManager.init(apiKey);
|
|
90
|
+
});
|
|
84
91
|
})
|
|
85
92
|
|
|
86
93
|
} catch (e) {
|