@subiz/widget-v4 4.1.25 → 4.1.27

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.
@@ -201,13 +201,15 @@ class Event extends _common.Com {
201
201
  });
202
202
  let $error = null;
203
203
  if (ev._error && ev.type === 'message_sent') {
204
+ let msg = this.props.t('error_send_message');
205
+ if (ev._error_message) msg = this.props.t(ev._error_message);
204
206
  $error = (0, _preact.h)("a", {
205
207
  class: "message_error",
206
208
  src: "javascript:;",
207
209
  onClick: e => this.resendMessage()
208
210
  }, (0, _preact.h)("div", {
209
211
  class: "message_error__text"
210
- }, this.props.t('error_send_message')), (0, _preact.h)("div", {
212
+ }, msg), (0, _preact.h)("div", {
211
213
  class: "message_error__icon"
212
214
  }));
213
215
  }
@@ -19,21 +19,22 @@ class Header extends _common.Com {
19
19
  let cls = 'widget-header';
20
20
  let renderSocial = false;
21
21
  let renderTeam = false;
22
- let renderCollapsed = this.props.view !== 'list' && headerMode === 'collapsed';
23
22
  let accSetting = this.props.plugin.chatbox || {};
24
23
  let layout = _index.default.get(accSetting, 'header.layout');
25
- if (renderCollapsed) {
24
+ let renderCollapsed = this.props.view !== 'list' && headerMode === 'collapsed';
25
+ let renderClassic = !renderCollapsed && layout === 'classic';
26
+ if (renderCollapsed || layout == 'classic') {
26
27
  cls += ' widget-header--collapsed';
27
28
  } else {
28
29
  cls += ' widget-header--convo-expanded';
29
30
  renderSocial = layout === 'social';
30
- renderTeam = !renderSocial;
31
+ renderTeam = !(renderSocial || renderClassic);
31
32
  }
32
33
  return (0, _preact.h)("div", {
33
34
  class: cls
34
- }, this.renderCollapsedHeader(renderCollapsed), this.renderSocial(renderSocial), this.renderTeam(renderTeam));
35
+ }, this.renderCollapsedHeader(renderCollapsed || renderClassic, renderClassic), this.renderSocial(renderSocial), this.renderTeam(renderTeam));
35
36
  }
36
- renderCollapsedHeader(show) {
37
+ renderCollapsedHeader(show, classic) {
37
38
  let accSetting = this.props.plugin.chatbox || {};
38
39
  let acc = this.props.store.matchAccount() || {};
39
40
  let state = acc.is_online ? this.props.t('agent_online') : this.props.t('agent_offline');
@@ -42,9 +43,13 @@ class Header extends _common.Com {
42
43
  let agentIdsJoined = _index.default.map(this.getAgentJoined(this.props.cid), agent => agent.id);
43
44
  let cls = 'widget-header--inner widget-header--inner--collapsed';
44
45
  if (!show) cls += ' widget-header--inner--hidden';
46
+ let $back = null;
47
+ let style = '';
48
+ if (!classic) $back = this.renderBackButton();else style = 'padding-bottom: 75px !important;';
45
49
  return (0, _preact.h)("div", {
46
- class: cls
47
- }, this.renderBackButton(), (0, _preact.h)(_AgentsAvatar.default, {
50
+ class: cls,
51
+ style: style
52
+ }, $back, (0, _preact.h)(_AgentsAvatar.default, {
48
53
  plugin: this.props.plugin,
49
54
  store: this.props.store,
50
55
  mode: "secondary",
@@ -585,7 +585,7 @@ class Widget extends _common.Com {
585
585
  let convoM = this.props.store.matchConvo('*');
586
586
  var convos = _index.default.map(convoM, convo => this.props.store.matchConvo(convo.id));
587
587
  convos = _index.default.filter(convos, convo => !!convo);
588
- convos = _index.default.orderBy(convos, 'actived', 'desc');
588
+ convos = _index.default.orderByF(convos, convo => _index.default.get(convo, 'last_message_sent.created', convo.actived), 'desc');
589
589
  var $convos = _index.default.map(convos, convo => {
590
590
  let ags = _index.default.filter(convo.members, m => {
591
591
  return (m.type === 'agent' || m.type === 'bot') && m.membership === 'active';
@@ -71,6 +71,7 @@ class _default {
71
71
  type: file.type
72
72
  });
73
73
  if (error) return {
74
+ body: signed,
74
75
  error
75
76
  };
76
77
  let contentType = file.type || 'application/octet-stream';
@@ -88,6 +89,7 @@ class _default {
88
89
  account_id: this.accid
89
90
  }));
90
91
  if (error) return {
92
+ body,
91
93
  error
92
94
  };
93
95
  return {
@@ -748,9 +748,13 @@ class Store {
748
748
  await this.convoGate.entry();
749
749
  await flow.map(files, 1, async att => {
750
750
  const {
751
+ body,
751
752
  url,
752
753
  error
753
754
  } = await this.api.uploadToS3(att._file);
755
+ if (_index.default.get(body, 'code') == 'invalid_field_size') {
756
+ event._error_message = 'cannot_send_too_big_file';
757
+ }
754
758
  event._error = error;
755
759
  att.url = url;
756
760
  });
@@ -38,6 +38,7 @@ exports.noop = noop;
38
38
  exports.norm = norm;
39
39
  exports.offsetToMin = offsetToMin;
40
40
  exports.orderBy = orderBy;
41
+ exports.orderByF = orderByF;
41
42
  exports.parseJSON = parseJSON;
42
43
  exports.preloadImg = preloadImg;
43
44
  exports.preloadWebfonts = preloadWebfonts;
@@ -342,6 +343,18 @@ function orderBy(a, k, d) {
342
343
  });
343
344
  return clone;
344
345
  }
346
+ function orderByF(a, f, d) {
347
+ var clone = [];
348
+ each(a, v => clone.push(v));
349
+ clone.sort((i, j) => {
350
+ let ik = f(i);
351
+ let jk = f(j);
352
+ if (ik === jk) return 0;
353
+ var r = ik < jk ? -1 : 1;
354
+ return d === 'desc' ? -r : r;
355
+ });
356
+ return clone;
357
+ }
345
358
  function isPhone(phone) {
346
359
  var re = /^[\+]?[(]?[0-9]{2,3}[)]?[-\s\.]?[0-9]{3,4}[-\s\.]?[0-9]{4,6}$/im;
347
360
  return re.test(String(phone));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@subiz/widget-v4",
3
- "version": "4.1.25",
3
+ "version": "4.1.27",
4
4
  "main": "./compiled_src/lib.js",
5
5
  "scripts": {
6
6
  "dev": "npx webpack serve --config webpack.dev.js",
@@ -32,8 +32,8 @@
32
32
  "babel-plugin-syntax-jsx": "^6.18.0",
33
33
  "html-webpack-plugin": "^5.5.0",
34
34
  "prettier": "^2.8.4",
35
- "puppeteer": "^19.7.2",
36
- "webpack": "^5.75.0",
35
+ "puppeteer": "^19.7.3",
36
+ "webpack": "^5.76.0",
37
37
  "webpack-bundle-analyzer": "^4.8.0",
38
38
  "webpack-cli": "^5.0.1",
39
39
  "webpack-dev-server": "^4.11.1"
@@ -182,9 +182,11 @@ export default class Event extends Com {
182
182
 
183
183
  let $error = null
184
184
  if (ev._error && ev.type === 'message_sent') {
185
+ let msg = this.props.t('error_send_message')
186
+ if (ev._error_message) msg = this.props.t(ev._error_message)
185
187
  $error = (
186
188
  <a class='message_error' src='javascript:;' onClick={(e) => this.resendMessage()}>
187
- <div class='message_error__text'>{this.props.t('error_send_message')}</div>
189
+ <div class='message_error__text'>{msg}</div>
188
190
  <div class='message_error__icon' />
189
191
  </a>
190
192
  )
@@ -15,30 +15,29 @@ export default class Header extends Com {
15
15
  let cls = 'widget-header'
16
16
  let renderSocial = false
17
17
  let renderTeam = false
18
- let renderCollapsed = this.props.view !== 'list' && headerMode === 'collapsed'
19
-
20
18
  // expaned header
21
19
  let accSetting = this.props.plugin.chatbox || {}
22
20
  let layout = sb.get(accSetting, 'header.layout')
21
+ let renderCollapsed = this.props.view !== 'list' && headerMode === 'collapsed'
22
+ let renderClassic = !renderCollapsed && layout === 'classic'
23
23
 
24
- if (renderCollapsed) {
24
+ if (renderCollapsed || layout == 'classic') {
25
25
  cls += ' widget-header--collapsed'
26
26
  } else {
27
27
  cls += ' widget-header--convo-expanded'
28
28
  renderSocial = layout === 'social'
29
- renderTeam = !renderSocial
29
+ renderTeam = !(renderSocial || renderClassic)
30
30
  }
31
-
32
31
  return (
33
32
  <div class={cls}>
34
- {this.renderCollapsedHeader(renderCollapsed)}
33
+ {this.renderCollapsedHeader(renderCollapsed || renderClassic, renderClassic)}
35
34
  {this.renderSocial(renderSocial)}
36
35
  {this.renderTeam(renderTeam)}
37
36
  </div>
38
37
  )
39
38
  }
40
39
 
41
- renderCollapsedHeader(show) {
40
+ renderCollapsedHeader(show, classic) {
42
41
  let accSetting = this.props.plugin.chatbox || {}
43
42
  let acc = this.props.store.matchAccount() || {}
44
43
  let state = acc.is_online ? this.props.t('agent_online') : this.props.t('agent_offline')
@@ -48,9 +47,13 @@ export default class Header extends Com {
48
47
  let cls = 'widget-header--inner widget-header--inner--collapsed'
49
48
  if (!show) cls += ' widget-header--inner--hidden'
50
49
 
50
+ let $back = null
51
+ let style = ''
52
+ if (!classic) $back = this.renderBackButton()
53
+ else style = 'padding-bottom: 75px !important;'
51
54
  return (
52
- <div class={cls}>
53
- {this.renderBackButton()}
55
+ <div class={cls} style={style}>
56
+ {$back}
54
57
  <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode='secondary' agent_ids={agentIdsJoined} />
55
58
  <div class='widget-header--title-container'>
56
59
  <div class='widget-header--title'>{this.getTitle()}</div>
@@ -586,7 +586,7 @@ export default class Widget extends Com {
586
586
  let convoM = this.props.store.matchConvo('*')
587
587
  var convos = sb.map(convoM, (convo) => this.props.store.matchConvo(convo.id))
588
588
  convos = sb.filter(convos, (convo) => !!convo)
589
- convos = sb.orderBy(convos, 'actived', 'desc')
589
+ convos = sb.orderByF(convos, (convo) => sb.get(convo, 'last_message_sent.created', convo.actived), 'desc')
590
590
 
591
591
  var $convos = sb.map(convos, (convo) => {
592
592
  let ags = sb.filter(convo.members, (m) => {
package/src/store/api.js CHANGED
@@ -252,7 +252,7 @@ export default class {
252
252
  size: file.size,
253
253
  type: file.type,
254
254
  })
255
- if (error) return {error}
255
+ if (error) return {body: signed, error}
256
256
 
257
257
  let contentType = file.type || 'application/octet-stream'
258
258
  ;({error} = await ajax.setContentType(contentType).put(signed.signed_url, file))
@@ -261,7 +261,7 @@ export default class {
261
261
  // finish uploading
262
262
  let body
263
263
  ;({body, error} = await this.apireq.post(`/accounts/${this.accid}/files/${signed.id}`, {account_id: this.accid}))
264
- if (error) return {error}
264
+ if (error) return {body, error}
265
265
 
266
266
  return {url: this.FileURL + body.url}
267
267
  }
@@ -903,7 +903,10 @@ export default class Store {
903
903
  // upload file first
904
904
 
905
905
  await flow.map(files, 1, async (att) => {
906
- const {url, error} = await this.api.uploadToS3(att._file)
906
+ const {body, url, error} = await this.api.uploadToS3(att._file)
907
+ if (sb.get(body, 'code') == 'invalid_field_size') {
908
+ event._error_message = 'cannot_send_too_big_file'
909
+ }
907
910
  event._error = error
908
911
  att.url = url
909
912
  })
@@ -313,6 +313,19 @@ export function orderBy(a, k, d) {
313
313
  return clone
314
314
  }
315
315
 
316
+ export function orderByF(a, f, d) {
317
+ var clone = []
318
+ each(a, (v) => clone.push(v))
319
+ clone.sort((i, j) => {
320
+ let ik = f(i)
321
+ let jk = f(j)
322
+ if (ik === jk) return 0
323
+ var r = ik < jk ? -1 : 1
324
+ return d === 'desc' ? -r : r
325
+ })
326
+ return clone
327
+ }
328
+
316
329
  export function isPhone(phone) {
317
330
  var re = /^[\+]?[(]?[0-9]{2,3}[)]?[-\s\.]?[0-9]{3,4}[-\s\.]?[0-9]{4,6}$/im
318
331
  return re.test(String(phone))