customerio-gist-web 3.6.1

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.
@@ -0,0 +1,60 @@
1
+ export function resolveMessageProperties(message) {
2
+ var elementId = "";
3
+ var routeRule = "";
4
+ var position = "";
5
+ var isEmbedded = false;
6
+ var hasRouteRule = false;
7
+ var hasPosition = false;
8
+ var shouldScale = false;
9
+ var campaignId = null;
10
+ var persistent = false;
11
+ var overlayColor = "#00000033";
12
+ var messageWidth = 414;
13
+ var hasCustomWidth = false;
14
+
15
+ if (message.properties && message.properties.gist) {
16
+ if (message.properties.gist.campaignId) {
17
+ campaignId = message.properties.gist.campaignId;
18
+ }
19
+ if (message.properties.gist.elementId) {
20
+ elementId = message.properties.gist.elementId;
21
+ isEmbedded = true;
22
+ }
23
+ if (message.properties.gist.routeRuleWeb) {
24
+ routeRule = message.properties.gist.routeRuleWeb;
25
+ hasRouteRule = true;
26
+ }
27
+ if (message.properties.gist.position) {
28
+ position = message.properties.gist.position;
29
+ hasPosition = true;
30
+ }
31
+ if (message.properties.gist.scale) {
32
+ shouldScale = message.properties.gist.scale;
33
+ }
34
+ if (message.properties.gist.overlayColor) {
35
+ overlayColor = message.properties.gist.overlayColor;
36
+ }
37
+ if (message.properties.gist.messageWidth && message.properties.gist.messageWidth > 0) {
38
+ messageWidth = message.properties.gist.messageWidth;
39
+ hasCustomWidth = true;
40
+ }
41
+ if (message.properties.gist.persistent)
42
+ {
43
+ persistent = true
44
+ }
45
+ }
46
+ return {
47
+ isEmbedded: isEmbedded,
48
+ elementId: elementId,
49
+ hasRouteRule: hasRouteRule,
50
+ routeRule: routeRule,
51
+ position: position,
52
+ hasPosition: hasPosition,
53
+ shouldScale: shouldScale,
54
+ campaignId: campaignId,
55
+ messageWidth: messageWidth,
56
+ overlayColor: overlayColor,
57
+ persistent: persistent,
58
+ hasCustomWidth: hasCustomWidth
59
+ }
60
+ }
@@ -0,0 +1,170 @@
1
+ import { log } from "../utilities/log";
2
+ import { v4 as uuidv4 } from 'uuid';
3
+ import { embedMessage } from "./message-manager";
4
+ import { resolveMessageProperties } from "./gist-properties-manager";
5
+ const delay = ms => new Promise(res => setTimeout(res, ms));
6
+
7
+ export function isElementLoaded(elementId) {
8
+ var element = safelyFetchElement(elementId);
9
+ if (element && element.classList.contains("gist-visible")) {
10
+ return true;
11
+ } else {
12
+ return false;
13
+ }
14
+ }
15
+
16
+ export async function preloadRenderer() {
17
+ var preloadFrameId = `G${uuidv4().substring(0,8)}`;
18
+ var preloadFrameElement = document.createElement("div");
19
+ preloadFrameElement.setAttribute("id", preloadFrameId);
20
+ preloadFrameElement.style.display = "none";
21
+ document.body.appendChild(preloadFrameElement);
22
+
23
+ await delay(5000);
24
+ embedMessage({messageId: ""}, preloadFrameId);
25
+ }
26
+
27
+ export function loadEmbedComponent(elementId, url, message) {
28
+ var element = safelyFetchElement(elementId);
29
+ if (element) {
30
+ if (!elementHasHeight(elementId)) {
31
+ element.style.height = "0px";
32
+ }
33
+ element.innerHTML = embed(url, message);
34
+ } else {
35
+ log(`Message could not be embedded, elementId ${elementId} not found.`);
36
+ }
37
+ }
38
+
39
+ export function showEmbedComponent(elementId) {
40
+ var element = safelyFetchElement(elementId);
41
+ if (element) {
42
+ element.classList.add("gist-visible");
43
+ }
44
+ }
45
+
46
+ export function hideEmbedComponent(elementId) {
47
+ var element = safelyFetchElement(elementId);
48
+ if (element) {
49
+ element.classList.remove("gist-visible");
50
+ element.style.removeProperty("height");
51
+ element.innerHTML = "";
52
+ }
53
+ }
54
+
55
+ export function elementHasHeight(elementId) {
56
+ var element = safelyFetchElement(elementId);
57
+ if (element) {
58
+ return element.style && element.style.height && element.style.height != "0px";
59
+ }
60
+ }
61
+
62
+ export function resizeComponent(elementId, size, shouldScale) {
63
+ var element = safelyFetchElement(elementId);
64
+ if (element) {
65
+ var style = element.style;
66
+ if (size.height > 0) {
67
+ if (size.height > window.innerHeight) {
68
+ var heightScale = 1 - ((size.height / window.innerHeight) - 1);
69
+ if (shouldScale && heightScale >= 0.4) {
70
+ style.height = `${size.height}px`;
71
+ style.transform = `translateX(-50%) translateY(-50%) scale(${heightScale})`;
72
+ } else {
73
+ style.height = `${window.innerHeight}px`;
74
+ }
75
+ } else {
76
+ style.height = `${size.height}px`;
77
+ }
78
+ }
79
+ }
80
+ }
81
+
82
+ export function loadOverlayComponent(url, message) {
83
+ document.body.insertAdjacentHTML('beforeend', component(url, message));
84
+ }
85
+
86
+ export function showOverlayComponent(message) {
87
+ var mainMessageElement = document.querySelector("#gist-overlay");
88
+ if (mainMessageElement) {
89
+ mainMessageElement.classList.add("visible");
90
+ var messageElement = document.querySelector("#gist-message");
91
+ if (message.position) {
92
+ messageElement.classList.add(message.position);
93
+ } else {
94
+ messageElement.classList.add("center");
95
+ }
96
+ setTimeout(showMessage, 100);
97
+ } else {
98
+ removeOverlayComponent();
99
+ }
100
+ }
101
+
102
+ export async function hideOverlayComponent() {
103
+ var message = document.querySelector("#gist-message");
104
+ if (message) {
105
+ message.classList.remove("visible");
106
+ await delay(300);
107
+ }
108
+ removeOverlayComponent();
109
+ }
110
+
111
+ export function removeOverlayComponent() {
112
+ var mainMessageElement = document.querySelector("#gist-embed-message");
113
+ if (mainMessageElement) {
114
+ mainMessageElement.parentNode.removeChild(mainMessageElement);
115
+ }
116
+ }
117
+
118
+ function showMessage() {
119
+ var messageElement = document.querySelector("#gist-message");
120
+ if (messageElement) messageElement.classList.add("visible");
121
+ }
122
+
123
+ function embed(url, message) {
124
+ const wideOverlayPositions = ["x-gist-bottom", "x-gist-bottom", "x-gist-floating-top", "x-gist-floating-bottom"];
125
+ var messageProperties = resolveMessageProperties(message);
126
+ var maxWidthBreakpoint = 800;
127
+ if (messageProperties.messageWidth > maxWidthBreakpoint) {
128
+ maxWidthBreakpoint = messageProperties.messageWidth;
129
+ }
130
+
131
+ var messageWidth = messageProperties.messageWidth + "px";
132
+ if (wideOverlayPositions.includes(messageProperties.elementId) && !messageProperties.hasCustomWidth) {
133
+ messageWidth = "100%";
134
+ }
135
+
136
+ var template = require("html-loader!../templates/embed.html");
137
+ template = template.replace("'${topBottomMessageWidth}'", messageWidth);
138
+ template = template.replace("'${cornersMessageWidth}'", messageWidth);
139
+ template = template.replace("'${maxWidth}'", maxWidthBreakpoint + "px");
140
+ template = template.replace("${url}", url);
141
+ return template;
142
+ }
143
+
144
+ function component(url, message) {
145
+ var messageProperties = resolveMessageProperties(message);
146
+ var maxWidthBreakpoint = 600;
147
+ if (messageProperties.messageWidth > maxWidthBreakpoint) {
148
+ maxWidthBreakpoint = messageProperties.messageWidth;
149
+ }
150
+ var template = require("html-loader!../templates/message.html");
151
+ template = template.replace("'${messageWidth}'", messageProperties.messageWidth + "px");
152
+ template = template.replace("'${maxWidth}'", maxWidthBreakpoint + "px");
153
+ template = template.replace("'${overlayColor}'", messageProperties.overlayColor);
154
+ template = template.replace("${url}", url);
155
+ template = template.replace("${instanceId}", message.instanceId);
156
+ return template;
157
+ }
158
+
159
+ function safelyFetchElement(elementId) {
160
+ try {
161
+ var element = document.querySelector(`#${elementId}`);
162
+ if (element) {
163
+ return element;
164
+ } else {
165
+ return null;
166
+ }
167
+ } catch {
168
+ return null;
169
+ }
170
+ }
@@ -0,0 +1,291 @@
1
+ import Gist from '../gist';
2
+ import { log } from "../utilities/log";
3
+ import { logMessageView, logUserMessageView } from "../services/log-service";
4
+ import { v4 as uuidv4 } from 'uuid';
5
+ import { settings } from "../services/settings";
6
+ import {
7
+ loadOverlayComponent,
8
+ showOverlayComponent,
9
+ hideOverlayComponent,
10
+ removeOverlayComponent,
11
+ loadEmbedComponent,
12
+ showEmbedComponent,
13
+ hideEmbedComponent,
14
+ resizeComponent,
15
+ elementHasHeight,
16
+ isElementLoaded
17
+ } from "./message-component-manager";
18
+ import { resolveMessageProperties } from "./gist-properties-manager";
19
+ import { positions, addPageElement } from "./page-component-manager";
20
+ import { checkMessageQueue } from "./queue-manager";
21
+
22
+ var shownMessages = [];
23
+
24
+ export async function showMessage(message) {
25
+ if (Gist.isDocumentVisible) {
26
+ if (Gist.overlayInstanceId) {
27
+ log(`Message ${Gist.overlayInstanceId} already showing.`);
28
+ return null;
29
+ } else {
30
+ var properties = resolveMessageProperties(message)
31
+ message.instanceId = uuidv4();
32
+ message.overlay = true;
33
+ message.firstLoad = true;
34
+ message.shouldResizeHeight = true;
35
+ message.shouldScale = properties.shouldScale;
36
+ message.renderStartTime = new Date().getTime();
37
+ Gist.overlayInstanceId = message.instanceId;
38
+ Gist.currentMessages.push(message);
39
+
40
+ return loadMessageComponent(message);
41
+ }
42
+ } else {
43
+ log("Document hidden, not showing message now.");
44
+ return null;
45
+ }
46
+ }
47
+
48
+ export async function embedMessage(message, elementId) {
49
+ if (Gist.isDocumentVisible) {
50
+ message.instanceId = uuidv4();
51
+ message.overlay = false;
52
+ message.firstLoad = true;
53
+ message.shouldScale = false;
54
+ message.elementId = elementId;
55
+ message.shouldResizeHeight = !elementHasHeight(elementId);
56
+ message.renderStartTime = new Date().getTime();
57
+ Gist.currentMessages.push(message);
58
+
59
+ return loadMessageComponent(message, elementId);
60
+ } else {
61
+ log("Document hidden, not showing message now.");
62
+ return null;
63
+ }
64
+ }
65
+
66
+ export async function hideMessage(message) {
67
+ if (message) {
68
+ Gist.messageDismissed(message);
69
+
70
+ if (message.overlay) {
71
+ await resetOverlayState(true, message);
72
+ } else {
73
+ resetEmbedState(message);
74
+ }
75
+ } else {
76
+ log(`Message with instance id: ${instanceId} not found`);
77
+ }
78
+ }
79
+
80
+ export async function removePersistentMessage(message) {
81
+ var messageProperties = resolveMessageProperties(message);
82
+ if (message) {
83
+ if (messageProperties.persistent) {
84
+ log(`Persistent message dismissed, logging view`);
85
+ await reportMessageView(message);
86
+ }
87
+ } else {
88
+ log(`Message with instance id: ${instanceId} not found`);
89
+ }
90
+ }
91
+
92
+ function resetEmbedState(message) {
93
+ removeMessageByInstanceId(message.instanceId);
94
+ hideEmbedComponent(message.elementId);
95
+ }
96
+
97
+ async function resetOverlayState(hideFirst, message) {
98
+ removeMessageByInstanceId(message.instanceId);
99
+ Gist.overlayInstanceId = null;
100
+ if (hideFirst) {
101
+ await hideOverlayComponent();
102
+ } else {
103
+ removeOverlayComponent();
104
+ }
105
+
106
+ if (Gist.currentMessages.length == 0) {
107
+ window.removeEventListener('message', handleGistEvents);
108
+ window.removeEventListener('touchstart', handleTouchStartEvents);
109
+ }
110
+ }
111
+
112
+ function loadMessageComponent(message, elementId = null) {
113
+ if (elementId && isElementLoaded(elementId)) {
114
+ log(`Message ${message.messageId} already showing in element ${elementId}.`);
115
+ return null;
116
+ }
117
+
118
+ var options = {
119
+ endpoint: settings.ENGINE_API_ENDPOINT[Gist.config.env],
120
+ siteId: Gist.config.siteId,
121
+ dataCenter: Gist.config.dataCenter,
122
+ messageId: message.messageId,
123
+ instanceId: message.instanceId,
124
+ livePreview: false,
125
+ properties: message.properties
126
+ }
127
+ var url = `${settings.GIST_VIEW_ENDPOINT[Gist.config.env]}/index.html?options=${encodeUnicode(JSON.stringify(options))}`
128
+ window.addEventListener('message', handleGistEvents);
129
+ window.addEventListener('touchstart', handleTouchStartEvents);
130
+
131
+ if (elementId) {
132
+ if (positions.includes(elementId)) { addPageElement(elementId); }
133
+ loadEmbedComponent(elementId, url, message);
134
+ } else {
135
+ loadOverlayComponent(url, message);
136
+ }
137
+
138
+ return message;
139
+ }
140
+
141
+ function encodeUnicode(str) {
142
+ var base64Unicode = btoa(encodeURIComponent(str).replace(/%([0-9A-F]{2})/g,
143
+ function toSolidBytes(match, p1) {
144
+ return String.fromCharCode('0x' + p1);
145
+ }));
146
+
147
+ return encodeURIComponent(base64Unicode);
148
+ }
149
+
150
+ async function reportMessageView(message) {
151
+ Gist.messageShown(message);
152
+ log(`Message shown, logging view for: ${message.messageId}`);
153
+ var response = {};
154
+ if (message.queueId != null) {
155
+ response = await logUserMessageView(message.queueId);
156
+ } else {
157
+ response = await logMessageView(message.messageId);
158
+ }
159
+
160
+ if (response.status === 200) {
161
+ log(`Message view logged`);
162
+ } else {
163
+ log(`Problem logging message: ${response.status}`);
164
+ }
165
+ }
166
+
167
+ export function fetchMessageByInstanceId(instanceId) {
168
+ return Gist.currentMessages.find(message => message.instanceId === instanceId);
169
+ }
170
+
171
+ function removeMessageByInstanceId(instanceId) {
172
+ Gist.currentMessages = Gist.currentMessages.filter(message => message.instanceId !== instanceId)
173
+ }
174
+
175
+ function updateMessageByInstanceId(instanceId, message) {
176
+ removeMessageByInstanceId(instanceId);
177
+ Gist.currentMessages.push(message);
178
+ }
179
+
180
+ // Added this to avoid errors in the console
181
+ function handleTouchStartEvents(e) {}
182
+
183
+ async function handleGistEvents(e) {
184
+ if (e.data.gist) {
185
+ var currentInstanceId = e.data.gist.instanceId;
186
+ var currentMessage = fetchMessageByInstanceId(currentInstanceId);
187
+ if (!currentMessage) { return; }
188
+ var messageProperties = resolveMessageProperties(currentMessage);
189
+ switch (e.data.gist.method) {
190
+ case "routeLoaded": {
191
+ var timeElapsed = (new Date().getTime() - currentMessage.renderStartTime) * 0.001;
192
+ log(`Engine render for message: ${currentMessage.messageId} timer elapsed in ${timeElapsed.toFixed(3)} seconds`);
193
+ currentMessage.currentRoute = e.data.gist.parameters.route;
194
+ if (currentMessage.firstLoad) {
195
+ shownMessages.push(currentMessage);
196
+ if (currentMessage.overlay) {
197
+ showOverlayComponent(currentMessage);
198
+ } else {
199
+ showEmbedComponent(currentMessage.elementId);
200
+ }
201
+
202
+ if (messageProperties.persistent) {
203
+ log(`Persistent message shown, skipping logging view`);
204
+ } else {
205
+ await reportMessageView(currentMessage);
206
+ }
207
+
208
+ currentMessage.firstLoad = false;
209
+ }
210
+ updateMessageByInstanceId(currentInstanceId, currentMessage);
211
+ break;
212
+ }
213
+ case "tap": {
214
+ var action = e.data.gist.parameters.action;
215
+ var name = e.data.gist.parameters.name;
216
+ Gist.messageAction(currentMessage, action, name);
217
+
218
+ if (e.data.gist.parameters.system && !messageProperties.persistent) {
219
+ await hideMessage(currentMessage);
220
+ break;
221
+ }
222
+
223
+ try {
224
+ var url = new URL(action);
225
+ if (url && url.protocol === "gist:") {
226
+ var gistAction = url.href.replace("gist://", "").split('?')[0];
227
+ switch (gistAction) {
228
+ case "close":
229
+ await hideMessage(currentMessage);
230
+ await removePersistentMessage(currentMessage);
231
+ await checkMessageQueue();
232
+ break;
233
+ case "showMessage":
234
+ var messageId = url.searchParams.get('messageId');
235
+ var properties = url.searchParams.get('properties');
236
+ if (messageId) {
237
+ if (properties) {
238
+ properties = JSON.parse(atob(properties));
239
+ }
240
+ await Gist.showMessage({ messageId: messageId, properties: properties });
241
+ }
242
+ break;
243
+ case "loadPage":
244
+ var url = url.href.substring(url.href.indexOf('?url=') + 5);
245
+ if (url) {
246
+ if (url.startsWith("https://") || url.startsWith("http://") || url.startsWith("/")) {
247
+ window.location.href = url;
248
+ } else {
249
+ window.location.href = window.location + url;
250
+ }
251
+ }
252
+ break;
253
+ }
254
+ }
255
+ } catch (_) {}
256
+
257
+ break;
258
+ }
259
+ case "routeChanged": {
260
+ currentMessage.currentRoute = e.data.gist.parameters.route;
261
+ currentMessage.renderStartTime = new Date().getTime();
262
+ updateMessageByInstanceId(currentInstanceId, currentMessage);
263
+ log(`Route changed to: ${currentMessage.currentRoute}`);
264
+ break;
265
+ }
266
+ case "sizeChanged": {
267
+ log(`Size Changed Width: ${e.data.gist.parameters.width} - Height: ${e.data.gist.parameters.height}`)
268
+ if (currentMessage.elementId && currentMessage.shouldResizeHeight) {
269
+ resizeComponent(currentMessage.elementId, e.data.gist.parameters, currentMessage.shouldScale);
270
+ } else {
271
+ resizeComponent("gist-message", e.data.gist.parameters, currentMessage.shouldScale);
272
+ }
273
+ break;
274
+ }
275
+ case "error":
276
+ case "routeError": {
277
+ Gist.messageError(currentMessage);
278
+ if (Gist.overlayInstanceId) {
279
+ resetOverlayState(false, currentMessage);
280
+ } else {
281
+ resetEmbedState(currentMessage);
282
+ }
283
+ break;
284
+ }
285
+ }
286
+ }
287
+ }
288
+
289
+ export function hasMessageBeenShownBefore(message) {
290
+ return shownMessages.find(msg => msg.queueId === message.queueId) !== undefined;
291
+ }
@@ -0,0 +1,19 @@
1
+ import { log } from "../utilities/log";
2
+
3
+ export var positions = ["x-gist-top", "x-gist-floating-top", "x-gist-bottom", "x-gist-floating-bottom", "x-gist-floating-bottom-left", "x-gist-floating-bottom-right", "x-gist-floating-top-left", "x-gist-floating-top-right"];
4
+
5
+ export function addPageElement(position) {
6
+ const element = document.createElement("div");
7
+ element.id = position
8
+
9
+ switch (position) {
10
+ case "x-gist-top":
11
+ document.body.insertBefore(element, document.body.firstChild);
12
+ break;
13
+ default:
14
+ document.body.insertAdjacentElement("beforeend", element);
15
+ break;
16
+ }
17
+
18
+ log('Top & bottom elements injected into page');
19
+ }
@@ -0,0 +1,112 @@
1
+ import Gist from '../gist';
2
+ import { log } from "../utilities/log";
3
+ import { getUserToken } from "./user-manager";
4
+ import { getUserQueue } from "../services/queue-service";
5
+ import { showMessage, embedMessage, hasMessageBeenShownBefore } from "./message-manager";
6
+ import { resolveMessageProperties } from "./gist-properties-manager";
7
+ import { preloadRenderer } from "./message-component-manager";
8
+ import { setKeyWithExpiryToLocalStore, getKeyFromLocalStore } from '../utilities/local-storage';
9
+
10
+ const userQueueLocalStoreName = "gist.web.userQueue";
11
+ const POLLING_DELAY_IN_SECONDS = 1000 * 10;
12
+ var sleep = time => new Promise(resolve => setTimeout(resolve, time))
13
+ var poll = (promiseFn, time) => promiseFn().then(sleep(time).then(() => poll(promiseFn, time)));
14
+ var pollingSetup = false;
15
+ var messages = [];
16
+
17
+ export async function startQueueListener() {
18
+ if (!pollingSetup) {
19
+ preloadRenderer();
20
+ if (getUserToken()) {
21
+ log("Queue watcher started");
22
+ pollingSetup = true;
23
+ poll(() => new Promise(() => pollMessageQueue()), POLLING_DELAY_IN_SECONDS);
24
+ } else {
25
+ log(`User token not setup, queue not started.`);
26
+ }
27
+ } else {
28
+ await checkMessageQueue();
29
+ }
30
+ }
31
+
32
+ export async function checkMessageQueue() {
33
+ log(`Messages in local queue: ${messages.length}`);
34
+ var keptMessages = [];
35
+ var orderedMessages = messages.sort((a, b) => a.priority - b.priority);
36
+ for (const message of orderedMessages) {
37
+ var handledMessage = await handleMessage(message);
38
+ if (!handledMessage) {
39
+ var duplicateMessage = keptMessages.find(queueMessages => queueMessages.queueId === message.queueId);
40
+ var showingMessage = Gist.currentMessages.find(currentMessage => currentMessage.queueId === message.queueId);
41
+ if (duplicateMessage || showingMessage) {
42
+ log(`Message with queueId: ${message.queueId} already in queue, discarding.`);
43
+ } else {
44
+ keptMessages.push(message);
45
+ }
46
+ }
47
+ }
48
+ messages = keptMessages;
49
+ }
50
+
51
+ async function handleMessage(message) {
52
+ if (hasMessageBeenShownBefore(message)) {
53
+ log(`Message with ${message.queueId} has been shown before, skipping.`);
54
+ return;
55
+ }
56
+
57
+ var messageProperties = resolveMessageProperties(message);
58
+ if (messageProperties.hasRouteRule) {
59
+ var currentUrl = Gist.currentRoute
60
+ if (currentUrl == null) {
61
+ currentUrl = new URL(window.location.href).pathname;
62
+ }
63
+ var routeRule = messageProperties.routeRule;
64
+ log(`Verifying route against rule: ${routeRule}`);
65
+ var urlTester = new RegExp(routeRule);
66
+ if (!urlTester.test(currentUrl)) {
67
+ log(`Route ${currentUrl} does not match rule.`);
68
+ return false;
69
+ }
70
+ }
71
+ if (messageProperties.hasPosition) {
72
+ message.position = messageProperties.position;
73
+ }
74
+ if (messageProperties.isEmbedded) {
75
+ return await embedMessage(message, messageProperties.elementId);
76
+ } else {
77
+ return await showMessage(message);
78
+ }
79
+ }
80
+
81
+ export async function pollMessageQueue() {
82
+ if (getUserToken()) {
83
+ if (Gist.isDocumentVisible) {
84
+ var response = await getUserQueue();
85
+ var responseData = [];
86
+ if (response) {
87
+ if (response.status === 200 || response.status === 204) {
88
+ var expiryDate = new Date(new Date().getTime() + 1 * 60000);
89
+ setKeyWithExpiryToLocalStore(userQueueLocalStoreName, response.data, expiryDate);
90
+ responseData = response.data;
91
+ }
92
+ else if (response.status === 304) {
93
+ responseData = getKeyFromLocalStore(userQueueLocalStoreName);
94
+ }
95
+ if (responseData && responseData.length > 0) {
96
+ log(`Message queue checked for user ${getUserToken()}, ${responseData.length} messages found.`);
97
+ messages = responseData;
98
+ await checkMessageQueue();
99
+ } else {
100
+ messages = [];
101
+ log(`No messages for user token.`);
102
+ }
103
+ } else {
104
+ log(`There was an error while checking message queue.`);
105
+ }
106
+ } else {
107
+ log(`Document not visible, skipping queue check.`);
108
+ }
109
+ } else {
110
+ log(`User token reset, skipping queue check.`);
111
+ }
112
+ }
@@ -0,0 +1,47 @@
1
+ import { log } from '../utilities/log';
2
+ import { setKeyWithExpiryToLocalStore, getKeyFromLocalStore, clearKeyFromLocalStore } from '../utilities/local-storage';
3
+ import { v4 as uuidv4 } from 'uuid';
4
+ const userTokenLocalStoreName = "gist.web.userToken";
5
+ const guestUserTokenLocalStoreName = "gist.web.guestUserToken";
6
+ const usingGuestUserTokenLocalStoreName = "gist.web.usingGuestUserToken";
7
+
8
+ export function isUsingGuestUserToken() {
9
+ return (getKeyFromLocalStore(usingGuestUserTokenLocalStoreName) !== null);
10
+ }
11
+
12
+ export function getUserToken() {
13
+ return getKeyFromLocalStore(userTokenLocalStoreName);
14
+ }
15
+
16
+ export function setUserToken(userToken, expiryDate) {
17
+ if (expiryDate === undefined) {
18
+ expiryDate = new Date();
19
+ expiryDate.setDate(expiryDate.getDate() + 30);
20
+ }
21
+ setKeyWithExpiryToLocalStore(userTokenLocalStoreName, userToken, expiryDate);
22
+ clearKeyFromLocalStore(usingGuestUserTokenLocalStoreName);
23
+ log(`Set user token "${userToken}" with expiry date set to ${expiryDate}`);
24
+ }
25
+
26
+ export function useGuestSession() {
27
+ var expiryDate = new Date();
28
+ expiryDate.setDate(expiryDate.getDate() + 365);
29
+
30
+ // Guest sessions should never override existing sessions
31
+ if (getUserToken() === null) {
32
+ var guestUserToken = getKeyFromLocalStore(guestUserTokenLocalStoreName);
33
+ if (guestUserToken == null) {
34
+ guestUserToken = uuidv4();
35
+ setKeyWithExpiryToLocalStore(guestUserTokenLocalStoreName, guestUserToken, expiryDate);
36
+ log(`Set guest user token "${guestUserToken}" with expiry date set to 1 year from today`);
37
+ }
38
+
39
+ setKeyWithExpiryToLocalStore(userTokenLocalStoreName, guestUserToken, expiryDate);
40
+ setKeyWithExpiryToLocalStore(usingGuestUserTokenLocalStoreName, true, expiryDate);
41
+ }
42
+ }
43
+
44
+ export function clearUserToken() {
45
+ clearKeyFromLocalStore(userTokenLocalStoreName);
46
+ log(`Cleared user token`);
47
+ }