@subiz/widget-v4 4.1.201 → 4.1.203
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/api.md +1284 -0
- package/compiled_src/bot.js +1 -7
- package/compiled_src/chatbox/ChatButton.js +19 -16
- package/compiled_src/chatbox/MessageInput.js +1 -0
- package/compiled_src/chatbox/Widget.js +1 -0
- package/compiled_src/chatbox/main.js +28 -3
- package/compiled_src/lib.js +16 -1
- package/compiled_src/store/api.js +36 -4
- package/compiled_src/store/store.js +14 -1
- package/compiled_src/util/common.js +18 -18
- package/dist/{19d6b530a9c.app.js → 19df158c2ea.app.js} +1 -1
- package/dist/{19d6b530a9c.chat.html → 19df158c2ea.chat.html} +1 -1
- package/dist/{19d6b530a9c.chat.js → 19df158c2ea.chat.js} +1 -1
- package/dist/{19d6b530a9c.form.html → 19df158c2ea.form.html} +1 -1
- package/dist/19df158c2ea.form.js +1 -0
- package/dist/{19d6b530a9c.index.html → 19df158c2ea.index.html} +1 -1
- package/dist/{19d6b530a9c.library.html → 19df158c2ea.library.html} +1 -1
- package/dist/{19d6b530a9c.library.js → 19df158c2ea.library.js} +1 -1
- package/dist/{19d6b530a9c.preview.html → 19df158c2ea.preview.html} +1 -1
- package/dist/{19d6b530a9c.preview.js → 19df158c2ea.preview.js} +1 -1
- package/dist/{19d6b530a9c.webview.js → 19df158c2ea.webview.js} +1 -1
- package/dist/HASH +1 -1
- package/dist/screenshoot.js +88 -39
- package/package.json +8 -8
- package/src/bot.js +1 -7
- package/src/chatbox/ChatButton.js +20 -15
- package/src/chatbox/MessageInput.js +1 -0
- package/src/chatbox/Widget.js +1 -1
- package/src/chatbox/main.js +24 -4
- package/src/lib.js +16 -1
- package/src/store/api.js +41 -3
- package/src/store/store.js +17 -2
- package/src/util/common.js +22 -21
- package/dist/19d6b530a9c.form.js +0 -1
- package/examples/track.js +0 -41
- /package/dist/{19d6b530a9c.127.js → 19df158c2ea.127.js} +0 -0
- /package/dist/{19d6b530a9c.132.js → 19df158c2ea.132.js} +0 -0
- /package/dist/{19d6b530a9c.185.js → 19df158c2ea.185.js} +0 -0
- /package/dist/{19d6b530a9c.27.js → 19df158c2ea.27.js} +0 -0
- /package/dist/{19d6b530a9c.278.js → 19df158c2ea.278.js} +0 -0
- /package/dist/{19d6b530a9c.339.js → 19df158c2ea.339.js} +0 -0
- /package/dist/{19d6b530a9c.459.js → 19df158c2ea.459.js} +0 -0
- /package/dist/{19d6b530a9c.490.js → 19df158c2ea.490.js} +0 -0
- /package/dist/{19d6b530a9c.74.js → 19df158c2ea.74.js} +0 -0
- /package/dist/{19d6b530a9c.997.js → 19df158c2ea.997.js} +0 -0
package/dist/HASH
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
19df158c2ea
|
package/dist/screenshoot.js
CHANGED
|
@@ -1971,12 +1971,6 @@ function filter(collection, predicate) {
|
|
|
1971
1971
|
if (!collection) return [];
|
|
1972
1972
|
if (!predicate) return collection;
|
|
1973
1973
|
var out = [];
|
|
1974
|
-
if (Array.isArray(collection)) {
|
|
1975
|
-
for (let i = 0; i < collection.length; i++) {
|
|
1976
|
-
if (predicate(collection[i], i)) out.push(collection[i]);
|
|
1977
|
-
}
|
|
1978
|
-
return out;
|
|
1979
|
-
}
|
|
1980
1974
|
if (typeof collection === 'object') {
|
|
1981
1975
|
var keys = Object.keys(collection);
|
|
1982
1976
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -1985,6 +1979,12 @@ function filter(collection, predicate) {
|
|
|
1985
1979
|
}
|
|
1986
1980
|
return out;
|
|
1987
1981
|
}
|
|
1982
|
+
if (Array.isArray(collection)) {
|
|
1983
|
+
for (let i = 0; i < collection.length; i++) {
|
|
1984
|
+
if (predicate(collection[i], i)) out.push(collection[i]);
|
|
1985
|
+
}
|
|
1986
|
+
return out;
|
|
1987
|
+
}
|
|
1988
1988
|
return out;
|
|
1989
1989
|
}
|
|
1990
1990
|
function includes(collection, value) {
|
|
@@ -1997,12 +1997,6 @@ function map(collection, predicate) {
|
|
|
1997
1997
|
if (!collection) return [];
|
|
1998
1998
|
if (!predicate) predicate = i => i;
|
|
1999
1999
|
var out = [];
|
|
2000
|
-
if (Array.isArray(collection)) {
|
|
2001
|
-
for (let i = 0; i < collection.length; i++) {
|
|
2002
|
-
out.push(predicate(collection[i], i));
|
|
2003
|
-
}
|
|
2004
|
-
return out;
|
|
2005
|
-
}
|
|
2006
2000
|
if (typeof collection === 'object') {
|
|
2007
2001
|
var keys = Object.keys(collection);
|
|
2008
2002
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -2011,6 +2005,12 @@ function map(collection, predicate) {
|
|
|
2011
2005
|
}
|
|
2012
2006
|
return out;
|
|
2013
2007
|
}
|
|
2008
|
+
if (Array.isArray(collection)) {
|
|
2009
|
+
for (let i = 0; i < collection.length; i++) {
|
|
2010
|
+
out.push(predicate(collection[i], i));
|
|
2011
|
+
}
|
|
2012
|
+
return out;
|
|
2013
|
+
}
|
|
2014
2014
|
return out;
|
|
2015
2015
|
}
|
|
2016
2016
|
function each(collection, predicate) {
|
|
@@ -2093,12 +2093,6 @@ function find(collection, f) {
|
|
|
2093
2093
|
function findIndex(collection, f) {
|
|
2094
2094
|
if (!collection) return -1;
|
|
2095
2095
|
if (!f) return -1;
|
|
2096
|
-
if (Array.isArray(collection)) {
|
|
2097
|
-
for (let i = 0; i < collection.length; i++) {
|
|
2098
|
-
if (f(collection[i], i)) return i;
|
|
2099
|
-
}
|
|
2100
|
-
return -1;
|
|
2101
|
-
}
|
|
2102
2096
|
if (typeof collection === 'object') {
|
|
2103
2097
|
var keys = Object.keys(collection);
|
|
2104
2098
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -2106,6 +2100,12 @@ function findIndex(collection, f) {
|
|
|
2106
2100
|
if (f(collection[k], k)) return k;
|
|
2107
2101
|
}
|
|
2108
2102
|
}
|
|
2103
|
+
if (Array.isArray(collection)) {
|
|
2104
|
+
for (let i = 0; i < collection.length; i++) {
|
|
2105
|
+
if (f(collection[i], i)) return i;
|
|
2106
|
+
}
|
|
2107
|
+
return -1;
|
|
2108
|
+
}
|
|
2109
2109
|
return -1;
|
|
2110
2110
|
}
|
|
2111
2111
|
function orderBy(a, k, d) {
|
|
@@ -4389,12 +4389,31 @@ let trackResponseFn = (param, done) => {
|
|
|
4389
4389
|
_defineProperty(this, "time", _ => ajax.setBaseUrl(this.ApiURL).withCredentials(true).setParser('json').get('/time'));
|
|
4390
4390
|
_defineProperty(this, "updateUser", data => this.apireq.post(`/accounts/${this.accid}/users/${this.uid}`, data));
|
|
4391
4391
|
_defineProperty(this, "getUser", _ => this.apireq.get(`/accounts/${this.accid}/users/${this.uid}`));
|
|
4392
|
-
_defineProperty(this, "getAccountSetting", p => {
|
|
4392
|
+
_defineProperty(this, "getAccountSetting", async p => {
|
|
4393
4393
|
let href = util/* default */.A.get(document, 'location.href');
|
|
4394
|
+
let res = {};
|
|
4394
4395
|
if (p && p.bot_id) {
|
|
4395
|
-
|
|
4396
|
-
}
|
|
4397
|
-
|
|
4396
|
+
res = await this.apireq.addQuery('url', href).addQuery('bot_id', p.bot_id).get(`/accounts/${this.accid}/settings`);
|
|
4397
|
+
} else {
|
|
4398
|
+
res = await this.apireq.addQuery('url', href).get(`/accounts/${this.accid}/settings`);
|
|
4399
|
+
}
|
|
4400
|
+
if (res.error) return res;
|
|
4401
|
+
let plugins = util/* default */.A.get(res, 'body.plugins') || [];
|
|
4402
|
+
util/* default */.A.map(plugins, plugin => {
|
|
4403
|
+
if (plugin.type === 'popup') {
|
|
4404
|
+
let pages = util/* default */.A.get(plugin, 'popup.pages') || [];
|
|
4405
|
+
util/* default */.A.map(pages, page => {
|
|
4406
|
+
util/* default */.A.map(page.components, com => {
|
|
4407
|
+
if (com.type === 'image') {
|
|
4408
|
+
let url = util/* default */.A.get(com, 'image.url');
|
|
4409
|
+
util/* default */.A.set(com, 'image.url', fallbackGCSUrl(url));
|
|
4410
|
+
}
|
|
4411
|
+
});
|
|
4412
|
+
});
|
|
4413
|
+
}
|
|
4414
|
+
});
|
|
4415
|
+
util/* default */.A.set(res, 'body.plugins', plugins);
|
|
4416
|
+
return res;
|
|
4398
4417
|
});
|
|
4399
4418
|
_defineProperty(this, "sendImpression", impression => this.apireq.post(`/accounts/${this.accid}/campaigns/${impression.campaign_id}/impressions`, impression));
|
|
4400
4419
|
_defineProperty(this, "sendConversion", conversion => this.apireq.post(`/accounts/${this.accid}/campaigns/${conversion.campaign_id}/conversions`, conversion));
|
|
@@ -4580,6 +4599,19 @@ let trackResponseFn = (param, done) => {
|
|
|
4580
4599
|
});
|
|
4581
4600
|
}
|
|
4582
4601
|
});
|
|
4602
|
+
function fallbackGCSUrl(url) {
|
|
4603
|
+
try {
|
|
4604
|
+
const u = new URL(url);
|
|
4605
|
+
const isGCS = u.hostname === 'storage.googleapis.com';
|
|
4606
|
+
const isSubizBucket = u.pathname.startsWith('/public-gcs.subiz-cdn.com/');
|
|
4607
|
+
if (isGCS && isSubizBucket) {
|
|
4608
|
+
return `https://${u.pathname.slice(1)}`;
|
|
4609
|
+
}
|
|
4610
|
+
return url;
|
|
4611
|
+
} catch (e) {
|
|
4612
|
+
return url;
|
|
4613
|
+
}
|
|
4614
|
+
}
|
|
4583
4615
|
;// ./src/store/lsdb.js
|
|
4584
4616
|
let memlocalStorage = __webpack_require__(450);
|
|
4585
4617
|
|
|
@@ -5900,7 +5932,17 @@ class Store {
|
|
|
5900
5932
|
}
|
|
5901
5933
|
this.readyGate.close();
|
|
5902
5934
|
accid = (accid || '').trim();
|
|
5903
|
-
|
|
5935
|
+
let lightConvos = this.kv.match('light_convos') || {};
|
|
5936
|
+
this.lightConvos = {};
|
|
5937
|
+
util/* default */.A.map(lightConvos, convo => {
|
|
5938
|
+
let in7Day = convo.created > util/* default */.A.Date.now() - 7 * 24 * 3_600_000;
|
|
5939
|
+
let events = util/* default */.A.filter(convo.events, ev => ev.type === 'message_sent');
|
|
5940
|
+
let messages = util/* default */.A.map(events, ev => util/* default */.A.get(ev, 'data.message') || {});
|
|
5941
|
+
messages = util/* default */.A.filter(messages, msg => !util/* default */.A.isEmptyMessage(msg));
|
|
5942
|
+
if (in7Day && util/* default */.A.size(messages)) {
|
|
5943
|
+
this.lightConvos[convo.id] = convo;
|
|
5944
|
+
}
|
|
5945
|
+
});
|
|
5904
5946
|
this.cache = new kv(new lsdb('sbz2023', true), 'kv');
|
|
5905
5947
|
if (this.realtime) this.realtime.stop();
|
|
5906
5948
|
if (this.fake) this.realtime = new realtime_fake();else this.realtime = new Realtime(this.RealtimeURL, realtimep, xhrsend, accid);
|
|
@@ -6124,6 +6166,9 @@ class Store {
|
|
|
6124
6166
|
if (traffic_source) this.kv.put('traffic_source', traffic_source);
|
|
6125
6167
|
return;
|
|
6126
6168
|
}
|
|
6169
|
+
if (typeof e === 'object') {
|
|
6170
|
+
if (!e.data) e.data = {};
|
|
6171
|
+
}
|
|
6127
6172
|
return this.api.sendEvent(e);
|
|
6128
6173
|
}
|
|
6129
6174
|
async onWs(ev) {
|
|
@@ -6840,21 +6885,8 @@ class ChatButton extends common/* Com */.Mw {
|
|
|
6840
6885
|
if (util/* default */.A.get(ev, 'type') !== 'message_sent') return;
|
|
6841
6886
|
let bytype = util/* default */.A.get(ev, 'by.type');
|
|
6842
6887
|
if (bytype !== 'system' && bytype !== 'agent' && bytype !== 'bot') return;
|
|
6843
|
-
let
|
|
6844
|
-
|
|
6845
|
-
if (!att) return;
|
|
6846
|
-
if (att.type === 'quick_replies') {
|
|
6847
|
-
isquickreplies = true;
|
|
6848
|
-
}
|
|
6849
|
-
});
|
|
6850
|
-
let format = util/* default */.A.get(ev, 'data.message.format');
|
|
6851
|
-
let block = util/* default */.A.get(ev, 'data.message.block');
|
|
6852
|
-
if (block || format == 'block') {
|
|
6853
|
-
if (util/* default */.A.isBlockEmpty(block) && isquickreplies) return;
|
|
6854
|
-
} else {
|
|
6855
|
-
let message = util/* default */.A.get(ev, 'data.message.text') || '';
|
|
6856
|
-
if (!message && isquickreplies) return;
|
|
6857
|
-
}
|
|
6888
|
+
let message = util/* default */.A.get(ev, 'data.message') || {};
|
|
6889
|
+
if (util/* default */.A.isEmptyMessage(message)) return;
|
|
6858
6890
|
let screen = util/* default */.A.get(this.props.store.matchLastview(), 'screen');
|
|
6859
6891
|
let minimized = util/* default */.A.get(this.props.store.matchLastview(), 'minimized');
|
|
6860
6892
|
if (screen === 'widget') return;
|
|
@@ -7213,6 +7245,9 @@ class ChatButton extends common/* Com */.Mw {
|
|
|
7213
7245
|
imgurl = this.props.store.replaceFileUrl(imgurl);
|
|
7214
7246
|
imgsrc = this.props.store.replaceFileUrl(imgsrc);
|
|
7215
7247
|
maskurl = this.props.store.replaceFileUrl(maskurl);
|
|
7248
|
+
imgurl = addVersionParam(imgurl);
|
|
7249
|
+
imgsrc = addVersionParam(imgsrc);
|
|
7250
|
+
maskurl = addVersionParam(maskurl);
|
|
7216
7251
|
if (!imgurl && !maskurl) {
|
|
7217
7252
|
whitebgcls += ' chat-button--white-bg--mask-only';
|
|
7218
7253
|
imgcontainerstyle = `
|
|
@@ -7344,6 +7379,19 @@ function randomAgent(agentM) {
|
|
|
7344
7379
|
const Ms30Mins = 30 * 60 * 1000;
|
|
7345
7380
|
const DEF_BG_URL = 'https://vcdn.subiz-cdn.com/file/bubble_11.svg?v=5';
|
|
7346
7381
|
const DEF_BG = 'linear-gradient(280.16deg, #0053d3 22.03%, #0265ff 78.2%)';
|
|
7382
|
+
function addVersionParam(url, version = 8) {
|
|
7383
|
+
if (!url) return url;
|
|
7384
|
+
try {
|
|
7385
|
+
const u = new URL(url);
|
|
7386
|
+
u.searchParams.set('v', version);
|
|
7387
|
+
return u.toString();
|
|
7388
|
+
} catch (e) {
|
|
7389
|
+
const [base, hash] = url.split('#');
|
|
7390
|
+
const hasQuery = base.includes('?');
|
|
7391
|
+
const newUrl = base + (hasQuery ? '&' : '?') + `v=${version}`;
|
|
7392
|
+
return hash ? newUrl + '#' + hash : newUrl;
|
|
7393
|
+
}
|
|
7394
|
+
}
|
|
7347
7395
|
;// ./src/chatbox/PoweredBy.js
|
|
7348
7396
|
var logo = __webpack_require__(9529);
|
|
7349
7397
|
|
|
@@ -11724,6 +11772,7 @@ class Widget extends common/* Com */.Mw {
|
|
|
11724
11772
|
agentids = agentids || util/* default */.A.agentsOfConvo(convo)[0];
|
|
11725
11773
|
return (0,preact_module.h)("div", {
|
|
11726
11774
|
class: "convo-list--item",
|
|
11775
|
+
"data-cid": convo.id,
|
|
11727
11776
|
onClick: () => this.goToConvo(convo.id),
|
|
11728
11777
|
key: convo.id
|
|
11729
11778
|
}, (0,preact_module.h)(AgentsAvatar, {
|
|
@@ -12694,7 +12743,7 @@ class lib_Widget {
|
|
|
12694
12743
|
lib_defineProperty(this, "getUser", () => util/* default */.A.parseJSON(util/* default */.A.stringify(this.store.matchUser())));
|
|
12695
12744
|
lib_defineProperty(this, "setViewingProduct", p => this.store.linkProduct(p));
|
|
12696
12745
|
lib_defineProperty(this, "getViewingProduct", () => this.store.getLinkedProduct());
|
|
12697
|
-
lib_defineProperty(this, "track",
|
|
12746
|
+
lib_defineProperty(this, "track", v => this.store.track(v));
|
|
12698
12747
|
this.impressionTokens = {};
|
|
12699
12748
|
this.domGate = new util/* default */.A.Gate();
|
|
12700
12749
|
this.store = new Store(ApiURL, FileURL, RealtimeURL, inmem, fake);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@subiz/widget-v4",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.203",
|
|
4
4
|
"main": "./compiled_src/lib.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"dev": "npx webpack serve --config webpack.dev.js",
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
"dependencies": {
|
|
12
12
|
"@subiz/ajax": "^3.0.22",
|
|
13
13
|
"@subiz/flow": "^1.1.0",
|
|
14
|
-
"@subiz/wsclient": "^4.0.
|
|
14
|
+
"@subiz/wsclient": "^4.0.35",
|
|
15
15
|
"cookie_js": "1.4.2",
|
|
16
16
|
"core-js": "^3.49.0",
|
|
17
17
|
"css-loader": "5.2.7",
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
"@babel/core": "^7.29.0",
|
|
27
27
|
"@babel/plugin-proposal-class-properties": "^7.18.6",
|
|
28
28
|
"@babel/plugin-transform-react-jsx": "^7.28.6",
|
|
29
|
-
"@babel/preset-env": "^7.29.
|
|
29
|
+
"@babel/preset-env": "^7.29.5",
|
|
30
30
|
"babel-loader": "^10.1.1",
|
|
31
31
|
"babel-plugin-syntax-jsx": "^6.18.0",
|
|
32
|
-
"html-webpack-plugin": "^5.6.
|
|
33
|
-
"puppeteer": "^24.
|
|
34
|
-
"webpack": "^5.
|
|
35
|
-
"webpack-bundle-analyzer": "^5.
|
|
32
|
+
"html-webpack-plugin": "^5.6.7",
|
|
33
|
+
"puppeteer": "^24.43.1",
|
|
34
|
+
"webpack": "^5.106.2",
|
|
35
|
+
"webpack-bundle-analyzer": "^5.3.0",
|
|
36
36
|
"webpack-cli": "^7.0.2",
|
|
37
|
-
"webpack-dev-server": "^5.2.
|
|
37
|
+
"webpack-dev-server": "^5.2.4"
|
|
38
38
|
}
|
|
39
39
|
}
|
package/src/bot.js
CHANGED
|
@@ -14,13 +14,7 @@ export default function (store) {
|
|
|
14
14
|
|
|
15
15
|
let welcomMessages = bot.welcome_messages
|
|
16
16
|
welcomMessages = sb.filter(welcomMessages, (msg) => {
|
|
17
|
-
if (
|
|
18
|
-
if (msg.block || msg.format === 'block') {
|
|
19
|
-
if (sb.isBlockEmpty(msg.block)) return false
|
|
20
|
-
} else {
|
|
21
|
-
if (!(msg.text || '').trim()) return false
|
|
22
|
-
}
|
|
23
|
-
}
|
|
17
|
+
if (sb.isEmptyMessage(msg)) return false
|
|
24
18
|
return true
|
|
25
19
|
})
|
|
26
20
|
if (sb.size(welcomMessages)) {
|
|
@@ -27,21 +27,8 @@ export default class ChatButton extends Com {
|
|
|
27
27
|
let bytype = sb.get(ev, 'by.type')
|
|
28
28
|
if (bytype !== 'system' && bytype !== 'agent' && bytype !== 'bot') return
|
|
29
29
|
|
|
30
|
-
let
|
|
31
|
-
|
|
32
|
-
if (!att) return
|
|
33
|
-
if (att.type === 'quick_replies') {
|
|
34
|
-
isquickreplies = true
|
|
35
|
-
}
|
|
36
|
-
})
|
|
37
|
-
let format = sb.get(ev, 'data.message.format')
|
|
38
|
-
let block = sb.get(ev, 'data.message.block')
|
|
39
|
-
if (block || format == 'block') {
|
|
40
|
-
if (sb.isBlockEmpty(block) && isquickreplies) return
|
|
41
|
-
} else {
|
|
42
|
-
let message = sb.get(ev, 'data.message.text') || ''
|
|
43
|
-
if (!message && isquickreplies) return
|
|
44
|
-
}
|
|
30
|
+
let message = sb.get(ev, 'data.message') || {}
|
|
31
|
+
if (sb.isEmptyMessage(message)) return
|
|
45
32
|
let screen = sb.get(this.props.store.matchLastview(), 'screen')
|
|
46
33
|
let minimized = sb.get(this.props.store.matchLastview(), 'minimized')
|
|
47
34
|
if (screen === 'widget') return
|
|
@@ -453,6 +440,9 @@ export default class ChatButton extends Com {
|
|
|
453
440
|
imgurl = this.props.store.replaceFileUrl(imgurl)
|
|
454
441
|
imgsrc = this.props.store.replaceFileUrl(imgsrc)
|
|
455
442
|
maskurl = this.props.store.replaceFileUrl(maskurl)
|
|
443
|
+
imgurl = addVersionParam(imgurl)
|
|
444
|
+
imgsrc = addVersionParam(imgsrc)
|
|
445
|
+
maskurl = addVersionParam(maskurl)
|
|
456
446
|
|
|
457
447
|
if (!imgurl && !maskurl) {
|
|
458
448
|
whitebgcls += ' chat-button--white-bg--mask-only'
|
|
@@ -595,3 +585,18 @@ const Ms30Mins = 30 * 60 * 1000
|
|
|
595
585
|
// v=5 trick to clear cache
|
|
596
586
|
const DEF_BG_URL = 'https://vcdn.subiz-cdn.com/file/bubble_11.svg?v=5'
|
|
597
587
|
const DEF_BG = 'linear-gradient(280.16deg, #0053d3 22.03%, #0265ff 78.2%)'
|
|
588
|
+
|
|
589
|
+
function addVersionParam(url, version = 8) {
|
|
590
|
+
if (!url) return url
|
|
591
|
+
try {
|
|
592
|
+
const u = new URL(url)
|
|
593
|
+
u.searchParams.set('v', version)
|
|
594
|
+
return u.toString()
|
|
595
|
+
} catch (e) {
|
|
596
|
+
// fallback nếu url không hợp lệ hoàn toàn
|
|
597
|
+
const [base, hash] = url.split('#')
|
|
598
|
+
const hasQuery = base.includes('?')
|
|
599
|
+
const newUrl = base + (hasQuery ? '&' : '?') + `v=${version}`
|
|
600
|
+
return hash ? newUrl + '#' + hash : newUrl
|
|
601
|
+
}
|
|
602
|
+
}
|
|
@@ -25,6 +25,7 @@ export default class MessageInput extends Com {
|
|
|
25
25
|
this.resizeInput = sb.throttle(function () {
|
|
26
26
|
// TODO: ctrl+A then press backspace dont reset size rightaway
|
|
27
27
|
const input = this.refMessageInput.current
|
|
28
|
+
if (!input) return
|
|
28
29
|
input.style.setProperty('height', '1em', 'important')
|
|
29
30
|
const height = Math.min(200, input.scrollHeight)
|
|
30
31
|
input.style.setProperty('height', `${height}px`, 'important')
|
package/src/chatbox/Widget.js
CHANGED
|
@@ -739,7 +739,7 @@ export default class Widget extends Com {
|
|
|
739
739
|
agentids = agentids || sb.agentsOfConvo(convo)[0]
|
|
740
740
|
|
|
741
741
|
return (
|
|
742
|
-
<div class='convo-list--item' onClick={() => this.goToConvo(convo.id)} key={convo.id}>
|
|
742
|
+
<div class='convo-list--item' data-cid={convo.id} onClick={() => this.goToConvo(convo.id)} key={convo.id}>
|
|
743
743
|
<AgentsAvatar
|
|
744
744
|
plugin={this.props.plugin}
|
|
745
745
|
store={this.props.store}
|
package/src/chatbox/main.js
CHANGED
|
@@ -17,6 +17,11 @@ export default class Main extends Com {
|
|
|
17
17
|
this.refWidget = createRef()
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
+
state = {
|
|
21
|
+
cssReady: false,
|
|
22
|
+
changing: false,
|
|
23
|
+
}
|
|
24
|
+
|
|
20
25
|
refreshCSS() {
|
|
21
26
|
// make sure you are still alive
|
|
22
27
|
let plugins = this.props.store.matchPlugin()
|
|
@@ -45,10 +50,6 @@ export default class Main extends Com {
|
|
|
45
50
|
this.$cssStyleDiv.id = 'subiz-style-for-' + this.props.plugin.id
|
|
46
51
|
}
|
|
47
52
|
|
|
48
|
-
this.setState({
|
|
49
|
-
cssReady: false,
|
|
50
|
-
})
|
|
51
|
-
|
|
52
53
|
this.checkExpand()
|
|
53
54
|
this.props.store.onResetCSS(this, () => this.refreshCSS())
|
|
54
55
|
this.props.store.onConvoEvent(this, (ev) => this.onConvoEvent(ev))
|
|
@@ -60,10 +61,29 @@ export default class Main extends Com {
|
|
|
60
61
|
})
|
|
61
62
|
})
|
|
62
63
|
this.refreshCSS()
|
|
64
|
+
|
|
65
|
+
let lastview = this.props.store.matchLastview() || {}
|
|
66
|
+
let cid = sb.get(lastview, 'opts.cid')
|
|
67
|
+
if (cid) {
|
|
68
|
+
this._last_cid = cid
|
|
69
|
+
this.setState({changing: true}, () => {
|
|
70
|
+
this.props.store.fetchConvo(cid).then(() => {
|
|
71
|
+
let convo = this.props.store.matchConvo(cid)
|
|
72
|
+
if (cid != this._last_cid) return // outdated
|
|
73
|
+
this.setState({changing: false})
|
|
74
|
+
if (!convo) return this.showWidget({}) // invalid convo, must redirect
|
|
75
|
+
})
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
|
|
63
79
|
this.setState({cssReady: true})
|
|
64
80
|
}
|
|
65
81
|
|
|
66
82
|
render() {
|
|
83
|
+
if (this.state.changing) {
|
|
84
|
+
if (typeof sbz_info != 'undefined') sbz_info.render_chatbox_changing_ready = sb.Date.now()
|
|
85
|
+
return null
|
|
86
|
+
}
|
|
67
87
|
if (!this.state.cssReady) {
|
|
68
88
|
if (typeof sbz_info != 'undefined') sbz_info.render_chatbox_css_not_ready = sb.Date.now()
|
|
69
89
|
return null
|
package/src/lib.js
CHANGED
|
@@ -316,7 +316,22 @@ class Widget {
|
|
|
316
316
|
setViewingProduct = (p) => this.store.linkProduct(p)
|
|
317
317
|
getViewingProduct = () => this.store.getLinkedProduct()
|
|
318
318
|
|
|
319
|
-
track = () => this.store.track()
|
|
319
|
+
track = (v) => this.store.track(v)
|
|
320
|
+
event = async (v) => {
|
|
321
|
+
await this.store.readyGate.entry()
|
|
322
|
+
return this.store.api.sendEvent(v)
|
|
323
|
+
}
|
|
324
|
+
pageview = (v) => {
|
|
325
|
+
v = v || {}
|
|
326
|
+
return this.event({
|
|
327
|
+
type: 'content_viewed',
|
|
328
|
+
payload: {
|
|
329
|
+
url: v.url || location.href,
|
|
330
|
+
title: v.title || document.title,
|
|
331
|
+
referrer: v.referrer || document.referrer,
|
|
332
|
+
},
|
|
333
|
+
})
|
|
334
|
+
}
|
|
320
335
|
|
|
321
336
|
async setLocale(locale) {
|
|
322
337
|
await this.domGate.entry()
|
package/src/store/api.js
CHANGED
|
@@ -394,12 +394,33 @@ export default class {
|
|
|
394
394
|
updateUser = (data) => this.apireq.post(`/accounts/${this.accid}/users/${this.uid}`, data)
|
|
395
395
|
|
|
396
396
|
getUser = (_) => this.apireq.get(`/accounts/${this.accid}/users/${this.uid}`)
|
|
397
|
-
getAccountSetting = (p) => {
|
|
397
|
+
getAccountSetting = async (p) => {
|
|
398
398
|
let href = sb.get(document, 'location.href') // send full href, this could be used to select which bot (ai-agent) should be returned
|
|
399
|
+
let res = {}
|
|
399
400
|
if (p && p.bot_id) {
|
|
400
|
-
|
|
401
|
+
res = await this.apireq.addQuery('url', href).addQuery('bot_id', p.bot_id).get(`/accounts/${this.accid}/settings`)
|
|
402
|
+
} else {
|
|
403
|
+
res = await this.apireq.addQuery('url', href).get(`/accounts/${this.accid}/settings`)
|
|
401
404
|
}
|
|
402
|
-
|
|
405
|
+
if (res.error) return res
|
|
406
|
+
|
|
407
|
+
// fix image error image url link in popup
|
|
408
|
+
let plugins = sb.get(res, 'body.plugins') || []
|
|
409
|
+
sb.map(plugins, (plugin) => {
|
|
410
|
+
if (plugin.type === 'popup') {
|
|
411
|
+
let pages = sb.get(plugin, 'popup.pages') || []
|
|
412
|
+
sb.map(pages, (page) => {
|
|
413
|
+
sb.map(page.components, (com) => {
|
|
414
|
+
if (com.type === 'image') {
|
|
415
|
+
let url = sb.get(com, 'image.url')
|
|
416
|
+
sb.set(com, 'image.url', fallbackGCSUrl(url))
|
|
417
|
+
}
|
|
418
|
+
})
|
|
419
|
+
})
|
|
420
|
+
}
|
|
421
|
+
})
|
|
422
|
+
sb.set(res, 'body.plugins', plugins)
|
|
423
|
+
return res
|
|
403
424
|
}
|
|
404
425
|
|
|
405
426
|
sendImpression = (impression) =>
|
|
@@ -432,3 +453,20 @@ export default class {
|
|
|
432
453
|
suggest_address = (keyword) => this.apireq.setQuery({keyword: keyword}).get(`/accounts/${this.accid}/addresses`)
|
|
433
454
|
create_ticket = (ticket) => this.apireq.post(`/accounts/${this.accid}/tickets`, ticket)
|
|
434
455
|
}
|
|
456
|
+
|
|
457
|
+
function fallbackGCSUrl(url) {
|
|
458
|
+
try {
|
|
459
|
+
const u = new URL(url)
|
|
460
|
+
|
|
461
|
+
const isGCS = u.hostname === 'storage.googleapis.com'
|
|
462
|
+
const isSubizBucket = u.pathname.startsWith('/public-gcs.subiz-cdn.com/')
|
|
463
|
+
|
|
464
|
+
if (isGCS && isSubizBucket) {
|
|
465
|
+
return `https://${u.pathname.slice(1)}`
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
return url
|
|
469
|
+
} catch (e) {
|
|
470
|
+
return url
|
|
471
|
+
}
|
|
472
|
+
}
|
package/src/store/store.js
CHANGED
|
@@ -403,7 +403,7 @@ export default class Store {
|
|
|
403
403
|
|
|
404
404
|
if (id === '*') {
|
|
405
405
|
this._touchAcc()
|
|
406
|
-
// combind with
|
|
406
|
+
// combind with light convo
|
|
407
407
|
return sb.filter(this.cache.all(), (value, k) => k.startsWith('convo_')).concat(sb.map(this.lightConvos))
|
|
408
408
|
}
|
|
409
409
|
|
|
@@ -633,7 +633,19 @@ export default class Store {
|
|
|
633
633
|
|
|
634
634
|
this.readyGate.close()
|
|
635
635
|
accid = (accid || '').trim()
|
|
636
|
-
|
|
636
|
+
let lightConvos = this.kv.match('light_convos') || {}
|
|
637
|
+
this.lightConvos = {}
|
|
638
|
+
sb.map(lightConvos, (convo) => {
|
|
639
|
+
let in7Day = convo.created > sb.Date.now() - 7 * 24 * 3_600_000
|
|
640
|
+
let events = sb.filter(convo.events, (ev) => ev.type === 'message_sent')
|
|
641
|
+
|
|
642
|
+
let messages = sb.map(events, (ev) => sb.get(ev, 'data.message') || {})
|
|
643
|
+
messages = sb.filter(messages, (msg) => !sb.isEmptyMessage(msg))
|
|
644
|
+
|
|
645
|
+
if (in7Day && sb.size(messages)) {
|
|
646
|
+
this.lightConvos[convo.id] = convo
|
|
647
|
+
}
|
|
648
|
+
})
|
|
637
649
|
this.cache = new KV(new LSDB('sbz2023', true), 'kv')
|
|
638
650
|
if (this.realtime) this.realtime.stop()
|
|
639
651
|
if (this.fake) this.realtime = new RealtimeFake()
|
|
@@ -920,6 +932,9 @@ export default class Store {
|
|
|
920
932
|
return
|
|
921
933
|
}
|
|
922
934
|
|
|
935
|
+
if (typeof e === 'object') {
|
|
936
|
+
if (!e.data) e.data = {}
|
|
937
|
+
}
|
|
923
938
|
return this.api.sendEvent(e)
|
|
924
939
|
}
|
|
925
940
|
|
package/src/util/common.js
CHANGED
|
@@ -329,13 +329,6 @@ export function filter(collection, predicate) {
|
|
|
329
329
|
if (!predicate) return collection
|
|
330
330
|
|
|
331
331
|
var out = []
|
|
332
|
-
if (Array.isArray(collection)) {
|
|
333
|
-
for (let i = 0; i < collection.length; i++) {
|
|
334
|
-
if (predicate(collection[i], i)) out.push(collection[i])
|
|
335
|
-
}
|
|
336
|
-
return out
|
|
337
|
-
}
|
|
338
|
-
|
|
339
332
|
if (typeof collection === 'object') {
|
|
340
333
|
var keys = Object.keys(collection)
|
|
341
334
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -345,6 +338,13 @@ export function filter(collection, predicate) {
|
|
|
345
338
|
return out
|
|
346
339
|
}
|
|
347
340
|
|
|
341
|
+
if (Array.isArray(collection)) {
|
|
342
|
+
for (let i = 0; i < collection.length; i++) {
|
|
343
|
+
if (predicate(collection[i], i)) out.push(collection[i])
|
|
344
|
+
}
|
|
345
|
+
return out
|
|
346
|
+
}
|
|
347
|
+
|
|
348
348
|
return out
|
|
349
349
|
}
|
|
350
350
|
|
|
@@ -361,13 +361,6 @@ export function map(collection, predicate) {
|
|
|
361
361
|
if (!predicate) predicate = (i) => i
|
|
362
362
|
|
|
363
363
|
var out = []
|
|
364
|
-
if (Array.isArray(collection)) {
|
|
365
|
-
for (let i = 0; i < collection.length; i++) {
|
|
366
|
-
out.push(predicate(collection[i], i))
|
|
367
|
-
}
|
|
368
|
-
return out
|
|
369
|
-
}
|
|
370
|
-
|
|
371
364
|
if (typeof collection === 'object') {
|
|
372
365
|
var keys = Object.keys(collection)
|
|
373
366
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -377,6 +370,13 @@ export function map(collection, predicate) {
|
|
|
377
370
|
return out
|
|
378
371
|
}
|
|
379
372
|
|
|
373
|
+
if (Array.isArray(collection)) {
|
|
374
|
+
for (let i = 0; i < collection.length; i++) {
|
|
375
|
+
out.push(predicate(collection[i], i))
|
|
376
|
+
}
|
|
377
|
+
return out
|
|
378
|
+
}
|
|
379
|
+
|
|
380
380
|
return out
|
|
381
381
|
}
|
|
382
382
|
|
|
@@ -483,13 +483,6 @@ function findIndex(collection, f) {
|
|
|
483
483
|
if (!collection) return -1
|
|
484
484
|
if (!f) return -1
|
|
485
485
|
|
|
486
|
-
if (Array.isArray(collection)) {
|
|
487
|
-
for (let i = 0; i < collection.length; i++) {
|
|
488
|
-
if (f(collection[i], i)) return i
|
|
489
|
-
}
|
|
490
|
-
return -1
|
|
491
|
-
}
|
|
492
|
-
|
|
493
486
|
if (typeof collection === 'object') {
|
|
494
487
|
var keys = Object.keys(collection)
|
|
495
488
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -497,6 +490,14 @@ function findIndex(collection, f) {
|
|
|
497
490
|
if (f(collection[k], k)) return k
|
|
498
491
|
}
|
|
499
492
|
}
|
|
493
|
+
|
|
494
|
+
if (Array.isArray(collection)) {
|
|
495
|
+
for (let i = 0; i < collection.length; i++) {
|
|
496
|
+
if (f(collection[i], i)) return i
|
|
497
|
+
}
|
|
498
|
+
return -1
|
|
499
|
+
}
|
|
500
|
+
|
|
500
501
|
return -1
|
|
501
502
|
}
|
|
502
503
|
|