@subiz/widget-v4 4.0.92 → 4.0.94
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/less/chatbox.less +8 -0
- package/assets/less/message.less +8 -3
- package/assets/less/order.less +10 -0
- package/compiled_src/bot.js +0 -11
- package/compiled_src/call/call.js +0 -61
- package/compiled_src/call/css.js +0 -2
- package/compiled_src/chatbox/AgentsAvatar.js +0 -16
- package/compiled_src/chatbox/AudioAttachments.js +0 -14
- package/compiled_src/chatbox/ButtonAttachments.js +1 -14
- package/compiled_src/chatbox/Buttons.js +0 -13
- package/compiled_src/chatbox/ChatButton.js +1 -78
- package/compiled_src/chatbox/DropdownSelect.js +3 -44
- package/compiled_src/chatbox/Emoji.js +0 -7
- package/compiled_src/chatbox/Event.js +0 -59
- package/compiled_src/chatbox/Events.js +4 -44
- package/compiled_src/chatbox/FileAttachments.js +0 -14
- package/compiled_src/chatbox/FormAttachment.js +1 -52
- package/compiled_src/chatbox/FormAttachments.js +0 -14
- package/compiled_src/chatbox/FormSubmitAttachments.js +0 -11
- package/compiled_src/chatbox/GenericTemplateAttachments.js +1 -20
- package/compiled_src/chatbox/Header.js +1 -46
- package/compiled_src/chatbox/ImageAttachments.js +0 -16
- package/compiled_src/chatbox/InfoMessage.js +0 -13
- package/compiled_src/chatbox/ListField.js +0 -16
- package/compiled_src/chatbox/MessageInput.js +1 -47
- package/compiled_src/chatbox/Order.js +0 -35
- package/compiled_src/chatbox/OrderAttachments.js +98 -39
- package/compiled_src/chatbox/PoweredBy.js +0 -7
- package/compiled_src/chatbox/ProductAttachments.js +0 -19
- package/compiled_src/chatbox/QuickReplies.js +0 -18
- package/compiled_src/chatbox/Rating.js +0 -37
- package/compiled_src/chatbox/ShadowDomRoot.js +0 -9
- package/compiled_src/chatbox/TextMessage.js +0 -64
- package/compiled_src/chatbox/Typing.js +0 -15
- package/compiled_src/chatbox/VideoAttachments.js +0 -14
- package/compiled_src/chatbox/Widget.js +6 -167
- package/compiled_src/chatbox/css.js +0 -2
- package/compiled_src/chatbox/dragscroll.js +1 -5
- package/compiled_src/chatbox/main.js +1 -40
- package/compiled_src/chatbox/releaseAnimation.js +0 -11
- package/compiled_src/chatbox/spinner.js +0 -10
- package/compiled_src/chatbox/time.js +0 -22
- package/compiled_src/chatbox/touchscroll.js +0 -7
- package/compiled_src/common.js +0 -22
- package/compiled_src/contact/contact.js +2 -52
- package/compiled_src/contact/css.js +0 -2
- package/compiled_src/lib.js +19 -46
- package/compiled_src/notif/css.js +0 -2
- package/compiled_src/notif/notif.js +0 -63
- package/compiled_src/order/address_picker.js +4 -38
- package/compiled_src/order/icon.js +0 -16
- package/compiled_src/order/index.js +1 -34
- package/compiled_src/order/order.js +2 -156
- package/compiled_src/plugin.js +1 -77
- package/compiled_src/popup/countdown.js +2 -33
- package/compiled_src/popup/css.js +0 -2
- package/compiled_src/popup/popup.js +2 -165
- package/compiled_src/popup/tick.core.commonjs.js +72 -222
- package/compiled_src/popup/tick.view.flip.commonjs.js +23 -31
- package/compiled_src/store/api.js +99 -65
- package/compiled_src/store/api_fake.js +3 -39
- package/compiled_src/store/realtime_fake.js +0 -6
- package/compiled_src/store/store.js +46 -249
- package/compiled_src/util/campaign.js +0 -13
- package/compiled_src/util/common.js +15 -185
- package/compiled_src/util/common.test.js +0 -4
- package/compiled_src/util/extractor.js +1 -21
- package/compiled_src/util/extractor.test.js +0 -3
- package/compiled_src/util/gate.js +0 -7
- package/compiled_src/util/gate.test.js +1 -2
- package/compiled_src/util/index.js +3 -7
- package/compiled_src/util/mutex.js +31 -0
- package/compiled_src/util/op.js +1 -14
- package/compiled_src/util/order.js +118 -0
- package/compiled_src/util/pubsub.js +0 -6
- package/compiled_src/util/pubsub.test.js +0 -2
- package/package.json +12 -13
- package/src/chatbox/OrderAttachments.js +111 -18
- package/src/lib.js +24 -2
- package/src/store/api.js +110 -21
- package/src/store/api_fake.js +5 -6
- package/src/store/store.js +47 -17
- package/src/util/index.js +4 -0
- package/src/util/mutex.js +27 -0
- package/src/util/order.js +120 -0
- package/dist/132.js +0 -7092
- package/dist/178.js +0 -406
- package/dist/18364d15f37.132.js +0 -1
- package/dist/18364d15f37.178.js +0 -1
- package/dist/18364d15f37.213.js +0 -1
- package/dist/18364d15f37.335.js +0 -1
- package/dist/18364d15f37.362.js +0 -1
- package/dist/18364d15f37.441.js +0 -1
- package/dist/18364d15f37.605.js +0 -1
- package/dist/18364d15f37.678.js +0 -1
- package/dist/18364d15f37.782.js +0 -1
- package/dist/18364d15f37.app.js +0 -1
- package/dist/18364d15f37.index.html +0 -26
- package/dist/18364d15f37.library.html +0 -26
- package/dist/18364d15f37.library.js +0 -1
- package/dist/18364d15f37.preview.html +0 -759
- package/dist/18364d15f37.preview.js +0 -1
- package/dist/18364d15f37.screenshoot.js +0 -1
- package/dist/213.js +0 -3215
- package/dist/335.js +0 -411
- package/dist/362.js +0 -107
- package/dist/441.js +0 -2834
- package/dist/605.js +0 -328
- package/dist/678.js +0 -107
- package/dist/782.js +0 -107
- package/dist/HASH +0 -1
- package/dist/assets/img/Facebook.64607ec.png +0 -0
- package/dist/assets/img/Zalo.6845707.png +0 -0
- package/dist/assets/img/award1a.1a58e10.png +0 -0
- package/dist/assets/img/award3a.3b74423.png +0 -0
- package/dist/assets/img/award4a.ed6ccd4.png +0 -0
- package/dist/assets/img/award5.39eb7ae.png +0 -0
- package/dist/assets/img/bubble_default.7d5e4ab.svg +0 -20
- package/dist/assets/img/caret.998eb8f.svg +0 -1
- package/dist/assets/img/convos_empty.2353007.svg +0 -72
- package/dist/assets/img/default.06e6ee0.jpg +0 -0
- package/dist/assets/img/default_avatar.5b74dc1.png +0 -0
- package/dist/assets/img/done_gray.d7e8203.svg +0 -4
- package/dist/assets/img/done_green.b817fd4.svg +0 -4
- package/dist/assets/img/emoji/messenger/sub_23.529_58.824.d5faf14.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_23.529_60.784.1420241.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_25.490_0.000.1e6b2c0.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_25.490_45.098.3dfbc08.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_25.490_5.882.4b49e94.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_27.451_72.549.7114f58.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_27.451_84.314.231e2b7.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_27.451_96.078.ddbb008.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_29.412_5.882.61f3359.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_100.000.6df72bc.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_45.098.3d7a7ad.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_47.059.0f4d6e2.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_54.902.65724c1.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_64.706.9da3cba.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_72.549.edca5cf.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_78.431.f910f2a.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_58.824_88.235.def4e71.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_60.784_11.765.49c03d0.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_60.784_27.451.46b54e5.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_60.784_29.412.e36d284.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_60.784_3.922.bb191b0.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_60.784_35.294.af7b927.png +0 -0
- package/dist/assets/img/emoji/messenger/sub_60.784_7.843.98f2a99.png +0 -0
- package/dist/assets/img/empty.29bed2d.svg +0 -23
- package/dist/assets/img/empty_1.0b98af0.svg +0 -11
- package/dist/assets/img/examplte_logo.f86535f.svg +0 -1
- package/dist/assets/img/external-link.90577cc.svg +0 -1
- package/dist/assets/img/fb_inverse_circle.36c2cfc.png +0 -0
- package/dist/assets/img/ghn.070f8e3.svg +0 -17
- package/dist/assets/img/ghtk.326eac1.svg +0 -18
- package/dist/assets/img/image_default.be0698b.png +0 -0
- package/dist/assets/img/info.ebce7ea.svg +0 -1
- package/dist/assets/img/loader.37000a7.svg +0 -1
- package/dist/assets/img/loading_static.8f403ae.svg +0 -10
- package/dist/assets/img/main-service1.d536cc2.png +0 -0
- package/dist/assets/img/main-service2.9b99549.png +0 -0
- package/dist/assets/img/not_found_search.2ddb8d1.png +0 -0
- package/dist/assets/img/package.8d37d0f.svg +0 -5
- package/dist/assets/img/package_fade.763c001.svg +0 -1
- package/dist/assets/img/rating--average.1ea492c.svg +0 -12
- package/dist/assets/img/rating--great.e3d712e.svg +0 -16
- package/dist/assets/img/rating--poor.2938a25.svg +0 -12
- package/dist/assets/img/search.f9705ff.svg +0 -1
- package/dist/assets/img/send.6db52a9.svg +0 -3
- package/dist/assets/img/shop.f7dc7d8.svg +0 -1
- package/dist/assets/img/shop_faded.df7845a.svg +0 -1
- package/dist/assets/img/subiz-mono.877e9f5.svg +0 -3
- package/dist/assets/img/x.26fdfa3.svg +0 -5
- package/dist/malicious-app.js +0 -13
- package/dist/screenshoot.html +0 -7
- package/dist/screenshoot.js +0 -5953
|
@@ -4,99 +4,69 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.default = void 0;
|
|
7
|
-
|
|
8
7
|
var _index = _interopRequireDefault(require("../util/index.js"));
|
|
9
|
-
|
|
10
8
|
var _storage = _interopRequireDefault(require("@subiz/storage"));
|
|
11
|
-
|
|
12
9
|
var _api = _interopRequireDefault(require("./api.js"));
|
|
13
|
-
|
|
14
10
|
var _api_fake = _interopRequireDefault(require("./api_fake.js"));
|
|
15
|
-
|
|
16
11
|
var _realtime_fake = _interopRequireDefault(require("./realtime_fake.js"));
|
|
17
|
-
|
|
18
12
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
19
|
-
|
|
20
13
|
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
|
|
21
|
-
|
|
22
14
|
var flow = require('@subiz/flow');
|
|
23
|
-
|
|
24
15
|
var Realtime = require('@subiz/wsclient/index.js');
|
|
25
|
-
|
|
26
16
|
var cookie = require('cookie_js');
|
|
27
|
-
|
|
28
17
|
cookie.defaults.path = '/';
|
|
29
18
|
cookie.expiresMultiplier = 60 * 60 * 24;
|
|
30
19
|
cookie.defaults.expires = 3650;
|
|
31
|
-
const MAX_CONVO = 20;
|
|
32
20
|
|
|
21
|
+
const MAX_CONVO = 20;
|
|
33
22
|
const page_loaded = _index.default.Date.now();
|
|
34
23
|
|
|
35
24
|
class Store {
|
|
36
|
-
constructor(ApiURL, FileURL, RealtimeURL, inmem, fakeapi
|
|
25
|
+
constructor(ApiURL, FileURL, RealtimeURL, inmem, fakeapi) {
|
|
37
26
|
_defineProperty(this, "inmem", false);
|
|
38
|
-
|
|
39
27
|
_defineProperty(this, "cookie", cookie);
|
|
40
|
-
|
|
41
28
|
_defineProperty(this, "_currentViewingProduct", {});
|
|
42
|
-
|
|
43
29
|
_defineProperty(this, "new_visitor", true);
|
|
44
|
-
|
|
45
30
|
_defineProperty(this, "matchUser", () => {
|
|
46
31
|
this._touchAcc();
|
|
47
|
-
|
|
48
32
|
return this.kv.match('user');
|
|
49
33
|
});
|
|
50
|
-
|
|
51
34
|
_defineProperty(this, "suggest_addresses", keyword => this.api.suggest_address(keyword));
|
|
52
|
-
|
|
53
35
|
_defineProperty(this, "matchAccount", () => this.cache.match('account'));
|
|
54
|
-
|
|
55
36
|
_defineProperty(this, "matchPaymentMethods", () => this.cache.match('payment_methods'));
|
|
56
|
-
|
|
57
37
|
_defineProperty(this, "matchUnread", () => {
|
|
58
38
|
let user = this.matchUser();
|
|
59
39
|
let allconvos = this.matchConvo('*');
|
|
60
40
|
let unreadcount = 0;
|
|
61
|
-
|
|
62
41
|
_index.default.map(allconvos, convo => {
|
|
63
42
|
if (!_index.default.isConvoSeen(convo, user.id)) unreadcount++;
|
|
64
43
|
});
|
|
65
|
-
|
|
66
44
|
return unreadcount;
|
|
67
45
|
});
|
|
68
|
-
|
|
69
46
|
_defineProperty(this, "matchPlugin", () => {
|
|
70
47
|
if (_index.default.size(this.forcePlugins) > 0) return _index.default.cloneDeep(this.forcePlugins);
|
|
71
48
|
return _index.default.cloneDeep(this.cache.match('plugin')) || {};
|
|
72
49
|
});
|
|
73
|
-
|
|
74
50
|
_defineProperty(this, "device", {});
|
|
75
|
-
|
|
76
51
|
_defineProperty(this, "browserVisibility", 'visible');
|
|
77
|
-
|
|
78
52
|
_defineProperty(this, "matchAgent", id => {
|
|
79
53
|
let agentM = this.cache.match('agent') || {};
|
|
80
54
|
if (id === '*') return agentM;
|
|
81
55
|
return agentM[id];
|
|
82
56
|
});
|
|
83
|
-
|
|
84
57
|
_defineProperty(this, "matchConvo", id => {
|
|
85
58
|
if (!id) return;
|
|
86
|
-
|
|
87
59
|
if (id === '*') {
|
|
88
60
|
this._touchAcc();
|
|
89
|
-
|
|
90
61
|
return _index.default.filter(this.cache.all(), (value, k) => k.startsWith('convo_'));
|
|
91
62
|
}
|
|
92
|
-
|
|
93
63
|
if (!this.isInsync(id)) this.fetchConvo(id);
|
|
94
64
|
return this.cache.match('convo_' + id);
|
|
95
65
|
});
|
|
96
|
-
|
|
97
66
|
_defineProperty(this, "fetchConvo", async cid => {
|
|
98
67
|
await this.readyGate.entry();
|
|
99
68
|
await this.reconnectGate.entry(undefined, true);
|
|
69
|
+
|
|
100
70
|
if (this.isInsync(cid)) return this.reconnectGate.open();
|
|
101
71
|
this.markSync(cid);
|
|
102
72
|
let {
|
|
@@ -106,18 +76,12 @@ class Store {
|
|
|
106
76
|
if (convo && !error) this._setConvo(convo);
|
|
107
77
|
return this.reconnectGate.open();
|
|
108
78
|
});
|
|
109
|
-
|
|
110
79
|
_defineProperty(this, "list_provinces", () => this.api.list_provinces());
|
|
111
|
-
|
|
112
80
|
_defineProperty(this, "list_districts", p => this.api.list_districts(p));
|
|
113
|
-
|
|
114
81
|
_defineProperty(this, "list_wards", p => this.api.list_wards(p));
|
|
115
|
-
|
|
116
82
|
_defineProperty(this, "list_provices", void 0);
|
|
117
|
-
|
|
118
83
|
_defineProperty(this, "listEvents", id => {
|
|
119
84
|
if (!id || id === '*' || typeof id !== 'string') return;
|
|
120
|
-
|
|
121
85
|
if (!this.isInsync('events' + id)) {
|
|
122
86
|
setTimeout(async () => {
|
|
123
87
|
await this.readyGate.entry();
|
|
@@ -129,10 +93,8 @@ class Store {
|
|
|
129
93
|
return this.reconnectGate.open();
|
|
130
94
|
}, 10);
|
|
131
95
|
}
|
|
132
|
-
|
|
133
96
|
return this.chain.listM(id);
|
|
134
97
|
});
|
|
135
|
-
|
|
136
98
|
_defineProperty(this, "fetchMoreEvents", async convoid => {
|
|
137
99
|
let {
|
|
138
100
|
error
|
|
@@ -142,76 +104,52 @@ class Store {
|
|
|
142
104
|
error
|
|
143
105
|
};
|
|
144
106
|
});
|
|
145
|
-
|
|
146
107
|
_defineProperty(this, "matchLocation", () => this.cache.match('location') || {});
|
|
147
|
-
|
|
148
108
|
_defineProperty(this, "matchBot", () => this.cache.match('bot') || {});
|
|
149
|
-
|
|
150
109
|
_defineProperty(this, "readyGate", new _index.default.Gate());
|
|
151
|
-
|
|
152
110
|
_defineProperty(this, "convoGate", new _index.default.Gate(true));
|
|
153
|
-
|
|
154
111
|
_defineProperty(this, "reconnectGate", new _index.default.Gate(true));
|
|
155
|
-
|
|
156
112
|
_defineProperty(this, "matchLastview", () => this.kv.match('lastview') || {});
|
|
157
|
-
|
|
158
113
|
_defineProperty(this, "matchIsOpen", () => !!this.kv.match('isopen'));
|
|
159
|
-
|
|
160
114
|
_defineProperty(this, "matchHasManuallyClosed", () => !!this.kv.match('hasManuallyClosed'));
|
|
161
|
-
|
|
162
115
|
_defineProperty(this, "matchClosePreviewAt", () => this.kv.match('close_preview_at') || 0);
|
|
163
|
-
|
|
164
116
|
_defineProperty(this, "sendPresence", _index.default.throttle(async () => {
|
|
165
117
|
await this.readyGate.entry();
|
|
166
118
|
if (!_index.default.get(this.kv.match('user'), 'id')) return;
|
|
167
119
|
if (_index.default.isUserBanned(this.kv.match('user'))) return;
|
|
168
120
|
return this.api.sendPresence(this.device, this.browserVisibility === 'visible' && document.hasFocus(), this._currentViewingProduct.id, this._currentViewingProduct.source_id, this._currentViewingProduct.sku);
|
|
169
|
-
}, 1000
|
|
170
|
-
|
|
121
|
+
}, 1000,
|
|
122
|
+
{
|
|
123
|
+
leading: false
|
|
124
|
+
}));
|
|
171
125
|
_defineProperty(this, "now", () => _index.default.Date.now() + this.timeDiff);
|
|
172
|
-
|
|
173
126
|
_defineProperty(this, "seenQueue", []);
|
|
174
|
-
|
|
175
127
|
_defineProperty(this, "matchTrafficSource", () => this.kv.match('traffic_source'));
|
|
176
|
-
|
|
177
128
|
_defineProperty(this, "_typing", _index.default.throttle(convoid => this.api.sendTyping(convoid), 3000, {
|
|
178
129
|
trailing: false
|
|
179
130
|
}));
|
|
180
|
-
|
|
181
131
|
_defineProperty(this, "onConvoEvent", (o, cb) => this.pubsub.on2(o, 'events', cb));
|
|
182
|
-
|
|
183
132
|
_defineProperty(this, "seenConvo", id => {
|
|
184
133
|
if (!id || id === 'create') return;
|
|
185
134
|
this.seenQueue.push(id);
|
|
186
135
|
});
|
|
187
|
-
|
|
188
136
|
_defineProperty(this, "onUpdate", (o, cb) => this.pubsub.on2(o, 'account', cb));
|
|
189
|
-
|
|
190
137
|
_defineProperty(this, "onResetCSS", (o, cb) => this.pubsub.on2(o, 'resetCSS', cb));
|
|
191
|
-
|
|
192
138
|
_defineProperty(this, "onHighlight", (o, cb) => this.pubsub.on2(o, 'highlight', cb));
|
|
193
|
-
|
|
194
139
|
_defineProperty(this, "setHasManuallyClosed", () => this.kv.put('hasManuallyClosed', true));
|
|
195
|
-
|
|
196
140
|
_defineProperty(this, "setIsOpen", isopen => {
|
|
197
141
|
let lastisopen = this.kv.match('isopen');
|
|
198
142
|
this.kv.put('isopen', isopen);
|
|
199
|
-
|
|
200
143
|
if (!lastisopen && isopen) {
|
|
201
144
|
sendEventToThirdParty('SUBIZ Chat', 'Opened', 'Subiz Windows');
|
|
202
145
|
}
|
|
203
146
|
});
|
|
204
|
-
|
|
205
147
|
_defineProperty(this, "closePreview", () => this.kv.put('close_preview_at', new _index.default.Date().getTime()));
|
|
206
|
-
|
|
207
148
|
_defineProperty(this, "setLastview", (view, opts) => this.kv.put('lastview', {
|
|
208
149
|
view,
|
|
209
150
|
opts
|
|
210
151
|
}));
|
|
211
|
-
|
|
212
152
|
_defineProperty(this, "timeDiff", 0);
|
|
213
|
-
|
|
214
|
-
this.agent_token = agenttoken;
|
|
215
153
|
this.g_sync = {};
|
|
216
154
|
this.forceDevice = null;
|
|
217
155
|
this.forcePlugins = {};
|
|
@@ -221,22 +159,23 @@ class Store {
|
|
|
221
159
|
this.fake = fakeapi;
|
|
222
160
|
this.FileURL = FileURL;
|
|
223
161
|
if (this.fake) this.api = new _api_fake.default(ApiURL, FileURL);else this.api = new _api.default(ApiURL, FileURL);
|
|
224
|
-
|
|
225
162
|
if (inmem) {
|
|
226
163
|
this.inmem = inmem;
|
|
227
164
|
this.cookie = inmemCookie;
|
|
228
165
|
}
|
|
229
|
-
|
|
230
166
|
this.pubsub = new _index.default.Pubsub();
|
|
231
167
|
this.kv = new _storage.default.kv(new _storage.default.lsdb('sbz2020', this.inmem), 'kv');
|
|
232
168
|
this.cache = new _storage.default.kv(new _storage.default.lsdb('sbz2020', true), 'kv');
|
|
233
169
|
this.chain = new _storage.default.chain(new _storage.default.lsdb('cbz2020', true), 'ch');
|
|
234
170
|
this.getLocaleContent = this.api.getLocaleContent;
|
|
171
|
+
|
|
235
172
|
this.g_haveSentSeenM = {};
|
|
236
173
|
window.addEventListener('blur', () => this.sendPresence());
|
|
237
174
|
window.addEventListener('focus', () => this.sendPresence());
|
|
175
|
+
|
|
238
176
|
setInterval(() => this.browserVisibility === 'visible' && document.hasFocus() && this.sendPresence(), 20000);
|
|
239
177
|
setInterval(() => (this.browserVisibility !== 'visible' || document.hasFocus()) && this.sendPresence(), 60000);
|
|
178
|
+
|
|
240
179
|
onVisibilityChange(val => {
|
|
241
180
|
this.browserVisibility = val;
|
|
242
181
|
this.sendPresence();
|
|
@@ -251,8 +190,8 @@ class Store {
|
|
|
251
190
|
if (!dev.ga_tracking_ids || !dev.ga_client_id) return;
|
|
252
191
|
clearInterval(_gaInterval);
|
|
253
192
|
this.device = dev;
|
|
254
|
-
let ga_client_id = dev.ga_client_id;
|
|
255
193
|
|
|
194
|
+
let ga_client_id = dev.ga_client_id;
|
|
256
195
|
if (ga_client_id !== _index.default.getUserAttr(user, 'ga_client_id', 'text')) {
|
|
257
196
|
this.setUser({
|
|
258
197
|
attributes: [{
|
|
@@ -264,13 +203,11 @@ class Store {
|
|
|
264
203
|
}
|
|
265
204
|
}, 2000);
|
|
266
205
|
}
|
|
267
|
-
|
|
268
206
|
linkProduct(p) {
|
|
269
207
|
if (!p) {
|
|
270
208
|
this._currentViewingProduct = {};
|
|
271
209
|
return;
|
|
272
210
|
}
|
|
273
|
-
|
|
274
211
|
if (p.id) this._currentViewingProduct.id = (p.id + '').trim();
|
|
275
212
|
if (p.source_id) this._currentViewingProduct.source_id = (p.source_id + '').trim();
|
|
276
213
|
if (p.sku) this._currentViewingProduct.sku = (p.sku + '').trim();
|
|
@@ -279,36 +216,29 @@ class Store {
|
|
|
279
216
|
getLinkedProduct() {
|
|
280
217
|
return _index.default.cloneDeep(this._currentViewingProduct);
|
|
281
218
|
}
|
|
282
|
-
|
|
283
219
|
isInsync(key) {
|
|
284
220
|
return _index.default.Date.now() - (this.g_sync[key] || 0) < 600000;
|
|
285
221
|
}
|
|
286
|
-
|
|
287
222
|
async fetchShippingAddresses() {
|
|
288
223
|
let out = await this.api.fetchShippingAddresses();
|
|
289
224
|
if (out.error) return null;
|
|
290
225
|
this.cache.put('shipping_address', out.body.shipping_addresses);
|
|
291
226
|
}
|
|
292
|
-
|
|
293
227
|
matchShippingAddresses() {
|
|
294
228
|
return this.cache.match('shipping_address');
|
|
295
229
|
}
|
|
296
|
-
|
|
297
230
|
updateOrder(order) {
|
|
298
231
|
return this.api.updateOrder(order);
|
|
299
232
|
}
|
|
300
|
-
|
|
301
233
|
createShippingAddress(addr) {
|
|
302
234
|
return this.api.createShippingAddress(addr);
|
|
303
235
|
}
|
|
304
|
-
|
|
305
236
|
async overrideAcc(acc) {
|
|
306
237
|
this.forceAcc = _index.default.cloneDeep(acc);
|
|
307
238
|
await this.readyGate.entry();
|
|
308
239
|
this.disconnect('account');
|
|
309
240
|
this.reconnect();
|
|
310
241
|
}
|
|
311
|
-
|
|
312
242
|
async overrideChatbox(chatbox) {
|
|
313
243
|
this.forceChatbox = chatbox;
|
|
314
244
|
await this.readyGate.entry();
|
|
@@ -316,7 +246,6 @@ class Store {
|
|
|
316
246
|
await this.reconnect();
|
|
317
247
|
setTimeout(this.pubsub.publish('resetCSS'), 10);
|
|
318
248
|
}
|
|
319
|
-
|
|
320
249
|
getDeviceInfo() {
|
|
321
250
|
let device = {
|
|
322
251
|
user_agent: window.navigator.userAgent,
|
|
@@ -335,28 +264,22 @@ class Store {
|
|
|
335
264
|
if (ga_tracking_ids.length > 0) device.ga_tracking_ids = ga_tracking_ids;
|
|
336
265
|
return device;
|
|
337
266
|
}
|
|
338
|
-
|
|
339
267
|
highlight(pluginid, ref) {
|
|
340
268
|
this.pubsub.publish('highlight', pluginid, ref);
|
|
341
269
|
}
|
|
342
|
-
|
|
343
270
|
overrideDeviceType(type) {
|
|
344
271
|
this.forceDevice = type;
|
|
345
272
|
this.pubsub.publish('account');
|
|
346
273
|
}
|
|
347
|
-
|
|
348
274
|
isMobile() {
|
|
349
275
|
return this.forceDevice === 'mobile' || mobileCheck;
|
|
350
276
|
}
|
|
351
|
-
|
|
352
277
|
isTablet() {
|
|
353
278
|
return this.forceDevice === 'tablet' || tabletCheck;
|
|
354
279
|
}
|
|
355
|
-
|
|
356
280
|
isDesktop() {
|
|
357
281
|
return this.forceDevice === 'desktop' || !this.isMobile() && !this.isTable();
|
|
358
282
|
}
|
|
359
|
-
|
|
360
283
|
disconnect(key) {
|
|
361
284
|
this.g_sync[key] = 0;
|
|
362
285
|
}
|
|
@@ -364,24 +287,19 @@ class Store {
|
|
|
364
287
|
pageLoaded() {
|
|
365
288
|
return page_loaded;
|
|
366
289
|
}
|
|
367
|
-
|
|
368
290
|
overridePlugin(plugins) {
|
|
369
291
|
if (!Array.isArray(plugins)) throw 'plugins must be be an array';
|
|
370
292
|
let pluginM = {};
|
|
371
|
-
|
|
372
293
|
_index.default.map(plugins, function (plugin) {
|
|
373
294
|
pluginM[plugin.id] = plugin;
|
|
374
295
|
});
|
|
375
|
-
|
|
376
296
|
this.forcePlugins = pluginM;
|
|
377
297
|
this.pubsub.publish('account');
|
|
378
298
|
this.pubsub.publish('resetCSS');
|
|
379
299
|
}
|
|
380
|
-
|
|
381
300
|
markSync(key) {
|
|
382
301
|
this.g_sync[key] = _index.default.Date.now();
|
|
383
302
|
}
|
|
384
|
-
|
|
385
303
|
async _touchAcc() {
|
|
386
304
|
if (this.isInsync('account')) return;
|
|
387
305
|
await this.readyGate.entry();
|
|
@@ -395,28 +313,23 @@ class Store {
|
|
|
395
313
|
accid: accid
|
|
396
314
|
});
|
|
397
315
|
this.g_sync = {};
|
|
398
|
-
|
|
399
316
|
if (!mask) {
|
|
400
317
|
try {
|
|
401
318
|
mask = this.cookie.get('__sbmask', '');
|
|
402
319
|
} catch (e) {}
|
|
403
320
|
}
|
|
404
|
-
|
|
405
321
|
let localstorageMask = this.kv.match('mask');
|
|
406
322
|
if (!mask && localstorageMask) mask = localstorageMask;
|
|
323
|
+
|
|
407
324
|
if (mask && localstorageMask && mask !== localstorageMask) this.clearBrowserData();
|
|
408
|
-
if (this.agent_token) mask = await this.api.createAgentUser(this.agent_token);
|
|
409
325
|
var userId = '';
|
|
410
|
-
|
|
411
326
|
if (mask) {
|
|
412
327
|
let parts = mask.split('@');
|
|
413
|
-
|
|
414
328
|
if (parts[0] != accid) {
|
|
415
329
|
mask = '';
|
|
416
330
|
this.clearBrowserData();
|
|
417
331
|
} else userId = parts[1];
|
|
418
332
|
}
|
|
419
|
-
|
|
420
333
|
if (!mask) {
|
|
421
334
|
let user = await this.api.createUser(accid);
|
|
422
335
|
this.new_visitor = true;
|
|
@@ -445,55 +358,72 @@ class Store {
|
|
|
445
358
|
this.reconnectWs(accid, userId);
|
|
446
359
|
return mask;
|
|
447
360
|
}
|
|
361
|
+
async login(accid, user_id, tokenGenerator) {
|
|
362
|
+
let user = await this.api.setTokenGenerator(accid, user_id, tokenGenerator);
|
|
363
|
+
if (user.error) return user;
|
|
364
|
+
this.clearBrowserData();
|
|
365
|
+
this.readyGate.close();
|
|
366
|
+
accid = (accid || '').trim();
|
|
367
|
+
this.g_sync = {};
|
|
368
|
+
this.new_visitor = false;
|
|
448
369
|
|
|
370
|
+
if (this.realtime) this.realtime.stop();
|
|
371
|
+
if (this.fake) this.realtime = new _realtime_fake.default();else this.realtime = new Realtime(this.RealtimeURL, {
|
|
372
|
+
getAccessToken: () => this.api.token_generator()
|
|
373
|
+
});
|
|
374
|
+
this.realtime.onEvent(this.onWs.bind(this));
|
|
375
|
+
this.realtime.onInterrupted(() => this.reconnectWs(accid, user.id));
|
|
376
|
+
this.seenLoop();
|
|
377
|
+
await this.reconnect();
|
|
378
|
+
this.readyGate.open();
|
|
379
|
+
this.reconnectWs(accid, user.id);
|
|
380
|
+
return user;
|
|
381
|
+
}
|
|
382
|
+
logout(user_id) {
|
|
383
|
+
this.api.setTokenGenerator(undefined, undefined, undefined);
|
|
384
|
+
}
|
|
449
385
|
seenLoop() {
|
|
450
386
|
this.seenQueue = [];
|
|
451
387
|
clearInterval(this._seenInterval);
|
|
452
388
|
this._seenInterval = setInterval(() => {
|
|
453
389
|
this.seenQueue = [...new Set(this.seenQueue)];
|
|
454
390
|
let user = this.kv.match('user') || {};
|
|
455
|
-
|
|
456
391
|
_index.default.map(this.seenQueue, id => {
|
|
457
392
|
var events = this.listEvents(id);
|
|
458
393
|
if (!events) return;
|
|
459
394
|
if (_index.default.size(events) === 0) return;
|
|
395
|
+
|
|
460
396
|
events = _index.default.filter(events, ev => ev.type === 'message_sent');
|
|
461
397
|
var lastmsgsent = events[_index.default.size(events) - 1];
|
|
462
398
|
if (!lastmsgsent) return;
|
|
463
399
|
if (this.g_haveSentSeenM[lastmsgsent.id]) return;
|
|
400
|
+
|
|
464
401
|
if (lastmsgsent.id === _index.default.getMsgField(lastmsgsent, 'idempotency')) return;
|
|
402
|
+
|
|
465
403
|
this.api.markAsSeen(id, lastmsgsent.id);
|
|
466
404
|
let convo = this.cache.match('convo_' + id) || {};
|
|
467
|
-
|
|
468
405
|
let mem = _index.default.find(convo.members, m => m.id === user.id);
|
|
469
|
-
|
|
470
406
|
mem.seen_at = Date.now();
|
|
471
|
-
|
|
472
407
|
this._setConvo(convo);
|
|
473
|
-
|
|
474
408
|
this.g_haveSentSeenM[lastmsgsent.id] = true;
|
|
475
409
|
});
|
|
476
|
-
|
|
477
410
|
this.seenQueue = [];
|
|
478
411
|
}, 1000);
|
|
479
412
|
}
|
|
480
|
-
|
|
481
413
|
async reconnectWs(accid, userid) {
|
|
482
414
|
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}`]);
|
|
483
415
|
await this.readyGate.entry();
|
|
484
416
|
this.disconnect('account');
|
|
485
417
|
return this.reconnect();
|
|
486
418
|
}
|
|
487
|
-
|
|
488
419
|
async reconnect() {
|
|
489
420
|
if (this._die) return;
|
|
421
|
+
|
|
490
422
|
await this.reconnectGate.entry(undefined, true);
|
|
491
423
|
if (this.isInsync('account')) return this.reconnectGate.open();
|
|
492
424
|
this.markSync('account');
|
|
493
425
|
let outs = await Promise.all([this.api.getUser(), this.api.getAccountSetting(), this.api.getIsOnline()]);
|
|
494
|
-
|
|
495
426
|
let error = _index.default.find(outs, out => out.error);
|
|
496
|
-
|
|
497
427
|
if (error) return console.error(error);
|
|
498
428
|
let set = Object.assign(outs[1].body, outs[2].body);
|
|
499
429
|
set.user = outs[0].body;
|
|
@@ -501,31 +431,24 @@ class Store {
|
|
|
501
431
|
let convob = await this.api.listConversations();
|
|
502
432
|
error = convob.error;
|
|
503
433
|
let body = convob.body;
|
|
504
|
-
|
|
505
434
|
if (!error) {
|
|
506
435
|
let convos = _index.default.get(body, 'conversations', []);
|
|
507
|
-
|
|
508
436
|
_index.default.map(this.cache.all(), (value, k) => {
|
|
509
437
|
if (k.startsWith('convo_')) {
|
|
510
438
|
if (this.now() - _index.default.getMs(_index.default.get(value, 'actived')) > 1209600000) this.cache.del(k);
|
|
511
439
|
}
|
|
512
440
|
});
|
|
513
|
-
|
|
514
441
|
_index.default.map(convos, convo => this._setConvo(convo));
|
|
515
442
|
}
|
|
516
|
-
|
|
517
443
|
return this.reconnectGate.open();
|
|
518
444
|
}
|
|
519
445
|
|
|
520
446
|
async setUser(user) {
|
|
521
447
|
if (!user) return;
|
|
522
448
|
await this.readyGate.entry();
|
|
523
|
-
|
|
524
449
|
this._setUser(user);
|
|
525
|
-
|
|
526
450
|
return this.api.updateUser(user);
|
|
527
451
|
}
|
|
528
|
-
|
|
529
452
|
_setUser(user) {
|
|
530
453
|
user = _index.default.cloneDeep(user);
|
|
531
454
|
let olduser = this.kv.match('user') || {};
|
|
@@ -539,7 +462,6 @@ class Store {
|
|
|
539
462
|
return oldattr.key !== newattr.key;
|
|
540
463
|
});
|
|
541
464
|
});
|
|
542
|
-
|
|
543
465
|
olduser.attributes = olduser.attributes || [];
|
|
544
466
|
olduser.attributes = olduser.attributes.concat(user.attributes);
|
|
545
467
|
olduser.account_id = accid;
|
|
@@ -547,28 +469,22 @@ class Store {
|
|
|
547
469
|
this.kv.put('user', olduser);
|
|
548
470
|
this.pubsub.publish('account');
|
|
549
471
|
}
|
|
550
|
-
|
|
551
472
|
async setSetting(setting) {
|
|
552
473
|
if (!setting) return;
|
|
553
474
|
await this.readyGate.entry();
|
|
554
475
|
return this._setSetting(setting);
|
|
555
476
|
}
|
|
556
|
-
|
|
557
477
|
async _setSetting(setting) {
|
|
558
478
|
setting = _index.default.cloneDeep(setting) || {};
|
|
559
479
|
setting.account = Object.assign({}, setting.account, this.forceAcc);
|
|
560
|
-
|
|
561
480
|
if (!setting.account.logo_url) {
|
|
562
481
|
setting.account.logo_url = 'https://file-subiz.com/fiqpezhkmeyesdscyetk-default_logo.jpg';
|
|
563
482
|
}
|
|
564
|
-
|
|
565
483
|
if (setting.user) {
|
|
566
484
|
setting.user.account_id = setting.account.id;
|
|
567
485
|
delete setting.user.session;
|
|
568
|
-
|
|
569
486
|
this._setUser(setting.user);
|
|
570
487
|
}
|
|
571
|
-
|
|
572
488
|
if (setting.account) {
|
|
573
489
|
setting.account.is_online = setting.is_online;
|
|
574
490
|
setting.account.is_in_business_hour = setting.is_in_business_hour;
|
|
@@ -577,48 +493,36 @@ class Store {
|
|
|
577
493
|
}
|
|
578
494
|
|
|
579
495
|
let location = _index.default.get(setting, 'location', []);
|
|
580
|
-
|
|
581
496
|
this.cache.put('location', location);
|
|
582
497
|
|
|
583
498
|
let bots = _index.default.get(setting, 'bots', []);
|
|
584
|
-
|
|
585
499
|
let botM = {};
|
|
586
|
-
|
|
587
500
|
_index.default.map(bots, bot => {
|
|
588
501
|
botM[bot.id] = bot;
|
|
589
502
|
});
|
|
590
|
-
|
|
591
503
|
this.cache.put('bot', botM);
|
|
592
504
|
|
|
593
505
|
let plugins = _index.default.get(setting, 'plugins', []);
|
|
594
|
-
|
|
595
506
|
let pluginM = {};
|
|
596
|
-
|
|
597
507
|
_index.default.map(plugins, plugin => {
|
|
598
508
|
if (plugin.type === 'chatbox') {
|
|
599
509
|
plugin = _index.default.merge(plugin, this.forceChatbox);
|
|
600
510
|
}
|
|
601
|
-
|
|
602
511
|
pluginM[plugin.id] = plugin;
|
|
603
512
|
});
|
|
604
|
-
|
|
605
513
|
this.cache.put('plugin', pluginM);
|
|
606
514
|
|
|
607
515
|
var agents = _index.default.get(setting, 'agents', []);
|
|
608
|
-
|
|
609
516
|
if (_index.default.size(agents) > 0) {
|
|
610
517
|
let agentM = {};
|
|
611
518
|
this.api.setAgentId(agents[0].id);
|
|
612
|
-
|
|
613
519
|
_index.default.map(agents, agent => {
|
|
614
520
|
agentM[agent.id] = agent;
|
|
615
521
|
});
|
|
616
|
-
|
|
617
522
|
this.cache.put('agent', agentM);
|
|
618
523
|
}
|
|
619
524
|
|
|
620
525
|
let pms = _index.default.get(setting, 'payment_methods', []);
|
|
621
|
-
|
|
622
526
|
this.cache.put('payment_methods', pms);
|
|
623
527
|
this.pubsub.publish('account');
|
|
624
528
|
}
|
|
@@ -626,38 +530,26 @@ class Store {
|
|
|
626
530
|
async track() {
|
|
627
531
|
let user = this.kv.match('user') || {};
|
|
628
532
|
let out = await this.api.sendContentView(this.device, location.href, document.title, this._currentViewingProduct.id, this._currentViewingProduct.source_id, this._currentViewingProduct.sku);
|
|
629
|
-
|
|
630
533
|
let traffic_source = _index.default.get(out, 'body.by.device.source', '');
|
|
631
|
-
|
|
632
534
|
if (traffic_source) this.kv.put('traffic_source', traffic_source);
|
|
633
535
|
this.sendPresence();
|
|
634
536
|
}
|
|
635
|
-
|
|
636
537
|
async onWs(ev) {
|
|
637
538
|
if (!ev || !ev.type) return;
|
|
638
539
|
ev.created = _index.default.getMs(ev.created);
|
|
639
|
-
|
|
640
540
|
if (ev.type === 'user_info_updated') {
|
|
641
541
|
let user = _index.default.cloneDeep(this.kv.match('user'));
|
|
642
|
-
|
|
643
542
|
let attrs = _index.default.get(ev, 'data.user.attributes') || [];
|
|
644
|
-
|
|
645
543
|
_index.default.map(attrs, attr => _index.default.setUserAttr(user, attr));
|
|
646
|
-
|
|
647
544
|
this._setUser(user);
|
|
648
|
-
|
|
649
545
|
return;
|
|
650
546
|
}
|
|
651
547
|
|
|
652
548
|
let user = this.kv.match('user') || {};
|
|
653
|
-
|
|
654
549
|
let cid = _index.default.convoOfEv(ev);
|
|
655
|
-
|
|
656
550
|
let convo;
|
|
657
|
-
|
|
658
551
|
if (cid) {
|
|
659
552
|
convo = this.matchConvo(cid);
|
|
660
|
-
|
|
661
553
|
if (!convo || !convo.id) {
|
|
662
554
|
let {
|
|
663
555
|
body: apiconvo,
|
|
@@ -667,60 +559,45 @@ class Store {
|
|
|
667
559
|
convo = apiconvo;
|
|
668
560
|
}
|
|
669
561
|
}
|
|
670
|
-
|
|
671
562
|
if (!convo) return;
|
|
672
563
|
|
|
673
564
|
let channel = _index.default.get(ev, 'touchpoint.channel', '');
|
|
674
|
-
|
|
675
565
|
if (channel && channel != 'subiz') return;
|
|
676
566
|
this.pubsub.publish('events', ev);
|
|
677
567
|
|
|
678
568
|
if (ev.type === 'conversation_joined') {
|
|
679
569
|
let members = _index.default.get(ev, 'data.conversation.members', []);
|
|
680
|
-
|
|
681
570
|
let me = _index.default.find(members, m => m.id === this.kv.match('user').id);
|
|
682
|
-
|
|
683
571
|
if (me) {
|
|
684
572
|
await this.chain.reload(cid, (type, anchor, limit) => this.listmessageapi(type, anchor, limit));
|
|
685
573
|
this.markSync('events' + cid);
|
|
686
574
|
let {
|
|
687
575
|
body: apiconvo
|
|
688
576
|
} = await this.api.getConversation(cid);
|
|
689
|
-
|
|
690
577
|
if (apiconvo) {
|
|
691
578
|
convo = apiconvo;
|
|
692
|
-
|
|
693
579
|
this._setConvo(convo);
|
|
694
580
|
}
|
|
695
|
-
|
|
696
581
|
this.pubsub.publish('account');
|
|
697
582
|
}
|
|
698
583
|
}
|
|
699
|
-
|
|
700
584
|
if (ev.type === 'message_sent') {
|
|
701
585
|
if (_index.default.get(ev, 'by.id') !== user.id) {
|
|
702
586
|
this.api.markAsReceived(cid, ev.id);
|
|
703
587
|
}
|
|
704
588
|
}
|
|
705
|
-
|
|
706
589
|
if (_index.default.startsWith(ev.type, 'message_') || _index.default.startsWith(ev.type, 'conversation_')) {
|
|
707
590
|
this.restConvoEvent(ev);
|
|
708
|
-
|
|
709
591
|
if (ev.type === 'message_sent' && _index.default.get(ev, 'by.id') !== user.id) {
|
|
710
592
|
sendEventToThirdParty('SUBIZ Chat', 'Received', 'User');
|
|
711
593
|
}
|
|
712
|
-
|
|
713
594
|
return;
|
|
714
595
|
}
|
|
715
596
|
}
|
|
716
|
-
|
|
717
597
|
async restConvoEvent(ev) {
|
|
718
598
|
let user = this.kv.match('user');
|
|
719
|
-
|
|
720
599
|
let cid = _index.default.convoOfEv(ev);
|
|
721
|
-
|
|
722
600
|
let convo = this.cache.match('convo_' + cid) || {};
|
|
723
|
-
|
|
724
601
|
if (ev.type === 'conversation_state_updated') {
|
|
725
602
|
if (!_index.default.get(convo, 'id')) {
|
|
726
603
|
let {
|
|
@@ -729,68 +606,50 @@ class Store {
|
|
|
729
606
|
} = await this.api.getConversation(cid);
|
|
730
607
|
if (error) return;
|
|
731
608
|
}
|
|
732
|
-
|
|
733
609
|
convo = Object.assign(convo, _index.default.get(ev, 'data.conversation'));
|
|
734
610
|
}
|
|
735
|
-
|
|
736
611
|
if (ev.type === 'message_pong') {
|
|
737
612
|
var msgid = _index.default.get(ev, 'data.message.id');
|
|
738
|
-
|
|
739
613
|
var oldev = this.chain.match(cid, msgid);
|
|
740
614
|
if (!_index.default.get(oldev, 'data.message')) return;
|
|
741
|
-
|
|
742
615
|
var pongs = _index.default.get(oldev, 'data.message.pongs', []);
|
|
743
|
-
|
|
744
616
|
pongs = pongs.concat(_index.default.get(ev, 'data.message.pongs', []));
|
|
745
617
|
oldev.data.message.pongs = pongs;
|
|
746
|
-
|
|
747
618
|
_index.default.map(pongs, pong => {
|
|
748
619
|
if (pong.member_id == user.id && pong.type === 'seen') {
|
|
749
620
|
let mem = _index.default.find(convo.members, mem => mem.id === user.id);
|
|
750
|
-
|
|
751
621
|
if (mem) mem.seen_at = pong.created;
|
|
752
622
|
}
|
|
753
623
|
});
|
|
754
|
-
|
|
755
624
|
this.chain.put(cid, oldev.id, _index.default.getMs(oldev.created), oldev);
|
|
756
625
|
}
|
|
757
|
-
|
|
758
626
|
if (ev.type === 'message_sent') {
|
|
759
627
|
let idemkey = _index.default.getMsgField(ev, 'idempotency');
|
|
760
|
-
|
|
761
628
|
let found = _index.default.find(this.listEvents(cid), oldev => oldev.id === idemkey);
|
|
762
|
-
|
|
763
629
|
if (found) {
|
|
764
630
|
this.chain.del(cid, found.id);
|
|
765
631
|
ev.created = found.created;
|
|
766
632
|
}
|
|
767
|
-
|
|
768
633
|
convo.last_message_sent = ev;
|
|
769
634
|
}
|
|
770
635
|
|
|
771
636
|
if (ev.type !== 'message_pong' && ev.type !== 'conversation_typing') {
|
|
772
637
|
this.chain.put(cid, ev.id, _index.default.getMs(ev.created), ev);
|
|
773
638
|
}
|
|
774
|
-
|
|
775
639
|
this._setConvo(convo);
|
|
776
|
-
|
|
777
640
|
this.pubsub.publish('account');
|
|
778
641
|
}
|
|
779
|
-
|
|
780
642
|
handleFormSubmit(convoKey, ev) {
|
|
781
643
|
if (ev.type !== 'message_sent') return;
|
|
782
644
|
let formSubmits = [];
|
|
783
645
|
let attachments = _index.default.get(ev, 'data.message.attachments') || [];
|
|
784
|
-
|
|
785
646
|
_index.default.each(attachments, att => {
|
|
786
647
|
if (!att) return;
|
|
787
648
|
if (att.type !== 'form_submit') return;
|
|
788
649
|
formSubmits.push(att.form_submit);
|
|
789
650
|
});
|
|
790
|
-
|
|
791
651
|
_index.default.each(formSubmits, submit => {
|
|
792
652
|
let formev = _index.default.get(this.convoEventM, convoKey + '.' + submit.form_message_id);
|
|
793
|
-
|
|
794
653
|
if (!formev) return;
|
|
795
654
|
|
|
796
655
|
let forms = _index.default.filter(_index.default.get(formev, 'data.message.attachments'), att => {
|
|
@@ -798,10 +657,8 @@ class Store {
|
|
|
798
657
|
if (att.type !== 'form' && att.type !== 'ask_info_form') return false;
|
|
799
658
|
return true;
|
|
800
659
|
});
|
|
801
|
-
|
|
802
660
|
_index.default.each(forms, form => {
|
|
803
661
|
form = form.form;
|
|
804
|
-
|
|
805
662
|
_index.default.each(form.fields, formfield => {
|
|
806
663
|
_index.default.each(submit.fields, submitfield => {
|
|
807
664
|
if (formfield.name !== submitfield.name) return;
|
|
@@ -810,17 +667,13 @@ class Store {
|
|
|
810
667
|
});
|
|
811
668
|
});
|
|
812
669
|
});
|
|
813
|
-
|
|
814
670
|
if (_index.default.size(forms) > 0) this.pubsub.publish('state.convoEventM', this.convoEventM, convoKey);
|
|
815
671
|
});
|
|
816
672
|
}
|
|
817
|
-
|
|
818
673
|
typing(cid) {
|
|
819
674
|
if (!cid) return;
|
|
820
|
-
|
|
821
675
|
this._typing(cid);
|
|
822
676
|
}
|
|
823
|
-
|
|
824
677
|
async startConvo(req) {
|
|
825
678
|
await this.readyGate.entry();
|
|
826
679
|
this.convoGate.close();
|
|
@@ -833,31 +686,23 @@ class Store {
|
|
|
833
686
|
if (error) return {
|
|
834
687
|
error
|
|
835
688
|
};
|
|
836
|
-
|
|
837
689
|
this._setConvo(convo);
|
|
838
|
-
|
|
839
690
|
return {
|
|
840
691
|
convo
|
|
841
692
|
};
|
|
842
693
|
}
|
|
843
|
-
|
|
844
694
|
fetchOrder(id) {
|
|
845
695
|
return this.api.getOrder(id);
|
|
846
696
|
}
|
|
847
|
-
|
|
848
697
|
lookupOrder(key) {
|
|
849
698
|
return this.api.lookupOrder(key);
|
|
850
699
|
}
|
|
851
|
-
|
|
852
700
|
createPostback(cid, postback) {
|
|
853
701
|
return this.api.createPostback(cid, postback);
|
|
854
702
|
}
|
|
855
|
-
|
|
856
703
|
async sendConvoEvent(cid, type, data) {
|
|
857
704
|
await this.readyGate.entry();
|
|
858
|
-
|
|
859
705
|
var idempotency = _index.default.randomString(36);
|
|
860
|
-
|
|
861
706
|
let user = this.kv.match('user') || {};
|
|
862
707
|
var event = {
|
|
863
708
|
id: idempotency,
|
|
@@ -870,28 +715,24 @@ class Store {
|
|
|
870
715
|
type,
|
|
871
716
|
created: this.now()
|
|
872
717
|
};
|
|
873
|
-
|
|
874
718
|
_index.default.convoToEv(cid, event);
|
|
875
|
-
|
|
876
719
|
let files = [];
|
|
877
|
-
|
|
878
720
|
if (type === 'message_sent') {
|
|
879
721
|
_index.default.setMsgField(event, 'idempotency', idempotency);
|
|
880
|
-
|
|
881
722
|
event.data.message.conversation_id = cid;
|
|
723
|
+
|
|
882
724
|
await flow.map(event.data.message.attachments, 2, async (att, i) => {
|
|
883
725
|
if (att.type !== 'file') return;
|
|
884
726
|
if (!att._file) return;
|
|
885
727
|
files.push(att);
|
|
886
|
-
|
|
887
728
|
if (ImageTypes.includes(att._file.type)) {
|
|
888
729
|
att.url = await loadImage(att._file);
|
|
889
730
|
}
|
|
890
731
|
});
|
|
891
732
|
}
|
|
892
|
-
|
|
893
733
|
this.onWs(event);
|
|
894
734
|
await this.convoGate.entry();
|
|
735
|
+
|
|
895
736
|
await flow.map(files, 1, async att => {
|
|
896
737
|
const {
|
|
897
738
|
url,
|
|
@@ -905,17 +746,14 @@ class Store {
|
|
|
905
746
|
body: ret,
|
|
906
747
|
error
|
|
907
748
|
} = await this.api.sendConvoEvent(cid, event);
|
|
908
|
-
|
|
909
749
|
if (error) {
|
|
910
750
|
event._error = error;
|
|
911
751
|
this.onWs(event);
|
|
912
752
|
return;
|
|
913
753
|
}
|
|
914
|
-
|
|
915
754
|
this.onWs(ret);
|
|
916
755
|
sendEventToThirdParty('SUBIZ Chat', 'Sent', 'User');
|
|
917
756
|
let lastMsgSent = this.kv.match('last_msg_sent');
|
|
918
|
-
|
|
919
757
|
if (!lastMsgSent) {
|
|
920
758
|
let dataLayer = window.dataLayer || [];
|
|
921
759
|
dataLayer.push({
|
|
@@ -925,50 +763,40 @@ class Store {
|
|
|
925
763
|
first_interaction: 1
|
|
926
764
|
});
|
|
927
765
|
}
|
|
928
|
-
|
|
929
766
|
this.kv.put('last_msg_sent', _index.default.Date.now());
|
|
930
767
|
return ret;
|
|
931
768
|
}
|
|
932
|
-
|
|
933
769
|
_setConvo(convo) {
|
|
934
770
|
let count = 0;
|
|
935
|
-
let user = this.kv.match('user');
|
|
936
771
|
|
|
772
|
+
let user = this.kv.match('user');
|
|
937
773
|
let channel = _index.default.get(convo, 'touchpoint.channel', '');
|
|
938
|
-
|
|
939
774
|
if (channel && channel != 'subiz') return;
|
|
940
775
|
let allconvo = {};
|
|
941
|
-
|
|
942
776
|
_index.default.map(this.cache.all(), (value, key) => {
|
|
943
777
|
if (key.startsWith('convo_')) {
|
|
944
778
|
allconvo[key] = value;
|
|
945
779
|
}
|
|
946
780
|
});
|
|
947
|
-
|
|
948
781
|
if (_index.default.size(allconvo) > MAX_CONVO - 2) {
|
|
949
782
|
allconvo = _index.default.orderBy(_index.default.map(allconvo), 'created', 'desc');
|
|
950
|
-
|
|
951
783
|
for (var i = MAX_CONVO - 2; i < _index.default.size(allconvo); i++) {
|
|
952
784
|
let convo = allconvo[i];
|
|
953
785
|
this.cache.del('convo_' + convo.id);
|
|
954
786
|
}
|
|
955
787
|
}
|
|
956
|
-
|
|
957
788
|
this.markSync(convo.id);
|
|
958
789
|
this.pubsub.publish('account');
|
|
959
790
|
this.cache.put('convo_' + convo.id, convo);
|
|
960
791
|
}
|
|
961
|
-
|
|
962
792
|
matchLastPluginRun(pluginid) {
|
|
963
793
|
let log = this.kv.match('plugin_run_logs') || {};
|
|
964
794
|
return log[pluginid];
|
|
965
795
|
}
|
|
966
|
-
|
|
967
796
|
matchLastBotRun(botid) {
|
|
968
797
|
let log = this.kv.match('bot_run_logs') || {};
|
|
969
798
|
return log[botid];
|
|
970
799
|
}
|
|
971
|
-
|
|
972
800
|
logBotRun(botid) {
|
|
973
801
|
let log = this.kv.match('bot_run_logs') || {};
|
|
974
802
|
log[botid] = {
|
|
@@ -977,7 +805,6 @@ class Store {
|
|
|
977
805
|
};
|
|
978
806
|
this.kv.put('bot_run_logs', log);
|
|
979
807
|
}
|
|
980
|
-
|
|
981
808
|
sendImpression(id) {
|
|
982
809
|
let user = this.kv.match('user') || {};
|
|
983
810
|
let log = this.kv.match('plugin_run_logs') || {};
|
|
@@ -995,7 +822,6 @@ class Store {
|
|
|
995
822
|
device: this.device
|
|
996
823
|
});
|
|
997
824
|
}
|
|
998
|
-
|
|
999
825
|
sendConversion(id, fields, impressionToken) {
|
|
1000
826
|
let user = this.kv.match('user') || {};
|
|
1001
827
|
let submission = {
|
|
@@ -1017,12 +843,10 @@ class Store {
|
|
|
1017
843
|
impression_token: impressionToken
|
|
1018
844
|
});
|
|
1019
845
|
}
|
|
1020
|
-
|
|
1021
846
|
isConverted(id) {
|
|
1022
847
|
let conv = this.kv.match('conversions') || {};
|
|
1023
848
|
return conv[id];
|
|
1024
849
|
}
|
|
1025
|
-
|
|
1026
850
|
async listmessageapi(type, anchor, limit) {
|
|
1027
851
|
let convoid = type;
|
|
1028
852
|
let {
|
|
@@ -1040,23 +864,19 @@ class Store {
|
|
|
1040
864
|
value: event
|
|
1041
865
|
};
|
|
1042
866
|
});
|
|
1043
|
-
let user = this.kv.match('user') || {};
|
|
1044
867
|
|
|
868
|
+
let user = this.kv.match('user') || {};
|
|
1045
869
|
for (let i = 0; i < events.length; i++) {
|
|
1046
870
|
let ev = events[i].value;
|
|
1047
871
|
if (ev.type !== 'message_sent') continue;
|
|
1048
872
|
if (_index.default.get(ev, 'by.id') === user.id) continue;
|
|
1049
|
-
|
|
1050
873
|
let pongbyme = _index.default.find(_index.default.get(ev, 'data.message.pongs'), p => p.member_id === user.id);
|
|
1051
|
-
|
|
1052
874
|
if (pongbyme) break;
|
|
1053
875
|
this.api.markAsReceived(convoid, ev.id);
|
|
1054
876
|
break;
|
|
1055
877
|
}
|
|
1056
|
-
|
|
1057
878
|
return [events, anchor];
|
|
1058
879
|
}
|
|
1059
|
-
|
|
1060
880
|
async loopTime() {
|
|
1061
881
|
let startms = _index.default.Date.now();
|
|
1062
882
|
|
|
@@ -1068,22 +888,17 @@ class Store {
|
|
|
1068
888
|
if (error) return setTimeout(() => this.loopTime(), 30000);
|
|
1069
889
|
var latences = Math.abs(_index.default.Date.now() - startms) / 2;
|
|
1070
890
|
var serverMs = new _index.default.Date(t).getTime() + latences;
|
|
1071
|
-
|
|
1072
891
|
var localMs = _index.default.Date.now();
|
|
1073
|
-
|
|
1074
892
|
this.timeDiff = Math.floor(serverMs - localMs);
|
|
1075
893
|
setTimeout(() => this.loopTime(), 240000);
|
|
1076
894
|
}
|
|
1077
|
-
|
|
1078
895
|
replaceFileUrl(src) {
|
|
1079
896
|
if (!src) return '';
|
|
1080
897
|
if (_index.default.startsWith(src, '/')) return src;
|
|
1081
898
|
if (_index.default.startsWith(src, 'data:')) return src;
|
|
1082
|
-
|
|
1083
899
|
if (!_index.default.startsWith(src, 'http://') && !_index.default.startsWith(src, 'https://') && !_index.default.startsWith(src, '//')) {
|
|
1084
900
|
src = _index.default.trim(this.FileURL, '/') + '/' + _index.default.trimStart(src, '/');
|
|
1085
901
|
}
|
|
1086
|
-
|
|
1087
902
|
src = src.replace('https://file-subiz.com/', this.FileURL);
|
|
1088
903
|
src = src.replace('http://file-subiz.com/', this.FileURL);
|
|
1089
904
|
src = src.replace('https://file-v4.subiz.com/', this.FileURL);
|
|
@@ -1098,33 +913,26 @@ class Store {
|
|
|
1098
913
|
src = src.replace('http://file.mysubiz.com/', this.FileURL);
|
|
1099
914
|
return src;
|
|
1100
915
|
}
|
|
1101
|
-
|
|
1102
916
|
clearBrowserData() {
|
|
1103
917
|
_index.default.each(this.cookie.all(), (v, k) => {
|
|
1104
918
|
if ((k || '').startsWith('__sb')) this.cookie.remove(k);
|
|
1105
919
|
});
|
|
1106
|
-
|
|
1107
920
|
this.kv.destroy();
|
|
1108
921
|
this.kv = new _storage.default.kv(new _storage.default.lsdb('sbz2020', this.inmem), 'kv');
|
|
1109
922
|
this.chain.destroy();
|
|
1110
923
|
this.chain = new _storage.default.chain(new _storage.default.lsdb('cbz2020', true), 'ch');
|
|
1111
924
|
}
|
|
1112
|
-
|
|
1113
925
|
destroy() {
|
|
1114
926
|
this._die = true;
|
|
1115
927
|
this.clearBrowserData();
|
|
1116
928
|
if (this.realtime) this.realtime.stop();
|
|
1117
929
|
this.readyGate.close();
|
|
1118
930
|
}
|
|
1119
|
-
|
|
1120
931
|
}
|
|
1121
|
-
|
|
1122
932
|
exports.default = Store;
|
|
1123
|
-
|
|
1124
933
|
function loadImage(file) {
|
|
1125
934
|
return new Promise(rs => {
|
|
1126
935
|
var reader = new window.FileReader();
|
|
1127
|
-
|
|
1128
936
|
reader.onload = e => {
|
|
1129
937
|
rs(e.target.result);
|
|
1130
938
|
};
|
|
@@ -1132,13 +940,13 @@ function loadImage(file) {
|
|
|
1132
940
|
reader.readAsDataURL(file);
|
|
1133
941
|
});
|
|
1134
942
|
}
|
|
1135
|
-
|
|
1136
943
|
const ImageTypes = ['image/gif', 'image/jpeg', 'image/png', 'image/svg+xml'];
|
|
1137
|
-
|
|
1138
944
|
function onVisibilityChange(cb) {
|
|
1139
945
|
var hidden = 'hidden';
|
|
1140
|
-
if (hidden in document) document.addEventListener('visibilitychange', onchange);else if ((hidden = 'mozHidden') in document) document.addEventListener('mozvisibilitychange', onchange);else if ((hidden = 'webkitHidden') in document) document.addEventListener('webkitvisibilitychange', onchange);else if ((hidden = 'msHidden') in document) document.addEventListener('msvisibilitychange', onchange);else if ('onfocusin' in document) document.onfocusin = document.onfocusout = onchange;else window.onpageshow = window.onpagehide = window.onfocus = window.onblur = onchange;
|
|
1141
946
|
|
|
947
|
+
if (hidden in document) document.addEventListener('visibilitychange', onchange);else if ((hidden = 'mozHidden') in document) document.addEventListener('mozvisibilitychange', onchange);else if ((hidden = 'webkitHidden') in document) document.addEventListener('webkitvisibilitychange', onchange);else if ((hidden = 'msHidden') in document) document.addEventListener('msvisibilitychange', onchange);
|
|
948
|
+
else if ('onfocusin' in document) document.onfocusin = document.onfocusout = onchange;
|
|
949
|
+
else window.onpageshow = window.onpagehide = window.onfocus = window.onblur = onchange;
|
|
1142
950
|
function onchange(evt) {
|
|
1143
951
|
var v = 'visible';
|
|
1144
952
|
var h = 'hidden';
|
|
@@ -1158,26 +966,20 @@ function onVisibilityChange(cb) {
|
|
|
1158
966
|
type: document[hidden] ? 'blur' : 'focus'
|
|
1159
967
|
});
|
|
1160
968
|
}
|
|
1161
|
-
|
|
1162
969
|
const inmemCookie = {
|
|
1163
970
|
data: {},
|
|
1164
|
-
|
|
1165
971
|
get(k, def) {
|
|
1166
972
|
return this.data[k] || def;
|
|
1167
973
|
},
|
|
1168
|
-
|
|
1169
974
|
set(k, v) {
|
|
1170
975
|
return this.data[k] = k;
|
|
1171
976
|
},
|
|
1172
|
-
|
|
1173
977
|
all() {
|
|
1174
978
|
return this.data;
|
|
1175
979
|
},
|
|
1176
|
-
|
|
1177
980
|
remove(k) {
|
|
1178
981
|
delete this.data[k];
|
|
1179
982
|
}
|
|
1180
|
-
|
|
1181
983
|
};
|
|
1182
984
|
|
|
1183
985
|
function getGaClientId() {
|
|
@@ -1203,7 +1005,6 @@ function getGaTrackingIds() {
|
|
|
1203
1005
|
});
|
|
1204
1006
|
return trackingIds;
|
|
1205
1007
|
}
|
|
1206
|
-
|
|
1207
1008
|
function sendToFBPixel(category, action, label) {
|
|
1208
1009
|
if (!window.fbq) return;
|
|
1209
1010
|
window.fbq('trackCustom', category, {
|
|
@@ -1211,13 +1012,11 @@ function sendToFBPixel(category, action, label) {
|
|
|
1211
1012
|
label: label
|
|
1212
1013
|
});
|
|
1213
1014
|
}
|
|
1214
|
-
|
|
1215
1015
|
function sendToGA(category, action, label) {
|
|
1216
1016
|
if (window.gtag) window.gtag('event', category, {
|
|
1217
1017
|
Action: action,
|
|
1218
1018
|
Label: label
|
|
1219
1019
|
});
|
|
1220
|
-
|
|
1221
1020
|
if (window.ga && window.ga.getAll) {
|
|
1222
1021
|
const allTrackers = window.ga.getAll() || [];
|
|
1223
1022
|
allTrackers.forEach(function (tracker) {
|
|
@@ -1226,7 +1025,6 @@ function sendToGA(category, action, label) {
|
|
|
1226
1025
|
});
|
|
1227
1026
|
}
|
|
1228
1027
|
}
|
|
1229
|
-
|
|
1230
1028
|
function sendEventToThirdParty(category, action, label) {
|
|
1231
1029
|
document.dispatchEvent(new CustomEvent('subiz', {
|
|
1232
1030
|
detail: {
|
|
@@ -1248,5 +1046,4 @@ function sendEventToThirdParty(category, action, label) {
|
|
|
1248
1046
|
let mobileCheck = function (a) {
|
|
1249
1047
|
return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4));
|
|
1250
1048
|
}(navigator.userAgent || navigator.vendor || window.opera);
|
|
1251
|
-
|
|
1252
1049
|
let tabletCheck = /(ipad|tablet|(android(?!.*mobile))|(windows(?!.*phone)(.*touch))|kindle|playbook|silk|(puffin(?!.*(IP|AP|WP))))/.test(navigator.userAgent);
|