@magicfeedback/popup-sdk 1.6.0 → 1.7.1
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 +34 -1
- package/dist/assets/assets/style.css +63 -14
- package/dist/{chunk-AN7JIVWB.mjs → chunk-W6MPSWMS.mjs} +352 -15
- package/dist/chunk-W6MPSWMS.mjs.map +1 -0
- package/dist/{chunk-Z3LLJMSH.mjs → chunk-WNIUIOKF.mjs} +332 -15
- package/dist/chunk-WNIUIOKF.mjs.map +1 -0
- package/dist/index.d.mts +99 -1
- package/dist/index.d.ts +99 -1
- package/dist/index.js +1647 -1366
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +200 -28
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +13 -0
- package/dist/react-native.d.ts +13 -0
- package/dist/react-native.js +550 -55
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +189 -28
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-SELXQ3UE.mjs → renderPopup-EWGKG53W.mjs} +42 -18
- package/dist/renderPopup-EWGKG53W.mjs.map +1 -0
- package/dist/renderPopup-HHQMAW3G.mjs +3114 -0
- package/dist/renderPopup-HHQMAW3G.mjs.map +1 -0
- package/package.json +2 -2
- package/dist/chunk-AN7JIVWB.mjs.map +0 -1
- package/dist/chunk-Z3LLJMSH.mjs.map +0 -1
- package/dist/renderPopup-M6MKTDEH.mjs +0 -3330
- package/dist/renderPopup-M6MKTDEH.mjs.map +0 -1
- package/dist/renderPopup-SELXQ3UE.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import {
|
|
2
2
|
InMemoryStorage,
|
|
3
|
+
LABELS,
|
|
4
|
+
RESOLVE_LOCALE_JS,
|
|
5
|
+
RTL_LOCALES,
|
|
3
6
|
STORAGE_KEYS,
|
|
7
|
+
SUPPORTED_LANGUAGES,
|
|
4
8
|
TrackingManager,
|
|
5
9
|
buildFontFaceCss,
|
|
6
10
|
buildFontFamilyValue,
|
|
7
11
|
buildSurveyIdentity,
|
|
8
12
|
createDefaultStorage,
|
|
13
|
+
directionFor,
|
|
14
|
+
getLabels,
|
|
15
|
+
isRtlLanguage,
|
|
16
|
+
resolveActionLabels,
|
|
17
|
+
resolveLocale,
|
|
9
18
|
sdkWarn,
|
|
10
19
|
setLogger,
|
|
11
20
|
style_default
|
|
12
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-W6MPSWMS.mjs";
|
|
13
22
|
|
|
14
23
|
// src/types/index.ts
|
|
15
24
|
var POPUP_TRIGGER_CONDITION_STATUSES = [
|
|
@@ -212,9 +221,13 @@ var POSITION_MAP = {
|
|
|
212
221
|
function jsonForScript(value) {
|
|
213
222
|
return JSON.stringify(value ?? null).replace(/</g, "\\u003C").replace(/\u2028/g, "\\u2028").replace(/\u2029/g, "\\u2029");
|
|
214
223
|
}
|
|
224
|
+
function trimmedOrNull(value) {
|
|
225
|
+
const trimmed = typeof value === "string" ? value.trim() : "";
|
|
226
|
+
return trimmed ? value : null;
|
|
227
|
+
}
|
|
215
228
|
function buildSurveyHtml(opts) {
|
|
216
229
|
const env = opts.env === "development" ? "dev" : "prod";
|
|
217
|
-
const version = opts.version ?? "2.2.
|
|
230
|
+
const version = opts.version ?? "2.2.22";
|
|
218
231
|
const cdn = `https://cdn.jsdelivr.net/npm/@magicfeedback/native@${version}/dist/magicfeedback-sdk.browser.js`;
|
|
219
232
|
const sid = jsonForScript(opts.surveyId);
|
|
220
233
|
const pid = jsonForScript(opts.productId);
|
|
@@ -246,10 +259,22 @@ function buildSurveyHtml(opts) {
|
|
|
246
259
|
const titleJson = jsonForScript(opts.title ?? "");
|
|
247
260
|
const customCss = (opts.surveyCss ?? "").replace(/<\/\s*style/gi, "<\\/style");
|
|
248
261
|
const progressPref = opts.showProgressBar === void 0 ? "null" : String(opts.showProgressBar);
|
|
249
|
-
const
|
|
250
|
-
const
|
|
251
|
-
const
|
|
252
|
-
const
|
|
262
|
+
const initLabels = getLabels(opts.language);
|
|
263
|
+
const initActionLabels = resolveActionLabels(opts.actions, opts.language);
|
|
264
|
+
const backLabel = jsonForScript(initActionLabels.back);
|
|
265
|
+
const startLabel = jsonForScript(initActionLabels.start);
|
|
266
|
+
const completeLabel = jsonForScript(initActionLabels.complete);
|
|
267
|
+
const submitLabel = jsonForScript(initActionLabels.accept);
|
|
268
|
+
const labelsTableJson = jsonForScript(LABELS);
|
|
269
|
+
const actionOverridesJson = jsonForScript({
|
|
270
|
+
accept: trimmedOrNull(opts.actions?.accept?.label),
|
|
271
|
+
start: trimmedOrNull(opts.actions?.start?.label),
|
|
272
|
+
complete: trimmedOrNull(opts.actions?.complete?.label),
|
|
273
|
+
back: trimmedOrNull(opts.actions?.back?.label)
|
|
274
|
+
});
|
|
275
|
+
const initLangJson = jsonForScript(opts.language ?? "");
|
|
276
|
+
const initDirection = directionFor(opts.language);
|
|
277
|
+
const rtlLocalesJson = jsonForScript(RTL_LOCALES);
|
|
253
278
|
return `<!DOCTYPE html><html><head>
|
|
254
279
|
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
255
280
|
<meta name="color-scheme" content="${colorScheme}"/>
|
|
@@ -262,8 +287,8 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
262
287
|
.deepdots-popup-header{display:flex;justify-content:space-between;align-items:center;gap:12px;width:100%;flex:0 0 auto}
|
|
263
288
|
/* Neutraliza la regla \`.deepdots-popup h2\` del CSS del survey (uppercase, centrado y
|
|
264
289
|
margin-bottom 40px), pensada para los enunciados y no para el t\xEDtulo de la cabecera. */
|
|
265
|
-
#dd-title{margin:0;font-family:var(--deepdots-font,'Montserrat',inherit);font-size:17px;font-weight:600;line-height:1.3;color:${textPrimary};text-transform:none;text-align:
|
|
266
|
-
#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;flex:0 0 auto;margin-
|
|
290
|
+
#dd-title{margin:0;font-family:var(--deepdots-font,'Montserrat',inherit);font-size:17px;font-weight:600;line-height:1.3;color:${textPrimary};text-transform:none;text-align:start;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
291
|
+
#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;flex:0 0 auto;margin-inline-start:auto}
|
|
267
292
|
/* Progreso alineado con la cabecera: sin padding horizontal propio, lo marca la tarjeta.
|
|
268
293
|
El vertical es el mismo arriba y abajo, y del mismo valor que el padding de la tarjeta. */
|
|
269
294
|
.deepdots-progress{display:none;flex-direction:column;gap:8px;width:100%;flex:0 0 auto;padding:16px 0;box-sizing:border-box}
|
|
@@ -320,10 +345,10 @@ body{display:${bodyDisplay};justify-content:${pos.justifyContent};align-items:${
|
|
|
320
345
|
${customCss}
|
|
321
346
|
</style>
|
|
322
347
|
</head><body>
|
|
323
|
-
<div class="${popupClass}" id="dd-popup">
|
|
348
|
+
<div class="${popupClass}" id="dd-popup" dir="${initDirection}">
|
|
324
349
|
<div class="deepdots-popup-header">
|
|
325
350
|
<h2 id="dd-title" class="deepdots-popup-title" hidden></h2>
|
|
326
|
-
<button type="button" id="dd-close" aria-label="
|
|
351
|
+
<button type="button" id="dd-close" aria-label="${initLabels.closeAria}">
|
|
327
352
|
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
328
353
|
<path d="M5 5L19 19M5 19L19 5" stroke="currentColor" stroke-width="1.5" stroke-linecap="butt"/>
|
|
329
354
|
</svg>
|
|
@@ -332,23 +357,23 @@ ${customCss}
|
|
|
332
357
|
<div class="deepdots-progress" id="dd-progress">
|
|
333
358
|
<div class="deepdots-progress-head">
|
|
334
359
|
<span id="dd-progress-label"><span id="dd-progress-current"></span><span id="dd-progress-total"></span></span>
|
|
335
|
-
<span id="dd-progress-followup"
|
|
360
|
+
<span id="dd-progress-followup">${initLabels.followUp}</span>
|
|
336
361
|
</div>
|
|
337
362
|
<div class="deepdots-progress-track"><div id="dd-progress-bar"></div></div>
|
|
338
363
|
</div>
|
|
339
364
|
<div class="deepdots-popup-container-content" id="dd-content">
|
|
340
365
|
<div class="deepdots-popup-main" id="dd-main">
|
|
341
366
|
<div id="dd-form-wrapper">
|
|
342
|
-
<div class="mf-spinner" id="dd-spinner" role="status" aria-label="
|
|
367
|
+
<div class="mf-spinner" id="dd-spinner" role="status" aria-label="${initLabels.loadingAria}"><div class="mf-spinner-circle"></div></div>
|
|
343
368
|
<div id="mf"></div>
|
|
344
369
|
</div>
|
|
345
370
|
<div class="deepdots-error-hint" id="dd-error" role="alert" aria-live="polite"></div>
|
|
346
371
|
</div>
|
|
347
372
|
<div class="deepdots-popup-footer" id="dd-footer">
|
|
348
|
-
<button type="button" class="dd-nav-btn" id="dd-submit"
|
|
349
|
-
<button type="button" class="dd-nav-btn" id="dd-back"
|
|
350
|
-
<button type="button" class="dd-nav-btn" id="dd-complete"
|
|
351
|
-
<button type="button" class="dd-nav-btn" id="dd-start"
|
|
373
|
+
<button type="button" class="dd-nav-btn" id="dd-submit"></button>
|
|
374
|
+
<button type="button" class="dd-nav-btn" id="dd-back"></button>
|
|
375
|
+
<button type="button" class="dd-nav-btn" id="dd-complete"></button>
|
|
376
|
+
<button type="button" class="dd-nav-btn" id="dd-start"></button>
|
|
352
377
|
</div>
|
|
353
378
|
</div>
|
|
354
379
|
</div>
|
|
@@ -377,6 +402,32 @@ ${customCss}
|
|
|
377
402
|
var progressTotal=document.getElementById('dd-progress-total');
|
|
378
403
|
var progressFollowUp=document.getElementById('dd-progress-followup');
|
|
379
404
|
var progressBar=document.getElementById('dd-progress-bar');
|
|
405
|
+
var closeEl=document.getElementById('dd-close');
|
|
406
|
+
|
|
407
|
+
// --- i18n del chrome -------------------------------------------------------------------
|
|
408
|
+
// La tabla completa viaja embebida porque el idioma del survey (\`formData.lang[0]\`) solo se
|
|
409
|
+
// conoce ya dentro del WebView. \`ddResolveLocale\` es el espejo del \`resolveLocale\` de TS
|
|
410
|
+
// (paridad cubierta por test).
|
|
411
|
+
var DD_LABELS=${labelsTableJson};
|
|
412
|
+
var DD_ACTION_OVERRIDES=${actionOverridesJson};
|
|
413
|
+
${RESOLVE_LOCALE_JS}
|
|
414
|
+
var DD_LABELS_ACTIVE=DD_LABELS[ddResolveLocale(${initLangJson})];
|
|
415
|
+
var DD_RTL=${rtlLocalesJson};
|
|
416
|
+
function ddIsRtl(lang){ return DD_RTL.indexOf(ddResolveLocale(lang))!==-1; }
|
|
417
|
+
function ddApplyLabels(lang){
|
|
418
|
+
var next=DD_LABELS[ddResolveLocale(lang)];
|
|
419
|
+
if(!next) return;
|
|
420
|
+
DD_LABELS_ACTIVE=next;
|
|
421
|
+
// El survey ya se ha volteado a s\xED mismo: el chrome tiene que acompa\xF1arlo.
|
|
422
|
+
popup.setAttribute('dir', ddIsRtl(lang) ? 'rtl' : 'ltr');
|
|
423
|
+
backBtn.textContent=DD_ACTION_OVERRIDES.back||next.back;
|
|
424
|
+
startBtn.textContent=DD_ACTION_OVERRIDES.start||next.start;
|
|
425
|
+
completeBtn.textContent=DD_ACTION_OVERRIDES.complete||next.complete;
|
|
426
|
+
submitBtn.textContent=DD_ACTION_OVERRIDES.accept||next.accept;
|
|
427
|
+
if(closeEl){ closeEl.setAttribute('aria-label',next.closeAria); }
|
|
428
|
+
if(spinner){ spinner.setAttribute('aria-label',next.loadingAria); }
|
|
429
|
+
progressFollowUp.textContent=next.followUp;
|
|
430
|
+
}
|
|
380
431
|
|
|
381
432
|
function setTitle(t){
|
|
382
433
|
if(!t) return;
|
|
@@ -417,8 +468,8 @@ ${customCss}
|
|
|
417
468
|
progressCurrent.textContent=Math.round(pct)+'%';
|
|
418
469
|
progressTotal.textContent='';
|
|
419
470
|
} else {
|
|
420
|
-
progressCurrent.textContent='
|
|
421
|
-
progressTotal.textContent=' of '+total;
|
|
471
|
+
progressCurrent.textContent=DD_LABELS_ACTIVE.question+' '+label;
|
|
472
|
+
progressTotal.textContent=' '+DD_LABELS_ACTIVE.of+' '+total;
|
|
422
473
|
}
|
|
423
474
|
progressFollowUp.style.display=p&&p.followup?'inline-block':'none';
|
|
424
475
|
}
|
|
@@ -428,7 +479,7 @@ ${customCss}
|
|
|
428
479
|
completeBtn.textContent=${completeLabel};
|
|
429
480
|
submitBtn.textContent=${submitLabel};
|
|
430
481
|
|
|
431
|
-
|
|
482
|
+
closeEl.onclick=function(){ emitJSON('popup_close'); };
|
|
432
483
|
backBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.back){ window.DeepdotsForm.back(); } };
|
|
433
484
|
startBtn.onclick=function(){
|
|
434
485
|
if(window.DeepdotsForm && window.DeepdotsForm.startForm){
|
|
@@ -523,6 +574,14 @@ ${customCss}
|
|
|
523
574
|
// fallback es un literal gen\xE9rico que ignora style.successMessage.
|
|
524
575
|
addSuccessScreen:false,
|
|
525
576
|
onLoadedEvent:function(args){
|
|
577
|
+
// Idioma del survey: manda sobre el del init para que el chrome no se quede en
|
|
578
|
+
// ingl\xE9s delante de un survey traducido.
|
|
579
|
+
var langs=args && args.formData ? args.formData.lang : null;
|
|
580
|
+
if(langs && langs.length){
|
|
581
|
+
for(var li=0;li<langs.length;li++){
|
|
582
|
+
if(typeof langs[li]==='string' && langs[li].trim()){ ddApplyLabels(langs[li]); break; }
|
|
583
|
+
}
|
|
584
|
+
}
|
|
526
585
|
var s=args && args.formData ? args.formData.style : null;
|
|
527
586
|
if(s && !stylesInjected){
|
|
528
587
|
stylesInjected=true;
|
|
@@ -549,8 +608,10 @@ ${customCss}
|
|
|
549
608
|
if(s.logoSize==='small'){ logoImg.style.maxHeight='30px'; }
|
|
550
609
|
else if(s.logoSize==='medium'){ logoImg.style.maxHeight='50px'; }
|
|
551
610
|
else if(s.logoSize==='large'){ logoImg.style.maxHeight='70px'; }
|
|
552
|
-
|
|
553
|
-
|
|
611
|
+
// M\xE1rgenes l\xF3gicos: con un survey RTL el popup va con dir="rtl" y el logo
|
|
612
|
+
// tiene que acompa\xF1ar al chrome. En LTR el resultado es el mismo de antes.
|
|
613
|
+
if(s.logoPosition==='left'){ logoImg.style.margin='12px 0 0 0'; logoImg.style.setProperty('margin-inline-start','0'); logoImg.style.setProperty('margin-inline-end','16px'); }
|
|
614
|
+
else if(s.logoPosition==='right'){ logoImg.style.margin='12px 0 0 0'; logoImg.style.setProperty('margin-inline-start','auto'); logoImg.style.setProperty('margin-inline-end','0'); }
|
|
554
615
|
else if(s.logoPosition==='center'){ logoImg.style.margin='12px auto 0 auto'; }
|
|
555
616
|
// Encima de la barra de progreso, como hermano del header (espejo de ui/logo.ts en
|
|
556
617
|
// web). Fuera de #dd-main, as\xED el logo no se va con el scroll del formulario.
|
|
@@ -576,12 +637,12 @@ ${customCss}
|
|
|
576
637
|
setLoading(false);
|
|
577
638
|
if(error.toLowerCase().indexOf('no response')!==-1){
|
|
578
639
|
// La p\xE1gina no ha cambiado: el estado de navegaci\xF3n se queda como estaba.
|
|
579
|
-
errorHint.textContent=
|
|
640
|
+
errorHint.textContent=DD_LABELS_ACTIVE.errorRequired;
|
|
580
641
|
errorHint.style.display='block';
|
|
581
642
|
updateNavButtons();
|
|
582
643
|
return;
|
|
583
644
|
}
|
|
584
|
-
errorHint.textContent=
|
|
645
|
+
errorHint.textContent=DD_LABELS_ACTIVE.errorSubmit;
|
|
585
646
|
errorHint.style.display='block';
|
|
586
647
|
return;
|
|
587
648
|
}
|
|
@@ -653,7 +714,8 @@ var ReactNativePopupRenderer = class {
|
|
|
653
714
|
chrome: renderChrome,
|
|
654
715
|
title: options?.title,
|
|
655
716
|
showProgressBar: options?.showProgressBar,
|
|
656
|
-
surveyCss: options?.surveyCss
|
|
717
|
+
surveyCss: options?.surveyCss,
|
|
718
|
+
language: options?.language
|
|
657
719
|
});
|
|
658
720
|
if (this.options.onShow) {
|
|
659
721
|
this.options.onShow({ surveyId, productId, html });
|
|
@@ -749,7 +811,7 @@ var BrowserPopupRenderer = class {
|
|
|
749
811
|
if (!this.container) return;
|
|
750
812
|
this.visible = true;
|
|
751
813
|
const container = this.container;
|
|
752
|
-
void import("./renderPopup-
|
|
814
|
+
void import("./renderPopup-HHQMAW3G.mjs").then(({ renderPopup }) => {
|
|
753
815
|
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId, options);
|
|
754
816
|
});
|
|
755
817
|
}
|
|
@@ -1501,6 +1563,75 @@ var CrashReporter = class {
|
|
|
1501
1563
|
}
|
|
1502
1564
|
};
|
|
1503
1565
|
|
|
1566
|
+
// src/core/popup-state-store.ts
|
|
1567
|
+
var POPUP_STATE_STORAGE_KEY = "deepdots.popups.state";
|
|
1568
|
+
var MAX_TRACKED_POPUP_ENTRIES = 200;
|
|
1569
|
+
function emptyState() {
|
|
1570
|
+
return { lastShown: {}, progress: {} };
|
|
1571
|
+
}
|
|
1572
|
+
function isValidTimestamp(value) {
|
|
1573
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
1574
|
+
}
|
|
1575
|
+
function capEntries(entries, timestampOf) {
|
|
1576
|
+
if (entries.length <= MAX_TRACKED_POPUP_ENTRIES) return entries;
|
|
1577
|
+
return [...entries].sort((a, b) => timestampOf(b[1]) - timestampOf(a[1])).slice(0, MAX_TRACKED_POPUP_ENTRIES);
|
|
1578
|
+
}
|
|
1579
|
+
function readPopupState(storage) {
|
|
1580
|
+
let raw = null;
|
|
1581
|
+
try {
|
|
1582
|
+
raw = storage.getItem(POPUP_STATE_STORAGE_KEY);
|
|
1583
|
+
} catch {
|
|
1584
|
+
return emptyState();
|
|
1585
|
+
}
|
|
1586
|
+
if (!raw) return emptyState();
|
|
1587
|
+
let parsed;
|
|
1588
|
+
try {
|
|
1589
|
+
parsed = JSON.parse(raw);
|
|
1590
|
+
} catch {
|
|
1591
|
+
return emptyState();
|
|
1592
|
+
}
|
|
1593
|
+
if (typeof parsed !== "object" || parsed === null) return emptyState();
|
|
1594
|
+
const source = parsed;
|
|
1595
|
+
const state = emptyState();
|
|
1596
|
+
if (typeof source.lastShown === "object" && source.lastShown !== null) {
|
|
1597
|
+
const valid = Object.entries(source.lastShown).filter((entry) => isValidTimestamp(entry[1]));
|
|
1598
|
+
capEntries(valid, (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
1599
|
+
state.lastShown[popupId] = timestamp;
|
|
1600
|
+
});
|
|
1601
|
+
}
|
|
1602
|
+
if (typeof source.progress === "object" && source.progress !== null) {
|
|
1603
|
+
const valid = Object.entries(source.progress).filter((entry) => {
|
|
1604
|
+
const value = entry[1];
|
|
1605
|
+
if (typeof value !== "object" || value === null) return false;
|
|
1606
|
+
const candidate = value;
|
|
1607
|
+
return POPUP_TRIGGER_CONDITION_STATUSES.includes(candidate.status) && isValidTimestamp(candidate.timestamp);
|
|
1608
|
+
});
|
|
1609
|
+
capEntries(valid, (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
1610
|
+
state.progress[surveyId] = { status: entry.status, timestamp: entry.timestamp };
|
|
1611
|
+
});
|
|
1612
|
+
}
|
|
1613
|
+
return state;
|
|
1614
|
+
}
|
|
1615
|
+
function writePopupState(storage, state) {
|
|
1616
|
+
const capped = emptyState();
|
|
1617
|
+
capEntries(Object.entries(state.lastShown), (timestamp) => timestamp).forEach(([popupId, timestamp]) => {
|
|
1618
|
+
capped.lastShown[popupId] = timestamp;
|
|
1619
|
+
});
|
|
1620
|
+
capEntries(Object.entries(state.progress), (entry) => entry.timestamp).forEach(([surveyId, entry]) => {
|
|
1621
|
+
capped.progress[surveyId] = entry;
|
|
1622
|
+
});
|
|
1623
|
+
try {
|
|
1624
|
+
storage.setItem(POPUP_STATE_STORAGE_KEY, JSON.stringify(capped));
|
|
1625
|
+
} catch {
|
|
1626
|
+
}
|
|
1627
|
+
}
|
|
1628
|
+
function clearPopupState(storage) {
|
|
1629
|
+
try {
|
|
1630
|
+
storage.removeItem(POPUP_STATE_STORAGE_KEY);
|
|
1631
|
+
} catch {
|
|
1632
|
+
}
|
|
1633
|
+
}
|
|
1634
|
+
|
|
1504
1635
|
// src/analytics/messaging.ts
|
|
1505
1636
|
var MESSAGE_CHANNELS = ["push", "in_app"];
|
|
1506
1637
|
function buildMessageParams(stage, o) {
|
|
@@ -1588,6 +1719,10 @@ var DeepdotsPopups = class {
|
|
|
1588
1719
|
this.popupDefinitions = [];
|
|
1589
1720
|
this.popupsLoaded = false;
|
|
1590
1721
|
this.pendingAutoLaunch = false;
|
|
1722
|
+
// Estado que alimenta las reglas de redisplay. Copia de trabajo en memoria; la fuente
|
|
1723
|
+
// duradera es el storage (`popup-state-store`), rehidratada en `init()` — sin eso, una
|
|
1724
|
+
// recarga reiniciaba el cooldown y el popup volvía a salir. `answeredSurveys` se deriva
|
|
1725
|
+
// de las entradas COMPLETED de `surveyProgress` (los dos los escribe `markSurveyAnswered`).
|
|
1591
1726
|
this.answeredSurveys = /* @__PURE__ */ new Set();
|
|
1592
1727
|
this.surveyProgress = /* @__PURE__ */ new Map();
|
|
1593
1728
|
this.lastShown = /* @__PURE__ */ new Map();
|
|
@@ -1663,6 +1798,7 @@ var DeepdotsPopups = class {
|
|
|
1663
1798
|
};
|
|
1664
1799
|
const storage = config.storage ?? createDefaultStorage();
|
|
1665
1800
|
this.storage = storage;
|
|
1801
|
+
this.loadPopupState(storage);
|
|
1666
1802
|
this.tracking = new TrackingManager({
|
|
1667
1803
|
storage,
|
|
1668
1804
|
clientUserId: this.config.userId,
|
|
@@ -1930,6 +2066,10 @@ var DeepdotsPopups = class {
|
|
|
1930
2066
|
}) : null;
|
|
1931
2067
|
this.analytics?.resetUserScope();
|
|
1932
2068
|
this.messageGuard.reset();
|
|
2069
|
+
this.lastShown.clear();
|
|
2070
|
+
this.surveyProgress.clear();
|
|
2071
|
+
this.answeredSurveys.clear();
|
|
2072
|
+
clearPopupState(storage);
|
|
1933
2073
|
this.log("tracking \xB7 user_change \xB7 user_id:", this.tracking.getUserId());
|
|
1934
2074
|
this.openSession();
|
|
1935
2075
|
}
|
|
@@ -2101,6 +2241,7 @@ var DeepdotsPopups = class {
|
|
|
2101
2241
|
this.log("Showing popup (definition)", def);
|
|
2102
2242
|
this.surveyToPopupId.set(def.surveyId, def.id);
|
|
2103
2243
|
this.lastShown.set(def.id, Date.now());
|
|
2244
|
+
this.persistPopupState();
|
|
2104
2245
|
this.renderPopup(def.surveyId, def.productId, def.actions, def.style, def.title);
|
|
2105
2246
|
this.emitEvent("popup_shown", def.surveyId, { popupId: def.id });
|
|
2106
2247
|
}
|
|
@@ -2459,13 +2600,13 @@ var DeepdotsPopups = class {
|
|
|
2459
2600
|
miniService,
|
|
2460
2601
|
analyticsFeedbackSessionId,
|
|
2461
2602
|
this.renderChrome,
|
|
2462
|
-
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
|
|
2603
|
+
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss, language: this.language }
|
|
2463
2604
|
);
|
|
2464
2605
|
return;
|
|
2465
2606
|
}
|
|
2466
2607
|
if (!this.popupContainer) return;
|
|
2467
2608
|
const container = this.popupContainer;
|
|
2468
|
-
void import("./renderPopup-
|
|
2609
|
+
void import("./renderPopup-HHQMAW3G.mjs").then(({ renderPopup }) => {
|
|
2469
2610
|
renderPopup(
|
|
2470
2611
|
container,
|
|
2471
2612
|
surveyId,
|
|
@@ -2479,7 +2620,7 @@ var DeepdotsPopups = class {
|
|
|
2479
2620
|
sessionId,
|
|
2480
2621
|
miniService,
|
|
2481
2622
|
analyticsFeedbackSessionId,
|
|
2482
|
-
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss }
|
|
2623
|
+
{ title, showProgressBar: this.showProgressBar, surveyCss: this.surveyCss, language: this.language }
|
|
2483
2624
|
);
|
|
2484
2625
|
});
|
|
2485
2626
|
}
|
|
@@ -2580,6 +2721,29 @@ var DeepdotsPopups = class {
|
|
|
2580
2721
|
return;
|
|
2581
2722
|
}
|
|
2582
2723
|
this.surveyProgress.set(surveyId, { status, timestamp: Date.now() });
|
|
2724
|
+
this.persistPopupState();
|
|
2725
|
+
}
|
|
2726
|
+
/**
|
|
2727
|
+
* Rehidrata el estado de redisplay desde el storage. `answeredSurveys` se reconstruye
|
|
2728
|
+
* desde las entradas COMPLETED: es exactamente lo que persiste `markSurveyAnswered`.
|
|
2729
|
+
*/
|
|
2730
|
+
loadPopupState(storage) {
|
|
2731
|
+
const state = readPopupState(storage);
|
|
2732
|
+
Object.entries(state.lastShown).forEach(([popupId, timestamp]) => {
|
|
2733
|
+
this.lastShown.set(popupId, timestamp);
|
|
2734
|
+
});
|
|
2735
|
+
Object.entries(state.progress).forEach(([surveyId, entry]) => {
|
|
2736
|
+
this.surveyProgress.set(surveyId, { status: entry.status, timestamp: entry.timestamp });
|
|
2737
|
+
if (entry.status === "COMPLETED") this.answeredSurveys.add(surveyId);
|
|
2738
|
+
});
|
|
2739
|
+
}
|
|
2740
|
+
/** Vuelca el estado de redisplay al storage. Sin storage (o bloqueado) degrada a memoria. */
|
|
2741
|
+
persistPopupState() {
|
|
2742
|
+
if (!this.storage) return;
|
|
2743
|
+
writePopupState(this.storage, {
|
|
2744
|
+
lastShown: Object.fromEntries(this.lastShown),
|
|
2745
|
+
progress: Object.fromEntries(this.surveyProgress)
|
|
2746
|
+
});
|
|
2583
2747
|
}
|
|
2584
2748
|
isPopupDefinition(value) {
|
|
2585
2749
|
if (typeof value !== "object" || value === null) return false;
|
|
@@ -2693,12 +2857,15 @@ export {
|
|
|
2693
2857
|
CrashReporter,
|
|
2694
2858
|
DeepdotsPopups,
|
|
2695
2859
|
InMemoryStorage,
|
|
2860
|
+
LABELS,
|
|
2696
2861
|
MAX_TRACKED_MESSAGES,
|
|
2697
2862
|
MESSAGE_CHANNELS,
|
|
2698
2863
|
MessageGuard,
|
|
2699
2864
|
NoopPopupRenderer,
|
|
2700
2865
|
POPUP_TRIGGER_CONDITION_STATUSES,
|
|
2866
|
+
RTL_LOCALES,
|
|
2701
2867
|
ReactNativePopupRenderer,
|
|
2868
|
+
SUPPORTED_LANGUAGES,
|
|
2702
2869
|
buildAnalyticsFeedbackBody,
|
|
2703
2870
|
buildMessageParams,
|
|
2704
2871
|
buildSurveyHtml,
|
|
@@ -2706,7 +2873,12 @@ export {
|
|
|
2706
2873
|
crashRecordToParams,
|
|
2707
2874
|
createDefaultRenderer,
|
|
2708
2875
|
createFeedbackSink,
|
|
2876
|
+
directionFor,
|
|
2877
|
+
getLabels,
|
|
2878
|
+
isRtlLanguage,
|
|
2709
2879
|
mmkvStorage,
|
|
2880
|
+
resolveActionLabels,
|
|
2881
|
+
resolveLocale,
|
|
2710
2882
|
setupReactNative
|
|
2711
2883
|
};
|
|
2712
2884
|
//# sourceMappingURL=index.mjs.map
|