@textback/notification-widget 2.0.0 → 2.0.1-102913

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 (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
+ }