@subiz/widget-v4 4.0.53 → 4.0.58

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 (95) hide show
  1. package/cloudflare_worker.js +1 -1
  2. package/compiled_src/chatbox/Header.js +2 -0
  3. package/compiled_src/lib.js +9 -2
  4. package/compiled_src/notif/notif.js +7 -3
  5. package/compiled_src/store/store.js +7 -5
  6. package/compiled_src/util/campaign.js +7 -2
  7. package/dist/178.js +406 -0
  8. package/dist/17d938a5acb.178.js +1 -0
  9. package/dist/17d938a5acb.213.js +1 -0
  10. package/dist/17d938a5acb.362.js +1 -0
  11. package/dist/17d938a5acb.441.js +1 -0
  12. package/dist/17d938a5acb.605.js +1 -0
  13. package/dist/17d938a5acb.619.js +1 -0
  14. package/dist/17d938a5acb.678.js +1 -0
  15. package/dist/17d938a5acb.74.js +1 -0
  16. package/dist/17d938a5acb.782.js +1 -0
  17. package/dist/17d938a5acb.app.js +1 -0
  18. package/dist/17d938a5acb.index.html +37 -0
  19. package/dist/17d938a5acb.library.html +37 -0
  20. package/dist/17d938a5acb.library.js +1 -0
  21. package/dist/17d938a5acb.preview.html +759 -0
  22. package/dist/17d938a5acb.preview.js +1 -0
  23. package/dist/17d938a5acb.screenshoot.js +1 -0
  24. package/dist/213.js +3223 -0
  25. package/dist/362.js +107 -0
  26. package/dist/441.js +2706 -0
  27. package/dist/605.js +391 -0
  28. package/dist/619.js +777 -0
  29. package/dist/678.js +107 -0
  30. package/dist/74.js +4734 -0
  31. package/dist/782.js +107 -0
  32. package/dist/HASH +1 -1
  33. package/dist/assets/img/Facebook.64607ec.png +0 -0
  34. package/dist/assets/img/Zalo.6845707.png +0 -0
  35. package/dist/assets/img/award1a.1a58e10.png +0 -0
  36. package/dist/assets/img/award3a.3b74423.png +0 -0
  37. package/dist/assets/img/award4a.ed6ccd4.png +0 -0
  38. package/dist/assets/img/award5.39eb7ae.png +0 -0
  39. package/dist/assets/img/bubble_default.7d5e4ab.svg +20 -0
  40. package/dist/assets/img/convos_empty.2353007.svg +72 -0
  41. package/dist/assets/img/default.06e6ee0.jpg +0 -0
  42. package/dist/assets/img/default_avatar.5b74dc1.png +0 -0
  43. package/dist/assets/img/done_gray.d7e8203.svg +4 -0
  44. package/dist/assets/img/emoji/messenger/sub_23.529_58.824.d5faf14.png +0 -0
  45. package/dist/assets/img/emoji/messenger/sub_23.529_60.784.1420241.png +0 -0
  46. package/dist/assets/img/emoji/messenger/sub_25.490_0.000.1e6b2c0.png +0 -0
  47. package/dist/assets/img/emoji/messenger/sub_25.490_45.098.3dfbc08.png +0 -0
  48. package/dist/assets/img/emoji/messenger/sub_25.490_5.882.4b49e94.png +0 -0
  49. package/dist/assets/img/emoji/messenger/sub_27.451_72.549.7114f58.png +0 -0
  50. package/dist/assets/img/emoji/messenger/sub_27.451_84.314.231e2b7.png +0 -0
  51. package/dist/assets/img/emoji/messenger/sub_27.451_96.078.ddbb008.png +0 -0
  52. package/dist/assets/img/emoji/messenger/sub_29.412_5.882.61f3359.png +0 -0
  53. package/dist/assets/img/emoji/messenger/sub_58.824_100.000.6df72bc.png +0 -0
  54. package/dist/assets/img/emoji/messenger/sub_58.824_45.098.3d7a7ad.png +0 -0
  55. package/dist/assets/img/emoji/messenger/sub_58.824_47.059.0f4d6e2.png +0 -0
  56. package/dist/assets/img/emoji/messenger/sub_58.824_54.902.65724c1.png +0 -0
  57. package/dist/assets/img/emoji/messenger/sub_58.824_64.706.9da3cba.png +0 -0
  58. package/dist/assets/img/emoji/messenger/sub_58.824_72.549.edca5cf.png +0 -0
  59. package/dist/assets/img/emoji/messenger/sub_58.824_78.431.f910f2a.png +0 -0
  60. package/dist/assets/img/emoji/messenger/sub_58.824_88.235.def4e71.png +0 -0
  61. package/dist/assets/img/emoji/messenger/sub_60.784_11.765.49c03d0.png +0 -0
  62. package/dist/assets/img/emoji/messenger/sub_60.784_27.451.46b54e5.png +0 -0
  63. package/dist/assets/img/emoji/messenger/sub_60.784_29.412.e36d284.png +0 -0
  64. package/dist/assets/img/emoji/messenger/sub_60.784_3.922.bb191b0.png +0 -0
  65. package/dist/assets/img/emoji/messenger/sub_60.784_35.294.af7b927.png +0 -0
  66. package/dist/assets/img/emoji/messenger/sub_60.784_7.843.98f2a99.png +0 -0
  67. package/dist/assets/img/empty.29bed2d.svg +23 -0
  68. package/dist/assets/img/examplte_logo.f86535f.svg +1 -0
  69. package/dist/assets/img/external-link.90577cc.svg +1 -0
  70. package/dist/assets/img/fb_inverse_circle.36c2cfc.png +0 -0
  71. package/dist/assets/img/image_default.be0698b.png +0 -0
  72. package/dist/assets/img/loading_static.8f403ae.svg +10 -0
  73. package/dist/assets/img/main-service1.d536cc2.png +0 -0
  74. package/dist/assets/img/main-service2.9b99549.png +0 -0
  75. package/dist/assets/img/rating--average.1ea492c.svg +12 -0
  76. package/dist/assets/img/rating--great.e3d712e.svg +16 -0
  77. package/dist/assets/img/rating--poor.2938a25.svg +12 -0
  78. package/dist/assets/img/send.6db52a9.svg +3 -0
  79. package/dist/assets/img/subiz-mono.877e9f5.svg +3 -0
  80. package/dist/screenshoot.html +7 -0
  81. package/dist/screenshoot.js +5757 -0
  82. package/index.html +18 -2
  83. package/package.json +10 -9
  84. package/screenshoot.html +15 -0
  85. package/screenshoot.js +59 -0
  86. package/src/chatbox/Header.js +42 -34
  87. package/src/lib.js +8 -3
  88. package/src/notif/notif.js +37 -28
  89. package/src/plugin.js +11 -4
  90. package/src/store/store.js +9 -5
  91. package/src/util/campaign.js +16 -12
  92. package/take.js +36 -0
  93. package/webpack.dev.js +7 -0
  94. package/webpack.prod.js +12 -2
  95. package/webpack.screenshoot.js +20 -0
package/index.html CHANGED
@@ -1,7 +1,7 @@
1
1
  <!DOCTYPE html>
2
2
  <html lang="en">
3
3
  <head>
4
- <meta name="description" content="Subiz preview">
4
+ <meta name="description" content="Subiz preview" />
5
5
  <meta charset="utf-8" />
6
6
  <title>Widget v4</title>
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
@@ -32,7 +32,23 @@
32
32
  }
33
33
  window.subiz.q = []
34
34
  // set account it in the very first call
35
- window.subiz('setAccount', accid)
35
+ let mask = '' // old mask
36
+ window.subiz('setAccount', accid, undefined, mask, (mask) => {
37
+ console.log('MKA', mask)
38
+ })
39
+
40
+ subiz('overrideChatbox', {
41
+ type: 'chatbox',
42
+ chatbox: {
43
+ triggers: [{type: 'after_pageview'}],
44
+ hide_close_button: true,
45
+ desktop_button: {hidden: true},
46
+ mobile_button: {hidden: true},
47
+ },
48
+ })
49
+ subiz('waitReady', () => {})
50
+ subiz('shrinkWidget')
51
+ subiz('expandWidget')
36
52
  </script>
37
53
  </body>
38
54
  </html>
package/package.json CHANGED
@@ -1,38 +1,39 @@
1
1
  {
2
2
  "name": "@subiz/widget-v4",
3
- "version": "4.0.53",
3
+ "version": "4.0.58",
4
4
  "main": "./compiled_src/lib.js",
5
5
  "scripts": {
6
6
  "dev": "npx webpack serve --config webpack.dev.js",
7
- "build": "npx webpack --config webpack.prod.js",
7
+ "build": "rm -rf dist && npx webpack --config webpack.screenshoot.js && npx webpack --config webpack.prod.js",
8
8
  "report": "npx webpack --config webpack.report.js",
9
9
  "lib": "rm -rf compiled_src && npx babel --out-dir=compiled_src src"
10
10
  },
11
11
  "dependencies": {
12
- "@babel/core": "^7.16.0",
13
- "@googlemaps/js-api-loader": "^1.11.4",
12
+ "@googlemaps/js-api-loader": "^1.12.11",
14
13
  "@subiz/ajax": "^3.0.12",
15
14
  "@subiz/flow": "^1.0.9",
16
15
  "@subiz/storage": "0.0.8",
17
16
  "@subiz/wsclient": "^3.1.7",
18
- "babel-loader": "^8.2.3",
19
17
  "cookie_js": "1.4.2",
20
- "core-js": "^3.19.2",
18
+ "core-js": "^3.19.3",
21
19
  "css-loader": "^5.2.6",
22
20
  "file-loader": "^6.2.0",
23
21
  "less": "^4.1.2",
24
22
  "less-loader": "^10.2.0",
25
- "marked": "^4.0.5",
26
- "preact": "^10.6.0"
23
+ "marked": "^4.0.6",
24
+ "preact": "^10.6.2"
27
25
  },
28
26
  "devDependencies": {
27
+ "babel-loader": "^8.2.3",
28
+ "@babel/core": "^7.16.0",
29
29
  "@babel/cli": "^7.16.0",
30
30
  "@babel/plugin-proposal-class-properties": "^7.16.0",
31
31
  "@babel/plugin-transform-react-jsx": "^7.16.0",
32
32
  "@babel/preset-env": "^7.16.4",
33
33
  "babel-plugin-syntax-jsx": "^6.18.0",
34
34
  "html-webpack-plugin": "^5.5.0",
35
- "webpack": "^5.64.4",
35
+ "puppeteer": "^12.0.1",
36
+ "webpack": "^5.65.0",
36
37
  "webpack-bundle-analyzer": "^4.5.0",
37
38
  "webpack-cli": "^4.9.1",
38
39
  "webpack-dev-server": "^4.6.0"
@@ -0,0 +1,15 @@
1
+ <html>
2
+ <head>
3
+ <meta name="viewport" content="width=device-width, intial-scale=1.0" />
4
+ <style>
5
+ /* make the environment look like widget environment */
6
+ #sbz-pop * {
7
+ all: unset;
8
+ }
9
+ body {
10
+ background: #ddd;
11
+ }
12
+ </style>
13
+ </head>
14
+ <body></body>
15
+ </html>
package/screenshoot.js ADDED
@@ -0,0 +1,59 @@
1
+ import Widget from './src/lib.js'
2
+
3
+ let accid = 'acqsulrowbxiugvginhw'
4
+ let widget = new Widget(
5
+ 'https://api.subiz.com.vn/4.0/',
6
+ 'https://file-subiz.com/',
7
+ 'https://rt-0.subiz.com.vn/',
8
+ true,
9
+ true,
10
+ )
11
+
12
+ function main() {
13
+ var $div = document.createElement('div')
14
+ document.body.appendChild($div)
15
+ let hash = document.location.hash.substr(1)
16
+
17
+ let plugin = JSON.parse(decodeURIComponent(atob(hash)))
18
+ plugin.triggers = [{type: 'after_pageview', after_pageview_sec: 0, enabled: true}]
19
+ if (plugin.popup) plugin.popup.overlay = false
20
+ plugin._dont_close = true
21
+ plugin._page_index = 0
22
+ plugin.conditions = []
23
+
24
+ if (plugin.type === 'notification') {
25
+ if (!plugin.notification) return console.log('EMPTY PLUGIN')
26
+
27
+ if (!plugin.notification.profiles || plugin.notification.profiles.length == 0) {
28
+ plugin.notification.profiles = [
29
+ {
30
+ address: 'Hàng Da, Hoàn Kiếm, Hà Nội',
31
+ age: 26,
32
+ avatar_url: 'https://vcdn.subiz-cdn.com/file/firegedmbhqftirxacho-avatar3.jpeg',
33
+ country: 'VN',
34
+ email: 'linhxx@gmail.com',
35
+ gender: 'Female',
36
+ fullname: 'Nguyễn Linh',
37
+ phone: '0823588xxx',
38
+ },
39
+ {
40
+ address: 'Lũng Cú, Đồng Văn, Hà Giang',
41
+ age: 23,
42
+ avatar_url: 'https://vcdn.subiz-cdn.com/file/fiqvzdstytzxlbsguaci-ellipse_2319.png',
43
+ country: 'VN',
44
+ email: 'lannhoanggxx@gmail.com',
45
+ gender: 'Female',
46
+ name: 'Nguyễn Hoàng Lan',
47
+ phone: '0326789xxx',
48
+ },
49
+ ]
50
+ }
51
+ }
52
+
53
+ plugin.account_id = accid
54
+ widget._overridePlugin([plugin])
55
+ // widget._overrideDeviceType('mobile')
56
+ widget.setAccount(accid, $div)
57
+ }
58
+
59
+ main()
@@ -44,17 +44,19 @@ export default class Header extends Com {
44
44
  let state = acc.is_online ? this.props.t('agent_online') : this.props.t('agent_offline')
45
45
  let tagline = sb.get(accSetting, `tagline`, {})
46
46
  let desc = this.props.t.i18n(tagline) || accSetting.introduction || state
47
- let agentIdsJoined = sb.map(this.getAgentJoined(this.props.cid), agent => agent.id)
47
+ let agentIdsJoined = sb.map(this.getAgentJoined(this.props.cid), (agent) => agent.id)
48
48
  let cls = 'widget-header--inner widget-header--inner--collapsed'
49
49
  if (!show) cls += ' widget-header--inner--hidden'
50
50
 
51
51
  return (
52
52
  <div class={cls}>
53
53
  {this.renderBackButton()}
54
- <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode="secondary" agent_ids={agentIdsJoined} />
55
- <div class="widget-header--title-container">
56
- <div class="widget-header--title">{this.getTitle()}</div>
57
- <div class="widget-header--description" title={desc}>{desc}</div>
54
+ <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode='secondary' agent_ids={agentIdsJoined} />
55
+ <div class='widget-header--title-container'>
56
+ <div class='widget-header--title'>{this.getTitle()}</div>
57
+ <div class='widget-header--description' title={desc}>
58
+ {desc}
59
+ </div>
58
60
  </div>
59
61
  {this.renderCloseButton()}
60
62
  </div>
@@ -65,7 +67,7 @@ export default class Header extends Com {
65
67
  let accSetting = this.props.plugin.chatbox || {}
66
68
  let acc = this.props.store.matchAccount()
67
69
  let links = sb.get(accSetting, 'header.links') || []
68
- let $links = sb.map(links, link => {
70
+ let $links = sb.map(links, (link) => {
69
71
  if (!link.url || !link.type || link.type === 'subiz') return null
70
72
  if (link.type === 'email') {
71
73
  return (
@@ -79,7 +81,7 @@ export default class Header extends Com {
79
81
 
80
82
  return (
81
83
  <div>
82
- <a href={link.url} target="_blank" title={link.url} rel="noreferrer">
84
+ <a href={link.url} target='_blank' title={link.url} rel='noreferrer'>
83
85
  <i class={`social__links-logo social__links-logo--${link.type}`}></i>
84
86
  </a>
85
87
  </div>
@@ -90,7 +92,7 @@ export default class Header extends Com {
90
92
  Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi của bạn`
91
93
  let tagline = sb.get(accSetting, `tagline`, {})
92
94
  var teamintro = this.props.t.i18n(tagline) || accSetting.introduction || this.props.t('team_intro') || DEFTEAMINTO
93
- var tags = sb.extractText(teamintro).map(tag => {
95
+ var tags = sb.extractText(teamintro).map((tag) => {
94
96
  if (tag.type === 'emoji') return <Emoji emojiCode={tag.text} />
95
97
  return tag.text
96
98
  })
@@ -99,17 +101,21 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
99
101
  if (!show) cls += ' widget-header--inner--hidden'
100
102
  return (
101
103
  <div class={cls}>
102
- <div class="widget-header-expand-container">
103
- <div class="widget-header--top-wrapper">
104
- <div class="widget-header--title">{this.getTitle()}</div>
104
+ <div class='widget-header-expand-container'>
105
+ <div class='widget-header--top-wrapper'>
106
+ <div class='widget-header--title'>{this.getTitle()}</div>
105
107
  {this.renderCloseButton()}
106
108
  </div>
107
- <div class="widget_header__body widget_header__body__social">
108
- <img alt="logo" class="social__account_logo" src={this.props.store.replaceFileUrl(sb.get(acc, 'logo_url'))} />
109
+ <div class='widget_header__body widget_header__body__social'>
110
+ <img
111
+ alt='logo'
112
+ class='social__account_logo'
113
+ src={this.props.store.replaceFileUrl(sb.get(acc, 'logo_url'))}
114
+ />
109
115
 
110
116
  <div>
111
- <div class="social__introduction">{tags}</div>
112
- <div class="social__links">{$links}</div>
117
+ <div class='social__introduction'>{tags}</div>
118
+ <div class='social__links'>{$links}</div>
113
119
  </div>
114
120
  </div>
115
121
  </div>
@@ -123,7 +129,7 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
123
129
  Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi của bạn`
124
130
  let tagline = sb.get(accSetting, `tagline`, {})
125
131
  var teamintro = this.props.t.i18n(tagline) || accSetting.introduction || this.props.t('team_intro') || DEFTEAMINTO
126
- var tags = sb.extractText(teamintro).map(tag => {
132
+ var tags = sb.extractText(teamintro).map((tag) => {
127
133
  if (tag.type === 'emoji') return <Emoji emojiCode={tag.text} />
128
134
  return tag.text
129
135
  })
@@ -132,17 +138,17 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
132
138
  if (!show) cls += ' widget-header--inner--hidden'
133
139
  return (
134
140
  <div class={cls}>
135
- <div class="widget-header-expand-container">
136
- <div class="widget-header--top-wrapper">
137
- <div class="widget-header--title">{this.getTitle()}</div>
141
+ <div class='widget-header-expand-container'>
142
+ <div class='widget-header--top-wrapper'>
143
+ <div class='widget-header--title'>{this.getTitle()}</div>
138
144
  {this.renderCloseButton()}
139
145
  </div>
140
- <div class="widget_header__body">
141
- <div class="widget-header--avatar-wrapper">
142
- <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode="primary" />
146
+ <div class='widget_header__body'>
147
+ <div class='widget-header--avatar-wrapper'>
148
+ <AgentsAvatar plugin={this.props.plugin} store={this.props.store} mode='primary' />
143
149
  </div>
144
- <div class="widget-header--title-container">
145
- <div class="widget-header--description">{tags}</div>
150
+ <div class='widget-header--title-container'>
151
+ <div class='widget-header--description'>{tags}</div>
146
152
  </div>
147
153
  </div>
148
154
  </div>
@@ -170,32 +176,34 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
170
176
  let user = this.props.store.matchUser()
171
177
 
172
178
  let unreadcount = 0
173
- sb.map(allconvos, convo => {
179
+ sb.map(allconvos, (convo) => {
174
180
  if (convo.id == this.props.cid) return
175
181
  if (!sb.isConvoSeen(convo, user.id)) unreadcount++
176
182
  })
177
183
 
178
184
  if (unreadcount !== 0) {
179
- $unreadcount = <span class="widget-header--total-unread-convo">{unreadcount}</span>
185
+ $unreadcount = <span class='widget-header--total-unread-convo'>{unreadcount}</span>
180
186
  }
181
187
  return (
182
188
  <div
183
189
  class={`widget-header--wrap-button-back ${unreadcount ? 'widget-header--has-convo-unred' : ''}`}
184
- onClick={e => this.onBackClick(e)}>
185
- <div class="widget-header--button-back" data-tooltip={this.props.t('menu_back')}></div>
190
+ onClick={(e) => this.onBackClick(e)}>
191
+ <div class='widget-header--button-back' data-tooltip={this.props.t('menu_back')}></div>
186
192
  {$unreadcount}
187
193
  </div>
188
194
  )
189
195
  }
190
196
 
191
197
  renderCloseButton() {
198
+ let accSetting = this.props.plugin.chatbox || {}
199
+ if (accSetting.hide_close_button) return null
192
200
  return (
193
201
  <div
194
- class="widget-header--button widget-header--button-close"
202
+ class='widget-header--button widget-header--button-close'
195
203
  data-tooltip={this.props.t('close')}
196
- data-tooltip-position="bottom"
197
- onClick={e => this.onCloseClick(e)}>
198
- <span class="widget-header--button-close-icon"></span>
204
+ data-tooltip-position='bottom'
205
+ onClick={(e) => this.onCloseClick(e)}>
206
+ <span class='widget-header--button-close-icon'></span>
199
207
  </div>
200
208
  )
201
209
  }
@@ -214,9 +222,9 @@ Vui lòng hỏi chúng tôi bất cứ điều gì hoặc chia sẻ phản hồi
214
222
 
215
223
  getAgentJoined(cid) {
216
224
  var convo = this.props.store.matchConvo(cid) || {}
217
- let joined = sb.filter(convo.members, mem => mem.type === 'agent' && mem.membership === 'active')
225
+ let joined = sb.filter(convo.members, (mem) => mem.type === 'agent' && mem.membership === 'active')
218
226
  return joined
219
227
  }
220
228
  }
221
229
 
222
- let getJoinedNameMember = agents => sb.map(agents, agent => agent.name).join(', ')
230
+ let getJoinedNameMember = (agents) => sb.map(agents, (agent) => agent.name).join(', ')
package/src/lib.js CHANGED
@@ -32,9 +32,13 @@ class Widget {
32
32
  xhttp.send()
33
33
  }
34
34
 
35
- async setAccount(id, $container) {
36
- await this.store.init(id)
35
+ async waitReady(cb) {
36
+ await this.store.readyGate.entry()
37
+ cb()
38
+ }
37
39
 
40
+ async setAccount(id, $container, mask, cb) {
41
+ let outmask = await this.store.init(id, mask)
38
42
  // add container to client site
39
43
  if (!$container) $container = document.body
40
44
  this.pluginMgr = new PluginMgr(this, $container)
@@ -45,8 +49,9 @@ class Widget {
45
49
  this.pluginMgr.destroy()
46
50
  clearInterval(clean)
47
51
  }, 1000)
48
-
49
52
  this.domGate.open()
53
+ cb && cb(outmask)
54
+ return outmask
50
55
  }
51
56
 
52
57
  // deprecated
@@ -68,17 +68,17 @@ export default class Notif extends Com {
68
68
 
69
69
  renderCloseButton() {
70
70
  return (
71
- <div class="btn_close" onClick={e => this.onCloseButtonClick(e)}>
71
+ <div class='btn_close' onClick={(e) => this.onCloseButtonClick(e)}>
72
72
  <svg
73
- class="btn_close__icon"
74
- xmlns="http://www.w3.org/2000/svg"
75
- width="24"
76
- height="24"
77
- viewBox="0 0 24 24"
78
- stroke-linecap="round"
79
- stroke-linejoin="round">
80
- <line x1="18" y1="6" x2="6" y2="18" style="stroke-width: 3 !important;"></line>
81
- <line x1="6" y1="6" x2="18" y2="18" style="stroke-width: 3 !important;"></line>
73
+ class='btn_close__icon'
74
+ xmlns='http://www.w3.org/2000/svg'
75
+ width='24'
76
+ height='24'
77
+ viewBox='0 0 24 24'
78
+ stroke-linecap='round'
79
+ stroke-linejoin='round'>
80
+ <line x1='18' y1='6' x2='6' y2='18' style='stroke-width: 3 !important;'></line>
81
+ <line x1='6' y1='6' x2='18' y2='18' style='stroke-width: 3 !important;'></line>
82
82
  </svg>
83
83
  </div>
84
84
  )
@@ -100,13 +100,13 @@ export default class Notif extends Com {
100
100
  this.setState({closeAnimation: false})
101
101
  let timestamp = this.randomTimestampt()
102
102
  let profiles = sb.get(this.props, 'plugin.notification.profiles', [])
103
- let user = profiles[Math.floor(Math.random() * sb.size(profiles))]
103
+ let user = profiles[Math.floor(Math.random() * sb.size(profiles))] || {}
104
104
  // make sure image loaded
105
105
  if (user.avatar_url && user.avatar_url.startsWith('http')) {
106
106
  await sb.preloadImg(user.avatar_url)
107
107
  }
108
108
 
109
- sb.map(sb.get(this.props.plugin, 'notification.custom_avatar_urls'), url => {
109
+ sb.map(sb.get(this.props.plugin, 'notification.custom_avatar_urls'), (url) => {
110
110
  profiles.push({
111
111
  type: 'person',
112
112
  fullname: randomName(),
@@ -119,7 +119,12 @@ export default class Notif extends Com {
119
119
  })
120
120
 
121
121
  let i18n_messages = sb.get(this.props, 'plugin.notification.i18n_message_quill_deltas', [])
122
+
122
123
  let i18n_message = i18n_messages[Math.floor(Math.random() * sb.size(i18n_messages))]
124
+
125
+ let fallbackmsgs = sb.get(this.props, 'plugin.notification.message_quill_deltas', [])
126
+ let fallbackmessage = fallbackmsgs[Math.floor(Math.random() * sb.size(fallbackmsgs))]
127
+
123
128
  let i18n_title = sb.get(this.props, 'plugin.notification.i18n_title_quill_delta')
124
129
 
125
130
  return this.setState({
@@ -127,8 +132,8 @@ export default class Notif extends Com {
127
132
  last_show: sb.Date.now(),
128
133
  timestamp: timestamp,
129
134
  user: user,
130
- title: this.props.t.i18n(i18n_title),
131
- message: this.props.t.i18n(i18n_message),
135
+ title: this.props.t.i18n(i18n_title) || sb.get(this.props, 'plugin.notification.title_quill_delta'),
136
+ message: this.props.t.i18n(i18n_message) || fallbackmessage,
132
137
  })
133
138
  }
134
139
  this.setState({closeAnimation: true})
@@ -140,7 +145,7 @@ export default class Notif extends Com {
140
145
  async refreshCSS() {
141
146
  // make sure you are still alive
142
147
  let plugins = this.props.store.matchPlugin()
143
- let found = sb.find(plugins, plugin => plugin.id === this.props.plugin.id)
148
+ let found = sb.find(plugins, (plugin) => plugin.id === this.props.plugin.id)
144
149
  if (!found) return
145
150
  let css = (await notifCSS).default.default.toString()
146
151
  // var outcss = sb.replaceCssVariablePlugin(css, this.props.plugin.popup)
@@ -191,7 +196,7 @@ export default class Notif extends Com {
191
196
  renderTextFromQuillDelta(quilldelta, profile) {
192
197
  let qd = sb.parseJSON(quilldelta)
193
198
  if (!qd || !qd.ops) return null
194
- return sb.map(qd.ops, op => {
199
+ return sb.map(qd.ops, (op) => {
195
200
  let out = null
196
201
  if (!op.insert) return null
197
202
 
@@ -215,7 +220,6 @@ export default class Notif extends Com {
215
220
  if (!this.state.imageReady) return null
216
221
  if (this.state.close) return null
217
222
  if (!this.state.message) return null
218
-
219
223
  let notif = sb.get(this.props.plugin, 'notification', {})
220
224
  if (!notif) return null
221
225
  let animation = ''
@@ -244,24 +248,29 @@ export default class Notif extends Com {
244
248
  return (
245
249
  <div
246
250
  class={animation + ' notif' + ' notif__' + pos}
247
- onClick={e => this.onClick(e)}
248
- onmouseover={e => this.setOver(true)}
251
+ onClick={(e) => this.onClick(e)}
252
+ onmouseover={(e) => this.setOver(true)}
249
253
  style={st}
250
- onmouseleave={e => this.setOver(false)}>
251
- <div style="position: relative !important; display: flex !important; align-items: center !important;">
252
- <img alt="notification background" class="notif_bg" src={notif.background_url} style={sb.js2css(notif.background_style)} />
254
+ onmouseleave={(e) => this.setOver(false)}>
255
+ <div style='position: relative !important; display: flex !important; align-items: center !important;'>
256
+ <img
257
+ alt='notification background'
258
+ class='notif_bg'
259
+ src={notif.background_url}
260
+ style={sb.js2css(notif.background_style)}
261
+ />
253
262
  {this.renderCloseButton()}
254
- <div class="notif_avatar" style={sb.js2css(notif.avatar_style)}>
255
- <img alt="notification avatar" class="notif_avatar__img" src={user.avatar_url} />
263
+ <div class='notif_avatar' style={sb.js2css(notif.avatar_style)}>
264
+ <img alt='notification avatar' class='notif_avatar__img' src={user.avatar_url} />
256
265
  </div>
257
- <div class="notif_body">
258
- <div class="notif_title" style={sb.js2css(notif.title_style)}>
266
+ <div class='notif_body'>
267
+ <div class='notif_title' style={sb.js2css(notif.title_style)}>
259
268
  {this.renderTextFromQuillDelta(this.state.title, user)}
260
269
  </div>
261
- <div class="notif_message" style={sb.js2css(notif.message_style)}>
270
+ <div class='notif_message' style={sb.js2css(notif.message_style)}>
262
271
  {this.renderTextFromQuillDelta(this.state.message, user)}
263
272
  </div>
264
- <div class="notif_time" style={sb.js2css(notif.subtext_style)}>
273
+ <div class='notif_time' style={sb.js2css(notif.subtext_style)}>
265
274
  {this.state.timestamp}
266
275
  </div>
267
276
  </div>
package/src/plugin.js CHANGED
@@ -29,10 +29,9 @@ function Plugin(plugin, store, $container, lib) {
29
29
 
30
30
  this.getState = () => state
31
31
 
32
- var run = async function () {
32
+ var run = async function() {
33
33
  if (_destroy) return
34
34
  if (state !== 'hold') return
35
-
36
35
  // dont run converted plugin twice
37
36
  if (plugin.type === 'popup' && store.isConverted(plugin.id)) return
38
37
 
@@ -375,8 +374,16 @@ const getLocale = (plugin, loc) => {
375
374
  if (found) return found
376
375
 
377
376
  found = sb.find(plugin.locales, (l) => {
378
- l = l.replace('-', '_').split('_')[0].trim().toLowerCase()
379
- let compareloc = loc.replace('-', '_').split('_')[0].trim().toLowerCase()
377
+ l = l
378
+ .replace('-', '_')
379
+ .split('_')[0]
380
+ .trim()
381
+ .toLowerCase()
382
+ let compareloc = loc
383
+ .replace('-', '_')
384
+ .split('_')[0]
385
+ .trim()
386
+ .toLowerCase()
380
387
  return l == compareloc
381
388
  })
382
389
  if (found) return found
@@ -276,16 +276,18 @@ export default class Store {
276
276
 
277
277
  now = () => sb.Date.now() + this.timeDiff // millisecond on server
278
278
 
279
- async init(accid) {
279
+ async init(accid, mask) {
280
280
  this.readyGate.close()
281
281
  accid = (accid || '').trim()
282
282
  this.api.setAuth({accid: accid})
283
283
 
284
284
  this.g_sync = {}
285
- let mask = '' // try to find mask in cookie
286
- try {
287
- mask = this.cookie.get('__sbmask', '')
288
- } catch (e) {}
285
+ // try to find mask in cookie
286
+ if (!mask) {
287
+ try {
288
+ mask = this.cookie.get('__sbmask', '')
289
+ } catch (e) {}
290
+ }
289
291
 
290
292
  let localstorageMask = this.kv.match('mask')
291
293
  // cookie is deleted, fallback to local storage
@@ -333,6 +335,8 @@ export default class Store {
333
335
  await this.reconnect()
334
336
  this.readyGate.open()
335
337
  this.reconnectWs(accid, userId)
338
+
339
+ return mask
336
340
  }
337
341
 
338
342
  seenQueue = [] // convoid will be seen
@@ -1,8 +1,8 @@
1
1
  var common = require('./common.js')
2
2
 
3
3
  // callback when user is about to leave site
4
- export function trackExitIntent (cb) {
5
- let handler = e => {
4
+ export function trackExitIntent(cb) {
5
+ let handler = (e) => {
6
6
  if (e.clientY > 10) return // not move to top
7
7
  if (cb) cb()
8
8
  document.removeEventListener('mouseout', handler)
@@ -11,14 +11,15 @@ export function trackExitIntent (cb) {
11
11
  }
12
12
 
13
13
  // callback after user has scrolled X% down on the current page
14
- export function trackScrollingPercentage (percent, cb) {
15
- let handleScroll = e => {
14
+ export function trackScrollingPercentage(percent, cb) {
15
+ let handleScroll = (e) => {
16
16
  let scrollTop = e.srcElement.scrollingElement ? e.srcElement.scrollingElement.scrollTop : e.srcElement.scrollTop
17
+
17
18
  let scrollHeight = e.srcElement.scrollingElement
18
19
  ? e.srcElement.scrollingElement.scrollHeight
19
20
  : e.srcElement.scrollHeight
20
21
 
21
- if (scrollTop > 0 && scrollHeight > 0 && scrollTop / scrollHeight >= percent) {
22
+ if (scrollTop > 0 && scrollHeight > 0 && (scrollTop + window.innerHeight) / scrollHeight >= percent) {
22
23
  if (cb) cb()
23
24
  window.removeEventListener('scroll', handleScroll, false)
24
25
  }
@@ -28,14 +29,17 @@ export function trackScrollingPercentage (percent, cb) {
28
29
  }
29
30
 
30
31
  // callback when user clicks on a specific part of page
31
- export function trackAreaClicked (selector, cb) {
32
+ export function trackAreaClicked(selector, cb) {
32
33
  if (!selector) return
33
34
  selector = selector || ''
34
- common.map(selector.split('\n'), selector => {
35
+ common.map(selector.split('\n'), (selector) => {
35
36
  selector = common.trim(selector)
36
37
  if (!selector) return
37
- let doms = document.querySelectorAll(selector)
38
- common.map(doms, dom => {
38
+ let doms = []
39
+ try {
40
+ doms = document.querySelectorAll(selector)
41
+ } catch (e) {}
42
+ common.map(doms, (dom) => {
39
43
  if (!dom) return
40
44
  dom.addEventListener('click', cb, false)
41
45
  })
@@ -43,7 +47,7 @@ export function trackAreaClicked (selector, cb) {
43
47
  }
44
48
 
45
49
  // callback when user has stopped all activity (clicking, scrolling, ...)
46
- export function trackInactivity (seconds, cb) {
50
+ export function trackInactivity(seconds, cb) {
47
51
  let events = [
48
52
  'scroll',
49
53
  'keyup',
@@ -80,9 +84,9 @@ let timeOnPage = 0 // seconds
80
84
  setInterval(() => timeOnPage++, 1000)
81
85
 
82
86
  // when user has been on the page for at least X seconds
83
- export function trackTimeOnPage (seconds, cb) {
87
+ export function trackTimeOnPage(seconds, cb) {
84
88
  if (seconds < 1) {
85
- return setTimeout(function () {
89
+ return setTimeout(function() {
86
90
  cb(seconds)
87
91
  }, 100)
88
92
  }