@magicfeedback/popup-sdk 1.15.0 → 1.16.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/dist/{chunk-C7VD3HY4.mjs → chunk-AFRHPS3K.mjs} +25 -13
- package/dist/chunk-AFRHPS3K.mjs.map +1 -0
- package/dist/{chunk-GUJSOVS6.mjs → chunk-VHTN5UXD.mjs} +25 -13
- package/dist/chunk-VHTN5UXD.mjs.map +1 -0
- package/dist/index.d.mts +18 -6
- package/dist/index.d.ts +18 -6
- package/dist/index.js +140 -40
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +74 -26
- package/dist/index.mjs.map +1 -1
- package/dist/react-native.d.mts +5 -1
- package/dist/react-native.d.ts +5 -1
- package/dist/react-native.js +140 -40
- package/dist/react-native.js.map +1 -1
- package/dist/react-native.mjs +74 -26
- package/dist/react-native.mjs.map +1 -1
- package/dist/{renderPopup-RWSU5Y2H.mjs → renderPopup-S3RU3Y6J.mjs} +47 -7
- package/dist/renderPopup-S3RU3Y6J.mjs.map +1 -0
- package/dist/{renderPopup-CHWH3KHR.mjs → renderPopup-YCAQ3ODC.mjs} +47 -7
- package/dist/renderPopup-YCAQ3ODC.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/chunk-C7VD3HY4.mjs.map +0 -1
- package/dist/chunk-GUJSOVS6.mjs.map +0 -1
- package/dist/renderPopup-CHWH3KHR.mjs.map +0 -1
- package/dist/renderPopup-RWSU5Y2H.mjs.map +0 -1
package/dist/react-native.mjs
CHANGED
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
sdkWarn,
|
|
19
19
|
setLogger,
|
|
20
20
|
style_default
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-VHTN5UXD.mjs";
|
|
22
22
|
|
|
23
23
|
// src/react-native/index.tsx
|
|
24
24
|
import { createContext, useContext, useEffect, useRef, useState } from "react";
|
|
@@ -294,12 +294,14 @@ function buildSurveyHtml(opts) {
|
|
|
294
294
|
const startLabel = jsonForScript(initActionLabels.start);
|
|
295
295
|
const completeLabel = jsonForScript(initActionLabels.complete);
|
|
296
296
|
const submitLabel = jsonForScript(initActionLabels.accept);
|
|
297
|
+
const cancelLabel = jsonForScript(initActionLabels.decline);
|
|
297
298
|
const labelsTableJson = jsonForScript(LABELS);
|
|
298
299
|
const actionOverridesJson = jsonForScript({
|
|
299
300
|
accept: trimmedOrNull(opts.actions?.accept?.label),
|
|
300
301
|
start: trimmedOrNull(opts.actions?.start?.label),
|
|
301
302
|
complete: trimmedOrNull(opts.actions?.complete?.label),
|
|
302
|
-
back: trimmedOrNull(opts.actions?.back?.label)
|
|
303
|
+
back: trimmedOrNull(opts.actions?.back?.label),
|
|
304
|
+
decline: trimmedOrNull(opts.actions?.decline?.label)
|
|
303
305
|
});
|
|
304
306
|
const initLangJson = jsonForScript(opts.language ?? "");
|
|
305
307
|
const initDirection = directionFor(opts.language);
|
|
@@ -361,6 +363,7 @@ body.dd-ready #dd-popup{visibility:visible}
|
|
|
361
363
|
#dd-logo{max-height:40px;max-width:100%;object-fit:contain;display:block;margin:12px 0 0 0}
|
|
362
364
|
.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}
|
|
363
365
|
/* Pantalla final: el HTML del editor de la plataforma (imagen + texto), centrado. */
|
|
366
|
+
.deepdots-load-error{display:none;width:100%;text-align:center;padding:24px 0;font-size:15px;color:${textPrimary}}
|
|
364
367
|
.deepdots-success{display:none;width:100%;text-align:center;padding:24px 0;color:${textPrimary}}
|
|
365
368
|
.deepdots-success img{max-width:100%;height:auto;margin:0 auto 16px auto;display:block}
|
|
366
369
|
.deepdots-success p{margin:0;font-size:16px;font-weight:600;line-height:1.4}
|
|
@@ -368,7 +371,7 @@ body.dd-ready #dd-popup{visibility:visible}
|
|
|
368
371
|
.dd-nav-btn{display:none;border:none;min-height:44px;padding:12px 24px;border-radius:999px;cursor:pointer;font-size:15px;font-weight:600;align-items:center;justify-content:center;text-align:center}
|
|
369
372
|
/* Secundario como bot\xF3n de texto: sin borde ni fondo, para que el primario sea la \xFAnica CTA. */
|
|
370
373
|
#dd-back{background:transparent;color:${textMuted};border:none}
|
|
371
|
-
#dd-start,#dd-complete,#dd-submit{background:#1E293B;color:#fff;border:none}
|
|
374
|
+
#dd-start,#dd-complete,#dd-submit,#dd-cancel{background:#1E293B;color:#fff;border:none}
|
|
372
375
|
#dd-submit:disabled,#dd-start:disabled,#dd-back:disabled,#dd-complete:disabled{opacity:0.6;cursor:not-allowed}
|
|
373
376
|
.mf-spinner{display:none;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}
|
|
374
377
|
.mf-spinner-circle{width:28px;height:28px;border:3px solid #e0e6ed;border-top-color:#1E293B;border-radius:50%;animation:ddspin 0.9s linear infinite}
|
|
@@ -409,6 +412,7 @@ ${customCss}
|
|
|
409
412
|
<div class="mf-spinner" id="dd-spinner" role="status" aria-label="${initLabels.loadingAria}"><div class="mf-spinner-circle"></div></div>
|
|
410
413
|
<div id="mf"></div>
|
|
411
414
|
</div>
|
|
415
|
+
<div class="deepdots-load-error" id="dd-load-error" role="alert"></div>
|
|
412
416
|
<div class="deepdots-error-hint" id="dd-error" role="alert" aria-live="polite"></div>
|
|
413
417
|
</div>
|
|
414
418
|
<div class="deepdots-popup-footer" id="dd-footer">
|
|
@@ -416,6 +420,7 @@ ${customCss}
|
|
|
416
420
|
<button type="button" class="dd-nav-btn" id="dd-back"></button>
|
|
417
421
|
<button type="button" class="dd-nav-btn" id="dd-complete"></button>
|
|
418
422
|
<button type="button" class="dd-nav-btn" id="dd-start"></button>
|
|
423
|
+
<button type="button" class="dd-nav-btn" id="dd-cancel"></button>
|
|
419
424
|
</div>
|
|
420
425
|
</div>
|
|
421
426
|
</div>
|
|
@@ -438,6 +443,8 @@ ${customCss}
|
|
|
438
443
|
var startBtn=document.getElementById('dd-start');
|
|
439
444
|
var completeBtn=document.getElementById('dd-complete');
|
|
440
445
|
var submitBtn=document.getElementById('dd-submit');
|
|
446
|
+
var cancelBtn=document.getElementById('dd-cancel');
|
|
447
|
+
var loadErrorEl=document.getElementById('dd-load-error');
|
|
441
448
|
var titleEl=document.getElementById('dd-title');
|
|
442
449
|
var progressEl=document.getElementById('dd-progress');
|
|
443
450
|
var progressLabel=document.getElementById('dd-progress-label');
|
|
@@ -467,6 +474,8 @@ ${customCss}
|
|
|
467
474
|
startBtn.textContent=DD_ACTION_OVERRIDES.start||next.start;
|
|
468
475
|
completeBtn.textContent=DD_ACTION_OVERRIDES.complete||next.complete;
|
|
469
476
|
submitBtn.textContent=DD_ACTION_OVERRIDES.accept||next.accept;
|
|
477
|
+
cancelBtn.textContent=DD_ACTION_OVERRIDES.decline||next.decline;
|
|
478
|
+
loadErrorEl.textContent=next.errorLoad;
|
|
470
479
|
if(closeEl){ closeEl.setAttribute('aria-label',next.closeAria); }
|
|
471
480
|
if(spinner){ spinner.setAttribute('aria-label',next.loadingAria); }
|
|
472
481
|
progressFollowUp.textContent=next.followUp;
|
|
@@ -521,6 +530,7 @@ ${customCss}
|
|
|
521
530
|
startBtn.textContent=${startLabel};
|
|
522
531
|
completeBtn.textContent=${completeLabel};
|
|
523
532
|
submitBtn.textContent=${submitLabel};
|
|
533
|
+
cancelBtn.textContent=${cancelLabel};
|
|
524
534
|
|
|
525
535
|
closeEl.onclick=function(){ emitJSON('popup_close'); };
|
|
526
536
|
backBtn.onclick=function(){ if(window.DeepdotsForm && window.DeepdotsForm.back){ window.DeepdotsForm.back(); } };
|
|
@@ -532,6 +542,8 @@ ${customCss}
|
|
|
532
542
|
}
|
|
533
543
|
};
|
|
534
544
|
completeBtn.onclick=function(){ emitJSON('popup_close'); };
|
|
545
|
+
// \xDAnica acci\xF3n del survey que no carga: cierra igual que la X.
|
|
546
|
+
cancelBtn.onclick=function(){ emitJSON('popup_close'); };
|
|
535
547
|
var surveyCompletedEmitted=false;
|
|
536
548
|
submitBtn.onclick=function(){
|
|
537
549
|
if(surveyCompletedEmitted) return;
|
|
@@ -573,6 +585,7 @@ ${customCss}
|
|
|
573
585
|
startBtn.style.display='none';
|
|
574
586
|
submitBtn.style.display='none';
|
|
575
587
|
completeBtn.style.display='none';
|
|
588
|
+
cancelBtn.style.display='none';
|
|
576
589
|
backBtn.style.width='';
|
|
577
590
|
startBtn.style.width='';
|
|
578
591
|
submitBtn.style.width='';
|
|
@@ -588,6 +601,8 @@ ${customCss}
|
|
|
588
601
|
} else if(state==='completed'){
|
|
589
602
|
completeBtn.style.display='inline-flex';
|
|
590
603
|
completeBtn.style.width='100%';
|
|
604
|
+
} else if(state==='load_error'){
|
|
605
|
+
cancelBtn.style.display='inline-flex';
|
|
591
606
|
}
|
|
592
607
|
}
|
|
593
608
|
|
|
@@ -634,6 +649,26 @@ ${REVEAL_JS}
|
|
|
634
649
|
}
|
|
635
650
|
setLoading(true);
|
|
636
651
|
|
|
652
|
+
// Survey que no ha cargado (406 de /info, sin red, bundle del CDN ca\xEDdo). Antes se emit\xEDa
|
|
653
|
+
// \`loaded\` y se pintaba un Send sobre un survey vac\xEDo. Espejo de KMP: aviso traducido, la X
|
|
654
|
+
// sigue, un \xFAnico Cancel, y se revela ya (manda \`ready\`): no hay nada m\xE1s que esperar.
|
|
655
|
+
// No es interacci\xF3n del usuario: el renderer no lo convierte en popup_clicked.
|
|
656
|
+
var ddLoadFailed=false;
|
|
657
|
+
function ddShowLoadError(name, reason){
|
|
658
|
+
if(ddLoadFailed){ return; }
|
|
659
|
+
ddLoadFailed=true;
|
|
660
|
+
var why=(reason && reason.message) ? reason.message : String(reason);
|
|
661
|
+
emitJSON(name, { message: why });
|
|
662
|
+
progressEl.style.display='none';
|
|
663
|
+
formWrapper.style.display='none';
|
|
664
|
+
errorHint.style.display='none';
|
|
665
|
+
loadErrorEl.textContent=DD_LABELS_ACTIVE.errorLoad;
|
|
666
|
+
loadErrorEl.style.display='block';
|
|
667
|
+
setLoading(false);
|
|
668
|
+
updateButtons('load_error');
|
|
669
|
+
ddReveal.reveal();
|
|
670
|
+
}
|
|
671
|
+
|
|
637
672
|
var initialized=false;
|
|
638
673
|
function initMF(){
|
|
639
674
|
if(initialized || !window.magicfeedback) return initialized;
|
|
@@ -657,6 +692,7 @@ ${REVEAL_JS}
|
|
|
657
692
|
// de native sin esta opci\xF3n la ignoran.
|
|
658
693
|
autofocus:'navigation',
|
|
659
694
|
onLoadedEvent:function(args){
|
|
695
|
+
if(args && args.error){ ddShowLoadError('error:load', args.error); return; }
|
|
660
696
|
// Idioma en el que native muestra el survey: manda sobre el del init para que el
|
|
661
697
|
// chrome no se quede en ingl\xE9s delante de un survey traducido. Native < 2.3 no lo
|
|
662
698
|
// env\xEDa: entonces el primero de formData.lang (el idioma por defecto).
|
|
@@ -760,13 +796,13 @@ ${REVEAL_JS}
|
|
|
760
796
|
updateProgress({ progress:p&&p.progress, total:form.total, completed:false, followup:p&&p.followup });
|
|
761
797
|
emitJSON('back', p);
|
|
762
798
|
}
|
|
763
|
-
}).catch(function(e){
|
|
764
|
-
}catch(e){
|
|
799
|
+
}).catch(function(e){ ddShowLoadError('error:init', e); });
|
|
800
|
+
}catch(e){ ddShowLoadError('error:exception', e); }
|
|
765
801
|
return true;
|
|
766
802
|
}
|
|
767
803
|
var s=document.createElement('script'); s.src=${JSON.stringify(cdn)}; s.async=true;
|
|
768
804
|
s.onload=function(){ initMF(); };
|
|
769
|
-
s.onerror=function(){
|
|
805
|
+
s.onerror=function(){ ddShowLoadError('error:load', 'survey script failed to load'); };
|
|
770
806
|
document.head.appendChild(s);
|
|
771
807
|
var tries=0, t=setInterval(function(){ if(initMF()||++tries>40){ clearInterval(t); } },150);
|
|
772
808
|
})();
|
|
@@ -883,6 +919,7 @@ var ReactNativePopupRenderer = class {
|
|
|
883
919
|
this.onCloseFn?.();
|
|
884
920
|
break;
|
|
885
921
|
default:
|
|
922
|
+
if (typeof name === "string" && name.startsWith("error:")) this.emitReady(surveyId);
|
|
886
923
|
break;
|
|
887
924
|
}
|
|
888
925
|
}
|
|
@@ -895,7 +932,7 @@ function createReactNativeRenderer() {
|
|
|
895
932
|
}
|
|
896
933
|
|
|
897
934
|
// src/ui/preload.ts
|
|
898
|
-
var defaultLoader = () => import("./renderPopup-
|
|
935
|
+
var defaultLoader = () => import("./renderPopup-S3RU3Y6J.mjs");
|
|
899
936
|
var pending = null;
|
|
900
937
|
function preloadRenderPopup(loader = defaultLoader) {
|
|
901
938
|
if (pending) return pending;
|
|
@@ -968,7 +1005,7 @@ var BrowserPopupRenderer = class {
|
|
|
968
1005
|
if (!this.container) return;
|
|
969
1006
|
this.visible = true;
|
|
970
1007
|
const container = this.container;
|
|
971
|
-
void import("./renderPopup-
|
|
1008
|
+
void import("./renderPopup-S3RU3Y6J.mjs").then(({ renderPopup }) => {
|
|
972
1009
|
renderPopup(container, surveyId, productId, actions, emit, onClose, env, userId, style, sessionId, miniService, analyticsFeedbackSessionId, options);
|
|
973
1010
|
});
|
|
974
1011
|
}
|
|
@@ -1689,12 +1726,12 @@ var EngagementTracker = class {
|
|
|
1689
1726
|
};
|
|
1690
1727
|
|
|
1691
1728
|
// src/contact/contact-manager.ts
|
|
1692
|
-
function stableSerialize(attrs) {
|
|
1729
|
+
function stableSerialize(userId, attrs) {
|
|
1693
1730
|
const sorted = {};
|
|
1694
1731
|
for (const key of Object.keys(attrs).sort()) {
|
|
1695
1732
|
sorted[key] = attrs[key];
|
|
1696
1733
|
}
|
|
1697
|
-
return JSON.stringify(sorted);
|
|
1734
|
+
return JSON.stringify({ userId, attributes: sorted });
|
|
1698
1735
|
}
|
|
1699
1736
|
var ContactManager = class {
|
|
1700
1737
|
constructor(options) {
|
|
@@ -1704,18 +1741,23 @@ var ContactManager = class {
|
|
|
1704
1741
|
this.post = options.post;
|
|
1705
1742
|
}
|
|
1706
1743
|
/**
|
|
1707
|
-
* Envía los atributos si cambiaron respecto a lo último enviado.
|
|
1708
|
-
*
|
|
1744
|
+
* Envía los atributos si cambiaron respecto a lo último enviado. La caché solo se guarda
|
|
1745
|
+
* cuando la API acepta el envío; si falla, la llamada siguiente reintenta. Nunca rechaza.
|
|
1746
|
+
* @returns `true` si se envió, `false` si no hubo cambios o el envío falló.
|
|
1709
1747
|
*/
|
|
1710
1748
|
async setAttributes(attributes) {
|
|
1711
|
-
const serialized = stableSerialize(attributes);
|
|
1749
|
+
const serialized = stableSerialize(this.userId, attributes);
|
|
1712
1750
|
const last = this.storage.getItem(STORAGE_KEYS.contactAttributes);
|
|
1713
1751
|
if (last === serialized) return false;
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1752
|
+
try {
|
|
1753
|
+
await this.post({
|
|
1754
|
+
publicKey: this.publicKey,
|
|
1755
|
+
userId: this.userId,
|
|
1756
|
+
userAttributes: attributes
|
|
1757
|
+
});
|
|
1758
|
+
} catch {
|
|
1759
|
+
return false;
|
|
1760
|
+
}
|
|
1719
1761
|
this.storage.setItem(STORAGE_KEYS.contactAttributes, serialized);
|
|
1720
1762
|
return true;
|
|
1721
1763
|
}
|
|
@@ -3109,25 +3151,31 @@ var DeepdotsPopups = class {
|
|
|
3109
3151
|
return null;
|
|
3110
3152
|
}
|
|
3111
3153
|
}
|
|
3112
|
-
/**
|
|
3154
|
+
/**
|
|
3155
|
+
* Envía los atributos de contact a la API (`POST /sdk/popups/contact`). Rechaza si no se
|
|
3156
|
+
* pudo enviar (sin red o respuesta no-2xx), para que `ContactManager` no guarde la caché
|
|
3157
|
+
* y la llamada siguiente reintente.
|
|
3158
|
+
*/
|
|
3113
3159
|
async postContact(body) {
|
|
3114
3160
|
const baseUrl = this.baseUrl;
|
|
3115
|
-
if (!baseUrl)
|
|
3161
|
+
if (!baseUrl) throw new Error("no base URL");
|
|
3116
3162
|
const endpoint = `${baseUrl}/sdk/popups/contact`;
|
|
3163
|
+
let response;
|
|
3117
3164
|
try {
|
|
3118
|
-
|
|
3165
|
+
response = await fetch(endpoint, {
|
|
3119
3166
|
method: "POST",
|
|
3120
3167
|
headers: { "Content-Type": "application/json" },
|
|
3121
3168
|
body: JSON.stringify(body)
|
|
3122
3169
|
});
|
|
3123
|
-
if (!response.ok) {
|
|
3124
|
-
this.log("Failed to post contact", response.status, response.statusText);
|
|
3125
|
-
return;
|
|
3126
|
-
}
|
|
3127
|
-
this.log("contact \xB7 sent attributes for user:", body.userId);
|
|
3128
3170
|
} catch (error) {
|
|
3129
3171
|
this.log("Error posting contact", error);
|
|
3172
|
+
throw error;
|
|
3173
|
+
}
|
|
3174
|
+
if (!response.ok) {
|
|
3175
|
+
this.log("Failed to post contact", response.status, response.statusText);
|
|
3176
|
+
throw new Error(`HTTP ${response.status}`);
|
|
3130
3177
|
}
|
|
3178
|
+
this.log("contact \xB7 sent attributes for user:", body.userId);
|
|
3131
3179
|
}
|
|
3132
3180
|
/** Notifica eventos de popup a la API */
|
|
3133
3181
|
async postPopupEvent(status, popupId, userId) {
|