@textback/notification-widget 2.0.1-110396 → 2.0.1-13997

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 (81) hide show
  1. package/build/index.js +2 -5
  2. package/build/sdk.js +2 -2
  3. package/package.json +4 -5
  4. package/readme.md +11 -90
  5. package/server.js +220 -224
  6. package/src/libraries/localization/getLocale.js +17 -17
  7. package/src/libraries/localization/locales/cs.js +21 -23
  8. package/src/libraries/localization/locales/en.js +21 -23
  9. package/src/libraries/localization/locales/pl.js +21 -23
  10. package/src/libraries/localization/locales/ro.js +21 -23
  11. package/src/libraries/localization/locales/ru.js +21 -22
  12. package/src/libraries/localization/locales/uk.js +21 -23
  13. package/src/sdk/channels/facebook.js +1 -1
  14. package/src/sdk/channels/factory.js +33 -33
  15. package/src/sdk/channels/skype.js +1 -1
  16. package/src/sdk/channels/telegram.js +2 -2
  17. package/src/sdk/channels/viber.js +1 -1
  18. package/src/sdk/channels/vk.js +147 -158
  19. package/src/sdk/channels/whatsapp.js +21 -27
  20. package/src/sdk/sdk.js +5 -42
  21. package/src/sdk/utils/appInsights.js +2 -2
  22. package/src/sdk/utils/cookies.js +1 -18
  23. package/src/sdk/utils/loadDeepLink.js +13 -40
  24. package/src/sdk/widget/widget.js +107 -159
  25. package/src/widget/components/index.js +48 -52
  26. package/src/widget/components/tb-notification-button/facebook.js +48 -55
  27. package/src/widget/components/tb-notification-button/skype.js +47 -0
  28. package/src/widget/components/tb-notification-button/styles.scss +16 -240
  29. package/src/widget/components/tb-notification-button/telegram.js +48 -55
  30. package/src/widget/components/tb-notification-button/viber.js +49 -56
  31. package/src/widget/components/tb-notification-button/vk.js +83 -92
  32. package/src/widget/components/tb-notification-button/whatsapp.js +51 -58
  33. package/src/widget/components/tb-notification-widget/index.js +473 -694
  34. package/src/widget/components/tb-notification-widget/normalize.scss +1 -2
  35. package/src/widget/components/tb-notification-widget/styles.scss +180 -543
  36. package/src/widget/config.js +1 -1
  37. package/src/widget/icons/icon_facebook_circle.svg +2 -0
  38. package/src/widget/icons/icon_tg_circle.svg +10 -0
  39. package/src/widget/icons/icon_viber_circle.svg +10 -0
  40. package/src/widget/icons/icon_viber_new.svg +1 -1
  41. package/src/widget/icons/icon_vk_circle.svg +1 -1
  42. package/src/widget/icons/icon_whatsapp.svg +4 -4
  43. package/src/widget/icons/icon_whatsapp_circle.svg +2 -2
  44. package/src/widget/icons/icon_whatsapp_new.svg +2 -2
  45. package/src/widget/icons/text-back-badge.png +0 -0
  46. package/src/widget/locales/cz.js +20 -0
  47. package/src/widget/locales/en.js +20 -42
  48. package/src/widget/locales/index.js +8 -8
  49. package/src/widget/locales/pl.js +20 -42
  50. package/src/widget/locales/ro.js +19 -40
  51. package/src/widget/locales/ru.js +20 -41
  52. package/src/widget/locales/uk.js +20 -41
  53. package/src/widget/utils/getLocale.js +14 -16
  54. package/src/widget/utils/stringifyAttributes.js +1 -1
  55. package/src/widget/utils/text.js +8 -9
  56. package/src/widget/widget.entry.js +1 -0
  57. package/tests/gf.html +2 -2
  58. package/v8-compile-cache-0/5.1.281.102/zSvstszSagentzS_workzS5zSszSnode_moduleszSwebpack-clizSbinzScli.js.BLOB +0 -0
  59. package/v8-compile-cache-0/5.1.281.102/zSvstszSagentzS_workzS5zSszSnode_moduleszSwebpack-clizSbinzScli.js.MAP +1 -0
  60. package/views/examples.ejs +47 -51
  61. package/views/sdk.html +17 -35
  62. package/webpack.dev.js +2 -2
  63. package/src/sdk/channels/whatsappb.js +0 -27
  64. package/src/widget/components/tb-notification-button/whatsappb.js +0 -58
  65. package/src/widget/components/tb-nw-wahunter/index.js +0 -261
  66. package/src/widget/components/tb-nw-wahunter/styles.scss +0 -471
  67. package/src/widget/icons/icon_chat_window.svg +0 -1
  68. package/src/widget/icons/icon_close.svg +0 -1
  69. package/src/widget/icons/icon_whatsapp_hollow.svg +0 -128
  70. package/src/widget/icons/icon_whatsappb.svg +0 -147
  71. package/src/widget/icons/icon_whatsappb_circle.svg +0 -4
  72. package/src/widget/icons/icon_whatsappb_new.svg +0 -127
  73. package/src/widget/icons/paper-plane-arrow.svg +0 -3
  74. package/src/widget/icons/tb-logo-dark-en.svg +0 -17
  75. package/src/widget/icons/tb-logo-dark-ru.svg +0 -17
  76. package/src/widget/icons/tb-logo-dark.svg +0 -16
  77. package/src/widget/icons/tb-logo-light-en.svg +0 -17
  78. package/src/widget/icons/tb-logo-light-ru.svg +0 -17
  79. package/src/widget/icons/tb-logo-white.svg +0 -16
  80. package/src/widget/icons/tb-logo.svg +0 -16
  81. package/src/widget/locales/cs.js +0 -42
@@ -1,694 +1,473 @@
1
- import MobileDetect from 'mobile-detect';
2
- import assign from 'lodash/assign';
3
- import Component from '../index.js';
4
-
5
- import stringifyAttributes from '../../utils/stringifyAttributes.js';
6
- import cookiesEx from '../../utils/cookiesEx.js';
7
- import appInsights from '../../../sdk/utils/appInsights';
8
- import config from '../../config';
9
- import widgetsStorage from '../../utils/widgetsStorage.js';
10
-
11
- import constants from '../../../sdk/utils/constants';
12
- import SDK from '../../../sdk/index.js';
13
-
14
- import iconBell from '../../icons/bell-icon.png';
15
- import iconBroadcast from '../../icons/broadcast-icon.png';
16
- import iconPaperPlane from '../../icons/paper-plane-icon.png';
17
- import iconTbLogoLightRu from '../../icons/tb-logo-light-ru.svg'
18
- import iconTbLogoLightEn from '../../icons/tb-logo-light-en.svg'
19
- import iconTbLogoDarkRu from '../../icons/tb-logo-dark-ru.svg'
20
- import iconTbLogoDarkEn from '../../icons/tb-logo-dark-en.svg'
21
- import iconChatWindow from '../../icons/icon_whatsapp_hollow.svg';
22
- import iconClose from '../../icons/icon_close.svg';
23
-
24
- import './normalize.scss';
25
- import './styles.scss';
26
-
27
- import Wahunter from '../tb-nw-wahunter/index.js';
28
-
29
-
30
- const channelButtons = {
31
- vk: require('../tb-notification-button/vk'),
32
- tg: require('../tb-notification-button/telegram'),
33
- facebook: require('../tb-notification-button/facebook'),
34
- viber: require('../tb-notification-button/viber'),
35
- whatsapp: require('../tb-notification-button/whatsapp'),
36
- whatsappb: require('../tb-notification-button/whatsappb')
37
- };
38
-
39
- const DEFAULT_BUTTONS_MARKUP = {
40
- style: 'gradient',
41
- displayMode: 'horizontal',
42
- align: 'center',
43
- };
44
-
45
- const getDeviceDisplayMap = () => {
46
- const md = new MobileDetect(window.navigator.userAgent);
47
- const isDesktop = () => !(/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent));
48
-
49
- return new Map([
50
- ['pc', isDesktop()],
51
- ['mobile', md.phone()],
52
- ['tablet', md.tablet()]
53
- ]);
54
- };
55
-
56
- const showOnDevice = deviceList => {
57
- if (deviceList === null || deviceList === undefined) return true;
58
-
59
- return deviceList.map(i => getDeviceDisplayMap().get(i)).some(x => x);
60
- };
61
-
62
- export default class Widget extends Component {
63
- constructor() {
64
- super(...arguments);
65
-
66
- this.apiPath = this.apiPath || config.apiPath;
67
- this.onlyManual = this.onlyManual || this.element.hasAttribute('only-manual');
68
- this.previewMode = this.previewMode || this.element.hasAttribute('preview-mode');
69
-
70
- const predefinedConfig = this.widgetConfig;
71
-
72
- //override widgetId property with data from widgetConfig
73
- if (!!predefinedConfig) {
74
- this.widgetId = predefinedConfig.id;
75
- }
76
-
77
- let widgetInitPromise = SDK.getWidget(this.widgetId);
78
-
79
- if (!widgetInitPromise) {
80
- // init widget
81
- widgetInitPromise = SDK.initWidget({
82
- widgetId: this.widgetId,
83
- apiPath: this.apiPath,
84
- insecureContext: this.data,
85
- secureContextToken: this.secureContextToken,
86
- overrideConfig: predefinedConfig,
87
- }, this.previewMode);
88
- }
89
-
90
- widgetInitPromise = widgetInitPromise
91
- .then(widget => {
92
- this.widget = widget;
93
-
94
- this.widgetUserId = widget.widgetUserId;
95
- this.config = widget.getConfig();
96
- this.config.type = this.config.type || constants.DEFAULT_WIDGET_TYPE;
97
- this.config.markUp = this.config.markUp || {};
98
- this.config.markUp.buttons = assign({}, DEFAULT_BUTTONS_MARKUP, this.config.markUp.buttons);
99
-
100
- this.widgetSubscriptions = widget.subscriptions;
101
- this.deepLink = widget.deeplink;
102
- this.lang = this.config.lang
103
-
104
- this.showWidgetSetting = (this.widget.config && this.widget.config.showWidgetSetting)
105
- ? this.widget.config.showWidgetSetting.devices
106
- : null;
107
-
108
- const aiKey = widget.aiKey;
109
-
110
-
111
-
112
- return appInsights.init(aiKey, this.widgetUserId, this.config.accountId);
113
- })
114
- .then(res => {
115
- this.set({
116
- ready: showOnDevice(this.showWidgetSetting)
117
- });
118
- return this;
119
- }, err => {
120
- console.error(err);
121
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.error', err);
122
- this.set({ error: err });
123
- return this;
124
- });
125
-
126
- widgetsStorage.setWidget(this.widgetId, widgetInitPromise);
127
- }
128
-
129
- get defaults() {
130
- return {
131
- widgetId: this.element.getAttribute('widget-id'),
132
- secureContextToken: this.element.getAttribute('secure-context-token'),
133
- apiPath: this.element.getAttribute('api-path') || config.apiPath
134
- };
135
- }
136
-
137
- render() {
138
- super.render();
139
-
140
- const wahunterElem = this.element.querySelector('tb-nw-wahunter');
141
-
142
- if (wahunterElem) {
143
- new Wahunter({
144
- element: wahunterElem,
145
- widgetAPI: this.widget,
146
- parentElement: this.element,
147
- });
148
- }
149
-
150
- this.element.id = this.element.id ? this.element.id : 'tb-notification-widget';
151
-
152
- const buttons = this.element.querySelectorAll('tb-notification-button');
153
-
154
- if (buttons) {
155
- for (let i = 0; i < buttons.length; i++) {
156
- const channel = buttons[i].getAttribute('channel');
157
- new channelButtons[channel]({
158
- element: buttons[i],
159
- accountId: this.config.accountId,
160
- userId: this.userId,
161
- apiPath: this.apiPath,
162
- insecureContext: this.data,
163
- secureContextToken: this.secureContextToken,
164
- deepLink: this.deepLink,
165
- lang: this.lang,
166
- vkApiId: this.config.vkApiId,
167
- widgetId: this.config.id,
168
- widget: this,
169
- widgetAPI: this.widget,
170
- });
171
- }
172
- }
173
-
174
- if (!this.config || !this.config.displayMode) return;
175
-
176
- if (this.config.displayMode === "popup") {
177
- let sessionShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_s_show_counter';
178
- let daysShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_show_counter';
179
- let daysCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_close_counter';
180
- let totalCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_total_close_counter';
181
- let showWidgetSetting = this.config.showWidgetSetting;
182
- let popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
183
-
184
- this.element.addEventListener("click", (e) => {
185
- const target = e.target;
186
-
187
- if (!target.matches('#tb-notification-widget-close') && !target.matches('tb-notification-widget-overlay')) return;
188
-
189
- popup.className += " hidden closed";
190
- e.preventDefault();
191
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.click.close', 'userAction');
192
- if (showWidgetSetting) {
193
- let daysTimeout = showWidgetSetting.showAfterDays * constants.SECONDS_IN_DAY;
194
-
195
- cookiesEx.incrementIntCookie(daysCloseCounterName, daysTimeout);
196
- cookiesEx.incrementIntCookie(totalCloseCounterName, constants.WIDGET_USER_ID_COOKIE_TTL);
197
- }
198
- });
199
-
200
-
201
- if (this.config.widgetKind === 'WAHUNTER') {
202
- // For uniformity of config object, "showIfSubscribed" here is "show wahunter again if it allready was run"
203
- const wahunterWasRun = cookiesEx.getBoolCookie(`${constants.COOKIE_NAME_PREFIX + this.widgetId}_wahunter_was_run`);
204
- const showIfWasRun = showWidgetSetting.showIfSubscribed;
205
-
206
- if (wahunterWasRun && !showIfWasRun) return;
207
- }
208
-
209
-
210
- if (showWidgetSetting) {
211
- if (!showWidgetSetting.showIfSubscribed && this.widgetSubscriptions.length > 0) {
212
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.notShown', 'alreadySubscribed');
213
- return;
214
- }
215
-
216
- let daysTimeout = showWidgetSetting.showAfterDays * constants.SECONDS_IN_DAY;
217
- let sessionTimeout = showWidgetSetting.showSessionLength * 60;
218
- let daysShowCounter = cookiesEx.incrementIntCookie(daysShowCounterName, daysTimeout);
219
- let sessionShowCounter = cookiesEx.incrementIntCookie(sessionShowCounterName, sessionTimeout);
220
- let daysCloseCounter = cookiesEx.getIntCookie(daysCloseCounterName) || 0;
221
- let totalCloseCounter = cookiesEx.getIntCookie(totalCloseCounterName) || 0;
222
-
223
- const sendNonDisplayed = (reason) => {
224
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.notShown', reason);
225
- return true;
226
- };
227
-
228
- if (sessionShowCounter > showWidgetSetting.showTimesInSession && sendNonDisplayed('timesPerSession') || // Не более N раз в сессию
229
- (showWidgetSetting.showTimesInRow > 0 && daysShowCounter > showWidgetSetting.showTimesInRow && sendNonDisplayed('timesPerDays')) ||// Не более N раз в M дней
230
- (showWidgetSetting.closeTimesInRow > 0 && daysCloseCounter >= showWidgetSetting.closeTimesInRow && sendNonDisplayed('closedTimesPerDays')) || // Не более N закрытий в M дней
231
- (showWidgetSetting.closeTimesInTotal > 0 && totalCloseCounter >= showWidgetSetting.closeTimesInTotal && sendNonDisplayed('closedTimes')) // Не более N закрытий всего
232
- ) {
233
- return;
234
- }
235
- }
236
-
237
- if (this.onlyManual) {
238
- popup.className = 'hidden';
239
- return;
240
- }
241
-
242
- if (this.config.displayOptions && (this.config.displayOptions.onTimeout || this.config.displayOptions.onLeave)) {
243
- let telemetryFlag = false;
244
-
245
- if (this.config.displayOptions.onTimeout && showOnDevice(this.showWidgetSetting)) {
246
- setTimeout(() => {
247
- if (popup.className.indexOf('closed') === -1 && !telemetryFlag) {
248
- telemetryFlag = true;
249
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'timeout');
250
- }
251
- popup.className = popup.className.indexOf('closed') === -1 ? "" : popup.className;
252
- }, +this.config.displayOptions.timeoutDelay * 1000);
253
- }
254
-
255
- if (this.config.displayOptions.onLeave && showOnDevice(this.showWidgetSetting)) {
256
- document.addEventListener('mousemove', (e) => {
257
- if (e.clientY < 50) {
258
- if (popup.className.indexOf('closed') === -1 && !telemetryFlag) {
259
- telemetryFlag = true;
260
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'onLeave');
261
- }
262
- popup.className = popup.className.indexOf('closed') === -1 ? "" : popup.className;
263
- }
264
- });
265
- }
266
- }
267
- }
268
-
269
- if (this.config.displayMode === "corner-popup" && showOnDevice(this.showWidgetSetting)) {
270
- const popupControlButtonElem = this.element.querySelector('tb-widget-corner-popup-button');
271
- const popupElem = popupControlButtonElem.parentElement;
272
- const popupTooltipContainer = popupElem.querySelector('tb-widget-corner-popup-tooltip-container');
273
- const fullscreenCloseButtonElem = popupElem.querySelector('.tb-fullscreen-close-rectangle .tb-icon-close');
274
-
275
- fullscreenCloseButtonElem.addEventListener('click', (e) => {
276
- popupElem.classList.remove('tb-opened-corner-popup');
277
- });
278
-
279
- popupControlButtonElem.addEventListener('click', (e) => {
280
- popupElem.classList.toggle('tb-opened-corner-popup');
281
- });
282
-
283
- popupElem.addEventListener('wahunter-success', (e) => {
284
- popupTooltipContainer.style.display = 'none';
285
- });
286
- }
287
- }
288
-
289
- get header() {
290
- if (this.config.markUp && this.config.markUp.header && this.config.markUp.header.value) {
291
- var color = this.config.markUp.header.color ? 'style="color: ' + this.config.markUp.header.color + '"' : undefined;
292
- var result = '';
293
-
294
- result += '<tb-widget-header-line ' + color + ' class="tb-widget-header-line">' + this.config.markUp.header.value + '</tb-widget-header-line>';
295
-
296
- return '<tb-widget-header-container>' + result + '</tb-widget-header-container>';
297
- } else {
298
- return '';
299
- }
300
- }
301
-
302
- get description() {
303
- if (this.config.markUp && this.config.markUp.description && this.config.markUp.description.value) {
304
- var color = this.config.markUp.description.color ? 'style="color: ' + this.config.markUp.description.color + '"' : undefined;
305
- var result = '';
306
-
307
- result += '<tb-widget-description-line ' + color + ' class="tb-widget-description-line">' + this.config.markUp.description.value + '</tb-widget-description-line>'
308
-
309
- return '<tb-widget-description-container>' + result + '</tb-widget-description-container>';
310
- }
311
- else {
312
- return '';
313
- }
314
- }
315
-
316
- static iconPreset(val) {
317
- switch (val) {
318
- case 'widgetIconBell':
319
- return iconBell;
320
- case 'widgetIconBroadcast':
321
- return iconBroadcast;
322
- case 'widgetIconPaperPlane':
323
- return iconPaperPlane;
324
- }
325
-
326
- }
327
-
328
- get icon() {
329
- if (this.config.markUp && this.config.markUp.icon && this.config.markUp.icon.type === "custom") {
330
- return '<tb-notification-widget-icon_body>'
331
- + '<img src="' + this.config.markUp.icon.url + '">'
332
- + '</tb-notification-widget-icon_body>'
333
- }
334
- if (this.config.markUp && this.config.markUp.icon && this.config.markUp.icon.type === "preset") {
335
- return '<tb-notification-widget-icon_body>'
336
- + '<img src="' + Widget.iconPreset(this.config.markUp.icon.value) + '">'
337
- + '</tb-notification-widget-icon_body>'
338
- }
339
- else {
340
- return '';
341
- }
342
- }
343
-
344
-
345
-
346
- getTbBrandBadge({ displayMode, widgetKind }) {
347
- const utmMedium = widgetKind === 'WAHUNTER' ? 'hunter' : 'widget-subscribe';
348
-
349
- if (widgetKind === 'WAHUNTER') {
350
- return `
351
- <a target="_blank"
352
- href="//textback.ru/?utm_source=TextBack_tool&utm_medium=${utmMedium}&utm_campaign=${window.location.origin}${window.location.pathname}&utm_content=${displayMode}"
353
-
354
- id="tb-notification-brand-badge"
355
- style="${displayMode === 'inline' ? 'fill:inherit; color: inherit;' : ''}"
356
- >
357
- ${this.iconLogo }
358
- </a>
359
- `;
360
- }
361
-
362
- return `
363
- <a target="_blank"
364
- href="//textback.ru/?utm_source=TextBack_tool&utm_medium=${utmMedium}&utm_campaign=${window.location.origin}${window.location.pathname}"
365
-
366
- id="tb-notification-brand-badge"
367
- style="${displayMode === 'inline' ? 'fill:inherit; color: inherit;' : ''}"
368
- >
369
- ${this.iconLogo }
370
- </a>
371
- `;
372
- }
373
-
374
-
375
- get image() {
376
- if (!this.config.markUp.image || !this.config.markUp.image.show) return '';
377
-
378
- return `
379
- <tb-notification-widget-image style="background-image: url(${this.config.markUp.image.url})">
380
- <img src="${this.config.markUp.image.url}">
381
- </tb-notification-widget-image>
382
- `;
383
- }
384
-
385
- get pallet() {
386
- return this.config && this.config.markUp.body.palette && this.config.markUp.body.palette === "light" ? 'tb-pallet-light' : 'tb-pallet-dark'
387
- }
388
-
389
- get iconLogo() {
390
- if (this.pallet === 'tb-pallet-dark' && this.lang === 'ru') {
391
- return iconTbLogoDarkRu;
392
- } else if (this.pallet === 'tb-pallet-dark' && this.lang === 'en') {
393
- return iconTbLogoDarkEn;
394
- } else if (this.pallet === 'tb-pallet-light' && this.lang === 'ru') {
395
- return iconTbLogoLightRu;
396
- } else if (this.pallet === 'tb-pallet-light' && this.lang === 'en') {
397
- return iconTbLogoLightEn;
398
- } else {
399
- return iconTbLogoLightEn
400
- }
401
- }
402
-
403
- get template() {
404
- if (this.ready && this.config && this.config.displayMode) {
405
- switch (this.config.displayMode) {
406
- case 'popup':
407
- return this.popupTemplate;
408
- case 'inline':
409
- return this.inlineTemplate;
410
- case 'corner-popup':
411
- return this.cornerPopupTemplate;
412
- default:
413
- return '';
414
- }
415
- } else if (this.error) {
416
- console.warn(`could not render widget. reason: ${this.error}`);
417
- }
418
-
419
- return '';
420
- }
421
-
422
- get popupTemplate() {
423
- this.element.className = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'tb-no-api-call' : '');
424
-
425
- const markUp = this.config.markUp;
426
- const isPopupWithImage = markUp.image && markUp.image.show;
427
-
428
- let imageUrlNotEmpty;
429
- let popupStyleClass = this.pallet;
430
-
431
- if (this.config.widgetKind === 'WAHUNTER' || isPopupWithImage) {
432
- imageUrlNotEmpty = !!markUp.image.url.trim();
433
- popupStyleClass += ` tb-popup-with-image tb-popup-${(markUp.image.align !== 'top' && imageUrlNotEmpty) ? 'horizontal' : 'vertical'}`;
434
- }
435
-
436
- if (this.config.widgetKind === 'WAHUNTER') {
437
- let wahunterImageAlignClassName = `tb-nw-wahunter_${imageUrlNotEmpty ? ('image-align_' + markUp.image.align) : 'without-image'}`;
438
-
439
- return `
440
- <tb-notification-widget-inner id="tb-notification-widget-inner" class="tb-notification-widget-inner">
441
- <tb-notification-widget-overlay class="hidden">
442
- <tb-notification-widget-popup class="${popupStyleClass}">
443
- <span id="tb-notification-widget-close" class="tb-notification-widget-close-icon">&times;</span>
444
- ${this.getTbBrandBadge(this.config)}
445
- <tb-nw-wahunter class="tb-nw-wahunter tb-nw-wahunter_mode_popup ${wahunterImageAlignClassName}"></tb-nw-wahunter>
446
- </tb-notification-widget-popup>
447
- </tb-notification-widget-overlay>
448
- </tb-notification-widget-inner>
449
- `;
450
- }
451
-
452
- const buttonsStyle = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'square' : 'rounded');
453
- const buttonsStyleClass = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'tb-btn-style-square' : 'tb-btn-style-rounded');
454
- let body = '';
455
-
456
- const channels = this.widget.getEnabledChannels();
457
-
458
- body = channels.map((channel, index) => {
459
- const item = assign({}, channel.config, {
460
- type: this.config.type,
461
- markUp: assign({}, markUp.buttons, { style: buttonsStyle }),
462
- });
463
-
464
- const attributes = stringifyAttributes({
465
- channel: item.channel,
466
- config: item,
467
- });
468
-
469
- return item.enabled ? `<div><tb-notification-button id="tb-notification-button-${index}" ${attributes}></tb-notification-button></div>` : '';
470
- }).join('');
471
-
472
-
473
- let popupBodyStyleClass = 'tb-notification-widget-popup-body';
474
-
475
- if (isPopupWithImage) {
476
- popupBodyStyleClass += ` ${popupBodyStyleClass}_image-align_${imageUrlNotEmpty ? markUp.image.align : 'none'}`
477
- }
478
-
479
- return `
480
- <tb-notification-widget-inner id="tb-notification-widget-inner" class="tb-notification-widget-inner">
481
- <tb-notification-widget-overlay class="hidden">
482
- <tb-notification-widget-popup class="${popupStyleClass}">
483
- <span id="tb-notification-widget-close" class="tb-notification-widget-close-icon">&times;</span>
484
- ${this.getTbBrandBadge(this.config)}
485
- <tb-notification-widget-popup-body class="${popupBodyStyleClass}">
486
- ${(markUp.image && markUp.image.show) ? this.image : this.icon}
487
- <tb-notification-widget-popup-main>
488
- ${this.header}
489
- ${this.description}
490
- <div class="tb-widget-buttons tb-btn-align-center ${buttonsStyleClass}">${body}</div>
491
- </tb-notification-widget-popup-main>
492
- </tb-notification-widget-popup-body>
493
- </tb-notification-widget-popup>
494
- </tb-notification-widget-overlay>
495
- </tb-notification-widget-inner>
496
- `;
497
- }
498
-
499
- get inlineTemplate() {
500
-
501
- this.element.className = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'tb-no-api-call' : '');
502
-
503
- const buttonsContainerClasses = this.config.type === constants.WIDGET_TYPE_WIDGET
504
- ? this.getButtonsClasses()
505
- : 'tb-btn-style-rounded tb-btn-mode-horizontal tb-btn-align-left';
506
-
507
- const channels = this.widget.getEnabledChannels();
508
-
509
- const body = channels.map((channel, index) => {
510
- const item = assign({}, channel.config, { type: this.config.type, markUp: this.config.markUp.buttons });
511
- const attributes = stringifyAttributes({
512
- channel: item.channel,
513
- config: item,
514
- });
515
-
516
- if (item.enabled) {
517
- let html = `<tb-notification-button id="tb-notification-button-${index}" ${attributes}></tb-notification-button>`;
518
- if (this.config.markUp.buttons.displayMode === 'vertical') {
519
- html = `<div>${html}</div>`;
520
- }
521
- return html;
522
- } else {
523
- return '';
524
- }
525
- }).join('');
526
-
527
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.inline.show', 'displaySettings');
528
-
529
- if (this.config.widgetKind === 'WAHUNTER') {
530
- return `
531
- <tb-notification-widget-inner id="tb-notification-widget-inner" class="tb-notification-widget-inner">
532
- <tb-nw-wahunter class="tb-nw-wahunter tb-nw-wahunter_mode_inline tb-nw-wahunter_inline-mode-align_${this.config.markUp.buttons.align}"></tb-nw-wahunter>
533
- </tb-notification-widget-inner>
534
- `;
535
- }
536
-
537
- return `
538
- <tb-notification-widget-inner id="tb-notification-widget-inner" class="tb-notification-widget-inner">
539
- <div class="tb-widget-buttons ${buttonsContainerClasses}">
540
- ${body}
541
- </div>
542
- </tb-notification-widget-inner>
543
- `;
544
- }
545
-
546
- get cornerPopupTemplate() {
547
- const markUp = this.config.markUp;
548
-
549
- if (this.config.widgetKind === 'WAHUNTER') {
550
- return `
551
- <tb-notification-widget-inner id="tb-notification-widget-inner" class="tb-notification-widget-inner">
552
- <tb-notification-widget-corner-popup>
553
- <tb-widget-corner-popup-window class="${this.pallet}">
554
- <div class="tb-fullscreen-close-rectangle">
555
- ${iconClose}
556
- </div>
557
- <tb-nw-wahunter class="tb-nw-wahunter tb-nw-wahunter_mode_corner-popup"></tb-nw-wahunter>
558
- ${this.getTbBrandBadge(this.config)}
559
- </tb-widget-corner-popup-window>
560
- <tb-widget-corner-popup-button style="background: ${markUp.wahunterButton.color}">
561
- ${iconChatWindow}
562
- ${iconClose}
563
- </tb-widget-corner-popup-button>
564
- <tb-widget-corner-popup-tooltip-container
565
- class="${markUp.description.showOnMobile ? 'tb-widget-corner-popup-tooltip-container_show-on-mobile' : ''}"
566
- style="${markUp.description.value.trim() ? '' : 'display:none'}"
567
- >
568
- <tb-widget-corner-popup-tooltip style="color:${markUp.description.color}">\
569
- ${markUp.description.value}\
570
- </tb-widget-corner-popup-tooltip>
571
- <tb-widget-corner-popup-tooltip-arrow />
572
- </tb-widget-corner-popup-tooltip-container>
573
- </tb-notification-widget-corner-popup>
574
- </tb-notification-widget-inner>
575
- `;
576
- }
577
-
578
- return '';
579
- }
580
-
581
- static get tagName() {
582
- return 'tb-notification-widget';
583
- }
584
-
585
- static getWidget(widgetId) {
586
- return widgetsStorage.getWidget(widgetId);
587
- }
588
-
589
- show() {
590
- if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
591
- const popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
592
- if (popup.className.indexOf('hidden') !== -1 || popup.className.indexOf('closed')) {
593
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'manual');
594
- }
595
- popup.className = '';
596
- }
597
- }
598
-
599
- showWithRules() {
600
- let showWidgetSetting = this.config.showWidgetSetting;
601
- let sessionShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_s_show_counter';
602
- let daysShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_show_counter';
603
- let daysCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_close_counter';
604
- let totalCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_total_close_counter';
605
-
606
- if (showWidgetSetting) {
607
- if (!showWidgetSetting.showIfSubscribed && this.widgetSubscriptions.length > 0) {
608
- return false;
609
- }
610
-
611
- let daysTimeout = showWidgetSetting.showAfterDays * constants.SECONDS_IN_DAY;
612
- let sessionTimeout = showWidgetSetting.showSessionLength * 60;
613
- let daysShowCounter = cookiesEx.incrementIntCookie(daysShowCounterName, daysTimeout);
614
- let sessionShowCounter = cookiesEx.incrementIntCookie(sessionShowCounterName, sessionTimeout);
615
- let daysCloseCounter = cookiesEx.getIntCookie(daysCloseCounterName) || 0;
616
- let totalCloseCounter = cookiesEx.getIntCookie(totalCloseCounterName) || 0;
617
-
618
- if (sessionShowCounter > showWidgetSetting.showTimesInSession ||
619
- (showWidgetSetting.showTimesInRow > 0 && daysShowCounter > showWidgetSetting.showTimesInRow) ||
620
- (showWidgetSetting.closeTimesInRow > 0 && daysCloseCounter >= showWidgetSetting.closeTimesInRow) ||
621
- (showWidgetSetting.closeTimesInTotal > 0 && totalCloseCounter >= showWidgetSetting.closeTimesInTotal)) {
622
- return false;
623
- }
624
- }
625
-
626
- if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
627
- const popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
628
- if (popup.className.indexOf('hidden') !== -1 || popup.className.indexOf('closed')) {
629
- appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'manual');
630
- }
631
- popup.className = '';
632
- return popup;
633
- }
634
-
635
- return false;
636
- }
637
-
638
- hide() {
639
- if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
640
- const popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
641
- if (popup.className.indexOf('hidden') !== -1) {
642
- popup.className += 'hidden';
643
- }
644
- }
645
- }
646
-
647
- getButtonsClasses() {
648
- const classes = [];
649
-
650
- if (this.config.markUp && this.config.markUp.buttons) {
651
- const markUp = this.config.markUp.buttons;
652
- classes.push(getButtonsStyleClass(markUp.style));
653
- classes.push(getButtonsAlignmentClass(markUp.align));
654
- classes.push(getButtonsDisplayModeClass(markUp.displayMode));
655
- }
656
-
657
- function getButtonsStyleClass(style) {
658
- const prefix = 'tb-btn-style';
659
- switch (style) {
660
- case 'rounded':
661
- return `${prefix}-rounded`;
662
- case 'icons':
663
- return `${prefix}-icons`;
664
- case 'gradient':
665
- return `${prefix}-gradient`;
666
- default:
667
- return `${prefix}-square`;
668
- }
669
- }
670
-
671
- function getButtonsAlignmentClass(align) {
672
- const prefix = 'tb-btn-align';
673
- switch (align) {
674
- case 'left':
675
- return `${prefix}-left`;
676
- case 'right':
677
- return `${prefix}-right`;
678
- default:
679
- return `${prefix}-center`;
680
- }
681
- }
682
-
683
- function getButtonsDisplayModeClass(mode) {
684
- const prefix = 'tb-btn-mode';
685
- if (mode === 'vertical') {
686
- return `${prefix}-vertical`;
687
- } else {
688
- return `${prefix}-horizontal`;
689
- }
690
- }
691
-
692
- return classes.join(' ');
693
- }
694
- };
1
+ import assign from 'lodash/assign';
2
+ import Component from '../index.js';
3
+
4
+ import stringifyAttributes from '../../utils/stringifyAttributes.js';
5
+ import cookiesEx from '../../utils/cookiesEx.js';
6
+ import appInsights from '../../../sdk/utils/appInsights';
7
+ import config from '../../config';
8
+ import widgetsStorage from '../../utils/widgetsStorage.js';
9
+
10
+ import constants from '../../../sdk/utils/constants';
11
+ import SDK from '../../../sdk/index.js';
12
+
13
+ import iconBell from '../../icons/bell-icon.png';
14
+ import iconBroadcast from '../../icons/broadcast-icon.png';
15
+ import iconPaperPlane from '../../icons/paper-plane-icon.png';
16
+ import iconTextBackBadge from '../../icons/text-back-badge.png';
17
+
18
+ import './normalize.scss';
19
+ import './styles.scss';
20
+
21
+ const channelButtons = {
22
+ vk: require('../tb-notification-button/vk'),
23
+ tg: require('../tb-notification-button/telegram'),
24
+ facebook: require('../tb-notification-button/facebook'),
25
+ skype: require('../tb-notification-button/skype'),
26
+ viber: require('../tb-notification-button/viber'),
27
+ whatsapp: require('../tb-notification-button/whatsapp')
28
+ };
29
+
30
+
31
+ const DEFAULT_BUTTONS_MARKUP = {
32
+ style: 'square',
33
+ displayMode: 'horizontal',
34
+ align: 'center',
35
+ };
36
+
37
+ export default class Widget extends Component {
38
+ constructor() {
39
+ super(...arguments);
40
+
41
+ this.apiPath = this.apiPath || config.apiPath;
42
+ this.onlyManual = this.onlyManual || this.element.hasAttribute('only-manual');
43
+
44
+ const predefinedConfig = this.widgetConfig;
45
+
46
+ //override widgetId property with data from widgetConfig
47
+ if (!!predefinedConfig) {
48
+ this.widgetId = predefinedConfig.id;
49
+ }
50
+
51
+ let widgetInitPromise = SDK.getWidget(this.widgetId);
52
+ if (!widgetInitPromise) {
53
+ // init widget
54
+ widgetInitPromise = SDK.initWidget({
55
+ widgetId: this.widgetId,
56
+ apiPath: this.apiPath,
57
+ insecureContext: this.data,
58
+ secureContextToken: this.secureContextToken,
59
+ overrideConfig: predefinedConfig,
60
+ });
61
+ }
62
+
63
+ widgetInitPromise = widgetInitPromise
64
+ .then(widget => {
65
+ this.widget = widget;
66
+
67
+ this.widgetUserId = widget.widgetUserId;
68
+ this.config = widget.getConfig();
69
+ this.config.type = this.config.type || constants.DEFAULT_WIDGET_TYPE;
70
+ this.config.markUp = this.config.markUp || {};
71
+ this.config.markUp.buttons = assign({}, DEFAULT_BUTTONS_MARKUP, this.config.markUp.buttons);
72
+
73
+ this.widgetSubscriptions = widget.subscriptions;
74
+ this.deepLink = widget.deeplink;
75
+ const aiKey = widget.aiKey;
76
+
77
+ return appInsights.init(aiKey, this.widgetUserId, this.config.accountId);
78
+ })
79
+ .then(res => {
80
+ this.set({
81
+ ready: true
82
+ });
83
+ return this;
84
+ }, err => {
85
+ console.error(err);
86
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.error', err);
87
+ this.set({error: err});
88
+ return this;
89
+ });
90
+
91
+ widgetsStorage.setWidget(this.widgetId, widgetInitPromise);
92
+ }
93
+
94
+ get defaults() {
95
+ return {
96
+ widgetId: this.element.getAttribute('widget-id'),
97
+ secureContextToken: this.element.getAttribute('secure-context-token'),
98
+ apiPath: this.element.getAttribute('api-path') || config.apiPath
99
+ }
100
+ }
101
+
102
+ render() {
103
+ super.render();
104
+
105
+ this.element.id = this.element.id ? this.element.id : 'tb-notification-widget';
106
+
107
+ const buttons = this.element.querySelectorAll('tb-notification-button');
108
+
109
+ if (buttons) {
110
+ for (let i = 0; i < buttons.length; i++) {
111
+ const channel = buttons[i].getAttribute('channel');
112
+ new channelButtons[channel]({
113
+ element: buttons[i],
114
+ accountId: this.config.accountId,
115
+ userId: this.userId,
116
+ apiPath: this.apiPath,
117
+ insecureContext: this.data,
118
+ secureContextToken: this.secureContextToken,
119
+ deepLink: this.deepLink,
120
+ lang: this.lang,
121
+ vkApiId: this.config.vkApiId,
122
+ widgetId: this.config.id,
123
+ widget: this,
124
+ widgetAPI: this.widget,
125
+ });
126
+ }
127
+ }
128
+
129
+ if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
130
+ let sessionShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_s_show_counter';
131
+ let daysShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_show_counter';
132
+ let daysCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_close_counter';
133
+ let totalCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_total_close_counter';
134
+
135
+ let showWidgetSetting = this.config.showWidgetSetting;
136
+
137
+ let popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
138
+ this.element.querySelector('#tb-notification-widget-close').addEventListener("click", (e) => {
139
+ popup.className += " hidden closed";
140
+ e.preventDefault();
141
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.click.close', 'userAction');
142
+ if (showWidgetSetting) {
143
+ let daysTimeout = showWidgetSetting.showAfterDays * constants.SECONDS_IN_DAY;
144
+
145
+ cookiesEx.incrementIntCookie(daysCloseCounterName, daysTimeout);
146
+ cookiesEx.incrementIntCookie(totalCloseCounterName, constants.WIDGET_USER_ID_COOKIE_TTL);
147
+ }
148
+ });
149
+
150
+
151
+ if (showWidgetSetting) {
152
+ if (!showWidgetSetting.showIfSubscribed && this.widgetSubscriptions.length > 0) {
153
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.notShown', 'alreadySubscribed');
154
+ return;
155
+ }
156
+
157
+
158
+ let daysTimeout = showWidgetSetting.showAfterDays * constants.SECONDS_IN_DAY;
159
+ let sessionTimeout = showWidgetSetting.showSessionLength * 60;
160
+
161
+ let daysShowCounter = cookiesEx.incrementIntCookie(daysShowCounterName, daysTimeout);
162
+ let sessionShowCounter = cookiesEx.incrementIntCookie(sessionShowCounterName, sessionTimeout);
163
+ let daysCloseCounter = cookiesEx.getIntCookie(daysCloseCounterName) || 0;
164
+ let totalCloseCounter = cookiesEx.getIntCookie(totalCloseCounterName) || 0;
165
+
166
+ const sendNonDisplayed = (reason) => {
167
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.notShown', reason);
168
+ return true;
169
+ };
170
+
171
+ if (sessionShowCounter > showWidgetSetting.showTimesInSession && sendNonDisplayed('timesPerSession')|| // Не более N раз в сессию
172
+ (showWidgetSetting.showTimesInRow > 0 && daysShowCounter > showWidgetSetting.showTimesInRow && sendNonDisplayed('timesPerDays')) ||// Не более N раз в M дней
173
+ (showWidgetSetting.closeTimesInRow > 0 && daysCloseCounter >= showWidgetSetting.closeTimesInRow && sendNonDisplayed('closedTimesPerDays')) || // Не более N закрытий в M дней
174
+ (showWidgetSetting.closeTimesInTotal > 0 && totalCloseCounter >= showWidgetSetting.closeTimesInTotal && sendNonDisplayed('closedTimes')) // Не более N закрытий всего
175
+ ) {
176
+ return;
177
+ }
178
+ }
179
+
180
+ if (this.onlyManual) {
181
+ popup.className = 'hidden';
182
+ return;
183
+ }
184
+
185
+ if (this.config.displayOptions && (this.config.displayOptions.onTimeout || this.config.displayOptions.onLeave)) {
186
+ let telemetryFlag = false;
187
+ if (this.config.displayOptions.onTimeout) {
188
+ setTimeout(() => {
189
+ if(popup.className.indexOf('closed') === -1 && !telemetryFlag){
190
+ telemetryFlag = true;
191
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'timeout');
192
+ }
193
+ popup.className = popup.className.indexOf('closed') === -1 ? "" : popup.className;
194
+ }, +this.config.displayOptions.timeoutDelay * 1000);
195
+ }
196
+ if (this.config.displayOptions.onLeave) {
197
+ document.addEventListener('mousemove', (e) => {
198
+ if (e.clientY < 50) {
199
+ if(popup.className.indexOf('closed') === -1 && !telemetryFlag){
200
+ telemetryFlag = true;
201
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'onLeave');
202
+ }
203
+ popup.className = popup.className.indexOf('closed') === -1 ? "" : popup.className;
204
+ }
205
+ });
206
+ }
207
+ }
208
+ }
209
+ }
210
+
211
+ get header() {
212
+ if (this.config.markUp && this.config.markUp.header && this.config.markUp.header.value) {
213
+ var color = this.config.markUp.header.color ? 'style="color: ' + this.config.markUp.header.color + '"' : undefined;
214
+ var result = '';
215
+
216
+ result += '<tb-widget-header-line ' + color + ' class="tb-widget-header-line">' + this.config.markUp.header.value + '</tb-widget-header-line>';
217
+
218
+ return '<tb-widget-header-container>' + result + '</tb-widget-header-container>';
219
+ }
220
+ else {
221
+ return '';
222
+ }
223
+
224
+ }
225
+
226
+ get description() {
227
+ if (this.config.markUp && this.config.markUp.description && this.config.markUp.description.value) {
228
+ var color = this.config.markUp.description.color ? 'style="color: ' + this.config.markUp.description.color + '"' : undefined;
229
+ var result = '';
230
+
231
+ result += '<tb-widget-description-line ' + color + ' class="tb-widget-description-line">' + this.config.markUp.description.value + '</tb-widget-description-line>'
232
+
233
+ return '<tb-widget-description-container>' + result + '</tb-widget-description-container>';
234
+ }
235
+ else {
236
+ return '';
237
+ }
238
+
239
+ }
240
+
241
+ static iconPreset(val) {
242
+ switch (val) {
243
+ case 'widgetIconBell':
244
+ return iconBell;
245
+ case 'widgetIconBroadcast':
246
+ return iconBroadcast;
247
+ case 'widgetIconPaperPlane':
248
+ return iconPaperPlane;
249
+ case 'text-back-badge':
250
+ return iconTextBackBadge;
251
+ }
252
+
253
+ }
254
+
255
+ get icon() {
256
+ if (this.config.markUp && this.config.markUp.icon && this.config.markUp.icon.type === "custom") {
257
+ return '<tb-notification-widget-icon_body>'
258
+ + '<img src="' + this.config.markUp.icon.url + '">'
259
+ + '</tb-notification-widget-icon_body>'
260
+ }
261
+ if (this.config.markUp && this.config.markUp.icon && this.config.markUp.icon.type === "preset") {
262
+ return '<tb-notification-widget-icon_body>'
263
+ + '<img src="' + Widget.iconPreset(this.config.markUp.icon.value) + '">'
264
+ + '</tb-notification-widget-icon_body>'
265
+ }
266
+ else {
267
+ return '';
268
+ }
269
+
270
+ }
271
+
272
+ get pallet() {
273
+ return this.config && this.config.markUp.body.palette && this.config.markUp.body.palette === "light" ? 'pallet-light' : 'pallet-dark'
274
+ }
275
+
276
+ get template() {
277
+ if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
278
+ this.element.className = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'tb-no-api-call' : '');
279
+
280
+ const buttonsStyle = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'square' : 'rounded'),
281
+ buttonsStyleClass = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'tb-btn-style-square' : 'tb-btn-style-rounded');
282
+
283
+ var body = '';
284
+ if (this.ready) {
285
+ const channels = this.widget.getEnabledChannels();
286
+ body = channels.map((channel, index) => {
287
+ const item = assign({}, channel.config, {
288
+ type: this.config.type,
289
+ markUp: assign({}, this.config.markUp.buttons, { style: buttonsStyle }),
290
+ });
291
+ const attributes = stringifyAttributes({
292
+ channel: item.channel,
293
+ config: item,
294
+ });
295
+
296
+ return item.enabled ? `<div><tb-notification-button id="tb-notification-button-${index}" ${attributes}></tb-notification-button></div>` : '';
297
+ }).join('');
298
+ } else if (this.error) {
299
+ console.warn('could not render widget. reason: ' + this.error);
300
+ body = '';
301
+ } else {
302
+ body = '';
303
+ }
304
+
305
+ return `<tb-notification-widget-inner id="tb-notification-widget-inner" class="tb-notification-widget-inner"><tb-notification-widget-overlay class="hidden">
306
+ <tb-notification-widget-popup class="${this.pallet}">
307
+ <span id="tb-notification-widget-close" class="tb-notification-widget-close-icon">&times;</span>
308
+ <a target="_blank" href="//textback.ru/?utm_source=${window.location.host}&utm_medium=link&utm_content=notify_widget_opened&utm_campaign=ref_ad">
309
+ <img id="tb-notification-brand-badge" src="${Widget.iconPreset('text-back-badge')}">
310
+ </a>
311
+ ${this.icon}
312
+ ${this.header}
313
+ ${this.description}
314
+ <div class="tb-widget-buttons tb-btn-align-center ${buttonsStyleClass}">${body}</div>
315
+ </tb-notification-widget-popup>
316
+ </tb-notification-widget-overlay></tb-notification-widget-inner>`;
317
+
318
+ } else {
319
+ if (this.ready) {
320
+ this.element.className = (this.config.type === constants.WIDGET_TYPE_WIDGET ? 'tb-no-api-call' : '');
321
+ const buttonsContainerClasses = (this.config.type === constants.WIDGET_TYPE_WIDGET
322
+ ? this.getButtonsClasses()
323
+ : 'tb-btn-style-rounded tb-btn-mode-horizontal tb-btn-align-left');
324
+ // let
325
+
326
+ const channels = this.widget.getEnabledChannels();
327
+ const body = channels.map((channel, index) => {
328
+ const item = assign({}, channel.config, { type: this.config.type, markUp: this.config.markUp.buttons });
329
+ const attributes = stringifyAttributes({
330
+ channel: item.channel,
331
+ config: item,
332
+ });
333
+
334
+ if (item.enabled) {
335
+ let html = `<tb-notification-button id="tb-notification-button-${index}" ${attributes}></tb-notification-button>`;
336
+ if (this.config.markUp.buttons.displayMode === 'vertical') {
337
+ html = `<div>${html}</div>`;
338
+ }
339
+ return html;
340
+ } else {
341
+ return '';
342
+ }
343
+ }).join('');
344
+
345
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.inline.show', 'displaySettings');
346
+ return `<tb-notification-widget-inner id="tb-notification-widget-inner" class="tb-notification-widget-inner">
347
+ <div class="tb-widget-buttons ${buttonsContainerClasses}">
348
+ ${body}
349
+ </div>
350
+ </tb-notification-widget-inner>`;
351
+ } else if (this.error) {
352
+ console.warn('could not render widget. reason: ' + this.error);
353
+ return '';
354
+ } else {
355
+ return ''
356
+ }
357
+
358
+ }
359
+ }
360
+
361
+ static get tagName() {
362
+ return 'tb-notification-widget';
363
+ }
364
+
365
+ static getWidget(widgetId) {
366
+ return widgetsStorage.getWidget(widgetId);
367
+ }
368
+
369
+ show() {
370
+ if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
371
+ const popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
372
+ if (popup.className.indexOf('hidden') !== -1 || popup.className.indexOf('closed')) {
373
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'manual');
374
+ }
375
+ popup.className = '';
376
+ }
377
+ }
378
+
379
+ showWithRules() {
380
+ let showWidgetSetting = this.config.showWidgetSetting;
381
+ let sessionShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_s_show_counter';
382
+ let daysShowCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_show_counter';
383
+ let daysCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_days_close_counter';
384
+ let totalCloseCounterName = constants.COOKIE_NAME_PREFIX + this.widgetId + '_total_close_counter';
385
+
386
+ if (showWidgetSetting) {
387
+ if (!showWidgetSetting.showIfSubscribed && this.widgetSubscriptions.length > 0) {
388
+ return false;
389
+ }
390
+
391
+ let daysTimeout = showWidgetSetting.showAfterDays * constants.SECONDS_IN_DAY;
392
+ let sessionTimeout = showWidgetSetting.showSessionLength * 60;
393
+ let daysShowCounter = cookiesEx.incrementIntCookie(daysShowCounterName, daysTimeout);
394
+ let sessionShowCounter = cookiesEx.incrementIntCookie(sessionShowCounterName, sessionTimeout);
395
+ let daysCloseCounter = cookiesEx.getIntCookie(daysCloseCounterName) || 0;
396
+ let totalCloseCounter = cookiesEx.getIntCookie(totalCloseCounterName) || 0;
397
+
398
+ if (sessionShowCounter > showWidgetSetting.showTimesInSession ||
399
+ (showWidgetSetting.showTimesInRow > 0 && daysShowCounter > showWidgetSetting.showTimesInRow) ||
400
+ (showWidgetSetting.closeTimesInRow > 0 && daysCloseCounter >= showWidgetSetting.closeTimesInRow) ||
401
+ (showWidgetSetting.closeTimesInTotal > 0 && totalCloseCounter >= showWidgetSetting.closeTimesInTotal)) {
402
+ return false;
403
+ }
404
+ }
405
+
406
+ if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
407
+ const popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
408
+ if (popup.className.indexOf('hidden') !== -1 || popup.className.indexOf('closed')) {
409
+ appInsights.trackWidgetEvent(this.config.id, 'notificationWidget.popup.show', 'manual');
410
+ }
411
+ popup.className = '';
412
+ return popup;
413
+ }
414
+
415
+ return false;
416
+ }
417
+
418
+ hide() {
419
+ if (this.config && this.config.displayMode && this.config.displayMode === "popup") {
420
+ const popup = this.element.getElementsByTagName("tb-notification-widget-overlay")[0];
421
+ if (popup.className.indexOf('hidden') !== -1) {
422
+ popup.className += 'hidden';
423
+ }
424
+ }
425
+ }
426
+
427
+ getButtonsClasses() {
428
+ console.log(this.config);
429
+ const classes = [];
430
+
431
+ if (this.config.markUp && this.config.markUp.buttons) {
432
+ const markUp = this.config.markUp.buttons;
433
+ classes.push( getButtonsStyleClass(markUp.style) );
434
+ classes.push( getButtonsAlignmentClass(markUp.align) );
435
+ classes.push( getButtonsDisplayModeClass(markUp.displayMode) );
436
+ }
437
+
438
+ function getButtonsStyleClass(style) {
439
+ const prefix = 'tb-btn-style';
440
+ switch (style) {
441
+ case 'rounded':
442
+ return `${prefix}-rounded`;
443
+ case 'icons':
444
+ return `${prefix}-icons`;
445
+ default:
446
+ return `${prefix}-square`;
447
+ }
448
+ }
449
+
450
+ function getButtonsAlignmentClass(align) {
451
+ const prefix = 'tb-btn-align';
452
+ switch (align) {
453
+ case 'left':
454
+ return `${prefix}-left`;
455
+ case 'right':
456
+ return `${prefix}-right`;
457
+ default:
458
+ return `${prefix}-center`;
459
+ }
460
+ }
461
+
462
+ function getButtonsDisplayModeClass(mode) {
463
+ const prefix = 'tb-btn-mode';
464
+ if (mode === 'vertical') {
465
+ return `${prefix}-vertical`;
466
+ } else {
467
+ return `${prefix}-horizontal`;
468
+ }
469
+ }
470
+
471
+ return classes.join(' ');
472
+ }
473
+ };