@eshal-bot/chat-widget 0.2.38 → 0.2.39
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/{chat-widget-MarkdownRenderer-DBibTmXG.esm.js → chat-widget-MarkdownRenderer-CCfze57L.esm.js} +1 -1
- package/dist/chat-widget-index--xs5FWxs.esm.js +20 -0
- package/dist/chat-widget-markdown-chunk.js +92 -18
- package/dist/chat-widget-markdown-chunk.min.js +1 -1
- package/dist/chat-widget.esm.js +1 -1
- package/dist/chat-widget.js +22 -3
- package/dist/chat-widget.min.js +2 -2
- package/dist/chat-widget.umd.js +6 -6
- package/package.json +1 -1
- package/dist/chat-widget-index-nFrn-Uh5.esm.js +0 -20
|
@@ -88751,6 +88751,27 @@
|
|
|
88751
88751
|
function fill(text, values) {
|
|
88752
88752
|
return Object.entries(values).reduce((s, [k, v]) => s.replace(`{${k}}`, String(v)), String(text));
|
|
88753
88753
|
}
|
|
88754
|
+
|
|
88755
|
+
/** EV-4941: keep a masked address on one line ("+91 ••••• 6138"). */
|
|
88756
|
+
const noBreak = text => String(text ?? '').replace(/ /g, '\u00a0');
|
|
88757
|
+
|
|
88758
|
+
/**
|
|
88759
|
+
* EV-4939: a number whose calling code is not among the allowed ones, so the
|
|
88760
|
+
* card can say so before Send. Only numbers typed with +; a partial code that
|
|
88761
|
+
* could still become an allowed one is not flagged.
|
|
88762
|
+
*/
|
|
88763
|
+
function blockedByCountry(address, codes) {
|
|
88764
|
+
if (!Array.isArray(codes) || codes.length === 0 || !String(address).trim().startsWith('+')) return false;
|
|
88765
|
+
const digits = String(address).replace(/\D/g, '');
|
|
88766
|
+
if (!digits) return false;
|
|
88767
|
+
return !codes.some(c => digits.startsWith(c) || c.startsWith(digits));
|
|
88768
|
+
}
|
|
88769
|
+
|
|
88770
|
+
/** "14:59" for a lockout's time left. */
|
|
88771
|
+
function clock(seconds) {
|
|
88772
|
+
const s = Math.max(0, Math.ceil(seconds));
|
|
88773
|
+
return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, '0')}`;
|
|
88774
|
+
}
|
|
88754
88775
|
function boxStyle(isDark) {
|
|
88755
88776
|
return {
|
|
88756
88777
|
border: `1px solid ${BRAND_BLUE$1}`,
|
|
@@ -88824,6 +88845,10 @@
|
|
|
88824
88845
|
const [error, setError] = React.useState(null);
|
|
88825
88846
|
const [resendIn, setResendIn] = React.useState(0);
|
|
88826
88847
|
const [cancelled, setCancelled] = React.useState(false);
|
|
88848
|
+
// EV-4939: a lockout's end from the server, and the allowed calling codes.
|
|
88849
|
+
const [lockUntil, setLockUntil] = React.useState(null);
|
|
88850
|
+
const [lockIn, setLockIn] = React.useState(0);
|
|
88851
|
+
const [callingCodes, setCallingCodes] = React.useState(null);
|
|
88827
88852
|
const resumedRef = React.useRef(false);
|
|
88828
88853
|
const pendingKey = React.useRef(Symbol('verify-card'));
|
|
88829
88854
|
// A card the conversation already moved past (a later visitor turn exists,
|
|
@@ -88871,6 +88896,31 @@
|
|
|
88871
88896
|
clearInterval(id);
|
|
88872
88897
|
};
|
|
88873
88898
|
}, [mode, step, ctx, t]);
|
|
88899
|
+
React.useEffect(() => {
|
|
88900
|
+
if (mode !== 'sms' || !ctx?.config) return undefined;
|
|
88901
|
+
let gone = false;
|
|
88902
|
+
ctx.config().then(res => {
|
|
88903
|
+
const codes = res?.body?.sms_calling_codes;
|
|
88904
|
+
if (!gone && Array.isArray(codes)) setCallingCodes(codes.map(String));
|
|
88905
|
+
}).catch(() => undefined);
|
|
88906
|
+
return () => {
|
|
88907
|
+
gone = true;
|
|
88908
|
+
};
|
|
88909
|
+
}, [mode, ctx]);
|
|
88910
|
+
React.useEffect(() => {
|
|
88911
|
+
if (!lockUntil) return undefined;
|
|
88912
|
+
const tick = () => {
|
|
88913
|
+
const left = (lockUntil - Date.now()) / 1000;
|
|
88914
|
+
if (left <= 0) {
|
|
88915
|
+
setLockUntil(null);
|
|
88916
|
+
setLockIn(0);
|
|
88917
|
+
setError(null);
|
|
88918
|
+
} else setLockIn(left);
|
|
88919
|
+
};
|
|
88920
|
+
tick();
|
|
88921
|
+
const id = setInterval(tick, 1000);
|
|
88922
|
+
return () => clearInterval(id);
|
|
88923
|
+
}, [lockUntil]);
|
|
88874
88924
|
React.useEffect(() => {
|
|
88875
88925
|
if (resendIn <= 0) return undefined;
|
|
88876
88926
|
const id = setTimeout(() => setResendIn(s => s - 1), 1000);
|
|
@@ -88908,12 +88958,20 @@
|
|
|
88908
88958
|
});
|
|
88909
88959
|
if (res.ok) {
|
|
88910
88960
|
setMasked(res.body?.masked || address.trim());
|
|
88961
|
+
setLockUntil(null);
|
|
88962
|
+
// EV-4941: if the card goes back to the number step (lockout, expiry,
|
|
88963
|
+
// a new number), the field reads "+91 90749 76138", not "+919074976138".
|
|
88964
|
+
if (res.body?.formatted) setAddress(String(res.body.formatted));
|
|
88911
88965
|
setResendIn(Number(res.body?.resend_after_s) || 60);
|
|
88912
88966
|
setCode('');
|
|
88913
88967
|
setStep('code');
|
|
88914
88968
|
} else {
|
|
88915
88969
|
setError(res.body?.error || t('verifyGenericError'));
|
|
88916
88970
|
if (res.body?.resendAfterS) setResendIn(Number(res.body.resendAfterS));
|
|
88971
|
+
if (res.body?.code === 'locked' && res.body?.lockedUntil) {
|
|
88972
|
+
setLockUntil(Date.parse(res.body.lockedUntil));
|
|
88973
|
+
setResendIn(0);
|
|
88974
|
+
}
|
|
88917
88975
|
}
|
|
88918
88976
|
} catch {
|
|
88919
88977
|
setError(t('verifyGenericError'));
|
|
@@ -88955,6 +89013,11 @@
|
|
|
88955
89013
|
} else {
|
|
88956
89014
|
setError(res.body?.error || t('verifyGenericError'));
|
|
88957
89015
|
if (res.body?.code === 'expired' || res.body?.code === 'locked') setStep('address');
|
|
89016
|
+
// EV-4939: a lockout holds Send for its whole length, as a countdown.
|
|
89017
|
+
if (res.body?.code === 'locked' && res.body?.lockedUntil) {
|
|
89018
|
+
setLockUntil(Date.parse(res.body.lockedUntil));
|
|
89019
|
+
setResendIn(0);
|
|
89020
|
+
}
|
|
88958
89021
|
}
|
|
88959
89022
|
} catch {
|
|
88960
89023
|
setError(t('verifyGenericError'));
|
|
@@ -88972,11 +89035,21 @@
|
|
|
88972
89035
|
fontWeight: 600
|
|
88973
89036
|
},
|
|
88974
89037
|
children: ["\u2713 ", fill(t('verifyDone'), {
|
|
88975
|
-
target: masked
|
|
89038
|
+
target: noBreak(masked)
|
|
88976
89039
|
})]
|
|
88977
89040
|
})
|
|
88978
89041
|
});
|
|
88979
89042
|
}
|
|
89043
|
+
const countryBlocked = mode === 'sms' && blockedByCountry(address, callingCodes);
|
|
89044
|
+
const errorLine = text => text ? /*#__PURE__*/jsxRuntimeExports.jsx("div", {
|
|
89045
|
+
role: "alert",
|
|
89046
|
+
style: {
|
|
89047
|
+
color: '#b42318',
|
|
89048
|
+
fontSize: 13
|
|
89049
|
+
},
|
|
89050
|
+
children: text
|
|
89051
|
+
}) : null;
|
|
89052
|
+
const sendDisabled = busy || !address.trim() || resendIn > 0 || lockIn > 0 || countryBlocked;
|
|
88980
89053
|
return /*#__PURE__*/jsxRuntimeExports.jsxs("div", {
|
|
88981
89054
|
style: boxStyle(isDark),
|
|
88982
89055
|
"data-testid": "verify-card",
|
|
@@ -89006,28 +89079,30 @@
|
|
|
89006
89079
|
value: address,
|
|
89007
89080
|
onChange: e => setAddress(e.target.value),
|
|
89008
89081
|
onKeyDown: e => {
|
|
89009
|
-
if (e.key === 'Enter') send();
|
|
89082
|
+
if (e.key === 'Enter' && !sendDisabled) send();
|
|
89010
89083
|
}
|
|
89011
89084
|
})]
|
|
89012
|
-
}), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
|
|
89085
|
+
}), errorLine(countryBlocked ? t('verifyCountryNotAllowed') : error), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
|
|
89013
89086
|
type: "button",
|
|
89014
|
-
style: buttonStyle(
|
|
89015
|
-
disabled:
|
|
89087
|
+
style: buttonStyle(sendDisabled),
|
|
89088
|
+
disabled: sendDisabled,
|
|
89016
89089
|
onClick: send,
|
|
89017
|
-
children: busy ? t('verifySending') :
|
|
89090
|
+
children: busy ? t('verifySending') : lockIn > 0 ? fill(t('verifyLockedFor'), {
|
|
89091
|
+
time: clock(lockIn)
|
|
89092
|
+
}) : resendIn > 0 ? fill(t('verifyResendIn'), {
|
|
89018
89093
|
seconds: resendIn
|
|
89019
89094
|
}) : t('verifySendCode')
|
|
89020
89095
|
})]
|
|
89021
89096
|
}) : /*#__PURE__*/jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, {
|
|
89022
89097
|
children: [/*#__PURE__*/jsxRuntimeExports.jsx("span", {
|
|
89023
89098
|
children: fill(t('verifyEnterCode'), {
|
|
89024
|
-
target: masked
|
|
89099
|
+
target: noBreak(masked)
|
|
89025
89100
|
})
|
|
89026
89101
|
}), /*#__PURE__*/jsxRuntimeExports.jsx("input", {
|
|
89102
|
+
// EV-4941: the widget's own font; spacing keeps the digits apart.
|
|
89027
89103
|
style: {
|
|
89028
89104
|
...inputStyle(isDark),
|
|
89029
89105
|
letterSpacing: '0.3em',
|
|
89030
|
-
fontFamily: 'monospace',
|
|
89031
89106
|
fontSize: 18
|
|
89032
89107
|
},
|
|
89033
89108
|
"aria-label": t('verifyCodeLabel'),
|
|
@@ -89039,7 +89114,7 @@
|
|
|
89039
89114
|
onKeyDown: e => {
|
|
89040
89115
|
if (e.key === 'Enter') confirm();
|
|
89041
89116
|
}
|
|
89042
|
-
}), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
|
|
89117
|
+
}), errorLine(error), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
|
|
89043
89118
|
type: "button",
|
|
89044
89119
|
style: buttonStyle(busy || code.length !== 6),
|
|
89045
89120
|
disabled: busy || code.length !== 6,
|
|
@@ -89065,23 +89140,22 @@
|
|
|
89065
89140
|
onClick: () => {
|
|
89066
89141
|
setStep('address');
|
|
89067
89142
|
setError(null);
|
|
89143
|
+
// EV-4939: the wait was for the old address; a new one starts fresh.
|
|
89144
|
+
setResendIn(0);
|
|
89068
89145
|
},
|
|
89069
|
-
children: t('verifyDifferent')
|
|
89146
|
+
children: mode === 'sms' ? t('verifyDifferentNumber') : t('verifyDifferent')
|
|
89070
89147
|
})]
|
|
89071
|
-
}), error && /*#__PURE__*/jsxRuntimeExports.jsx("div", {
|
|
89072
|
-
role: "alert",
|
|
89073
|
-
style: {
|
|
89074
|
-
color: '#b42318',
|
|
89075
|
-
fontSize: 12
|
|
89076
|
-
},
|
|
89077
|
-
children: error
|
|
89078
89148
|
}), /*#__PURE__*/jsxRuntimeExports.jsx("button", {
|
|
89079
89149
|
type: "button",
|
|
89080
89150
|
style: {
|
|
89081
89151
|
...linkStyle,
|
|
89082
89152
|
color: isDark ? '#9ca3af' : '#6b7280'
|
|
89083
89153
|
},
|
|
89084
|
-
onClick: () =>
|
|
89154
|
+
onClick: () => {
|
|
89155
|
+
// EV-4942: tell the server, so the agent sees the cancel.
|
|
89156
|
+
if (ctx.cancel) Promise.resolve(ctx.cancel()).catch(() => undefined);
|
|
89157
|
+
setCancelled(true);
|
|
89158
|
+
},
|
|
89085
89159
|
disabled: busy,
|
|
89086
89160
|
children: t('verifyCancel')
|
|
89087
89161
|
})]
|