@subiz/widget-v4 4.0.52 → 4.0.57

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 (52) hide show
  1. package/cloudflare_worker.js +1 -1
  2. package/compiled_src/chatbox/OrderAttachments.js +1 -4
  3. package/compiled_src/notif/notif.js +7 -3
  4. package/compiled_src/plugin.js +1 -1
  5. package/compiled_src/store/store.js +0 -140
  6. package/compiled_src/util/campaign.js +7 -2
  7. package/dist/178.js +406 -0
  8. package/dist/{17d517e44e2.178.js → 17d83c40640.178.js} +0 -0
  9. package/dist/{17d517e44e2.213.js → 17d83c40640.213.js} +0 -0
  10. package/dist/{17d517e44e2.362.js → 17d83c40640.362.js} +0 -0
  11. package/dist/17d83c40640.441.js +1 -0
  12. package/dist/17d83c40640.605.js +1 -0
  13. package/dist/{17d517e44e2.619.js → 17d83c40640.619.js} +1 -1
  14. package/dist/{17d517e44e2.678.js → 17d83c40640.678.js} +0 -0
  15. package/dist/17d83c40640.74.js +1 -0
  16. package/dist/{17d517e44e2.782.js → 17d83c40640.782.js} +0 -0
  17. package/dist/17d83c40640.app.js +1 -0
  18. package/dist/{17d517e44e2.index.html → 17d83c40640.index.html} +1 -1
  19. package/dist/{17d517e44e2.library.html → 17d83c40640.library.html} +1 -1
  20. package/dist/17d83c40640.library.js +1 -0
  21. package/dist/{17d517e44e2.preview.html → 17d83c40640.preview.html} +1 -1
  22. package/dist/17d83c40640.preview.js +1 -0
  23. package/dist/17d83c40640.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 +4732 -0
  31. package/dist/782.js +107 -0
  32. package/dist/HASH +1 -1
  33. package/dist/screenshoot.html +7 -0
  34. package/dist/screenshoot.js +5747 -0
  35. package/package.json +11 -11
  36. package/screenshoot.html +15 -0
  37. package/screenshoot.js +59 -0
  38. package/src/chatbox/OrderAttachments.js +1 -3
  39. package/src/notif/notif.js +37 -28
  40. package/src/plugin.js +12 -5
  41. package/src/store/store.js +0 -129
  42. package/src/util/campaign.js +16 -12
  43. package/take.js +36 -0
  44. package/webpack.dev.js +7 -0
  45. package/webpack.prod.js +12 -2
  46. package/webpack.screenshoot.js +20 -0
  47. package/dist/17d517e44e2.441.js +0 -1
  48. package/dist/17d517e44e2.605.js +0 -1
  49. package/dist/17d517e44e2.74.js +0 -1
  50. package/dist/17d517e44e2.app.js +0 -1
  51. package/dist/17d517e44e2.library.js +0 -1
  52. package/dist/17d517e44e2.preview.js +0 -1
package/package.json CHANGED
@@ -1,41 +1,41 @@
1
1
  {
2
2
  "name": "@subiz/widget-v4",
3
- "version": "4.0.52",
3
+ "version": "4.0.57",
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.1",
18
+ "core-js": "^3.19.2",
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.4",
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
- "prettier": "^2.4.1",
36
- "webpack": "^5.64.3",
35
+ "puppeteer": "^12.0.1",
36
+ "webpack": "^5.64.4",
37
37
  "webpack-bundle-analyzer": "^4.5.0",
38
38
  "webpack-cli": "^4.9.1",
39
- "webpack-dev-server": "^4.5.0"
39
+ "webpack-dev-server": "^4.6.0"
40
40
  }
41
41
  }
@@ -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()
@@ -53,13 +53,11 @@ export default class ProductAttachments extends Com {
53
53
  )
54
54
  }
55
55
 
56
- let {total} = this.props.store.getOrderTotal(order)
57
-
58
56
  let $total = (
59
57
  <div class='order_attachment__footer'>
60
58
  <div>{this.props.t('total')}</div>{' '}
61
59
  <div>
62
- <b>{sb.formatCurrency(total)}</b>
60
+ <b>{sb.formatCurrency(order.total)}</b>
63
61
  </div>
64
62
  </div>
65
63
  )
@@ -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
 
@@ -372,11 +371,19 @@ function downloadLanguage(store, locale, force) {
372
371
  const getLocale = (plugin, loc) => {
373
372
  if (!loc) loc = ''
374
373
  let found = sb.find(plugin.locales, (l) => l.toLowerCase().trim() === loc.toLowerCase().trim())
375
- if (found) return loc
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
@@ -930,135 +930,6 @@ export default class Store {
930
930
  setTimeout(() => this.loopTime(), 60000)
931
931
  }
932
932
 
933
- getOrderTotal(order) {
934
- let subtotal = 0
935
- sb.map(order.items, (item) => {
936
- if (!item.product) return 0
937
- let price = item.product.price * item.quantity
938
-
939
- if (item.discount_type) {
940
- if (item.discount_type == 'percentage') {
941
- if (item.discount_before_tax && item.discount_percentage > 0) {
942
- price = price * (1 - item.discount_percentage / 10000)
943
- }
944
- } else if (item.discount_type == 'amount') {
945
- let computed_discount = item.discount
946
- if (item.discount_before_tax && computed_discount > 0) {
947
- price = price - computed_discount
948
- if (price <= 0) price = 0
949
- }
950
- }
951
- }
952
- subtotal += price
953
- })
954
-
955
- let computed_discount = 0
956
- // add specific item discount after tax to computed_discount
957
- sb.map(order.items, (item) => {
958
- if (!item.discount_type) return
959
- if (!item.product) return 0
960
- let price = item.product.price * item.quantity
961
-
962
- let tax = item.product.tax
963
- let taxprice = 0
964
- if (tax && tax.id) taxprice = (price * tax.percentage) / 10000
965
-
966
- if (item.discount_type == 'percentage' && !item.discount_before_tax && item.discount_percentage > 0) {
967
- computed_discount += ((price + taxprice) * item.discount_percentage) / 10000
968
- } else if (item.discount_type == 'amount') {
969
- let itemdiscount = item.discount
970
- if (!item.discount_before_tax && itemdiscount > 0) {
971
- // CAUTION: easy to miss condition
972
- if (itemdiscount > price + taxprice) itemdiscount = price + taxprice
973
- computed_discount += itemdiscount
974
- }
975
- }
976
- })
977
-
978
- // TAX
979
- let totaltax = 0
980
- let taxM = {}
981
- sb.map(order.items, (item, i) => {
982
- if (!item.product) return
983
- let tax = item.product.tax
984
- if (!tax) return
985
- if (!tax.id) return
986
- let price = item.product.price * item.quantity
987
-
988
- if (item.discount_type) {
989
- if (item.discount_type == 'percentage') {
990
- if (item.discount_before_tax && item.discount_percentage > 0) {
991
- price = price * (1 - item.discount_percentage / 10000)
992
- }
993
- } else if (item.discount_type == 'amount') {
994
- let computed_discount = item.discount
995
- if (item.discount_before_tax && computed_discount > 0) {
996
- price = price - computed_discount
997
- if (price <= 0) price = 0
998
- }
999
- }
1000
- }
1001
- let taxprice = (price * tax.percentage) / 10000
1002
-
1003
- taxM[i] = {
1004
- tax: tax,
1005
- taxprice: taxprice,
1006
- }
1007
- })
1008
-
1009
- // have discount before tax
1010
- if (order.discount_before_tax) {
1011
- // decrease tax by discount percentage
1012
- if (order.discount_type == 'percentage' && order.discount_percentage > 0) {
1013
- sb.map(taxM, (t) => {
1014
- t.taxprice = t.taxprice * (1 - order.discount_percentage / 10000)
1015
- })
1016
- computed_discount += (subtotal * order.discount_percentage) / 10000
1017
- } else if (order.discount_type == 'amount') {
1018
- let discount = order.discount
1019
- if (subtotal > 0) {
1020
- sb.map(taxM, (t) => {
1021
- // CAUTION: easy to miss
1022
- if (discount > subtotal) discount = subtotal
1023
-
1024
- t.taxprice = t.taxprice * (1 - discount / subtotal)
1025
- })
1026
- }
1027
- computed_discount += discount
1028
- }
1029
- } else {
1030
- if (order.discount_type == 'percentage' && order.discount_percentage > 0) {
1031
- let taxprice = 0
1032
- sb.map(taxM, (t) => (taxprice += t.taxprice))
1033
- computed_discount += ((subtotal + taxprice) * order.discount_percentage) / 10000
1034
- } else if (order.discount_type == 'amount') {
1035
- let discount = order.discount
1036
- computed_discount += discount
1037
- }
1038
- }
1039
-
1040
- // SHIP
1041
- let shippingfee = lo.get(order, 'shipping.fee')
1042
- if (shippingfee > 0) {
1043
- if (sb.get(order, 'shipping.tax.id')) {
1044
- let tax = order.shipping.tax
1045
- let taxprice = (shippingfee * tax.percentage) / 10000
1046
- taxM['ship'] = {tax: tax, taxprice: taxprice}
1047
- }
1048
- }
1049
-
1050
- let taxprice = 0
1051
- sb.map(taxM, (t) => (taxprice += t.taxprice))
1052
- let total = subtotal + taxprice - computed_discount + shippingfee
1053
-
1054
- // add adjustment
1055
- let adj = order.adjustment
1056
- total += adj
1057
-
1058
- if (total < 0) total = 0
1059
- return {subtotal, computed_discount, taxM, total}
1060
- }
1061
-
1062
933
  replaceFileUrl(src) {
1063
934
  if (!src) return ''
1064
935
 
@@ -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
  }
package/take.js ADDED
@@ -0,0 +1,36 @@
1
+ const puppeteer = require('puppeteer')
2
+
3
+ async function take() {
4
+ const browser = await puppeteer.launch({args: ['--no-sandbox']})
5
+ const page = await browser.newPage()
6
+ let templateBase64 = Buffer.from(encodeURIComponent(process.argv[2])).toString('base64')
7
+
8
+ await page.setViewport({width: 940, height: 700})
9
+ await page.goto('file://' + __dirname + '/dist/screenshoot.html#' + templateBase64, {
10
+ waitUntil: 'networkidle2',
11
+ })
12
+ await timeout(3000)
13
+ let out = makeid(20) + '.jpg'
14
+ await page.screenshot({path: out})
15
+ console.log(out)
16
+ browser.close()
17
+ }
18
+
19
+ function timeout(ms) {
20
+ return new Promise((resolve) => setTimeout(resolve, ms))
21
+ }
22
+
23
+ function makeid(length) {
24
+ var result = []
25
+ var characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
26
+ var charactersLength = characters.length
27
+ for (var i = 0; i < length; i++) {
28
+ result.push(characters.charAt(Math.floor(Math.random() * charactersLength)))
29
+ }
30
+ return result.join('')
31
+ }
32
+
33
+ take()
34
+
35
+ // try (remember to run 'npm run build' before running following command)
36
+ // node take.js '{"account_id":"acpxkgumifuoofoosble","id":"cpqzpnooosdhodmkjlixs","name":"Đặt hàng trước","type":"notification","created":1620813049308,"created_by":"agqmwfyuehpuzpehmv","updated":1620816899738,"updated_by":"agqmwfyuehpuzpehmv","triggers":[{"type":"after_pageview"}],"initiative_frequency":{"once_per_session":true},"notification":{"profile_tags":["nam thanh niên","nữ thanh niên"],"profiles":[{"avatar_url":"https://public-gcs.subiz-cdn.com/widget_assets/profile_images/VNM02.png","fullname":"Đoàn Hải Nam","country":"vn","gender":"Male","age":26,"tags":["nam thanh niên","vui tươi"],"email":"hainamxx@gmail.com","phone":"0823588xxx","address":"Hàng Da, Hoàn Kiếm, Hà Nội"},{"avatar_url":"https://public-gcs.subiz-cdn.com/widget_assets/profile_images/VNF03.png","fullname":"Nguyễn Hoàng Lan","country":"vn","gender":"Female","age":36,"tags":["nữ trung niên","lịch sự","vui tươi"],"email":"lannhoanggxx@gmail.com","phone":"0326789xxx","address":"Lũng Cú, Đồng Văn, Hà Giang"},{"avatar_url":"https://public-gcs.subiz-cdn.com/widget_assets/profile_images/VNM04.png","fullname":"Nguyễn Quý Tiến","country":"vn","gender":"Male","age":40,"tags":["nam trung niên","lịch sự"],"email":"tiendzxxx@gmail.com","phone":"056189xxxx","address":"Thụy Khuê, Tây Hồ, Hà Nội"},{"avatar_url":"https://public-gcs.subiz-cdn.com/widget_assets/profile_images/VNF05.png","fullname":"Phạm Hồng Thắm","country":"vn","gender":"Female","age":36,"tags":["nữ trung niên","lịch sự"],"email":"thampham1506xxx@gmail.com","phone":"033820xxxx","address":"Ngọc Đào, Hà Quang, Cao Bằng"},{"avatar_url":"https://public-gcs.subiz-cdn.com/widget_assets/profile_images/VNF06.png","fullname":"Ngô Thị Như Hòa","country":"vn","gender":"Female","age":29,"tags":["nữ thanh niên","lịch sự"],"email":"alice29xxx@gmail.com","phone":"058104xxxx","address":"Xuân Đỉnh, Bắc Từ Liêm, Hà Nội"}],"title_quill_delta":"{\"ops\":[{\"insert\":{\"dynamicField\":{\"id\":\"hesivydbbhoybwyk\",\"value\":\"Họ tên\",\"key\":\"user.fullname\"}}},{\"insert\":\" Ba \\n\"}]}","title_style":{"color":"rgba(255,255,255,1)"},"message_quill_deltas":["{\"ops\":[{\"insert\":\"Đặt trước Note 20 thành công\\n\"}]}"],"message_style":{"color":"rgba(216,207,207,1)"},"url":"https://subiz.com.vn","new_tab":true,"background_url":"https://public-gcs.subiz-cdn.com/widget_assets/notification_background/Frame%20129.png","subtext_style":{},"avatar_style":{"border_radius":"50%"},"position":"bottom-left","interval_sec":60000},"conversion_notification":{"all_agents":true},"template_title":"Đặt hàng trước","thumbnail_url":"https://file-subiz.com/fiqzpohaoyckhgxylulxcpqzpnooosdhodmkjlixs.jpg"}'
package/webpack.dev.js CHANGED
@@ -7,6 +7,7 @@ module.exports = {
7
7
  inject: './inject.js',
8
8
  preview: './preview.js',
9
9
  library: './library.js',
10
+ screenshoot: './screenshoot.js',
10
11
  },
11
12
  output: {publicPath: '/'},
12
13
  devServer: {port: 8082, host: '0.0.0.0', hot: false, liveReload: false},
@@ -16,6 +17,12 @@ module.exports = {
16
17
  new HtmlWebpackPlugin({filename: './preview.html', template: './preview.html', chunks: ['preview']}),
17
18
  new HtmlWebpackPlugin({filename: './inject.html', template: './inject.html', inject: 'body', chunks: ['inject']}),
18
19
  new HtmlWebpackPlugin({filename: './library.html', template: './index.html', inject: 'body', chunks: ['library']}),
20
+ new HtmlWebpackPlugin({
21
+ filename: './screenshoot.html',
22
+ template: './screenshoot.html',
23
+ inject: 'body',
24
+ chunks: ['screenshoot'],
25
+ }),
19
26
  ],
20
27
  module: {
21
28
  rules: [
package/webpack.prod.js CHANGED
@@ -2,11 +2,15 @@ var HtmlWebpackPlugin = require('html-webpack-plugin')
2
2
  let webpackconfig = require('./webpack.dev.js')
3
3
  var fs = require('fs')
4
4
 
5
-
6
5
  // webpackconfig.output.publicPath = 'https://public-gcs.subiz-cdn.com/widget-v4/public/'
7
6
  webpackconfig.output.publicPath = 'https://vcdn.subiz-cdn.com/widget-v4/public/'
8
7
 
9
- webpackconfig.entry = {app: './app.js', preview: './preview.js', library: './library.js'}
8
+ webpackconfig.entry = {
9
+ app: './app.js',
10
+ preview: './preview.js',
11
+ library: './library.js',
12
+ screenshoot: './screenshoot.js',
13
+ }
10
14
 
11
15
  const HASH = Date.now().toString(16)
12
16
  // create hash
@@ -29,6 +33,12 @@ webpackconfig.plugins = [
29
33
  inject: 'body',
30
34
  chunks: ['app'],
31
35
  }),
36
+ new HtmlWebpackPlugin({
37
+ filename: 'screenshoot.html',
38
+ template: './screenshoot.html',
39
+ inject: 'body',
40
+ chunks: ['screenshoot'],
41
+ }),
32
42
  new HtmlWebpackPlugin({
33
43
  filename: HASH + '.preview.html',
34
44
  template: './preview.html',
@@ -0,0 +1,20 @@
1
+ var HtmlWebpackPlugin = require('html-webpack-plugin')
2
+ let webpackconfig = require('./webpack.dev.js')
3
+ var fs = require('fs')
4
+
5
+ webpackconfig.output.publicPath = './'
6
+
7
+ webpackconfig.entry = {screenshoot: './screenshoot.js'}
8
+
9
+ webpackconfig.optimization.minimize = false
10
+ webpackconfig.mode = 'production'
11
+ webpackconfig.plugins = [
12
+ new HtmlWebpackPlugin({
13
+ filename: 'screenshoot.html',
14
+ template: './screenshoot.html',
15
+ inject: 'body',
16
+ chunks: ['screenshoot'],
17
+ }),
18
+ ]
19
+
20
+ module.exports = webpackconfig