@magicfeedback/popup-sdk 1.2.0 → 1.4.0
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/README.md +119 -70
- package/dist/assets/assets/style.css +5 -1
- package/dist/chunk-R4B3K2ZW.mjs +176 -0
- package/dist/chunk-R4B3K2ZW.mjs.map +1 -0
- package/dist/chunk-XFA2Y6CK.mjs +197 -0
- package/dist/chunk-XFA2Y6CK.mjs.map +1 -0
- package/dist/index.d.mts +40 -7
- package/dist/index.d.ts +40 -7
- package/dist/index.js +281 -900
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +276 -33
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +22 -2
- package/dist/react-native.d.ts +22 -2
- package/dist/react-native.js +283 -901
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +278 -34
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-R53C7DB3.mjs → renderPopup-TCKR5Z3P.mjs} +5 -871
- package/dist/renderPopup-TCKR5Z3P.mjs.map +1 -0
- package/dist/{renderPopup-NHWJ7YSI.mjs → renderPopup-UYMGEBSI.mjs} +5 -871
- package/dist/renderPopup-UYMGEBSI.mjs.map +1 -0
- package/package.json +5 -10
- package/dist/chunk-4UXOEIAB.mjs +0 -172
- package/dist/chunk-4UXOEIAB.mjs.map +0 -1
- package/dist/chunk-XOTM5CHX.mjs +0 -193
- package/dist/chunk-XOTM5CHX.mjs.map +0 -1
- package/dist/renderPopup-NHWJ7YSI.mjs.map +0 -1
- package/dist/renderPopup-R53C7DB3.mjs.map +0 -1
package/dist/react-native.mjs
CHANGED
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
buildSurveyIdentity,
|
|
8
8
|
createDefaultStorage,
|
|
9
9
|
sdkWarn,
|
|
10
|
-
setLogger
|
|
11
|
-
|
|
10
|
+
setLogger,
|
|
11
|
+
style_default
|
|
12
|
+
} from "./chunk-R4B3K2ZW.mjs";
|
|
12
13
|
|
|
13
14
|
// src/react-native/index.tsx
|
|
14
15
|
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
@@ -23,6 +24,10 @@ var POPUP_TRIGGER_CONDITION_STATUSES = [
|
|
|
23
24
|
];
|
|
24
25
|
|
|
25
26
|
// src/triggers/index.ts
|
|
27
|
+
function toNumericValue(value, fallback) {
|
|
28
|
+
const n = Number(value);
|
|
29
|
+
return Number.isFinite(n) ? n : fallback;
|
|
30
|
+
}
|
|
26
31
|
function setupTrigger(popups, trigger) {
|
|
27
32
|
switch (trigger.type) {
|
|
28
33
|
case "time":
|
|
@@ -43,14 +48,14 @@ function setupTrigger(popups, trigger) {
|
|
|
43
48
|
}
|
|
44
49
|
}
|
|
45
50
|
function setupTimeTrigger(popups, trigger) {
|
|
46
|
-
const delay = trigger.value
|
|
51
|
+
const delay = toNumericValue(trigger.value, 5e3);
|
|
47
52
|
setTimeout(() => {
|
|
48
53
|
popups.triggerSurvey(trigger.surveyId, trigger.popupId);
|
|
49
54
|
}, delay);
|
|
50
55
|
popups.debug(`Time trigger set for ${delay}ms`);
|
|
51
56
|
}
|
|
52
57
|
function setupScrollTrigger(popups, trigger) {
|
|
53
|
-
const threshold = trigger.value
|
|
58
|
+
const threshold = toNumericValue(trigger.value, 50);
|
|
54
59
|
const handler = () => {
|
|
55
60
|
const scrollPercentage = window.scrollY / (document.documentElement.scrollHeight - window.innerHeight) * 100;
|
|
56
61
|
if (scrollPercentage >= threshold) {
|
|
@@ -200,6 +205,15 @@ function resolveEnvironment(nodeEnv) {
|
|
|
200
205
|
}
|
|
201
206
|
|
|
202
207
|
// src/ui/surveyHtml.ts
|
|
208
|
+
var POSITION_MAP = {
|
|
209
|
+
center: { justifyContent: "center", alignItems: "center", padding: "0", background: "rgba(0,0,0,0.5)" },
|
|
210
|
+
bottom: { justifyContent: "center", alignItems: "flex-end", padding: "16px", background: "transparent" },
|
|
211
|
+
"bottom-right": { justifyContent: "flex-end", alignItems: "flex-end", padding: "16px", background: "transparent" },
|
|
212
|
+
"bottom-left": { justifyContent: "flex-start", alignItems: "flex-end", padding: "16px", background: "transparent" },
|
|
213
|
+
top: { justifyContent: "center", alignItems: "flex-start", padding: "16px", background: "transparent" },
|
|
214
|
+
"top-right": { justifyContent: "flex-end", alignItems: "flex-start", padding: "16px", background: "transparent" },
|
|
215
|
+
"top-left": { justifyContent: "flex-start", alignItems: "flex-start", padding: "16px", background: "transparent" }
|
|
216
|
+
};
|
|
203
217
|
function buildSurveyHtml(opts) {
|
|
204
218
|
const env = opts.env === "development" ? "dev" : "prod";
|
|
205
219
|
const version = opts.version ?? "2.2.4";
|
|
@@ -210,17 +224,152 @@ function buildSurveyHtml(opts) {
|
|
|
210
224
|
const metaJson = JSON.stringify(opts.metadata ?? []);
|
|
211
225
|
const fontFaceCss = opts.font ? buildFontFaceCss(opts.font.family, opts.font.url) : "";
|
|
212
226
|
const fontFamilyValue = opts.font ? buildFontFamilyValue(opts.font.family) : "-apple-system,system-ui,sans-serif";
|
|
227
|
+
const popupClass = opts.font?.family ? "deepdots-popup deepdots-has-font" : "deepdots-popup";
|
|
228
|
+
const isDark = opts.theme === "dark";
|
|
229
|
+
const popupBg = isDark ? "#1e1e1e" : "#fff";
|
|
230
|
+
const colorScheme = isDark ? "dark" : "light";
|
|
231
|
+
const textPrimary = isDark ? "#f0f0f0" : "#111";
|
|
232
|
+
const pos = POSITION_MAP[opts.position ?? "center"] ?? POSITION_MAP.center;
|
|
233
|
+
const chrome = opts.chrome !== false;
|
|
234
|
+
const bodyBg = chrome ? pos.background : "transparent";
|
|
235
|
+
const bodyPadding = chrome ? pos.padding : "0";
|
|
236
|
+
const bodyDisplay = chrome ? "flex" : "block";
|
|
237
|
+
const cardBg = chrome ? popupBg : "transparent";
|
|
238
|
+
const cardShadow = chrome ? "0 4px 6px rgba(0,0,0,0.1)" : "none";
|
|
239
|
+
const cardRadius = chrome ? "8px" : "0";
|
|
240
|
+
const cardMaxWidth = chrome ? "600px" : "none";
|
|
241
|
+
const cardWidth = chrome ? "90%" : "100%";
|
|
242
|
+
const cardMinHeight = chrome ? "200px" : "0";
|
|
243
|
+
const backLabel = JSON.stringify(opts.actions?.back?.label ?? "Back");
|
|
244
|
+
const startLabel = JSON.stringify(opts.actions?.start?.label ?? "Start survey");
|
|
245
|
+
const completeLabel = JSON.stringify(opts.actions?.complete?.label ?? "Complete survey");
|
|
246
|
+
const submitLabel = JSON.stringify(opts.actions?.accept?.label ?? "Send");
|
|
213
247
|
return `<!DOCTYPE html><html><head>
|
|
214
248
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
215
|
-
<meta name="color-scheme" content="
|
|
216
|
-
<style
|
|
249
|
+
<meta name="color-scheme" content="${colorScheme}"/>
|
|
250
|
+
<style>
|
|
251
|
+
${style_default}
|
|
252
|
+
${fontFaceCss}
|
|
253
|
+
html,body{margin:0;padding:0;height:100%;font-family:${fontFamilyValue}}
|
|
254
|
+
body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${pos.alignItems};background:${bodyBg};padding:${bodyPadding};box-sizing:border-box}
|
|
255
|
+
.deepdots-popup{position:relative;display:flex;flex-direction:column;justify-content:flex-start;background:${cardBg};color-scheme:${colorScheme};border-radius:${cardRadius};padding:24px;box-shadow:${cardShadow};max-width:${cardMaxWidth};width:${cardWidth};min-height:${cardMinHeight};box-sizing:border-box}
|
|
256
|
+
.deepdots-popup-header{display:flex;justify-content:flex-end;align-items:center;width:100%}
|
|
257
|
+
#dd-close{background:transparent;border:none;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:8px;cursor:pointer;color:${textPrimary};padding:4px}
|
|
258
|
+
.deepdots-popup-container-content{display:flex;flex-direction:column;padding:0 20px 12px 20px;max-height:80vh;overflow:hidden;box-sizing:border-box}
|
|
259
|
+
.deepdots-popup-main{display:flex;flex-direction:column;width:100%;max-height:80vh;overflow-y:auto;overflow-x:hidden;position:relative}
|
|
260
|
+
#dd-form-wrapper{width:100%;flex:1 1 auto}
|
|
261
|
+
#mf{width:100%;box-sizing:border-box;visibility:hidden}
|
|
262
|
+
.deepdots-popup-main *{max-width:100%;box-sizing:border-box}
|
|
263
|
+
#dd-logo{max-height:40px;max-width:100%;object-fit:contain}
|
|
264
|
+
.deepdots-error-hint{display:none;margin:12px 0 0 0;padding:10px 12px;border-radius:6px;background:#FEF3C7;color:#92400E;border:1px solid #FCD34D;font-size:13px}
|
|
265
|
+
.deepdots-popup-footer{display:flex;flex-direction:row-reverse;justify-content:space-between;align-items:center;gap:8px;margin-top:auto;width:100%;padding-top:16px}
|
|
266
|
+
.dd-nav-btn{display:none;border:none;padding:12px 24px;border-radius:4px;cursor:pointer;font-size:14px;box-shadow:0 2px 4px rgba(0,0,0,0.1);align-items:center;justify-content:center;text-align:center}
|
|
267
|
+
#dd-back{background:transparent;color:#333;border:1px solid #999}
|
|
268
|
+
#dd-start,#dd-complete,#dd-submit{background:#1E293B;color:#fff;border:none}
|
|
269
|
+
#dd-submit:disabled,#dd-start:disabled,#dd-back:disabled,#dd-complete:disabled{opacity:0.6;cursor:not-allowed}
|
|
270
|
+
.mf-spinner{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}
|
|
271
|
+
.mf-spinner-circle{width:28px;height:28px;border:3px solid #e0e6ed;border-top-color:#1E293B;border-radius:50%;animation:ddspin 0.9s linear infinite}
|
|
272
|
+
@keyframes ddspin{0%{transform:rotate(0deg)}100%{transform:rotate(360deg)}}
|
|
273
|
+
@media (max-width:640px){
|
|
274
|
+
.deepdots-popup{width:calc(100% - 24px);max-width:calc(100% - 24px);border-radius:12px}
|
|
275
|
+
.deepdots-popup-footer{flex-direction:column-reverse;gap:12px}
|
|
276
|
+
.dd-nav-btn{width:100%}
|
|
277
|
+
.magicfeedback-checkbox-container,.magicfeedback-radio-container{margin:4px 0;padding:4px 8px}
|
|
278
|
+
.magicfeedback-checkbox label,.magicfeedback-radio-container label{font-size:15px}
|
|
279
|
+
.deepdots-popup input[type="radio"]{margin:6px 0 6px 8px}
|
|
280
|
+
.deepdots-popup input[type="checkbox"]{width:16px;height:16px}
|
|
281
|
+
}
|
|
282
|
+
</style>
|
|
217
283
|
</head><body>
|
|
218
|
-
<div id="
|
|
284
|
+
<div class="${popupClass}" id="dd-popup">
|
|
285
|
+
<div class="deepdots-popup-header">
|
|
286
|
+
<button type="button" id="dd-close" aria-label="Close popup">
|
|
287
|
+
<svg width="28" height="28" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
288
|
+
<path d="M6 6L18 18M6 18L18 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
|
|
289
|
+
</svg>
|
|
290
|
+
</button>
|
|
291
|
+
</div>
|
|
292
|
+
<div class="deepdots-popup-container-content">
|
|
293
|
+
<div class="deepdots-popup-main" id="dd-main">
|
|
294
|
+
<div id="dd-form-wrapper">
|
|
295
|
+
<div class="mf-spinner" id="dd-spinner" role="status" aria-label="Loading survey"><div class="mf-spinner-circle"></div></div>
|
|
296
|
+
<div id="mf"></div>
|
|
297
|
+
</div>
|
|
298
|
+
<div class="deepdots-error-hint" id="dd-error" role="alert" aria-live="polite"></div>
|
|
299
|
+
<div class="deepdots-popup-footer" id="dd-footer">
|
|
300
|
+
<button type="button" class="dd-nav-btn" id="dd-submit">Send</button>
|
|
301
|
+
<button type="button" class="dd-nav-btn" id="dd-back">Back</button>
|
|
302
|
+
<button type="button" class="dd-nav-btn" id="dd-complete">Complete survey</button>
|
|
303
|
+
<button type="button" class="dd-nav-btn" id="dd-start">Start survey</button>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
</div>
|
|
307
|
+
</div>
|
|
219
308
|
<script>
|
|
220
309
|
(function(){
|
|
221
310
|
function emit(s){ try{ if(window.ReactNativeWebView){ window.ReactNativeWebView.postMessage(s); } }catch(e){} }
|
|
222
311
|
function emitJSON(n,p){ try{ emit(JSON.stringify({name:n,payload:p||{}})); }catch(e){} }
|
|
223
312
|
window.DeepdotsClose = function(){ emitJSON('popup_close'); };
|
|
313
|
+
var chromeOn=${chrome ? "true" : "false"};
|
|
314
|
+
|
|
315
|
+
var popup=document.getElementById('dd-popup');
|
|
316
|
+
var main=document.getElementById('dd-main');
|
|
317
|
+
var footer=document.getElementById('dd-footer');
|
|
318
|
+
var spinner=document.getElementById('dd-spinner');
|
|
319
|
+
var formHost=document.getElementById('mf');
|
|
320
|
+
var errorHint=document.getElementById('dd-error');
|
|
321
|
+
var backBtn=document.getElementById('dd-back');
|
|
322
|
+
var startBtn=document.getElementById('dd-start');
|
|
323
|
+
var completeBtn=document.getElementById('dd-complete');
|
|
324
|
+
var submitBtn=document.getElementById('dd-submit');
|
|
325
|
+
|
|
326
|
+
backBtn.textContent=${backLabel};
|
|
327
|
+
startBtn.textContent=${startLabel};
|
|
328
|
+
completeBtn.textContent=${completeLabel};
|
|
329
|
+
submitBtn.textContent=${submitLabel};
|
|
330
|
+
|
|
331
|
+
document.getElementById('dd-close').onclick=function(){ emitJSON('popup_close'); };
|
|
332
|
+
backBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.back){ window.DeepdotsForm.back(); } };
|
|
333
|
+
startBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.startForm){ window.DeepdotsForm.startForm(); } };
|
|
334
|
+
completeBtn.onclick=function(){ emitJSON('popup_close'); };
|
|
335
|
+
var surveyCompletedEmitted=false;
|
|
336
|
+
submitBtn.onclick=function(){
|
|
337
|
+
if(surveyCompletedEmitted) return;
|
|
338
|
+
if(window.DeepdotsForm && window.DeepdotsForm.send){ window.DeepdotsForm.send(); }
|
|
339
|
+
};
|
|
340
|
+
|
|
341
|
+
function updateButtons(state){
|
|
342
|
+
backBtn.style.display='none';
|
|
343
|
+
startBtn.style.display='none';
|
|
344
|
+
submitBtn.style.display='none';
|
|
345
|
+
completeBtn.style.display='none';
|
|
346
|
+
backBtn.style.width='';
|
|
347
|
+
startBtn.style.width='';
|
|
348
|
+
submitBtn.style.width='';
|
|
349
|
+
completeBtn.style.width='';
|
|
350
|
+
if(state==='start'){
|
|
351
|
+
startBtn.style.display='inline-flex';
|
|
352
|
+
startBtn.style.width='100%';
|
|
353
|
+
} else if(state==='in_progress_first'){
|
|
354
|
+
submitBtn.style.display='inline-flex';
|
|
355
|
+
} else if(state==='in_progress_next'){
|
|
356
|
+
backBtn.style.display='inline-flex';
|
|
357
|
+
submitBtn.style.display='inline-flex';
|
|
358
|
+
} else if(state==='completed'){
|
|
359
|
+
completeBtn.style.display='inline-flex';
|
|
360
|
+
completeBtn.style.width='100%';
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
function setLoading(isLoading){
|
|
365
|
+
spinner.style.display=isLoading?'flex':'none';
|
|
366
|
+
if(!isLoading){ formHost.style.visibility='visible'; }
|
|
367
|
+
footer.style.display=isLoading?'none':'flex';
|
|
368
|
+
backBtn.disabled=isLoading; startBtn.disabled=isLoading; completeBtn.disabled=isLoading; submitBtn.disabled=isLoading;
|
|
369
|
+
if(isLoading){ updateButtons(null); }
|
|
370
|
+
}
|
|
371
|
+
setLoading(true);
|
|
372
|
+
|
|
224
373
|
var initialized=false;
|
|
225
374
|
function initMF(){
|
|
226
375
|
if(initialized || !window.magicfeedback) return initialized;
|
|
@@ -229,23 +378,85 @@ function buildSurveyHtml(opts) {
|
|
|
229
378
|
window.magicfeedback.init({ debug:false, env:'${env}' });
|
|
230
379
|
var form = window.magicfeedback.form(${sid}, ${pid}, ${profileJson}, ${metaJson});
|
|
231
380
|
window.DeepdotsForm = form;
|
|
381
|
+
var stylesInjected=false;
|
|
232
382
|
form.generate('mf', {
|
|
233
383
|
addButton:false,
|
|
234
384
|
getMetaData:true,
|
|
235
|
-
onLoadedEvent:function(){
|
|
236
|
-
|
|
385
|
+
onLoadedEvent:function(args){
|
|
386
|
+
var s=args && args.formData ? args.formData.style : null;
|
|
387
|
+
if(s && !stylesInjected){
|
|
388
|
+
stylesInjected=true;
|
|
389
|
+
if(chromeOn && s.boxBackgroundColor){ popup.style.background=s.boxBackgroundColor; }
|
|
390
|
+
if(s.contentAlign){ main.style.justifyContent = s.contentAlign==='center' ? 'center' : 'flex-start'; }
|
|
391
|
+
if(s.buttonPrimaryColor){
|
|
392
|
+
submitBtn.style.background=s.buttonPrimaryColor; submitBtn.style.border='none'; submitBtn.style.color='#fff';
|
|
393
|
+
startBtn.style.background=s.buttonPrimaryColor; startBtn.style.border='none'; startBtn.style.color='#fff';
|
|
394
|
+
completeBtn.style.background=s.buttonPrimaryColor; completeBtn.style.border='none'; completeBtn.style.color='#fff';
|
|
395
|
+
}
|
|
396
|
+
if(s.buttonSecondaryColor){
|
|
397
|
+
backBtn.style.background='#fff'; backBtn.style.color=s.buttonSecondaryColor; backBtn.style.border='1px solid '+s.buttonSecondaryColor;
|
|
398
|
+
}
|
|
399
|
+
if(s.logo && !document.getElementById('dd-logo')){
|
|
400
|
+
var logoImg=document.createElement('img');
|
|
401
|
+
logoImg.id='dd-logo'; logoImg.src=s.logo; logoImg.alt='Logo';
|
|
402
|
+
if(s.logoSize==='small'){ logoImg.style.maxHeight='30px'; }
|
|
403
|
+
else if(s.logoSize==='medium'){ logoImg.style.maxHeight='50px'; }
|
|
404
|
+
else if(s.logoSize==='large'){ logoImg.style.maxHeight='70px'; }
|
|
405
|
+
if(s.logoPosition==='left'){ logoImg.style.margin='0 16px 20px 0'; logoImg.style.display='block'; logoImg.style.marginLeft='0'; }
|
|
406
|
+
else if(s.logoPosition==='right'){ logoImg.style.margin='0 0 20px 16px'; logoImg.style.display='block'; logoImg.style.marginLeft='auto'; }
|
|
407
|
+
else if(s.logoPosition==='center'){ logoImg.style.margin='0 auto 20px auto'; logoImg.style.display='block'; }
|
|
408
|
+
main.insertBefore(logoImg, document.getElementById('dd-form-wrapper'));
|
|
409
|
+
}
|
|
410
|
+
if(s.startMessage && s.startMessage!==''){ updateButtons('start'); }
|
|
411
|
+
else { updateButtons('in_progress_first'); }
|
|
412
|
+
} else {
|
|
413
|
+
updateButtons('in_progress_first');
|
|
414
|
+
}
|
|
415
|
+
emitJSON('loaded');
|
|
416
|
+
setLoading(false);
|
|
417
|
+
},
|
|
418
|
+
beforeSubmitEvent:function(){
|
|
419
|
+
setLoading(true);
|
|
420
|
+
emitJSON('before_submit');
|
|
421
|
+
},
|
|
237
422
|
afterSubmitEvent:function(p){
|
|
238
|
-
|
|
239
|
-
|
|
423
|
+
var error=p && p.error ? (typeof p.error==='string' ? p.error : String(p.error)) : '';
|
|
424
|
+
if(error){
|
|
425
|
+
setLoading(false);
|
|
426
|
+
if(error.toLowerCase().indexOf('no response')!==-1){
|
|
427
|
+
errorHint.textContent='Please answer the required question to continue.';
|
|
428
|
+
errorHint.style.display='block';
|
|
429
|
+
updateButtons('in_progress_next');
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
errorHint.textContent='An error occurred while submitting. Please try again or close the popup.';
|
|
433
|
+
errorHint.style.display='block';
|
|
434
|
+
return;
|
|
435
|
+
}
|
|
436
|
+
errorHint.style.display='none';
|
|
437
|
+
setLoading(false);
|
|
438
|
+
if(p && p.completed){
|
|
439
|
+
surveyCompletedEmitted=true;
|
|
440
|
+
updateButtons('completed');
|
|
441
|
+
emitJSON('survey_completed', p);
|
|
442
|
+
return;
|
|
443
|
+
}
|
|
444
|
+
if(p && p.total>1 && p.progress>0 && p.progress<p.total){ updateButtons('in_progress_next'); }
|
|
445
|
+
else { updateButtons('in_progress_first'); }
|
|
446
|
+
emitJSON('after_submit', p);
|
|
240
447
|
},
|
|
241
|
-
onBackEvent:function(p){
|
|
242
|
-
|
|
243
|
-
|
|
448
|
+
onBackEvent:function(p){
|
|
449
|
+
if(p && p.progress===0){ updateButtons('in_progress_first'); }
|
|
450
|
+
else { updateButtons('in_progress_next'); }
|
|
451
|
+
emitJSON('back', p);
|
|
452
|
+
}
|
|
453
|
+
}).catch(function(e){ setLoading(false); emit('error:init'); });
|
|
454
|
+
}catch(e){ setLoading(false); emit('error:exception'); }
|
|
244
455
|
return true;
|
|
245
456
|
}
|
|
246
457
|
var s=document.createElement('script'); s.src=${JSON.stringify(cdn)}; s.async=true;
|
|
247
458
|
s.onload=function(){ initMF(); };
|
|
248
|
-
s.onerror=function(){ emit('error:load'); };
|
|
459
|
+
s.onerror=function(){ setLoading(false); emit('error:load'); };
|
|
249
460
|
document.head.appendChild(s);
|
|
250
461
|
var tries=0, t=setInterval(function(){ if(initMF()||++tries>40){ clearInterval(t); } },150);
|
|
251
462
|
})();
|
|
@@ -264,18 +475,30 @@ var ReactNativePopupRenderer = class {
|
|
|
264
475
|
}
|
|
265
476
|
init() {
|
|
266
477
|
}
|
|
267
|
-
show(surveyId, productId,
|
|
478
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, renderChrome) {
|
|
268
479
|
this.emitFn = emit;
|
|
269
480
|
this.onCloseFn = onClose;
|
|
270
481
|
this.currentSurveyId = surveyId;
|
|
271
482
|
this.partialEmitted = false;
|
|
272
483
|
const { profile, metadata } = buildSurveyIdentity(userId ?? null, sessionId ?? null, miniService ?? null, analyticsFeedbackSessionId ?? null);
|
|
273
|
-
const html = buildSurveyHtml({
|
|
484
|
+
const html = buildSurveyHtml({
|
|
485
|
+
surveyId,
|
|
486
|
+
productId,
|
|
487
|
+
env,
|
|
488
|
+
profile,
|
|
489
|
+
metadata,
|
|
490
|
+
font: style?.font,
|
|
491
|
+
theme: style?.theme,
|
|
492
|
+
position: style?.position,
|
|
493
|
+
actions,
|
|
494
|
+
// renderChrome:false (init) → HTML sin tarjeta/overlay: el host lo envuelve en su Modal.
|
|
495
|
+
chrome: renderChrome
|
|
496
|
+
});
|
|
274
497
|
if (this.options.onShow) {
|
|
275
498
|
this.options.onShow({ surveyId, productId, html });
|
|
276
499
|
} else {
|
|
277
500
|
sdkWarn(
|
|
278
|
-
"[Deepdots] ReactNativePopupRenderer
|
|
501
|
+
"[Deepdots] ReactNativePopupRenderer has no onShow: pass { onShow } to new ReactNativePopupRenderer({...}) to mount the survey WebView."
|
|
279
502
|
);
|
|
280
503
|
}
|
|
281
504
|
}
|
|
@@ -360,13 +583,13 @@ var BrowserPopupRenderer = class {
|
|
|
360
583
|
document.body.appendChild(this.container);
|
|
361
584
|
}
|
|
362
585
|
}
|
|
363
|
-
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId) {
|
|
586
|
+
show(surveyId, productId, actions, emit, onClose, env = "production", userId, style, sessionId, miniService, analyticsFeedbackSessionId, _renderChrome) {
|
|
364
587
|
if (this.visible) return;
|
|
365
588
|
if (!this.container || !document.body.contains(this.container)) this.init();
|
|
366
589
|
if (!this.container) return;
|
|
367
590
|
this.visible = true;
|
|
368
591
|
const container = this.container;
|
|
369
|
-
void import("./renderPopup-
|
|
592
|
+
void import("./renderPopup-UYMGEBSI.mjs").then(({ renderPopup }) => {
|
|
370
593
|
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId);
|
|
371
594
|
});
|
|
372
595
|
}
|
|
@@ -390,7 +613,7 @@ function createDefaultRenderer() {
|
|
|
390
613
|
// src/analytics/analytics-manager.ts
|
|
391
614
|
function createDryRunSink(log = console.log) {
|
|
392
615
|
return (payload) => log(
|
|
393
|
-
"[DeepdotsAnalytics] (dry-run \xB7
|
|
616
|
+
"[DeepdotsAnalytics] (dry-run \xB7 NOT sent \xB7 no init.analytics) POST /sdk/feedback \u2192",
|
|
394
617
|
JSON.stringify(payload, null, 2)
|
|
395
618
|
);
|
|
396
619
|
}
|
|
@@ -632,14 +855,14 @@ function createFeedbackSink(options) {
|
|
|
632
855
|
if (final && options.sendBeaconImpl && small) {
|
|
633
856
|
const payload = typeof Blob !== "undefined" ? new Blob([json], { type: "application/json" }) : json;
|
|
634
857
|
if (options.sendBeaconImpl(url, payload)) {
|
|
635
|
-
options.log?.("[DeepdotsAnalytics] flush
|
|
858
|
+
options.log?.("[DeepdotsAnalytics] final flush via sendBeacon");
|
|
636
859
|
return;
|
|
637
860
|
}
|
|
638
|
-
options.log?.("[DeepdotsAnalytics] sendBeacon
|
|
861
|
+
options.log?.("[DeepdotsAnalytics] sendBeacon rejected the batch; falling back to fetch");
|
|
639
862
|
}
|
|
640
863
|
const f = options.fetchImpl ?? (typeof fetch !== "undefined" ? fetch : void 0);
|
|
641
864
|
if (!f) {
|
|
642
|
-
options.log?.("[DeepdotsAnalytics] no fetch
|
|
865
|
+
options.log?.("[DeepdotsAnalytics] no fetch available; payload not sent", body);
|
|
643
866
|
return;
|
|
644
867
|
}
|
|
645
868
|
const res = await f(url, {
|
|
@@ -652,10 +875,10 @@ function createFeedbackSink(options) {
|
|
|
652
875
|
if (!res.ok) {
|
|
653
876
|
const detail = await safeBodyText(res);
|
|
654
877
|
if (isRetryableStatus(res.status)) {
|
|
655
|
-
throw new Error(`POST /sdk/feedback ${res.status} (
|
|
878
|
+
throw new Error(`POST /sdk/feedback ${res.status} (retryable): ${detail}`);
|
|
656
879
|
}
|
|
657
880
|
options.log?.(
|
|
658
|
-
`[DeepdotsAnalytics] POST /sdk/feedback
|
|
881
|
+
`[DeepdotsAnalytics] POST /sdk/feedback rejected with ${res.status}; batch DISCARDED:`,
|
|
659
882
|
detail
|
|
660
883
|
);
|
|
661
884
|
return;
|
|
@@ -665,7 +888,7 @@ function createFeedbackSink(options) {
|
|
|
665
888
|
const data = await res.json();
|
|
666
889
|
if (data?.sessionId && data.sessionId !== feedbackSessionId) {
|
|
667
890
|
feedbackSessionId = data.sessionId;
|
|
668
|
-
options.log?.("[DeepdotsAnalytics] feedbackSessionId
|
|
891
|
+
options.log?.("[DeepdotsAnalytics] feedbackSessionId cached:", feedbackSessionId);
|
|
669
892
|
options.onSessionId?.(feedbackSessionId);
|
|
670
893
|
}
|
|
671
894
|
} catch {
|
|
@@ -1145,7 +1368,7 @@ var MessageGuard = class {
|
|
|
1145
1368
|
return {
|
|
1146
1369
|
emit: false,
|
|
1147
1370
|
reason: "invalid_channel",
|
|
1148
|
-
detail: `channel "${channel}"
|
|
1371
|
+
detail: `invalid channel "${channel}" (expected ${MESSAGE_CHANNELS.join(" | ")})`
|
|
1149
1372
|
};
|
|
1150
1373
|
}
|
|
1151
1374
|
const entry = this.seen.get(options.id);
|
|
@@ -1157,14 +1380,14 @@ var MessageGuard = class {
|
|
|
1157
1380
|
return {
|
|
1158
1381
|
emit: false,
|
|
1159
1382
|
reason: "channel_conflict",
|
|
1160
|
-
detail: `message_id "${options.id}"
|
|
1383
|
+
detail: `message_id "${options.id}" was already reported on channel "${entry.channel}"; discarding "${channel}"`
|
|
1161
1384
|
};
|
|
1162
1385
|
}
|
|
1163
1386
|
if (entry.stages.has(stage)) {
|
|
1164
1387
|
return {
|
|
1165
1388
|
emit: false,
|
|
1166
1389
|
reason: "duplicate_stage",
|
|
1167
|
-
detail: `stage "${stage}"
|
|
1390
|
+
detail: `stage "${stage}" was already sent for message_id "${options.id}"`
|
|
1168
1391
|
};
|
|
1169
1392
|
}
|
|
1170
1393
|
entry.stages.add(stage);
|
|
@@ -1214,6 +1437,8 @@ var DeepdotsPopups = class {
|
|
|
1214
1437
|
this.deferredExitTimers = [];
|
|
1215
1438
|
this.baseUrl = "";
|
|
1216
1439
|
this.env = "production";
|
|
1440
|
+
/** Si el SDK pinta el "modal" del popup (RN). Default true; false = el host lo envuelve. */
|
|
1441
|
+
this.renderChrome = true;
|
|
1217
1442
|
/** Identidad + sesión (Fase 1 tracking). Null hasta init(). */
|
|
1218
1443
|
this.tracking = null;
|
|
1219
1444
|
/** Capa de analytics (canal separado del feedback). Null hasta init(). */
|
|
@@ -1264,6 +1489,7 @@ var DeepdotsPopups = class {
|
|
|
1264
1489
|
const env = resolveEnvironment(config.nodeEnv);
|
|
1265
1490
|
this.baseUrl = env.apiBaseUrl;
|
|
1266
1491
|
this.env = config.nodeEnv || "production";
|
|
1492
|
+
this.renderChrome = config.renderChrome ?? true;
|
|
1267
1493
|
this.config = {
|
|
1268
1494
|
apiKey: config.apiKey || void 0,
|
|
1269
1495
|
debug: config.debug || false,
|
|
@@ -1449,6 +1675,22 @@ var DeepdotsPopups = class {
|
|
|
1449
1675
|
trackFunnelStep(funnel, step, taskId, params) {
|
|
1450
1676
|
this.track("deepdots_funnel_step", { funnel, step, task_id: taskId, ...params ?? {} });
|
|
1451
1677
|
}
|
|
1678
|
+
/**
|
|
1679
|
+
* Product Effectiveness: una interacción significativa del usuario (`interaction_type` es la
|
|
1680
|
+
* dimensión de agrupación, p. ej. `get_help`, `homepage`, `contact_support`).
|
|
1681
|
+
*
|
|
1682
|
+
* Existe como evento RESERVADO para que la convención no la invente cada host: un `track()`
|
|
1683
|
+
* custom acaba como `deepdots_event_…` y no lo cuenta la analítica de effectiveness.
|
|
1684
|
+
* Un `interactionType` vacío se descarta con warning (no aporta dato agrupable).
|
|
1685
|
+
*/
|
|
1686
|
+
trackMeaningfulInteraction(interactionType, params) {
|
|
1687
|
+
const type = typeof interactionType === "string" ? interactionType.trim() : "";
|
|
1688
|
+
if (!type) {
|
|
1689
|
+
console.warn("[DeepdotsPopups] trackMeaningfulInteraction discarded: empty interaction_type");
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
this.track("deepdots_meaningful_interaction", { interaction_type: type, ...params ?? {} });
|
|
1693
|
+
}
|
|
1452
1694
|
/**
|
|
1453
1695
|
* Messaging (#18–22): registra una etapa del funnel de una notificación (push/in-app).
|
|
1454
1696
|
* No-op si tracking off. El evento se descarta (con warning) si el `channel` no es válido,
|
|
@@ -1458,7 +1700,7 @@ var DeepdotsPopups = class {
|
|
|
1458
1700
|
trackMessage(stage, options) {
|
|
1459
1701
|
const verdict = this.messageGuard.evaluate(stage, options);
|
|
1460
1702
|
if (!verdict.emit) {
|
|
1461
|
-
console.warn(`[DeepdotsPopups] trackMessage
|
|
1703
|
+
console.warn(`[DeepdotsPopups] trackMessage discarded (${verdict.reason}): ${verdict.detail}`);
|
|
1462
1704
|
return;
|
|
1463
1705
|
}
|
|
1464
1706
|
this.track("deepdots_message", buildMessageParams(stage, options));
|
|
@@ -2049,13 +2291,14 @@ var DeepdotsPopups = class {
|
|
|
2049
2291
|
style,
|
|
2050
2292
|
sessionId,
|
|
2051
2293
|
miniService,
|
|
2052
|
-
analyticsFeedbackSessionId
|
|
2294
|
+
analyticsFeedbackSessionId,
|
|
2295
|
+
this.renderChrome
|
|
2053
2296
|
);
|
|
2054
2297
|
return;
|
|
2055
2298
|
}
|
|
2056
2299
|
if (!this.popupContainer) return;
|
|
2057
2300
|
const container = this.popupContainer;
|
|
2058
|
-
void import("./renderPopup-
|
|
2301
|
+
void import("./renderPopup-UYMGEBSI.mjs").then(({ renderPopup }) => {
|
|
2059
2302
|
renderPopup(
|
|
2060
2303
|
container,
|
|
2061
2304
|
surveyId,
|
|
@@ -2315,9 +2558,10 @@ function DeepdotsProvider({ config, children }) {
|
|
|
2315
2558
|
survey ? /* @__PURE__ */ jsx(Modal, { visible: true, transparent: true, animationType: "slide", children: /* @__PURE__ */ jsx(View, { style: { flex: 1 }, children: /* @__PURE__ */ jsx(
|
|
2316
2559
|
WebView,
|
|
2317
2560
|
{
|
|
2561
|
+
style: { flex: 1 },
|
|
2318
2562
|
originWhitelist: ["*"],
|
|
2319
2563
|
javaScriptEnabled: true,
|
|
2320
|
-
source: { html: survey.html },
|
|
2564
|
+
source: { html: survey.html, baseUrl: "https://sdk.deepdots.com/" },
|
|
2321
2565
|
onMessage: (e) => rendererRef.current?.handleMessage(e.nativeEvent.data)
|
|
2322
2566
|
}
|
|
2323
2567
|
) }) }) : null
|