@subiz/widget-v4 4.1.215 → 4.1.216
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 +6 -0
- package/api.md +9 -5
- package/assets/img/bubble_default.svg +1 -0
- package/assets/less/widget.less +12 -0
- package/compiled_src/chatbox/ChatButton.js +19 -17
- package/compiled_src/store/store.js +4 -1
- package/dist/{1a12a5ed6a9.278.js → 1a12ecfb6db.278.js} +1 -1
- package/dist/1a12ecfb6db.app.js +1 -0
- package/dist/{1a12a5ed6a9.chat.html → 1a12ecfb6db.chat.html} +1 -1
- package/dist/1a12ecfb6db.chat.js +1 -0
- package/dist/{1a12a5ed6a9.form.html → 1a12ecfb6db.form.html} +1 -1
- package/dist/{1a12a5ed6a9.form.js → 1a12ecfb6db.form.js} +1 -1
- package/dist/{1a12a5ed6a9.index.html → 1a12ecfb6db.index.html} +1 -1
- package/dist/{1a12a5ed6a9.library.html → 1a12ecfb6db.library.html} +1 -1
- package/dist/1a12ecfb6db.library.js +1 -0
- package/dist/{1a12a5ed6a9.preview.html → 1a12ecfb6db.preview.html} +1 -1
- package/dist/1a12ecfb6db.preview.js +1 -0
- package/dist/1a12ecfb6db.webview.js +1 -0
- package/dist/HASH +1 -0
- package/dist/assets/img/{bubble_default.7d5e4ab.svg → bubble_default.6f6eec8.svg} +1 -0
- package/dist/screenshoot.js +25 -20
- package/package.json +1 -1
- package/src/chatbox/ChatButton.js +22 -20
- package/src/store/store.js +3 -2
- package/up +18 -0
- package/dist/.HASH +0 -1
- package/dist/1a12a5ed6a9.app.js +0 -1
- package/dist/1a12a5ed6a9.chat.js +0 -1
- package/dist/1a12a5ed6a9.library.js +0 -1
- package/dist/1a12a5ed6a9.preview.js +0 -1
- package/dist/1a12a5ed6a9.webview.js +0 -1
- /package/dist/{1a12a5ed6a9.127.js → 1a12ecfb6db.127.js} +0 -0
- /package/dist/{1a12a5ed6a9.132.js → 1a12ecfb6db.132.js} +0 -0
- /package/dist/{1a12a5ed6a9.185.js → 1a12ecfb6db.185.js} +0 -0
- /package/dist/{1a12a5ed6a9.27.js → 1a12ecfb6db.27.js} +0 -0
- /package/dist/{1a12a5ed6a9.339.js → 1a12ecfb6db.339.js} +0 -0
- /package/dist/{1a12a5ed6a9.459.js → 1a12ecfb6db.459.js} +0 -0
- /package/dist/{1a12a5ed6a9.490.js → 1a12ecfb6db.490.js} +0 -0
package/package.json
CHANGED
|
@@ -391,6 +391,7 @@ export default class ChatButton extends Com {
|
|
|
391
391
|
|
|
392
392
|
let imgurl = sb.get(accountSetting, 'desktop_button.background_image_url')
|
|
393
393
|
let maskurl = sb.get(accountSetting, 'desktop_button.background_mask_url')
|
|
394
|
+
// Keep configured dimensions even when the image fails; default only missing dimensions to 70px.
|
|
394
395
|
let imgwidth = sb.get(accountSetting, 'desktop_button.width') || 70
|
|
395
396
|
let imgheight = sb.get(accountSetting, 'desktop_button.height') || 70
|
|
396
397
|
|
|
@@ -450,18 +451,10 @@ export default class ChatButton extends Com {
|
|
|
450
451
|
appearance.maskAsset ? prepareButtonMask(appearance.maskAsset) : Promise.resolve(null),
|
|
451
452
|
])
|
|
452
453
|
const stale = () => !this._isMounted || this._buttonImageVersion !== version
|
|
453
|
-
if (stale())
|
|
454
|
-
if (mask) URL.revokeObjectURL(mask)
|
|
455
|
-
return
|
|
456
|
-
}
|
|
454
|
+
if (stale()) return
|
|
457
455
|
const fallback = loaded.some((success) => !success) || (!!appearance.maskAsset && !mask)
|
|
458
456
|
const ready = !fallback || (await preloadButtonImage(defaultBubble))
|
|
459
|
-
if (stale())
|
|
460
|
-
if (mask) URL.revokeObjectURL(mask)
|
|
461
|
-
return
|
|
462
|
-
}
|
|
463
|
-
if (this._buttonMaskUrl) URL.revokeObjectURL(this._buttonMaskUrl)
|
|
464
|
-
this._buttonMaskUrl = mask
|
|
457
|
+
if (stale()) return
|
|
465
458
|
// Commit the hidden style before revealing even when images are cached.
|
|
466
459
|
// Otherwise older browsers can paint only the final state and skip the transition.
|
|
467
460
|
if (this._buttonElement) window.getComputedStyle(this._buttonElement).transform
|
|
@@ -470,7 +463,6 @@ export default class ChatButton extends Com {
|
|
|
470
463
|
}
|
|
471
464
|
|
|
472
465
|
componentWillUnmount() {
|
|
473
|
-
if (this._buttonMaskUrl) URL.revokeObjectURL(this._buttonMaskUrl)
|
|
474
466
|
if (this._animateTimeout) clearTimeout(this._animateTimeout)
|
|
475
467
|
}
|
|
476
468
|
|
|
@@ -478,12 +470,13 @@ export default class ChatButton extends Com {
|
|
|
478
470
|
if (typeof sbz_info != 'undefined') sbz_info.render_chatbox_button = sb.Date.now()
|
|
479
471
|
const appearance = this.getButtonAppearance()
|
|
480
472
|
let {imgsrc, imgurl, maskurl, background, position, imgwidth, imgheight} = appearance
|
|
473
|
+
const fallback = this.state.readyImageKey === appearance.key && this.state.fallbackButtonImage
|
|
481
474
|
// Never attach a remote CSS mask while the local copy is being prepared.
|
|
482
475
|
if (appearance.maskAsset) {
|
|
483
476
|
maskurl = this.state.readyImageKey === appearance.key ? this.state.buttonMaskUrl : ''
|
|
484
477
|
if (imgsrc === appearance.maskAsset) imgsrc = maskurl || ''
|
|
485
478
|
}
|
|
486
|
-
if (
|
|
479
|
+
if (fallback) {
|
|
487
480
|
imgsrc = imgurl = defaultBubble
|
|
488
481
|
maskurl = ''
|
|
489
482
|
}
|
|
@@ -548,7 +541,12 @@ export default class ChatButton extends Com {
|
|
|
548
541
|
`
|
|
549
542
|
}
|
|
550
543
|
|
|
544
|
+
if (fallback) {
|
|
545
|
+
imgcontainerstyle += `width: ${imgwidth}px !important; height: ${imgheight}px !important;`
|
|
546
|
+
}
|
|
547
|
+
|
|
551
548
|
let cls = 'chat-button chat-button--' + position
|
|
549
|
+
if (fallback) cls += ' chat-button--fallback'
|
|
552
550
|
// dont render till all image is loaded
|
|
553
551
|
|
|
554
552
|
let whiteBgStyle = `
|
|
@@ -679,18 +677,22 @@ function preloadButtonImage(src, {crossOrigin = false} = {}) {
|
|
|
679
677
|
})
|
|
680
678
|
}
|
|
681
679
|
|
|
682
|
-
//
|
|
683
|
-
//
|
|
680
|
+
// Pin the mask bytes with a data URL: some sites allow data: images but block blob:.
|
|
681
|
+
// If inline images or fetch are blocked, preload the original URL with CORS for CSS masks.
|
|
684
682
|
async function prepareButtonMask(src) {
|
|
685
|
-
let url
|
|
686
683
|
try {
|
|
687
684
|
const response = await fetch(src)
|
|
688
685
|
if (!response.ok) return null
|
|
689
|
-
|
|
690
|
-
|
|
686
|
+
const blob = await response.blob()
|
|
687
|
+
const url = await new Promise((resolve) => {
|
|
688
|
+
const reader = new FileReader()
|
|
689
|
+
reader.onload = () => resolve(reader.result)
|
|
690
|
+
reader.onerror = reader.onabort = () => resolve('')
|
|
691
|
+
reader.readAsDataURL(blob)
|
|
692
|
+
})
|
|
693
|
+
if (url && await preloadButtonImage(url)) return url
|
|
691
694
|
} catch (_) {
|
|
692
|
-
//
|
|
695
|
+
// A blocked fetch or failed conversion does not mean the original image is unavailable.
|
|
693
696
|
}
|
|
694
|
-
|
|
695
|
-
return null
|
|
697
|
+
return await preloadButtonImage(src, {crossOrigin: true}) ? src : null
|
|
696
698
|
}
|
package/src/store/store.js
CHANGED
|
@@ -959,9 +959,10 @@ export default class Store {
|
|
|
959
959
|
await this.readyGate.entry()
|
|
960
960
|
const key = websiteFormStorageKey(this.api, formid)
|
|
961
961
|
const kv = this.kv
|
|
962
|
+
const values = sb.cloneDeep(payload.values)
|
|
962
963
|
const result = formResult(await this.api.submitWebsiteForm(formid, payload))
|
|
963
964
|
try {
|
|
964
|
-
kv.put(key, {conversation_id: result.conversation_id, expires_at: sb.Date.now() + 7 * 24 * 60 * 60 * 1000})
|
|
965
|
+
kv.put(key, {conversation_id: result.conversation_id, values, expires_at: sb.Date.now() + 7 * 24 * 60 * 60 * 1000})
|
|
965
966
|
} catch (_) { /* Storage failure must not make callers retry a successful submission. */ }
|
|
966
967
|
return result
|
|
967
968
|
}
|
|
@@ -979,7 +980,7 @@ export default class Store {
|
|
|
979
980
|
this.kv.del(key)
|
|
980
981
|
return {submitted: false, status: 'expired'}
|
|
981
982
|
}
|
|
982
|
-
return {submitted: true, status: 'found', conversation_id: receipt.conversation_id}
|
|
983
|
+
return {submitted: true, status: 'found', conversation_id: receipt.conversation_id, values: Array.isArray(receipt.values) ? sb.cloneDeep(receipt.values) : []}
|
|
983
984
|
} catch (_) {
|
|
984
985
|
return {submitted: false, status: 'storage_unavailable'}
|
|
985
986
|
}
|
package/up
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
#!/bin/sh
|
|
2
2
|
set -e # exit when any command fails
|
|
3
3
|
|
|
4
|
+
# The storage client still references ssl.PROTOCOL_TLSv1; the local Python 3.14
|
|
5
|
+
# uses OpenSSL 4, which removed the underlying legacy API.
|
|
6
|
+
# Respect an explicit interpreter; otherwise prefer a compatible installed Python.
|
|
7
|
+
if [ -z "${CLOUDSDK_PYTHON:-}" ]; then
|
|
8
|
+
for python in python3.13 python3.12 python3.11 python3.10; do
|
|
9
|
+
if command -v "$python" >/dev/null 2>&1; then
|
|
10
|
+
CLOUDSDK_PYTHON=$(command -v "$python")
|
|
11
|
+
export CLOUDSDK_PYTHON
|
|
12
|
+
break
|
|
13
|
+
fi
|
|
14
|
+
done
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Fail before rebuilding if gcloud cannot load the upload command.
|
|
18
|
+
gcloud storage cp --help >/dev/null
|
|
19
|
+
|
|
4
20
|
# safety first
|
|
5
21
|
echo "Clean"
|
|
6
22
|
#rm -rf node_modules && rm -rf package-lock.json && npm i --no-optional
|
|
@@ -17,8 +33,10 @@ echo "Build OK. New version hash: $(cat dist/HASH)"
|
|
|
17
33
|
# DEPLOY TO WIDGET SERVER
|
|
18
34
|
# (do not deploy dist/HASH)
|
|
19
35
|
mv dist/HASH dist/.HASH
|
|
36
|
+
trap 'if [ -f dist/.HASH ]; then mv dist/.HASH dist/HASH; fi' 0
|
|
20
37
|
gcloud storage cp -r --cache-control="public, max-age=31536000" --gzip-local="html,js,css,svg,jpg,png" dist/* gs://public-gcs.subiz-cdn.com/widget-v4/public/
|
|
21
38
|
mv dist/.HASH dist/HASH
|
|
39
|
+
trap - 0
|
|
22
40
|
|
|
23
41
|
if [ "$1" = 'prod' ]; then
|
|
24
42
|
gcloud storage cp --cache-control="public, max-age=10" --content-type="text/plain" dist/HASH gs://public-gcs.subiz-cdn.com/widget-v4/public/
|
package/dist/.HASH
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
1a12a5ed6a9
|