@textback/notification-widget 2.0.0 → 2.0.1-102913

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. package/.eslintrc.js +291 -291
  2. package/build/index.js +12 -0
  3. package/build/sdk.js +9 -0
  4. package/package.json +70 -68
  5. package/promote_tag.sh +1 -1
  6. package/readme.md +569 -490
  7. package/server.js +8 -4
  8. package/src/libraries/ai.1.0.11.js +4088 -4088
  9. package/src/libraries/localization/locales/cs.js +14 -12
  10. package/src/libraries/localization/locales/en.js +14 -12
  11. package/src/libraries/localization/locales/index.js +8 -8
  12. package/src/libraries/localization/locales/pl.js +14 -12
  13. package/src/libraries/localization/locales/ro.js +14 -12
  14. package/src/libraries/localization/locales/ru.js +13 -12
  15. package/src/libraries/localization/locales/uk.js +14 -12
  16. package/src/libraries/localization/text.js +9 -9
  17. package/src/libraries/t.js +82 -82
  18. package/src/sdk/channels/channel.js +30 -30
  19. package/src/sdk/channels/facebook.js +13 -13
  20. package/src/sdk/channels/factory.js +3 -3
  21. package/src/sdk/channels/skype.js +12 -12
  22. package/src/sdk/channels/telegram.js +18 -18
  23. package/src/sdk/channels/viber.js +12 -12
  24. package/src/sdk/channels/vk-modal/vk-modal.html +17 -17
  25. package/src/sdk/channels/vk-modal/vk-modal.js +25 -25
  26. package/src/sdk/channels/vk-modal/vk-modal.scss +116 -116
  27. package/src/sdk/channels/vk.js +195 -184
  28. package/src/sdk/channels/whatsapp.js +16 -10
  29. package/src/sdk/channels/whatsappb.js +27 -0
  30. package/src/sdk/events/observer.js +46 -46
  31. package/src/sdk/index.js +5 -5
  32. package/src/sdk/sdk.js +67 -30
  33. package/src/sdk/utils/apiErrorHandler.js +11 -11
  34. package/src/sdk/utils/appInsights.js +88 -88
  35. package/src/sdk/utils/browserInfo.js +8 -8
  36. package/src/sdk/utils/constants.js +17 -17
  37. package/src/sdk/utils/cookies.js +67 -50
  38. package/src/sdk/utils/find.js +7 -7
  39. package/src/sdk/utils/loadConfig.js +20 -20
  40. package/src/sdk/utils/loadDeepLink.js +48 -21
  41. package/src/sdk/utils/loadScript.js +25 -25
  42. package/src/sdk/utils/loadSubscriptions.js +6 -6
  43. package/src/sdk/utils/parseQueryString.js +33 -33
  44. package/src/sdk/utils/windowHelper.js +25 -25
  45. package/src/sdk/widget/widget.js +192 -140
  46. package/src/widget/components/index.js +6 -2
  47. package/src/widget/components/tb-notification-button/facebook.js +9 -2
  48. package/src/widget/components/tb-notification-button/index.js +34 -34
  49. package/src/widget/components/tb-notification-button/styles.scss +657 -433
  50. package/src/widget/components/tb-notification-button/telegram.js +9 -2
  51. package/src/widget/components/tb-notification-button/viber.js +9 -2
  52. package/src/widget/components/tb-notification-button/vk.js +59 -50
  53. package/src/widget/components/tb-notification-button/whatsapp.js +15 -8
  54. package/src/widget/components/tb-notification-button/whatsappb.js +58 -0
  55. package/src/widget/components/tb-notification-widget/index.js +589 -384
  56. package/src/widget/components/tb-notification-widget/normalize.scss +395 -394
  57. package/src/widget/components/tb-notification-widget/styles.scss +502 -139
  58. package/src/widget/components/tb-nw-wahunter/index.js +259 -0
  59. package/src/widget/components/tb-nw-wahunter/styles.scss +471 -0
  60. package/src/widget/config.js +5 -5
  61. package/src/widget/icons/icon_chat_window.svg +1 -0
  62. package/src/widget/icons/icon_close.svg +1 -0
  63. package/src/widget/icons/icon_facebook.svg +7 -7
  64. package/src/widget/icons/icon_facebook_circle.svg +7 -9
  65. package/src/widget/icons/icon_instagram_circle.svg +95 -95
  66. package/src/widget/icons/icon_skype.svg +44 -44
  67. package/src/widget/icons/icon_skype_circle.svg +46 -46
  68. package/src/widget/icons/icon_skype_new.svg +113 -113
  69. package/src/widget/icons/icon_tg.svg +25 -25
  70. package/src/widget/icons/icon_tg_circle.svg +17 -27
  71. package/src/widget/icons/icon_viber.svg +75 -75
  72. package/src/widget/icons/icon_viber_circle.svg +67 -77
  73. package/src/widget/icons/icon_viber_new.svg +102 -102
  74. package/src/widget/icons/icon_vk.svg +14 -14
  75. package/src/widget/icons/icon_vk_circle.svg +16 -16
  76. package/src/widget/icons/icon_whatsapp.svg +147 -147
  77. package/src/widget/icons/icon_whatsapp_circle.svg +3 -3
  78. package/src/widget/icons/icon_whatsapp_hollow.svg +128 -0
  79. package/src/widget/icons/icon_whatsapp_new.svg +127 -127
  80. package/src/widget/icons/icon_whatsappb.svg +147 -0
  81. package/src/widget/icons/icon_whatsappb_circle.svg +4 -0
  82. package/src/widget/icons/icon_whatsappb_new.svg +127 -0
  83. package/src/widget/icons/paper-plane-arrow.svg +3 -0
  84. package/src/widget/icons/tb-logo.svg +21 -0
  85. package/src/widget/index.js +28 -28
  86. package/src/widget/locales/cs.js +42 -0
  87. package/src/widget/locales/en.js +42 -20
  88. package/src/widget/locales/index.js +2 -2
  89. package/src/widget/locales/pl.js +41 -19
  90. package/src/widget/locales/ro.js +41 -20
  91. package/src/widget/locales/ru.js +40 -19
  92. package/src/widget/locales/uk.js +40 -19
  93. package/src/widget/utils/cookiesEx.js +41 -41
  94. package/src/widget/utils/getLocale.js +4 -2
  95. package/src/widget/utils/stringifyAttributes.js +19 -19
  96. package/src/widget/utils/text.js +2 -1
  97. package/src/widget/utils/widgetsStorage.js +28 -28
  98. package/src/widget/widget.entry.js +3 -4
  99. package/tests/gf.html +35 -35
  100. package/tests/gf.js +21 -21
  101. package/tests/index.js +61 -61
  102. package/views/examples.ejs +7 -3
  103. package/views/sdk.html +274 -256
  104. package/webpack.common.js +72 -72
  105. package/webpack.dev.js +15 -15
  106. package/webpack.prod.js +10 -10
  107. package/src/widget/components/tb-notification-button/skype.js +0 -47
  108. package/src/widget/icons/text-back-badge.png +0 -0
  109. package/src/widget/locales/cz.js +0 -20
@@ -1,184 +1,195 @@
1
- import UUID from 'uuid-js';
2
-
3
- import loadScript from '../utils/loadScript.js';
4
- import apiErrorHandler from '../utils/apiErrorHandler.js';
5
-
6
- import Channel from './channel.js';
7
- import VKModal from './vk-modal/vk-modal.js';
8
- import constants from "../utils/constants";
9
-
10
- const VK_API_VERSION = '5.73';
11
- const LOGIN_TIMEOUT = 4096;
12
-
13
- function loadVkLib(){
14
- return new Promise((resolve, reject) => {
15
- if (window.VK && window.VK.Auth) {
16
- resolve('vk cache')
17
- }
18
- else {
19
- loadScript('//vk.com/js/api/openapi.js')
20
- .then(function () {
21
- resolve('vk load')
22
- }, function (err) {
23
- reject(err)
24
- })
25
- }
26
- });
27
- }
28
-
29
- function initVK(apiId) {
30
- return new Promise((resolve, reject) => {
31
- if (apiId) {
32
- if (!window.VK._apiId) {
33
- window.VK.init({apiId});
34
- }
35
- window.VK.Auth.getLoginStatus(resolve)
36
- } else {
37
- reject('noVKApiId')
38
- }
39
- })
40
- }
41
-
42
- function handleVKLoadingError(error) {
43
- console.error('Failed to load VK openapi.js. VK channel will be unavailable');
44
- return null;
45
- }
46
-
47
- // isVkAppUsed :: Object -> Boolean
48
- const isVkAppUsed = config => {
49
- return config.useVkApp
50
- ? config.useVkApp
51
- : false;
52
- };
53
-
54
- export default class VKChannel extends Channel {
55
- constructor(channelData = {}, deeplink, widget) {
56
- super(channelData, deeplink, widget);
57
-
58
- this.vkApiId = this.widget.config.vkApiId;
59
- this.initPromise = null;
60
- this.vkPluginContainerId = null;
61
- this.authorized = false;
62
-
63
- if (this.enabled) {
64
- if (!this.widget.useVKApi) {
65
- this.vkPluginContainerId = UUID.create(4).hex;
66
- this.initPromise = loadVkLib()
67
- .catch(err => this.__handleVKLoadingError(err));
68
- } else {
69
- this.initPromise = loadVkLib()
70
- .then(() => initVK(this.vkApiId))
71
- .then(() => {
72
- this.authorized = !!(window.VK.Auth.getSession());
73
- })
74
- .catch(err => this.__handleVKLoadingError(err));
75
- }
76
- }
77
- }
78
-
79
- subscribe() {
80
- super.subscribe();
81
- return isVkAppUsed(this.widget.config)
82
- ? window.open(`https://vk.com/app${this.widget.config.vkApiId}_-${this.config.id}#r=subscribe_${this.deeplink}&accountId=${this.widget.config.accountId}&channelId=${this.channelId}`, 'vk',constants.SUBSCRIPTION_WINDOW_PROPS)
83
- : this.subscribeViaPlugin();
84
- }
85
-
86
- subscribeViaApi() {
87
- let promise = null;
88
- if (!this.authorized) {
89
- promise = this.__login().then( res => this.__allowMessagesFromGroup() );
90
- } else {
91
- promise = this.__allowMessagesFromGroup();
92
- }
93
- return promise;
94
- }
95
-
96
- __allowMessagesFromGroup () {
97
- window.VK.Api.call(
98
- 'messages.allowMessagesFromGroup',
99
- {
100
- group_id: this.id,
101
- v: VK_API_VERSION,
102
- },
103
- res => {
104
- const vkSession = window.VK.Auth.getSession();
105
- const vkUserId = vkSession.mid;
106
-
107
- if (res.response === 1) {
108
- this.__textbackSubscribe(vkUserId);
109
- } else {
110
- console.log('VK res error:', res)
111
- }
112
- }
113
- );
114
- }
115
-
116
-
117
- __login () {
118
- return new Promise(resolve => {
119
- window.VK.Auth.login(res => {
120
- resolve(res)
121
- }, LOGIN_TIMEOUT)
122
- })
123
- }
124
-
125
- __textbackSubscribe (vkUserId) {
126
- return fetch(`${this.widget.initialConfig.apiPath}/endUserNotifications/subscriptions`, {
127
- method: 'POST',
128
- headers: {
129
- 'Content-Type': 'application/json'
130
- },
131
- body: JSON.stringify({
132
- 'accountId': this.widget.config.accountId,
133
- 'insecureContext': this.widget.insecureContext,
134
- 'secureContextToken': this.widget.secureContextToken,
135
- 'address': {
136
- 'channel': 'vk',
137
- 'channelId': this.config.channelId,
138
- 'accountId': this.widget.config.accountId,
139
- 'remoteAddress': vkUserId,
140
- 'chatId': vkUserId
141
- },
142
- widgetId: this.widget.id,
143
- 'user': {
144
- 'id': this.widget.widgetUserId
145
- }
146
- })
147
- }).then(apiErrorHandler);
148
- }
149
-
150
- __handleVKLoadingError(err) {
151
- super.reportError('Failed to load VK openapi.js. VK channel will be unavailable.', err);
152
- return null;
153
- }
154
-
155
- subscribeViaPlugin() {
156
- const modal = new VKModal(this.vkPluginContainerId);
157
- this.renderVKSubscriptionButton();
158
-
159
- modal.onClose = () => {
160
- if (this.vkSubscribeHandler) {
161
- window.VK.Observer.unsubscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
162
- this.vkSubscribeHandler = null;
163
- }
164
- };
165
- }
166
-
167
- renderVKSubscriptionButton(height = 30, containerId = this.vkPluginContainerId) {
168
- if (this.vkSubscribeHandler) {
169
- window.VK.Observer.unsubscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
170
- this.vkSubscribeHandler = null;
171
- }
172
-
173
- const options = {
174
- height,
175
- key: this.deeplink
176
- };
177
-
178
- window.VK.Widgets.AllowMessagesFromCommunity(containerId, options, this.id);
179
- if (!this.config.disableAllowMessageEvents) {
180
- this.vkSubscribeHandler = this.__textbackSubscribe.bind(this);
181
- window.VK.Observer.subscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
182
- }
183
- }
184
- }
1
+ import UUID from 'uuid-js';
2
+
3
+ import loadScript from '../utils/loadScript.js';
4
+ import apiErrorHandler from '../utils/apiErrorHandler.js';
5
+
6
+ import Channel from './channel.js';
7
+ import VKModal from './vk-modal/vk-modal.js';
8
+ import constants from "../utils/constants";
9
+
10
+ const VK_API_VERSION = '5.131';
11
+ const LOGIN_TIMEOUT = 4096;
12
+
13
+ function loadVkLib(){
14
+ return new Promise((resolve, reject) => {
15
+ if (window.VK && window.VK.Auth) {
16
+ resolve('vk cache');
17
+ }
18
+ else {
19
+ loadScript('//vk.com/js/api/openapi.js')
20
+ .then(function () {
21
+ resolve('vk load');
22
+ }, function (err) {
23
+ reject(err);
24
+ });
25
+ }
26
+ });
27
+ }
28
+
29
+ function initVK(apiId) {
30
+ return new Promise((resolve, reject) => {
31
+ if (apiId) {
32
+ if (!window.VK._apiId) {
33
+ window.VK.init({apiId});
34
+ }
35
+ window.VK.Auth.getLoginStatus(resolve);
36
+ } else {
37
+ reject('noVKApiId');
38
+ }
39
+ });
40
+ }
41
+
42
+ function handleVKLoadingError(error) {
43
+ console.error('Failed to load VK openapi.js. VK channel will be unavailable');
44
+ return null;
45
+ }
46
+
47
+ // isVkAppUsed :: Object -> Boolean
48
+ const isVkAppUsed = config => {
49
+ return config.useVkApp
50
+ ? config.useVkApp
51
+ : false;
52
+ };
53
+
54
+ export default class VKChannel extends Channel {
55
+ constructor(channelData = {}, deeplink, widget) {
56
+ super(channelData, deeplink, widget);
57
+
58
+ this.isDoubleCheck = widget.config.isDoubleCheck;
59
+ this.vkApiId = this.widget.config.vkApiId;
60
+ this.initPromise = null;
61
+ this.vkPluginContainerId = null;
62
+ this.authorized = false;
63
+ this.landingUrl = this.config.additionalProperties ? this.config.additionalProperties.landingUrl : undefined;
64
+
65
+ if (this.enabled) {
66
+ this.vkPluginContainerId = UUID.create(4).hex;
67
+
68
+ if (!this.widget.useVKApi) {
69
+ this.initPromise = loadVkLib()
70
+ .catch(err => this.__handleVKLoadingError(err));
71
+ } else {
72
+ this.initPromise = loadVkLib()
73
+ .then(() => initVK(this.vkApiId))
74
+ .then(() => {
75
+ this.authorized = !!(window.VK.Auth.getSession());
76
+ })
77
+ .catch(err => this.__handleVKLoadingError(err));
78
+ }
79
+ }
80
+ }
81
+
82
+ subscribe() {
83
+ super.subscribe();
84
+ return this.landingUrl ?
85
+ window.open(this.landingUrl, '_blank')
86
+ :
87
+ (isVkAppUsed(this.widget.config)
88
+ ? window.open(`https://vk.com/app${this.widget.config.vkApiId}_-${this.config.id}#r=subscribe_${this.deeplink}&accountId=${this.widget.config.accountId}&channelId=${this.channelId}`, 'vk')
89
+ : this.subscribeViaPlugin());
90
+ }
91
+
92
+ subscribeViaApi() {
93
+ let promise = null;
94
+
95
+ if (!this.authorized) {
96
+ promise = this.__login().then( res => this.__allowMessagesFromGroup() );
97
+ } else {
98
+ promise = this.__allowMessagesFromGroup();
99
+ }
100
+ return promise;
101
+ }
102
+
103
+ __allowMessagesFromGroup () {
104
+ window.VK.Api.call(
105
+ 'messages.allowMessagesFromGroup',
106
+ {
107
+ group_id: this.id,
108
+ v: VK_API_VERSION,
109
+ },
110
+ res => {
111
+ const vkSession = window.VK.Auth.getSession();
112
+ const vkUserId = vkSession.mid;
113
+
114
+ if (res.response === 1) {
115
+ this.__textbackSubscribe(vkUserId);
116
+ } else {
117
+ console.log('VK res error:', res);
118
+ }
119
+ }
120
+ );
121
+ }
122
+
123
+
124
+ __login () {
125
+ return new Promise(resolve => {
126
+ window.VK.Auth.login(res => {
127
+ resolve(res);
128
+ }, LOGIN_TIMEOUT);
129
+ });
130
+ }
131
+
132
+ __textbackSubscribe (vkUserId, channelWidgetIdx) {
133
+ //we shall parse deeplink from server webhook. This method looks like artifact from age without webhhoks.
134
+ if(!this.isDoubleCheck) return null;
135
+
136
+ return fetch(`${this.widget.initialConfig.apiPath}/endUserNotifications/subscriptions`, {
137
+ method: 'POST',
138
+ headers: {
139
+ 'Content-Type': 'application/json'
140
+ },
141
+ body: JSON.stringify({
142
+ 'accountId': this.widget.config.accountId,
143
+ 'insecureContext': this.widget.insecureContext,
144
+ 'secureContextToken': this.widget.secureContextToken,
145
+ 'address': {
146
+ 'channel': 'vk',
147
+ 'channelId': this.config.channelId,
148
+ 'accountId': this.widget.config.accountId,
149
+ 'remoteAddress': vkUserId,
150
+ 'chatId': vkUserId
151
+ },
152
+ deepLinkId: this.deeplink.replace('subscribe_',''),
153
+ widgetId: this.widget.id,
154
+ 'user': {
155
+ 'id': this.widget.widgetUserId
156
+ }
157
+ })
158
+ }).then(apiErrorHandler);
159
+ }
160
+
161
+ __handleVKLoadingError(err) {
162
+ super.reportError('Failed to load VK openapi.js. VK channel will be unavailable.', err);
163
+ return null;
164
+ }
165
+
166
+ subscribeViaPlugin() {
167
+ const modal = new VKModal(this.vkPluginContainerId);
168
+ this.renderVKSubscriptionButton();
169
+
170
+ modal.onClose = () => {
171
+ if (this.vkSubscribeHandler) {
172
+ window.VK.Observer.unsubscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
173
+ this.vkSubscribeHandler = null;
174
+ }
175
+ };
176
+ }
177
+
178
+ renderVKSubscriptionButton(height = 30, containerId = this.vkPluginContainerId) {
179
+ if (this.vkSubscribeHandler) {
180
+ window.VK.Observer.unsubscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
181
+ this.vkSubscribeHandler = null;
182
+ }
183
+
184
+ const options = {
185
+ height,
186
+ key: this.deeplink
187
+ };
188
+
189
+ window.VK.Widgets.AllowMessagesFromCommunity(containerId, options, this.id);
190
+ if (!this.config.disableAllowMessageEvents) {
191
+ this.vkSubscribeHandler = this.__textbackSubscribe.bind(this);
192
+ window.VK.Observer.subscribe('widgets.allowMessagesFromCommunity.allowed', this.vkSubscribeHandler);
193
+ }
194
+ }
195
+ }
@@ -1,21 +1,27 @@
1
1
  import Channel from './channel.js';
2
2
  import browserInfo from '../utils/browserInfo.js';
3
- import constants from '../utils/constants.js';
4
3
  import getLocale from '../../libraries/localization/getLocale.js';
5
4
  import text from '../../libraries/localization/text.js';
6
5
 
7
6
  export default class WhatsappChannel extends Channel {
8
- constructor(channelData = {}, deeplink, widget) {
9
- super(channelData, deeplink, widget);
7
+ constructor(channelData = {}, deeplink, widget) {
8
+ super(channelData, deeplink, widget);
10
9
 
11
- this.domainPrefix = browserInfo.isMobile() ? 'api' : 'web';
10
+ this.domainPrefix = browserInfo.isMobile() ? 'api' : 'web';
11
+
12
+ if(channelData.hasOwnProperty('additionalProperties') && channelData.additionalProperties.hasOwnProperty('customDeeplinkValue')) {
13
+ this.customText = channelData.additionalProperties.customDeeplinkValue;
14
+ } else {
15
+ this.customText = null;
12
16
  }
17
+ }
13
18
 
14
- subscribe() {
15
- super.subscribe();
19
+ subscribe() {
20
+ super.subscribe();
16
21
 
17
- let prefixText = encodeURIComponent(text('whatsapp_prefixtext', getLocale()));
18
-
19
- window.open(`https://${this.domainPrefix}.whatsapp.com/send?phone=${this.id}&text=${prefixText} ${this.deeplink}`, 'whatsapp', constants.SUBSCRIPTION_WINDOW_PROPS);
20
- }
22
+ let prefixText = text('whatsapp_prefixtext', getLocale());
23
+ let deeplink = this.customText ? this.customText : `${prefixText} ${this.deeplink}`;
24
+
25
+ window.open(`https://api.whatsapp.com/send/?phone=+${this.id}&text=${encodeURIComponent(deeplink)}&app_absent=0`, 'whatsapp');
26
+ }
21
27
  }
@@ -0,0 +1,27 @@
1
+ import Channel from './channel.js';
2
+ import browserInfo from '../utils/browserInfo.js';
3
+ import getLocale from '../../libraries/localization/getLocale.js';
4
+ import text from '../../libraries/localization/text.js';
5
+
6
+ export default class WhatsappbChannel extends Channel {
7
+ constructor(channelData = {}, deeplink, widget) {
8
+ super(channelData, deeplink, widget);
9
+
10
+ this.domainPrefix = browserInfo.isMobile() ? 'api' : 'web';
11
+
12
+ if(channelData.hasOwnProperty('additionalProperties') && channelData.additionalProperties.hasOwnProperty('customDeeplinkValue')) {
13
+ this.customText = channelData.additionalProperties.customDeeplinkValue;
14
+ } else {
15
+ this.customText = null;
16
+ }
17
+ }
18
+
19
+ subscribe() {
20
+ super.subscribe();
21
+
22
+ let prefixText = text('whatsapp_prefixtext', getLocale());
23
+ let deeplink = this.customText ? this.customText : `${prefixText} ${this.deeplink}`;
24
+
25
+ window.open(`https://api.whatsapp.com/send/?phone=+${this.id}&text=${encodeURIComponent(deeplink)}&app_absent=0`, 'whatsappb');
26
+ }
27
+ }
@@ -1,46 +1,46 @@
1
- import assign from 'lodash/assign';
2
-
3
- const EVENTS = {
4
- WIDGET_INIT: 'widget.init',
5
- SUBSCRIBE_START: 'subscribe.start',
6
- };
7
-
8
- const _handlers = {};
9
-
10
- window.TextBack = window.TextBack || {};
11
- window.TextBack.Observer = window.TextBack.Observer || {
12
- on(eventName, fn) {
13
- if (!_handlers[eventName]) {
14
- _handlers[eventName] = [ fn ];
15
- } else {
16
- _handlers[eventName].push(fn);
17
- }
18
-
19
- return () => {
20
- const fnIndex = _handlers[eventName].indexOf(fn);
21
- if (fnIndex !== -1) {
22
- _handlers[eventName].splice(fnIndex, 1);
23
- }
24
- };
25
- },
26
-
27
- trigger(eventName, data) {
28
- if (_handlers[eventName]) {
29
- const eventData = assign({}, data, { type: eventName });
30
- setTimeout(() => {
31
- _handlers[eventName].forEach(handler => {
32
- try {
33
- handler(eventData)
34
- } catch (err) {
35
- console.error(`Error occuired while executing event handler on event ${eventName}`, err);
36
- }
37
- });
38
- }, 0);
39
-
40
- }
41
- }
42
- };
43
-
44
- const Observer = window.TextBack.Observer;
45
-
46
- export { Observer, EVENTS };
1
+ import assign from 'lodash/assign';
2
+
3
+ const EVENTS = {
4
+ WIDGET_INIT: 'widget.init',
5
+ SUBSCRIBE_START: 'subscribe.start',
6
+ };
7
+
8
+ const _handlers = {};
9
+
10
+ window.TextBack = window.TextBack || {};
11
+ window.TextBack.Observer = window.TextBack.Observer || {
12
+ on(eventName, fn) {
13
+ if (!_handlers[eventName]) {
14
+ _handlers[eventName] = [ fn ];
15
+ } else {
16
+ _handlers[eventName].push(fn);
17
+ }
18
+
19
+ return () => {
20
+ const fnIndex = _handlers[eventName].indexOf(fn);
21
+ if (fnIndex !== -1) {
22
+ _handlers[eventName].splice(fnIndex, 1);
23
+ }
24
+ };
25
+ },
26
+
27
+ trigger(eventName, data) {
28
+ if (_handlers[eventName]) {
29
+ const eventData = assign({}, data, { type: eventName });
30
+ setTimeout(() => {
31
+ _handlers[eventName].forEach(handler => {
32
+ try {
33
+ handler(eventData)
34
+ } catch (err) {
35
+ console.error(`Error occuired while executing event handler on event ${eventName}`, err);
36
+ }
37
+ });
38
+ }, 0);
39
+
40
+ }
41
+ }
42
+ };
43
+
44
+ const Observer = window.TextBack.Observer;
45
+
46
+ export { Observer, EVENTS };
package/src/sdk/index.js CHANGED
@@ -1,6 +1,6 @@
1
- import SDK from './sdk.js';
2
-
3
- window.TextBack = window.TextBack || {};
4
- window.TextBack.SDK = window.TextBack.SDK || new SDK();
5
-
1
+ import SDK from './sdk.js';
2
+
3
+ window.TextBack = window.TextBack || {};
4
+ window.TextBack.SDK = window.TextBack.SDK || new SDK();
5
+
6
6
  export default window.TextBack.SDK;
package/src/sdk/sdk.js CHANGED
@@ -1,30 +1,67 @@
1
- require('es6-promise').polyfill();
2
- import 'whatwg-fetch';
3
-
4
- import Widget from './widget/widget.js';
5
- import { Observer, EVENTS } from './events/observer.js';
6
-
7
- export default class SDK {
8
- constructor() {
9
- this.widgets = {};
10
- }
11
-
12
- initWidget(config) {
13
- if (config && config.widgetId) {
14
- const widget = new Widget(config, this);
15
- this.widgets[config.widgetId] = widget.initialize();
16
- this.widgets[config.widgetId].then(widget => Observer.trigger(EVENTS.WIDGET_INIT, { widgetId: config.widgetId }), err => console.error(err));
17
- return this.widgets[config.widgetId];
18
- } else {
19
- throw new Error('Widget id is not defined');
20
- }
21
- }
22
-
23
- getWidget(widgetId) {
24
- return this.widgets[widgetId] ? this.widgets[widgetId] : null;
25
- }
26
-
27
- on(eventName, fn) {
28
- return Observer.on(eventName, fn);
29
- }
30
- }
1
+ import apiErrorHandler from "./utils/apiErrorHandler";
2
+ import 'whatwg-fetch';
3
+
4
+ import Widget from './widget/widget.js';
5
+ import {EVENTS, Observer} from './events/observer.js';
6
+ import {deeplinkUpdater} from './utils/loadDeepLink.js';
7
+
8
+ require('es6-promise').polyfill();
9
+
10
+ export default class SDK {
11
+ constructor() {
12
+ this.widgets = {};
13
+ this._deeplinkUpdater = deeplinkUpdater;
14
+ }
15
+
16
+ initWidget(config, preventViewCounting = false) {
17
+ if (config && config.widgetId) {
18
+ const widget = new Widget(config, this);
19
+ this.widgets[config.widgetId] = widget.initialize();
20
+ this.widgets[config.widgetId].then(widget => {
21
+ Observer.trigger(EVENTS.WIDGET_INIT, {widgetId: config.widgetId});
22
+
23
+ // First of all, this is a restriction on the count of views for textback settings page ( = for widget preview)
24
+ if (preventViewCounting) return;
25
+
26
+ this.countWidgetView(widget);
27
+ }, err => console.error(err));
28
+ return this.widgets[config.widgetId];
29
+ } else {
30
+ throw new Error('Widget id is not defined');
31
+ }
32
+ }
33
+
34
+ countWidgetView(widget) {
35
+ return fetch(`${widget.initialConfig.apiPath}/endUserNotifications/subscriptions/notificationWidget/views`, {
36
+ method: 'POST',
37
+ headers: {
38
+ 'Content-Type': 'application/json'
39
+ },
40
+ body: JSON.stringify({
41
+ 'accountId': widget.config.accountId,
42
+ 'widgetId': widget.id
43
+ })
44
+ }).then(apiErrorHandler);
45
+ }
46
+
47
+ getWidget(widgetId) {
48
+ return this.widgets[widgetId] ? this.widgets[widgetId] : null;
49
+ }
50
+
51
+ on(eventName, fn) {
52
+ return Observer.on(eventName, fn);
53
+ }
54
+
55
+ getDeeplinkUpdater(widgetId) {
56
+ let _getWidget = this.widgets[widgetId];
57
+
58
+ if (!_getWidget) return null;
59
+
60
+ return _getWidget.then(x => {
61
+ return this._deeplinkUpdater(
62
+ x.initialConfig.apiPath,
63
+ x.deeplink.split('_')[1]
64
+ );
65
+ });
66
+ }
67
+ }