@subiz/widget-v4 4.1.121 → 4.1.123

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.
Files changed (53) hide show
  1. package/assets/less/avatar.less +0 -29
  2. package/assets/less/chatbox.less +7 -10
  3. package/assets/less/form.less +26 -9
  4. package/assets/less/message.less +14 -7
  5. package/assets/less/message_input.less +2 -3
  6. package/assets/less/widget.less +5 -11
  7. package/assets/less/widget_header.less +22 -18
  8. package/compiled_src/chatbox/AgentsAvatar.js +2 -2
  9. package/compiled_src/chatbox/Event.js +15 -11
  10. package/compiled_src/chatbox/Events.js +5 -2
  11. package/compiled_src/chatbox/Header.js +2 -7
  12. package/compiled_src/chatbox/TextMessage.js +6 -2
  13. package/compiled_src/chatbox/Widget.js +54 -43
  14. package/compiled_src/lib.js +0 -5
  15. package/compiled_src/store/api.js +5 -1
  16. package/compiled_src/store/store.js +2 -3
  17. package/compiled_src/util/common.js +2 -2
  18. package/dist/1964db39388.278.js +1 -0
  19. package/dist/1964db39388.app.js +1 -0
  20. package/dist/{19642b47dfe.index.html → 1964db39388.index.html} +1 -1
  21. package/dist/{19642b47dfe.library.html → 1964db39388.library.html} +1 -1
  22. package/dist/1964db39388.library.js +1 -0
  23. package/dist/{19642b47dfe.preview.html → 1964db39388.preview.html} +1 -1
  24. package/dist/1964db39388.preview.js +1 -0
  25. package/dist/1964db39388.webview.js +1 -0
  26. package/dist/278.js +1 -1
  27. package/dist/HASH +1 -1
  28. package/dist/screenshoot.js +102 -86
  29. package/package.json +2 -2
  30. package/src/chatbox/AgentsAvatar.js +3 -2
  31. package/src/chatbox/Event.js +5 -3
  32. package/src/chatbox/Events.js +5 -2
  33. package/src/chatbox/Header.js +2 -3
  34. package/src/chatbox/TextMessage.js +6 -2
  35. package/src/chatbox/Widget.js +53 -45
  36. package/src/lib.js +2 -0
  37. package/src/store/api.js +5 -1
  38. package/src/store/store.js +5 -4
  39. package/src/util/common.js +2 -2
  40. package/up +3 -6
  41. package/dist/19642b47dfe.278.js +0 -1
  42. package/dist/19642b47dfe.app.js +0 -1
  43. package/dist/19642b47dfe.library.js +0 -1
  44. package/dist/19642b47dfe.preview.js +0 -1
  45. package/dist/19642b47dfe.webview.js +0 -1
  46. /package/dist/{19642b47dfe.127.js → 1964db39388.127.js} +0 -0
  47. /package/dist/{19642b47dfe.132.js → 1964db39388.132.js} +0 -0
  48. /package/dist/{19642b47dfe.185.js → 1964db39388.185.js} +0 -0
  49. /package/dist/{19642b47dfe.27.js → 1964db39388.27.js} +0 -0
  50. /package/dist/{19642b47dfe.459.js → 1964db39388.459.js} +0 -0
  51. /package/dist/{19642b47dfe.490.js → 1964db39388.490.js} +0 -0
  52. /package/dist/{19642b47dfe.74.js → 1964db39388.74.js} +0 -0
  53. /package/dist/{19642b47dfe.997.js → 1964db39388.997.js} +0 -0
@@ -863,7 +863,7 @@ function Conn(apiUrl, credential, onDead, onEvents, callAPI, accid) {
863
863
  // the polling loop starts after the first subscribe call finished successfully
864
864
  var polling = function (backoff) {
865
865
  if (dead) return
866
- callAPI('get', apiUrl + 'poll?token=' + lastToken + '&account-id=' + accid, undefined, function (body, code) {
866
+ callAPI('get', apiUrl + 'poll?version=2&token=' + lastToken + '&account-id=' + accid, undefined, function (body, code) {
867
867
  if (dead) return
868
868
  if (retryable(code)) return setTimeout(polling, calcNextBackoff(backoff), backoff + 1)
869
869
  if (code !== 200) {
@@ -899,7 +899,7 @@ function Conn(apiUrl, credential, onDead, onEvents, callAPI, accid) {
899
899
  else if (credential.user_mask) query += '&user-mask=' + encodeURIComponent(credential.user_mask)
900
900
  else if (access_token) query += '&access-token=' + access_token
901
901
 
902
- let fullurl = apiUrl + 'subs' + query + '&account-id=' + encodeURIComponent(accid || credential.account_id)
902
+ let fullurl = apiUrl + 'subs' + query + '&version=2&account-id=' + encodeURIComponent(accid || credential.account_id)
903
903
  callAPI('post', fullurl, JSON.stringify({events: events}), function (body, code) {
904
904
  if (dead) {
905
905
  out = repeat('dead', events.length)
@@ -3064,7 +3064,7 @@ function replaceCssVariablePlugin(css, setting) {
3064
3064
  green: 238
3065
3065
  };
3066
3066
  let hue = rgbToHsl(parseColor.red, parseColor.green, parseColor.blue)[0];
3067
- let [r, g, b] = hslToRgb(hue, 0.5, 0.95);
3067
+ let [r, g, b] = hslToRgb(hue, 0.25, 0.95);
3068
3068
  DEFVAL.primary_color_faded = `rgb(${r},${g},${b})`;
3069
3069
  var ret = [];
3070
3070
  for (var i = 0; i < tokens.length; i++) {
@@ -3115,7 +3115,7 @@ function replaceCssVariable(css, setting) {
3115
3115
  green: 238
3116
3116
  };
3117
3117
  let hue = rgbToHsl(parseColor.red, parseColor.green, parseColor.blue)[0];
3118
- let [r, g, b] = hslToRgb(hue, 0.5, 0.95);
3118
+ let [r, g, b] = hslToRgb(hue, 0.25, 0.95);
3119
3119
  DEFVAL.primary_color_faded = `rgb(${r},${g},${b})`;
3120
3120
  var ret = [];
3121
3121
  for (var i = 0; i < tokens.length; i++) {
@@ -4161,7 +4161,11 @@ function jsonifyTextPlain(param, done) {
4161
4161
  let outuser;
4162
4162
  for (let i = 0; true; i++) {
4163
4163
  outuser = await ajax.setBaseUrl(this.ApiURL).withCredentials(true).addQuery('v', '6').addQuery('x-user-ref', this.ref).setParser('json').get(`/accounts/${this.accid}/users/${this.ref}`);
4164
- if (outuser.error && util/* default */.A.get(outuser, 'body.error.code', '').indexOf('locked_account') != -1) break;
4164
+ if (util/* default */.A.get(outuser, 'body.error.code', '').indexOf('locked_account') != -1) break;
4165
+ if (util/* default */.A.get(outuser, 'body.error.code', '').indexOf('user_is_banned') != -1) {
4166
+ await util/* default */.A.sleep(120000);
4167
+ continue;
4168
+ }
4165
4169
  if (!util/* default */.A.get(outuser, 'body.id')) {
4166
4170
  let sleeptime = Math.min(2000 + i * 400, 60000);
4167
4171
  await util/* default */.A.sleep(sleeptime);
@@ -5190,7 +5194,7 @@ class Store {
5190
5194
  }, 1000);
5191
5195
  }
5192
5196
  async reconnectWs(accid, userid) {
5193
- await this.realtime.subscribe([`conversation_state_updated.account.${accid}.user.${userid}`, `conversation_joined.account.${accid}.user.${userid}`, `conversation_typing.account.${accid}.user.${userid}`, `message_sent.account.${accid}.user.${userid}`, `conversation_pending.account.${accid}.user.${userid}`, `user_info_updated.account.${accid}.user.${userid}`, `message_pong.account.${accid}.user.${userid}`, `conversation_rating_requested.account.${accid}.user.${userid}`, `conversation_rated.account.${accid}.user.${userid}`]);
5197
+ await this.realtime.subscribe([`conversation_state_updated.account.${accid}.user.${userid}`, `conversation_joined.account.${accid}.user.${userid}`, `conversation_typing.account.${accid}.user.${userid}`, `message_sent.account.${accid}.user.${userid}`, `message_pong.account.${accid}.user.${userid}`, `conversation_rating_requested.account.${accid}.user.${userid}`, `conversation_rated.account.${accid}.user.${userid}`]);
5194
5198
  await this.readyGate.entry();
5195
5199
  this.disconnect('account');
5196
5200
  return this.reconnect();
@@ -5327,9 +5331,10 @@ class Store {
5327
5331
  if (!ev || !ev.type) return;
5328
5332
  ev.created = util/* default */.A.getMs(ev.created);
5329
5333
  if (ev.type === 'user_info_updated') {
5330
- let user = util/* default */.A.cloneDeep(this.cache.match('user'));
5331
- let attrs = util/* default */.A.get(ev, 'data.user.attributes') || [];
5332
- util/* default */.A.map(attrs, attr => util/* default */.A.setUserAttr(user, attr));
5334
+ return;
5335
+ let user = sb.cloneDeep(this.cache.match('user'));
5336
+ let attrs = sb.get(ev, 'data.user.attributes') || [];
5337
+ sb.map(attrs, attr => sb.setUserAttr(user, attr));
5333
5338
  this._setUser(user);
5334
5339
  return;
5335
5340
  }
@@ -5351,8 +5356,6 @@ class Store {
5351
5356
  }
5352
5357
  }
5353
5358
  if (!convo) return;
5354
- let channel = util/* default */.A.get(ev, 'touchpoint.channel', '');
5355
- if (channel && channel != 'subiz') return;
5356
5359
  this.pubsub.publish('events', ev);
5357
5360
  if (ev.type === 'conversation_joined') {
5358
5361
  let members = util/* default */.A.get(ev, 'data.conversation.members', []);
@@ -6334,7 +6337,7 @@ function AgentsAvatar(props) {
6334
6337
  }
6335
6338
  let agentM = props.store.matchAgent('*');
6336
6339
  var agents = util/* default */.A.map(props.agent_ids, id => agentM[id]);
6337
- if (props.agent_ids === undefined || util/* default */.A.size(props.agent_ids) === 0) {
6340
+ if (props.agent_ids !== undefined && util/* default */.A.size(props.agent_ids) == 0) {
6338
6341
  var agids = util/* default */.A.get(accountSetting, 'header.agent_ids', []);
6339
6342
  agids = util/* default */.A.filter(agids, id => !!agentM[id]);
6340
6343
  if (agids.length !== 0) {
@@ -6344,7 +6347,7 @@ function AgentsAvatar(props) {
6344
6347
  }
6345
6348
  }
6346
6349
  agents = util/* default */.A.filter(agents, ag => !!ag);
6347
- if (agents.length === 0 || props.agent_ids === undefined || util/* default */.A.size(props.agent_ids) === 0) {
6350
+ if (util/* default */.A.size(agents) === 0) {
6348
6351
  return (0,preact_module.h)("div", {
6349
6352
  class: `group-avatar group-avatar--${mode}`
6350
6353
  }, (0,preact_module.h)("div", {
@@ -6486,12 +6489,6 @@ class Header extends common/* Com */.Mw {
6486
6489
  class: cls,
6487
6490
  style: style
6488
6491
  }, $back, (0,preact_module.h)("div", {
6489
- class: "mr-2"
6490
- }), (0,preact_module.h)(AgentsAvatar, {
6491
- plugin: this.props.plugin,
6492
- store: this.props.store,
6493
- mode: "secondary"
6494
- }), (0,preact_module.h)("div", {
6495
6492
  class: "widget-header--title-container"
6496
6493
  }, (0,preact_module.h)("div", {
6497
6494
  class: "widget-header--title"
@@ -6583,7 +6580,8 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
6583
6580
  }, (0,preact_module.h)(AgentsAvatar, {
6584
6581
  plugin: this.props.plugin,
6585
6582
  store: this.props.store,
6586
- mode: "primary"
6583
+ mode: "primary",
6584
+ agent_ids: []
6587
6585
  })), (0,preact_module.h)("div", {
6588
6586
  class: "widget-header--title-container"
6589
6587
  }, (0,preact_module.h)("div", {
@@ -8021,10 +8019,11 @@ var chatbox_time = __webpack_require__(1620);
8021
8019
 
8022
8020
  class TextMessage extends common/* Com */.Mw {
8023
8021
  renderTime() {
8022
+ return null;
8024
8023
  if (!this.props.showTime && !this.props.isLast && !this.props.isFirst) return null;
8025
- return (0,preact_module.h)("div", null, (0,preact_module.h)(chatbox_time/* default */.A, {
8024
+ return h("div", null, h(Time, {
8026
8025
  class: "inline-time",
8027
- time: util/* default */.A.get(this.props.ev, 'created', util/* default */.A.Date.now()),
8026
+ time: sb.get(this.props.ev, 'created', sb.Date.now()),
8028
8027
  t: this.props.t
8029
8028
  }));
8030
8029
  }
@@ -8070,8 +8069,10 @@ class TextMessage extends common/* Com */.Mw {
8070
8069
  class: "message-agent message-text--agent",
8071
8070
  title: t
8072
8071
  }, tags, this.renderTime());
8072
+ let msgcls = 'message-user message-text--user';
8073
+ if (this.props.ev._error) msgcls += ' message-user--error';
8073
8074
  return (0,preact_module.h)("div", {
8074
- class: "message-user message-text--user",
8075
+ class: msgcls,
8075
8076
  title: t
8076
8077
  }, tags);
8077
8078
  }
@@ -8089,8 +8090,10 @@ class TextMessage extends common/* Com */.Mw {
8089
8090
  onLink: this.props.onLink
8090
8091
  }), this.renderTime());
8091
8092
  }
8093
+ let msgcls = 'message-user message-text--user';
8094
+ if (this.props.ev._error) msgcls += ' message-user--error';
8092
8095
  return (0,preact_module.h)("div", {
8093
- class: "message-user message-text--user",
8096
+ class: msgcls,
8094
8097
  title: t
8095
8098
  }, (0,preact_module.h)(chatbox_block/* default */.A, {
8096
8099
  block: block,
@@ -8139,6 +8142,9 @@ class InfoMessage extends common/* Com */.Mw {
8139
8142
  }
8140
8143
  }
8141
8144
  ;// ./src/chatbox/Event.js
8145
+ function Event_defineProperty(e, r, t) { return (r = Event_toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
8146
+ function Event_toPropertyKey(t) { var i = Event_toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; }
8147
+ function Event_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
8142
8148
 
8143
8149
 
8144
8150
 
@@ -8160,6 +8166,13 @@ const LoadOrderAttachments = () => __webpack_require__.e(/* import() */ 127).the
8160
8166
  class Event extends common/* Com */.Mw {
8161
8167
  constructor(props) {
8162
8168
  super(props);
8169
+ Event_defineProperty(this, "resendMessage", () => {
8170
+ let cid = util/* default */.A.convoOfEv(this.props.event.ev);
8171
+ const message = util/* default */.A.get(this.props.event, 'ev.data.message');
8172
+ this.props.store.sendConvoEvent(cid, 'message_sent', {
8173
+ message
8174
+ });
8175
+ });
8163
8176
  this.props.store.onConvoEvent(this, ev => this.onEvent(ev));
8164
8177
  this.refForm = (0,preact_module/* createRef */._3)();
8165
8178
  this.state = {
@@ -8447,21 +8460,22 @@ class Event extends common/* Com */.Mw {
8447
8460
  }
8448
8461
  let $sender = null;
8449
8462
  if (this.props.event.mode === 'lead') $sender = (0,preact_module.h)("div", {
8450
- class: "pt-2"
8463
+ class: "pt-3"
8451
8464
  });
8452
8465
  let $error = null;
8466
+ if (ev._error) $dot = null;
8453
8467
  if (ev._error && ev.type === 'message_sent') {
8454
8468
  let msg = this.props.t('error_send_message');
8455
8469
  if (ev._error_message) msg = this.props.t(ev._error_message);
8456
8470
  $error = (0,preact_module.h)("a", {
8457
8471
  class: "message_error",
8458
8472
  src: "javascript:;",
8459
- onClick: e => this.resendMessage()
8473
+ onClick: this.resendMessage
8460
8474
  }, (0,preact_module.h)("div", {
8461
- class: "message_error__text"
8462
- }, msg), (0,preact_module.h)("div", {
8463
8475
  class: "message_error__icon"
8464
- }));
8476
+ }), "\xA0", (0,preact_module.h)("div", {
8477
+ class: "message_error__text"
8478
+ }, msg));
8465
8479
  }
8466
8480
  return (0,preact_module.h)("div", {
8467
8481
  class: "convo-event user-message"
@@ -8612,13 +8626,6 @@ class Event extends common/* Com */.Mw {
8612
8626
  state
8613
8627
  }));
8614
8628
  }
8615
- resendMessage() {
8616
- let cid = util/* default */.A.convoOfEv(this.props.event.ev);
8617
- const message = util/* default */.A.get(this.props.event, 'ev.data.message');
8618
- this.props.store.sendConvoEvent(cid, 'message_sent', {
8619
- message
8620
- });
8621
- }
8622
8629
  getSenderName(ev) {
8623
8630
  let bytype = util/* default */.A.get(ev, 'by.type');
8624
8631
  let byid = util/* default */.A.get(ev, 'by.display_id', util/* default */.A.get(ev, 'by.id'));
@@ -8930,7 +8937,7 @@ function processEvents(convo, events) {
8930
8937
  }
8931
8938
  if (visibleEvent(curEvent.ev)) {
8932
8939
  let elapsedSec = util/* default */.A.unixSec(curEvent.ev.created) - util/* default */.A.unixSec(lastEvent.ev.created);
8933
- if (elapsedSec > 120) curEvent.show_time = true;
8940
+ if (elapsedSec > 300) curEvent.show_time = true;
8934
8941
  }
8935
8942
  }
8936
8943
  if (lastAgentEvent) lastAgentEvent.show_time = true;
@@ -8955,7 +8962,10 @@ function processEvents(convo, events) {
8955
8962
  }
8956
8963
  function visibleEvent(ev) {
8957
8964
  let type = util/* default */.A.get(ev, 'type');
8958
- return type === 'message_sent' || type === 'conversation_state_updated';
8965
+ if (type === 'message_sent') return true;
8966
+ if (type === 'conversation_state_updated') {
8967
+ return util/* default */.A.get(ev, 'data.conversation.state') == 'ended';
8968
+ }
8959
8969
  }
8960
8970
  function Events_isSummited(form) {
8961
8971
  let fields = util/* default */.A.get(form, 'fields') || [];
@@ -9466,26 +9476,25 @@ class Widget extends common/* Com */.Mw {
9466
9476
  class: cls
9467
9477
  }, $header, $body);
9468
9478
  }
9469
- async submitPrechatForm(form, formName) {
9470
- if (this.state.submiting) return;
9471
- var hasError = false;
9472
- util/* default */.A.map(this.state.formData, (field, key) => {
9479
+ validateForm(formData) {
9480
+ let newformdata = {};
9481
+ util/* default */.A.map(formData, (field, key) => {
9482
+ field = Object.assign({}, field);
9483
+ field.is_empty_error = false;
9473
9484
  if (field.is_required && (field.value === undefined || field.value === '' || util/* default */.A.size(field.value) === 0 && Array.isArray(field.value))) {
9485
+ field.is_empty_error = true;
9474
9486
  field.error = this.props.t('error_empty');
9475
- hasError = true;
9476
9487
  } else field.error = '';
9477
9488
  if (key.substr(5) === 'emails') {
9478
9489
  if (field.is_required) {
9479
9490
  if (!util/* default */.A.isEmail(field.value)) {
9480
9491
  field.error = this.props.t('error_email_invalid');
9481
- hasError = true;
9482
9492
  }
9483
9493
  } else {
9484
9494
  let value = field.value || '';
9485
9495
  if (typeof value !== 'string') value = value + '';
9486
9496
  if (value.trim() && !util/* default */.A.isEmail(field.value)) {
9487
9497
  field.error = this.props.t('error_email_invalid');
9488
- hasError = true;
9489
9498
  }
9490
9499
  }
9491
9500
  }
@@ -9493,19 +9502,30 @@ class Widget extends common/* Com */.Mw {
9493
9502
  if (field.is_required) {
9494
9503
  if (!util/* default */.A.isPhone(field.value)) {
9495
9504
  field.error = this.props.t('error_phone_invalid');
9496
- hasError = true;
9497
9505
  }
9498
9506
  } else {
9499
9507
  let value = field.value || '';
9500
9508
  if (typeof value !== 'string') value = value + '';
9501
9509
  if (value.trim() && !util/* default */.A.isPhone(field.value)) {
9502
9510
  field.error = this.props.t('error_phone_invalid');
9503
- hasError = true;
9504
9511
  }
9505
9512
  }
9506
9513
  }
9514
+ newformdata[key] = field;
9507
9515
  });
9508
- if (hasError) return this.forceUpdate();
9516
+ return newformdata;
9517
+ }
9518
+ async submitPrechatForm(form, formName) {
9519
+ if (this.state.submiting) return;
9520
+ let newData = this.validateForm(this.state.formData);
9521
+ let hasError = util/* default */.A.find(newData, field => !!field.error);
9522
+ if (hasError) {
9523
+ this.setState({
9524
+ formData: newData
9525
+ });
9526
+ this.focusInput();
9527
+ return;
9528
+ }
9509
9529
  let data = util/* default */.A.cloneDeep(this.state.formData);
9510
9530
  let user = util/* default */.A.cloneDeep(this.props.store.matchUser());
9511
9531
  let is_lead = false;
@@ -9629,6 +9649,7 @@ class Widget extends common/* Com */.Mw {
9629
9649
  let field = util/* default */.A.find(formData, (_, fkkey) => fkkey === key);
9630
9650
  if (!field) return;
9631
9651
  field.value = val;
9652
+ field.error = undefined;
9632
9653
  this.setState({
9633
9654
  formData
9634
9655
  });
@@ -9755,7 +9776,7 @@ class Widget extends common/* Com */.Mw {
9755
9776
  if (field.type === 'text') {
9756
9777
  if (key == 'question' || util/* default */.A.get(field, 'def.multiple_line')) {
9757
9778
  $field = (0,preact_module.h)("textarea", {
9758
- class: "form-control",
9779
+ class: `form-control ${errclass}`,
9759
9780
  ref: ref => {
9760
9781
  this['form_' + Widget_encode(key)] = ref;
9761
9782
  },
@@ -9763,8 +9784,7 @@ class Widget extends common/* Com */.Mw {
9763
9784
  value: field.value || '',
9764
9785
  onInput: e => this.onInputChange(key, e.target.value),
9765
9786
  onChange: e => this.onInputChange(key, e.target.value),
9766
- row: "4",
9767
- class: "form-control"
9787
+ row: "4"
9768
9788
  });
9769
9789
  } else if (util/* default */.A.get(field, 'def.select') === 'checkbox') {
9770
9790
  $field = this.renderCheckboxField(field);
@@ -9865,10 +9885,10 @@ class Widget extends common/* Com */.Mw {
9865
9885
  class: "label",
9866
9886
  for: 'form_' + Widget_encode(key)
9867
9887
  }, label, field.is_required ? (0,preact_module.h)("span", {
9868
- class: "ml-1 red"
9869
- }, "*") : ''), field.error ? (0,preact_module.h)("div", {
9888
+ class: "red"
9889
+ }, "*") : ''), $field, field.error ? (0,preact_module.h)("div", {
9870
9890
  class: "form-control--valid-input--error"
9871
- }, field.error) : '', $field);
9891
+ }, field.error) : '');
9872
9892
  });
9873
9893
  return (0,preact_module.h)("div", {
9874
9894
  class: "pt-2"
@@ -9878,6 +9898,10 @@ class Widget extends common/* Com */.Mw {
9878
9898
  let title = this.props.t.i18n(util/* default */.A.get(form, `i18n_title`, {}));
9879
9899
  if (!title) title = util/* default */.A.get(form, 'title', this.props.t('capture_lead_title'));
9880
9900
  title = title.replace('↵', '');
9901
+ let btncls = 'btn--start-convo ';
9902
+ let hasError = util/* default */.A.find(this.state.formData, field => !!field.error);
9903
+ let newData = this.validateForm(this.state.formData);
9904
+ let hasEmptyError = util/* default */.A.find(newData, field => !!field.is_empty_error);
9881
9905
  return (0,preact_module.h)("div", {
9882
9906
  class: "widget-body"
9883
9907
  }, (0,preact_module.h)(FormMounter, {
@@ -9885,22 +9909,15 @@ class Widget extends common/* Com */.Mw {
9885
9909
  form: form,
9886
9910
  onMount: this.formMounted
9887
9911
  }), (0,preact_module.h)("div", {
9888
- class: "widget-body--content flex-grow-1 pl-3 pr-3 d-flex flex-column"
9889
- }, (0,preact_module.h)("div", {
9890
- class: "flex-grow-1"
9912
+ class: "widget-body--content flex-grow-1 pl-3 pr-3 pb-2 d-flex flex-column"
9891
9913
  }, (0,preact_module.h)("div", {
9892
- class: "form mt-3 pl-3 pr-3 pt-3 pb-3 d-flex flex-column"
9893
- }, (0,preact_module.h)("div", null, title), this.renderFields(form, formName))), (0,preact_module.h)("div", {
9894
- class: "mt-2"
9895
- }), (0,preact_module.h)(PoweredBy, {
9896
- store: this.props.store,
9897
- t: this.props.t
9898
- })), (0,preact_module.h)("div", {
9899
- class: "message-input message-input--preform"
9900
- }, (0,preact_module.h)("button", {
9901
- class: "btn--start-convo",
9914
+ class: "mt-2 d-flex flex-column"
9915
+ }, (0,preact_module.h)("div", null, title), this.renderFields(form, formName)), (0,preact_module.h)("div", {
9916
+ style: "min-height: 15px !important; flex: 1 !important; flex-shrink: 0 !important"
9917
+ }), (0,preact_module.h)("button", {
9918
+ class: btncls,
9902
9919
  onClick: _ => this.submitPrechatForm(form, formName),
9903
- disabled: this.state.creating
9920
+ disabled: !!hasEmptyError || !!hasError || this.state.creating
9904
9921
  }, submitLabel)));
9905
9922
  }
9906
9923
  goToConvo(cid) {
@@ -9927,10 +9944,10 @@ class Widget extends common/* Com */.Mw {
9927
9944
  }, (0,preact_module.h)(AgentsAvatar, {
9928
9945
  plugin: this.props.plugin,
9929
9946
  store: this.props.store,
9930
- mode: "member",
9947
+ mode: "secondary",
9931
9948
  class: "d-flex flex-row",
9932
9949
  tooltipPos: "right",
9933
- agent_ids: agentids
9950
+ agent_ids: [agentids[0]]
9934
9951
  }), this.renderConvoSummary(convo));
9935
9952
  });
9936
9953
  let $body = (0,preact_module.h)("div", {
@@ -9956,7 +9973,9 @@ class Widget extends common/* Com */.Mw {
9956
9973
  class: "convo-list--title"
9957
9974
  }, this.props.t('conversations')), $body), (0,preact_module.h)("div", {
9958
9975
  class: "convo-list--footer"
9959
- }, (0,preact_module.h)("button", {
9976
+ }, (0,preact_module.h)(PoweredBy, {
9977
+ store: this.props.store
9978
+ }), (0,preact_module.h)("button", {
9960
9979
  class: "btn--start-convo",
9961
9980
  onClick: _ => this.goToConvo('')
9962
9981
  }, (0,preact_module.h)("span", null, this.props.t('start_conversation')), (0,preact_module.h)("img", {
@@ -9966,8 +9985,6 @@ class Widget extends common/* Com */.Mw {
9966
9985
  height: "26"
9967
9986
  })), (0,preact_module.h)("div", {
9968
9987
  class: "mt-2"
9969
- }), (0,preact_module.h)(PoweredBy, {
9970
- store: this.props.store
9971
9988
  })));
9972
9989
  }
9973
9990
  blur() {
@@ -9980,17 +9997,21 @@ class Widget extends common/* Com */.Mw {
9980
9997
  focusInput(text) {
9981
9998
  if (this.props.store.isPreview) return;
9982
9999
  if (this.shouldShowForm()) {
9983
- let firstemptykey = '';
10000
+ let focusfieldkey = '';
9984
10001
  util/* default */.A.map(this.state.formData, (field, key) => {
9985
- if (field.type !== 'text') return;
9986
- if (firstemptykey) return;
9987
- if (!field.value) firstemptykey = key;
10002
+ if (focusfieldkey || field.type !== 'text') return;
10003
+ if (!field.value || field.error) focusfieldkey = key;
9988
10004
  });
10005
+ var $input = this['form_' + Widget_encode(focusfieldkey)];
10006
+ if ($input) $input.focus();
9989
10007
  util/* default */.A.setTimeout(() => {
9990
- var $input = this['form_' + Widget_encode(firstemptykey)];
9991
- if (!$input) return;
9992
- $input.focus();
9993
- }, 300);
10008
+ util/* default */.A.map(this.state.formData, (field, key) => {
10009
+ if (focusfieldkey || field.type !== 'text') return;
10010
+ if (!field.value || field.error) focusfieldkey = key;
10011
+ });
10012
+ var $input = this['form_' + Widget_encode(focusfieldkey)];
10013
+ if ($input) $input.focus();
10014
+ }, 200);
9994
10015
  return;
9995
10016
  }
9996
10017
  var $input = this.msgInput.current;
@@ -10822,11 +10843,6 @@ function lib_toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e
10822
10843
 
10823
10844
 
10824
10845
 
10825
- var $link = document.createElement('link');
10826
- $link.href = 'https://fonts.googleapis.com/css2?family=Inter:wght@400;500&display=swap';
10827
- $link.rel = 'stylesheet';
10828
- document.head.append($link);
10829
- util/* default */.A.preloadWebfonts(['Inter'], [400, 500]);
10830
10846
  class lib_Widget {
10831
10847
  constructor(ApiURL, FileURL, RealtimeURL, inmem, fake) {
10832
10848
  lib_defineProperty(this, "version", () => '4.5');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subiz/widget-v4",
3
- "version": "4.1.121",
3
+ "version": "4.1.123",
4
4
  "main": "./compiled_src/lib.js",
5
5
  "scripts": {
6
6
  "dev": "npx webpack serve --config webpack.dev.js",
@@ -31,7 +31,7 @@
31
31
  "babel-plugin-syntax-jsx": "^6.18.0",
32
32
  "html-webpack-plugin": "^5.6.3",
33
33
  "puppeteer": "^24.6.1",
34
- "webpack": "^5.99.5",
34
+ "webpack": "^5.99.6",
35
35
  "webpack-bundle-analyzer": "^4.10.2",
36
36
  "webpack-cli": "^6.0.1",
37
37
  "webpack-dev-server": "^5.2.1"
@@ -27,7 +27,8 @@ export default function AgentsAvatar(props) {
27
27
 
28
28
  let agentM = props.store.matchAgent('*')
29
29
  var agents = sb.map(props.agent_ids, (id) => agentM[id])
30
- if (props.agent_ids === undefined || sb.size(props.agent_ids) === 0) {
30
+
31
+ if (props.agent_ids !== undefined && sb.size(props.agent_ids) == 0) {
31
32
  var agids = sb.get(accountSetting, 'header.agent_ids', [])
32
33
  agids = sb.filter(agids, (id) => !!agentM[id])
33
34
  if (agids.length !== 0) {
@@ -38,7 +39,7 @@ export default function AgentsAvatar(props) {
38
39
  }
39
40
 
40
41
  agents = sb.filter(agents, (ag) => !!ag)
41
- if (agents.length === 0 || props.agent_ids === undefined || sb.size(props.agent_ids) === 0) {
42
+ if (sb.size(agents) === 0) {
42
43
  // use account avatar
43
44
  return (
44
45
  <div class={`group-avatar group-avatar--${mode}`}>
@@ -302,13 +302,15 @@ export default class Event extends Com {
302
302
  if (this.props.event.mode === 'lead') $sender = <div class='pt-3'></div>
303
303
 
304
304
  let $error = null
305
+ if (ev._error) $dot = null
305
306
  if (ev._error && ev.type === 'message_sent') {
306
307
  let msg = this.props.t('error_send_message')
307
308
  if (ev._error_message) msg = this.props.t(ev._error_message)
308
309
  $error = (
309
- <a class='message_error' src='javascript:;' onClick={(e) => this.resendMessage()}>
310
- <div class='message_error__text'>{msg}</div>
310
+ <a class='message_error' src='javascript:;' onClick={this.resendMessage}>
311
311
  <div class='message_error__icon' />
312
+ &nbsp;
313
+ <div class='message_error__text'>{msg}</div>
312
314
  </a>
313
315
  )
314
316
  }
@@ -436,7 +438,7 @@ export default class Event extends Com {
436
438
  return <div class='message-system'>{this.props.t('conversation_state_updated', {state})}</div>
437
439
  }
438
440
 
439
- resendMessage() {
441
+ resendMessage = () => {
440
442
  let cid = sb.convoOfEv(this.props.event.ev)
441
443
  const message = sb.get(this.props.event, 'ev.data.message')
442
444
  this.props.store.sendConvoEvent(cid, 'message_sent', {message})
@@ -306,7 +306,7 @@ function processEvents(convo, events) {
306
306
 
307
307
  if (visibleEvent(curEvent.ev)) {
308
308
  let elapsedSec = sb.unixSec(curEvent.ev.created) - sb.unixSec(lastEvent.ev.created)
309
- if (elapsedSec > 120) curEvent.show_time = true // 2 mins
309
+ if (elapsedSec > 300) curEvent.show_time = true // 5 mins
310
310
  }
311
311
  }
312
312
 
@@ -340,7 +340,10 @@ function processEvents(convo, events) {
340
340
 
341
341
  function visibleEvent(ev) {
342
342
  let type = sb.get(ev, 'type')
343
- return type === 'message_sent' || type === 'conversation_state_updated'
343
+ if (type === 'message_sent') return true
344
+ if (type === 'conversation_state_updated') {
345
+ return sb.get(ev, 'data.conversation.state') == 'ended'
346
+ }
344
347
  }
345
348
 
346
349
  function isSummited(form) {
@@ -28,6 +28,7 @@ export default class Header extends Com {
28
28
  renderSocial = layout === 'social'
29
29
  renderTeam = !(renderSocial || renderClassic)
30
30
  }
31
+
31
32
  return (
32
33
  <div class={cls}>
33
34
  {this.renderCollapsedHeader(renderCollapsed || renderClassic, renderClassic)}
@@ -54,8 +55,6 @@ export default class Header extends Com {
54
55
  return (
55
56
  <div class={cls} style={style}>
56
57
  {$back}
57
- <div class="mr-2"></div>
58
- <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode='secondary' />
59
58
  <div class='widget-header--title-container'>
60
59
  <div class='widget-header--title'>{this.getTitle()}</div>
61
60
  <div class='widget-header--description' title={desc}>
@@ -149,7 +148,7 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
149
148
  </div>
150
149
  <div class='widget_header__body'>
151
150
  <div class='widget-header--avatar-wrapper'>
152
- <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode='primary' />
151
+ <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode='primary' agent_ids={[]} />
153
152
  </div>
154
153
  <div class='widget-header--title-container'>
155
154
  <div class='widget-header--description'>{tags}</div>
@@ -63,8 +63,10 @@ export default class TextMessage extends Com {
63
63
  {this.renderTime()}
64
64
  </div>
65
65
  )
66
+ let msgcls = 'message-user message-text--user'
67
+ if (this.props.ev._error) msgcls += ' message-user--error'
66
68
  return (
67
- <div class='message-user message-text--user' title={t}>
69
+ <div class={msgcls} title={t}>
68
70
  {tags}
69
71
  </div>
70
72
  )
@@ -83,8 +85,10 @@ export default class TextMessage extends Com {
83
85
  </div>
84
86
  )
85
87
  }
88
+ let msgcls = 'message-user message-text--user'
89
+ if (this.props.ev._error) msgcls += ' message-user--error'
86
90
  return (
87
- <div class='message-user message-text--user' title={t}>
91
+ <div class={msgcls} title={t}>
88
92
  <Block block={block} onLink={this.props.onLink} />
89
93
  </div>
90
94
  )