@seamly/web-ui 20.4.0 → 20.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/dist/lib/index.debug.js +35 -68
- package/build/dist/lib/index.debug.min.js +1 -1
- package/build/dist/lib/index.debug.min.js.LICENSE.txt +4 -16
- package/build/dist/lib/index.js +374 -3850
- package/build/dist/lib/index.min.js +1 -1
- package/build/dist/lib/index.min.js.LICENSE.txt +0 -5
- package/build/dist/lib/standalone.js +394 -3862
- package/build/dist/lib/standalone.min.js +1 -1
- package/build/dist/lib/style-guide.js +200 -113
- package/build/dist/lib/style-guide.min.js +1 -1
- package/package.json +2 -4
- package/src/javascripts/api/index.js +17 -1
- package/src/javascripts/domains/config/reducer.js +2 -0
- package/src/javascripts/domains/forms/provider.js +14 -6
- package/src/javascripts/domains/visibility/actions.js +2 -0
- package/src/javascripts/domains/visibility/hooks.js +60 -1
- package/src/javascripts/domains/visibility/reducer.js +5 -0
- package/src/javascripts/domains/visibility/selectors.js +5 -0
- package/src/javascripts/domains/visibility/utils.js +5 -1
- package/src/javascripts/style-guide/components/app.js +2 -0
- package/src/javascripts/style-guide/states.js +30 -50
- package/src/javascripts/ui/components/conversation/event/card-component.js +1 -2
- package/src/javascripts/ui/components/conversation/event/conversation-suggestions.js +19 -9
- package/src/javascripts/ui/components/conversation/event/cta.js +1 -2
- package/src/javascripts/ui/components/conversation/event/participant.js +2 -11
- package/src/javascripts/ui/components/conversation/event/splash.js +1 -3
- package/src/javascripts/ui/components/conversation/event/text.js +9 -9
- package/src/javascripts/ui/components/layout/chat.js +52 -48
- package/src/javascripts/ui/components/suggestions/suggestions-list.js +12 -14
- package/src/javascripts/ui/components/view/deprecated-view.js +16 -11
- package/src/javascripts/ui/components/view/inline-view.js +13 -8
- package/src/javascripts/ui/hooks/seamly-entry-hooks.js +3 -2
- package/src/javascripts/ui/hooks/seamly-state-hooks.js +4 -3
- package/src/javascripts/ui/hooks/use-seamly-chat.js +41 -29
- package/src/javascripts/ui/hooks/use-seamly-commands.js +16 -4
- package/src/javascripts/ui/utils/seamly-utils.js +16 -6
- package/src/javascripts/lib/parse-body.js +0 -10
- package/src/javascripts/ui/components/conversation/event/hooks/use-text-rendering.js +0 -35
|
@@ -273,8 +273,7 @@ const infoMessage = {
|
|
|
273
273
|
payload: {
|
|
274
274
|
body: {
|
|
275
275
|
text: 'This is a system generated info message',
|
|
276
|
-
type: 'text'
|
|
277
|
-
variables: {}
|
|
276
|
+
type: 'text'
|
|
278
277
|
},
|
|
279
278
|
fromClient: false,
|
|
280
279
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
@@ -327,7 +326,7 @@ const participantMessage = {
|
|
|
327
326
|
participant: {
|
|
328
327
|
avatar,
|
|
329
328
|
id: 'agent',
|
|
330
|
-
introduction: "You're now talking to
|
|
329
|
+
introduction: "You're now talking to Mrs. Bot gimme a minit",
|
|
331
330
|
name: 'Mrs. Bot',
|
|
332
331
|
service: {
|
|
333
332
|
expose: {
|
|
@@ -353,7 +352,7 @@ const participantMessageDefaultIcon = {
|
|
|
353
352
|
messageStatus: 'received',
|
|
354
353
|
participant: {
|
|
355
354
|
id: 'user',
|
|
356
|
-
introduction: "You're now talking to
|
|
355
|
+
introduction: "You're now talking to Mrs. Bot gimme a minit",
|
|
357
356
|
name: 'Mrs. Bot',
|
|
358
357
|
service: {
|
|
359
358
|
expose: {
|
|
@@ -381,8 +380,7 @@ const getCustomMessage = ({
|
|
|
381
380
|
body: {
|
|
382
381
|
type,
|
|
383
382
|
text,
|
|
384
|
-
data
|
|
385
|
-
variables: {}
|
|
383
|
+
data
|
|
386
384
|
},
|
|
387
385
|
participant: 'agent',
|
|
388
386
|
service: {
|
|
@@ -407,8 +405,7 @@ const shortTextMessage = {
|
|
|
407
405
|
payload: {
|
|
408
406
|
body: {
|
|
409
407
|
text: 'What do you want to do?',
|
|
410
|
-
type: 'text'
|
|
411
|
-
variables: {}
|
|
408
|
+
type: 'text'
|
|
412
409
|
},
|
|
413
410
|
fromClient: false,
|
|
414
411
|
fromHistory: true,
|
|
@@ -443,7 +440,7 @@ const ctaMessage = {
|
|
|
443
440
|
type: 'message',
|
|
444
441
|
payload: {
|
|
445
442
|
body: {
|
|
446
|
-
description: 'Thanks for chatting!\n\nMore info about our
|
|
443
|
+
description: 'Thanks for chatting!\n\nMore info about our <strong>products</strong>?',
|
|
447
444
|
buttonLink: 'https://seamly.ai',
|
|
448
445
|
buttonText: 'View website',
|
|
449
446
|
buttonNewTab: true
|
|
@@ -472,8 +469,7 @@ const longTextMessage = {
|
|
|
472
469
|
payload: {
|
|
473
470
|
body: {
|
|
474
471
|
text: 'What do you want to do? This is a really long message from a bot that has a lot to say about a lot of things. Currently I am contemplating my own bot existence and constantly asking myself who I am. What do you want to do? This is a really long message from a bot that has a lot to say about a lot of things. Currently I am contemplating my own bot existence and constantly asking myself who I am. What do you want to do? This is a really long message from a bot that has a lot to say about a lot of things. Currently I am contemplating my own bot existence and constantly asking myself who I am.',
|
|
475
|
-
type: 'text'
|
|
476
|
-
variables: {}
|
|
472
|
+
type: 'text'
|
|
477
473
|
},
|
|
478
474
|
fromClient: false,
|
|
479
475
|
fromHistory: true,
|
|
@@ -496,9 +492,8 @@ const textMessageBoldItalicUnderline = {
|
|
|
496
492
|
type: 'message',
|
|
497
493
|
payload: {
|
|
498
494
|
body: {
|
|
499
|
-
text: 'Bubble with
|
|
500
|
-
type: 'text'
|
|
501
|
-
variables: {}
|
|
495
|
+
text: 'Bubble with <strong>bold</strong> <em>italic</em> <u>underline</u>',
|
|
496
|
+
type: 'text'
|
|
502
497
|
},
|
|
503
498
|
fromClient: false,
|
|
504
499
|
fromHistory: true,
|
|
@@ -523,24 +518,8 @@ const textMessageWithLinks = {
|
|
|
523
518
|
type: 'message',
|
|
524
519
|
payload: {
|
|
525
520
|
body: {
|
|
526
|
-
text: '
|
|
527
|
-
type: 'text'
|
|
528
|
-
variables: {
|
|
529
|
-
link_1: {
|
|
530
|
-
id: '1',
|
|
531
|
-
name: 'Link in same window',
|
|
532
|
-
newTab: false,
|
|
533
|
-
type: 'link',
|
|
534
|
-
url: 'https://google.com'
|
|
535
|
-
},
|
|
536
|
-
link_2: {
|
|
537
|
-
id: '2',
|
|
538
|
-
name: 'link in new window',
|
|
539
|
-
newTab: true,
|
|
540
|
-
type: 'link',
|
|
541
|
-
url: 'https://google.com'
|
|
542
|
-
}
|
|
543
|
-
}
|
|
521
|
+
text: '<a href="https://google.com" data-link-id="1">Link in same window</a> and <a href="https://google.com" data-link-id="2" target="_blank">link in new window</a> embedded in text',
|
|
522
|
+
type: 'text'
|
|
544
523
|
},
|
|
545
524
|
fromClient: false,
|
|
546
525
|
fromHistory: true,
|
|
@@ -565,17 +544,8 @@ const textMessageWithLongLink = {
|
|
|
565
544
|
type: 'message',
|
|
566
545
|
payload: {
|
|
567
546
|
body: {
|
|
568
|
-
text: 'Here is a long link
|
|
569
|
-
type: 'text'
|
|
570
|
-
variables: {
|
|
571
|
-
link_1: {
|
|
572
|
-
id: '1',
|
|
573
|
-
name: 'click me click me please click me yoohoooo please please click me here I am click me now what are you waiting for click me now now now now now click meeeeeeeeeeeeee',
|
|
574
|
-
newTab: false,
|
|
575
|
-
type: 'link',
|
|
576
|
-
url: 'https://google.com'
|
|
577
|
-
}
|
|
578
|
-
}
|
|
547
|
+
text: 'Here is a long link <a href="https://google.com" data-link-id="1">click me click me please click me yoohoooo please please click me here I am click me now what are you waiting for click me now now now now now click meeeeeeeeeeeeee</a> embedded in text',
|
|
548
|
+
type: 'text'
|
|
579
549
|
},
|
|
580
550
|
fromClient: false,
|
|
581
551
|
fromHistory: true,
|
|
@@ -601,8 +571,7 @@ const textMesageWithBullets = {
|
|
|
601
571
|
payload: {
|
|
602
572
|
body: {
|
|
603
573
|
text: '<ul>\n<li>Bullets</li>\n<li>bullets</li>\n<li>bullets</li>\n</ul>\n',
|
|
604
|
-
type: 'text'
|
|
605
|
-
variables: {}
|
|
574
|
+
type: 'text'
|
|
606
575
|
},
|
|
607
576
|
fromClient: false,
|
|
608
577
|
fromHistory: true,
|
|
@@ -763,8 +732,7 @@ const userMessage = {
|
|
|
763
732
|
payload: {
|
|
764
733
|
body: {
|
|
765
734
|
text: 'This is what the user typed',
|
|
766
|
-
type: 'text'
|
|
767
|
-
variables: {}
|
|
735
|
+
type: 'text'
|
|
768
736
|
},
|
|
769
737
|
fromClient: true,
|
|
770
738
|
fromHistory: true,
|
|
@@ -781,8 +749,24 @@ const userMessageLong = {
|
|
|
781
749
|
payload: {
|
|
782
750
|
body: {
|
|
783
751
|
text: 'This is what the user typed. And sometimes the user has quite a lot to say and then we get longer lines that need to wrap well and not break the styling so here goes with just such a line right here!!',
|
|
784
|
-
type: 'text'
|
|
785
|
-
|
|
752
|
+
type: 'text'
|
|
753
|
+
},
|
|
754
|
+
fromClient: true,
|
|
755
|
+
fromHistory: true,
|
|
756
|
+
id: (0,web_ui_namespaceObject.randomId)(),
|
|
757
|
+
messageStatus: 'read',
|
|
758
|
+
participant: 'user',
|
|
759
|
+
transactionId: '1cdefea9-7437-4672-bcf8-2c75dc99244c',
|
|
760
|
+
transactionLast: null,
|
|
761
|
+
type: 'text'
|
|
762
|
+
}
|
|
763
|
+
};
|
|
764
|
+
const userMessageWithLinks = {
|
|
765
|
+
type: 'message',
|
|
766
|
+
payload: {
|
|
767
|
+
body: {
|
|
768
|
+
text: '<a href="https://google.com" data-link-id="1">Link in same window</a> and <a href="https://google.com" data-link-id="2" target="_blank">link in new window</a> embedded in text',
|
|
769
|
+
type: 'text'
|
|
786
770
|
},
|
|
787
771
|
fromClient: true,
|
|
788
772
|
fromHistory: true,
|
|
@@ -968,7 +952,7 @@ const cardAskText = {
|
|
|
968
952
|
type: 'ask'
|
|
969
953
|
},
|
|
970
954
|
buttonText: 'Ask about pizzas!',
|
|
971
|
-
description: 'Pizza Margherita is a
|
|
955
|
+
description: 'Pizza Margherita is a <strong>typical Neapolitan pizza</strong>.\n\nIt is made with San Marzano tomatoes, mozzarella cheese, fresh basil, salt, and extra-virgin olive oil.',
|
|
972
956
|
image: 'https://developers.seamly.ai/clients/web-ui/static/photos/card-square.jpg',
|
|
973
957
|
title: 'Pizza Margherita'
|
|
974
958
|
}
|
|
@@ -986,7 +970,7 @@ const cardNavigate = {
|
|
|
986
970
|
type: 'navigate'
|
|
987
971
|
},
|
|
988
972
|
buttonText: 'Order now!',
|
|
989
|
-
description: 'Pizza Margherita is a
|
|
973
|
+
description: 'Pizza Margherita is a <strong>typical Neapolitan pizza</strong>.',
|
|
990
974
|
image: 'https://developers.seamly.ai/clients/web-ui/static/photos/card-landscape.jpg',
|
|
991
975
|
title: 'Pizza Margherita'
|
|
992
976
|
}
|
|
@@ -1164,7 +1148,7 @@ const standardState = {
|
|
|
1164
1148
|
payload: states_objectSpread(states_objectSpread({}, choicePromptMessage.payload), {}, {
|
|
1165
1149
|
id: `${choicePromptMessage.payload.id}XXX`
|
|
1166
1150
|
})
|
|
1167
|
-
}), longTextMessage, userMessage, textMessageBoldItalicUnderline, newTopicDivider, imageMessage, fileDownloadAgentMessage, deletedFileDownloadAgentMessage, userMessageLong, videoMessage, textMessageWithLinks, textMessageWithLongLink, imageMessageWithLightbox, fileDownloadUserMessage, emptyUrlFileDownloadUserMessage, textMesageWithBullets, choicePromptMessage, ctaMessage]
|
|
1151
|
+
}), longTextMessage, userMessage, textMessageBoldItalicUnderline, userMessageWithLinks, newTopicDivider, imageMessage, fileDownloadAgentMessage, deletedFileDownloadAgentMessage, userMessageLong, videoMessage, textMessageWithLinks, textMessageWithLongLink, imageMessageWithLightbox, fileDownloadUserMessage, emptyUrlFileDownloadUserMessage, textMesageWithBullets, choicePromptMessage, ctaMessage]
|
|
1168
1152
|
}),
|
|
1169
1153
|
userMessages: states_objectSpread(states_objectSpread({
|
|
1170
1154
|
category: categoryKeys.messages,
|
|
@@ -1172,7 +1156,7 @@ const standardState = {
|
|
|
1172
1156
|
description: ''
|
|
1173
1157
|
}, baseState), {}, {
|
|
1174
1158
|
participantInfo,
|
|
1175
|
-
events: [userMessage, userMessageLong, fileDownloadUserMessage, emptyUrlFileDownloadUserMessage]
|
|
1159
|
+
events: [userMessage, userMessageLong, fileDownloadUserMessage, emptyUrlFileDownloadUserMessage, userMessageWithLinks]
|
|
1176
1160
|
}),
|
|
1177
1161
|
withParticipants: states_objectSpread(states_objectSpread({
|
|
1178
1162
|
category: categoryKeys.messages,
|
|
@@ -1239,8 +1223,7 @@ const standardState = {
|
|
|
1239
1223
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1240
1224
|
body: {
|
|
1241
1225
|
text: 'Long ago when a dialog started',
|
|
1242
|
-
type: 'text'
|
|
1243
|
-
variables: {}
|
|
1226
|
+
type: 'text'
|
|
1244
1227
|
}
|
|
1245
1228
|
})
|
|
1246
1229
|
}, participantMessage, participantMessageDefaultIcon, newTopicDivider, transcriptInfoMessage, ...[newTranslationDividerStart, newTranslationDividerStop].map(addTranslationData), infoMessage]
|
|
@@ -1284,8 +1267,7 @@ const standardState = {
|
|
|
1284
1267
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1285
1268
|
body: {
|
|
1286
1269
|
text: 'Long ago when a dialog started',
|
|
1287
|
-
type: 'text'
|
|
1288
|
-
variables: {}
|
|
1270
|
+
type: 'text'
|
|
1289
1271
|
}
|
|
1290
1272
|
})
|
|
1291
1273
|
}, {
|
|
@@ -1295,8 +1277,7 @@ const standardState = {
|
|
|
1295
1277
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1296
1278
|
body: {
|
|
1297
1279
|
text: 'Above me should be a time indicator showing the full date',
|
|
1298
|
-
type: 'text'
|
|
1299
|
-
variables: {}
|
|
1280
|
+
type: 'text'
|
|
1300
1281
|
}
|
|
1301
1282
|
})
|
|
1302
1283
|
}, {
|
|
@@ -1306,8 +1287,7 @@ const standardState = {
|
|
|
1306
1287
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1307
1288
|
body: {
|
|
1308
1289
|
text: 'Another message',
|
|
1309
|
-
type: 'text'
|
|
1310
|
-
variables: {}
|
|
1290
|
+
type: 'text'
|
|
1311
1291
|
}
|
|
1312
1292
|
})
|
|
1313
1293
|
}, {
|
|
@@ -1317,8 +1297,7 @@ const standardState = {
|
|
|
1317
1297
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1318
1298
|
body: {
|
|
1319
1299
|
text: 'And another message',
|
|
1320
|
-
type: 'text'
|
|
1321
|
-
variables: {}
|
|
1300
|
+
type: 'text'
|
|
1322
1301
|
}
|
|
1323
1302
|
})
|
|
1324
1303
|
}, {
|
|
@@ -1328,8 +1307,7 @@ const standardState = {
|
|
|
1328
1307
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1329
1308
|
body: {
|
|
1330
1309
|
text: 'Above me should be a time indicator showing "yesterday"',
|
|
1331
|
-
type: 'text'
|
|
1332
|
-
variables: {}
|
|
1310
|
+
type: 'text'
|
|
1333
1311
|
}
|
|
1334
1312
|
})
|
|
1335
1313
|
}, {
|
|
@@ -1339,8 +1317,7 @@ const standardState = {
|
|
|
1339
1317
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1340
1318
|
body: {
|
|
1341
1319
|
text: 'Another message',
|
|
1342
|
-
type: 'text'
|
|
1343
|
-
variables: {}
|
|
1320
|
+
type: 'text'
|
|
1344
1321
|
}
|
|
1345
1322
|
})
|
|
1346
1323
|
}, {
|
|
@@ -1350,8 +1327,7 @@ const standardState = {
|
|
|
1350
1327
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1351
1328
|
body: {
|
|
1352
1329
|
text: 'And another message',
|
|
1353
|
-
type: 'text'
|
|
1354
|
-
variables: {}
|
|
1330
|
+
type: 'text'
|
|
1355
1331
|
}
|
|
1356
1332
|
})
|
|
1357
1333
|
}, {
|
|
@@ -1361,8 +1337,7 @@ const standardState = {
|
|
|
1361
1337
|
id: (0,web_ui_namespaceObject.randomId)(),
|
|
1362
1338
|
body: {
|
|
1363
1339
|
text: 'Above me should be a time indicator showing me the dialog continues today',
|
|
1364
|
-
type: 'text'
|
|
1365
|
-
variables: {}
|
|
1340
|
+
type: 'text'
|
|
1366
1341
|
}
|
|
1367
1342
|
})
|
|
1368
1343
|
}]
|
|
@@ -1940,7 +1915,7 @@ const newInterface = {
|
|
|
1940
1915
|
headingText: 'Suggestions message',
|
|
1941
1916
|
description: ''
|
|
1942
1917
|
}, baseState), {}, {
|
|
1943
|
-
events: [{
|
|
1918
|
+
events: [getCustomMessage(shortTextMessage.payload.body), {
|
|
1944
1919
|
type: 'service_data',
|
|
1945
1920
|
payload: {
|
|
1946
1921
|
type: 'suggestion',
|
|
@@ -2413,14 +2388,16 @@ const orderHistory = events => {
|
|
|
2413
2388
|
};
|
|
2414
2389
|
|
|
2415
2390
|
const mergeHistory = (stateEvents, historyEvents) => {
|
|
2416
|
-
const
|
|
2417
|
-
|
|
2391
|
+
const newStateEvents = stateEvents.filter(stateEvent => // Deduplicate the event streams, giving events in historyEvents
|
|
2392
|
+
// precedence so the server is able to push changes to events.
|
|
2393
|
+
!historyEvents.some(historyEvent => historyEvent.payload.id === stateEvent.payload.id));
|
|
2394
|
+
const newHistoryEvents = historyEvents.filter(historyEvent => // Remove all non displayable participant messages
|
|
2418
2395
|
!(historyEvent.type === 'participant' && !historyEvent.payload.participant.introduction)) // Reverse is done here because the server sends the history in the order
|
|
2419
2396
|
// newest to oldest. In the case of exactly the same occurredAt timestamps
|
|
2420
2397
|
// these messages will be shown in the wrong order if not reversed. For
|
|
2421
2398
|
// the normal merging logic there is no added effect.
|
|
2422
2399
|
.reverse();
|
|
2423
|
-
return orderHistory([...newHistoryEvents, ...
|
|
2400
|
+
return orderHistory([...newHistoryEvents, ...newStateEvents]);
|
|
2424
2401
|
};
|
|
2425
2402
|
|
|
2426
2403
|
const participantReducer = (state, action) => {
|
|
@@ -2801,8 +2778,12 @@ const seamlyStateReducer = (state, action) => {
|
|
|
2801
2778
|
});
|
|
2802
2779
|
|
|
2803
2780
|
case SET_INITIAL_STATE:
|
|
2781
|
+
const {
|
|
2782
|
+
initialState
|
|
2783
|
+
} = action;
|
|
2804
2784
|
return seamly_utils_objectSpread(seamly_utils_objectSpread({}, state), {}, {
|
|
2805
|
-
initialState
|
|
2785
|
+
initialState,
|
|
2786
|
+
unreadEvents: initialState.unreadMessageCount
|
|
2806
2787
|
});
|
|
2807
2788
|
|
|
2808
2789
|
case SET_SERVICE_DATA_ITEM:
|
|
@@ -3765,18 +3746,23 @@ const useEntryTextLimit = () => {
|
|
|
3765
3746
|
entryMeta: {
|
|
3766
3747
|
options: {
|
|
3767
3748
|
text
|
|
3749
|
+
},
|
|
3750
|
+
optionsOverride: {
|
|
3751
|
+
text: overrideText
|
|
3768
3752
|
}
|
|
3769
3753
|
}
|
|
3770
3754
|
} = seamly_state_hooks_useSeamlyStateContext();
|
|
3771
3755
|
const {
|
|
3772
3756
|
limit
|
|
3773
|
-
} = text || {
|
|
3757
|
+
} = overrideText || text || {
|
|
3758
|
+
limit: null
|
|
3759
|
+
};
|
|
3774
3760
|
return {
|
|
3775
|
-
hasLimit: limit
|
|
3776
|
-
limit: limit
|
|
3761
|
+
hasLimit: limit !== null,
|
|
3762
|
+
limit: limit !== null ? limit : null
|
|
3777
3763
|
};
|
|
3778
3764
|
};
|
|
3779
|
-
const
|
|
3765
|
+
const seamly_state_hooks_useSeamlyLayoutMode = () => {
|
|
3780
3766
|
const {
|
|
3781
3767
|
layoutMode
|
|
3782
3768
|
} = useConfig();
|
|
@@ -3809,7 +3795,12 @@ const calculateVisibility = ({
|
|
|
3809
3795
|
} = config;
|
|
3810
3796
|
const {
|
|
3811
3797
|
visible: defaultVisibility
|
|
3812
|
-
} = defaults || {}; //
|
|
3798
|
+
} = defaults || {}; // The app layout should always be open by default.
|
|
3799
|
+
|
|
3800
|
+
if (layoutMode === 'app' && !previousVisibility) {
|
|
3801
|
+
return constants_visibilityStates.open;
|
|
3802
|
+
} // Requesting open should override the responded check.
|
|
3803
|
+
|
|
3813
3804
|
|
|
3814
3805
|
if (layoutMode === 'window' && hideOnNoUserResponse && requestedVisibility !== constants_visibilityStates.open) {
|
|
3815
3806
|
return hasResponded ? requestedVisibility || previousVisibility || constants_visibilityStates.open : constants_visibilityStates.hidden;
|
|
@@ -3828,6 +3819,7 @@ const calculateVisibility = ({
|
|
|
3828
3819
|
|
|
3829
3820
|
|
|
3830
3821
|
const selectVisibility = createSelector(visibility_utils_selectState, state => state.visibility);
|
|
3822
|
+
const selectors_selectShowInlineView = createSelector(visibility_utils_selectState, state => state.showInlineView);
|
|
3831
3823
|
|
|
3832
3824
|
;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/actions.js
|
|
3833
3825
|
function actions_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
@@ -3845,6 +3837,7 @@ function actions_defineProperty(obj, key, value) { if (key in obj) { Object.defi
|
|
|
3845
3837
|
const setFromStorage = visibility_utils_createAction('setFromStorage', visibility => ({
|
|
3846
3838
|
visibility
|
|
3847
3839
|
}));
|
|
3840
|
+
const setShowInlineView = visibility_utils_createAction('setShowInlineView');
|
|
3848
3841
|
const validVisibilityStates = [constants_visibilityStates.open, constants_visibilityStates.minimized, constants_visibilityStates.hidden];
|
|
3849
3842
|
const setVisibility = visibility_utils_createThunk('set', (requestedVisibility, {
|
|
3850
3843
|
getState,
|
|
@@ -3992,7 +3985,7 @@ const clear = interrupt_utils_createAction('clear');
|
|
|
3992
3985
|
|
|
3993
3986
|
|
|
3994
3987
|
|
|
3995
|
-
const
|
|
3988
|
+
const actions_setHasResponded = app_utils_createAction('setHasResponded', hasResponded => ({
|
|
3996
3989
|
hasResponded
|
|
3997
3990
|
}));
|
|
3998
3991
|
const app_actions_initialize = app_utils_createThunk('initialize', async (_, {
|
|
@@ -4050,7 +4043,7 @@ const app_actions_initialize = app_utils_createThunk('initialize', async (_, {
|
|
|
4050
4043
|
locale = initialState.translation?.locale || locale;
|
|
4051
4044
|
|
|
4052
4045
|
if ('userResponded' in initialState) {
|
|
4053
|
-
dispatch(
|
|
4046
|
+
dispatch(actions_setHasResponded(initialState.userResponded));
|
|
4054
4047
|
}
|
|
4055
4048
|
} else {
|
|
4056
4049
|
if (config?.context?.topic) {
|
|
@@ -4356,6 +4349,7 @@ function provider_objectWithoutPropertiesLoose(source, excluded) { if (source ==
|
|
|
4356
4349
|
|
|
4357
4350
|
|
|
4358
4351
|
|
|
4352
|
+
|
|
4359
4353
|
function provider_FormProvider(_ref) {
|
|
4360
4354
|
let {
|
|
4361
4355
|
children,
|
|
@@ -4411,13 +4405,13 @@ function provider_FormProvider(_ref) {
|
|
|
4411
4405
|
setIsSubmitted(!ariaDisabled);
|
|
4412
4406
|
|
|
4413
4407
|
if (!ariaDisabled && validationIsValid) {
|
|
4408
|
+
dispatch(setHasResponded(true));
|
|
4414
4409
|
onSubmit(values, {
|
|
4415
4410
|
updateControlValue,
|
|
4416
4411
|
setError
|
|
4417
4412
|
});
|
|
4418
4413
|
}
|
|
4419
|
-
}, [validationIsValid, onSubmit, values, updateControlValue, setError]);
|
|
4420
|
-
|
|
4414
|
+
}, [validationIsValid, dispatch, onSubmit, values, updateControlValue, setError]);
|
|
4421
4415
|
useEffect(() => {
|
|
4422
4416
|
if (onError) {
|
|
4423
4417
|
onError({
|
|
@@ -4662,6 +4656,7 @@ function config_reducer_defineProperty(obj, key, value) { if (key in obj) { Obje
|
|
|
4662
4656
|
|
|
4663
4657
|
const config_reducer_initialState = config_reducer_objectSpread(config_reducer_objectSpread({}, defaultConfig), {}, {
|
|
4664
4658
|
hideOnNoUserResponse: false,
|
|
4659
|
+
connectWhenInView: true,
|
|
4665
4660
|
showDisclaimer: false,
|
|
4666
4661
|
showFaq: false,
|
|
4667
4662
|
customComponents: {},
|
|
@@ -4669,7 +4664,7 @@ const config_reducer_initialState = config_reducer_objectSpread(config_reducer_o
|
|
|
4669
4664
|
preChatEvents: []
|
|
4670
4665
|
});
|
|
4671
4666
|
|
|
4672
|
-
const configKeys = ['hideOnNoUserResponse', 'showDisclaimer', 'showFaq', 'namespace', 'customComponents', 'defaults', 'layoutMode', 'api', 'zIndex', 'context', 'appContainerClassNames', 'messages', 'visible', 'visibilityCallback', 'errorCallback', 'agentParticipant', 'userParticipant', 'startChatIcon'];
|
|
4667
|
+
const configKeys = ['hideOnNoUserResponse', 'connectWhenInView', 'showDisclaimer', 'showFaq', 'namespace', 'customComponents', 'defaults', 'layoutMode', 'api', 'zIndex', 'context', 'appContainerClassNames', 'messages', 'visible', 'visibilityCallback', 'errorCallback', 'agentParticipant', 'userParticipant', 'startChatIcon'];
|
|
4673
4668
|
|
|
4674
4669
|
const updateState = (state, {
|
|
4675
4670
|
config
|
|
@@ -5938,6 +5933,7 @@ function hooks_useUserHasResponded() {
|
|
|
5938
5933
|
|
|
5939
5934
|
|
|
5940
5935
|
|
|
5936
|
+
|
|
5941
5937
|
const hooks_useVisibility = () => {
|
|
5942
5938
|
const dispatch = useStoreDispatch();
|
|
5943
5939
|
const visible = useSelector(Selectors.selectVisibility);
|
|
@@ -5953,6 +5949,69 @@ const hooks_useVisibility = () => {
|
|
|
5953
5949
|
setVisibility
|
|
5954
5950
|
};
|
|
5955
5951
|
};
|
|
5952
|
+
/**
|
|
5953
|
+
* Custom hook which enables initializing of IntersectionObserver on any node ref.
|
|
5954
|
+
* @param {object} options Hook options.
|
|
5955
|
+
* @param {boolean=} options.freezeOnceVisible Stops observing when the root element is visible.
|
|
5956
|
+
* @param {boolean=} options.enabled Determines if useIntersect is enabled.
|
|
5957
|
+
*/
|
|
5958
|
+
|
|
5959
|
+
const useIntersect = ({
|
|
5960
|
+
freezeOnceVisible = false,
|
|
5961
|
+
enabled = true
|
|
5962
|
+
}) => {
|
|
5963
|
+
const [entry, setEntry] = useState(null);
|
|
5964
|
+
const containerRef = useRef(null);
|
|
5965
|
+
const isVisible = !!entry?.isIntersecting || !enabled;
|
|
5966
|
+
const frozen = isVisible && freezeOnceVisible;
|
|
5967
|
+
|
|
5968
|
+
const observerCallback = ([updatedEntry]) => setEntry(updatedEntry);
|
|
5969
|
+
|
|
5970
|
+
useEffect(() => {
|
|
5971
|
+
const node = containerRef?.current;
|
|
5972
|
+
const hasIOSupport = !!window.IntersectionObserver;
|
|
5973
|
+
|
|
5974
|
+
if (!node && "production" === 'development') {} // Return an arrow function to have a consistent return value
|
|
5975
|
+
|
|
5976
|
+
|
|
5977
|
+
if (!hasIOSupport || frozen || !node || !enabled) return () => undefined;
|
|
5978
|
+
const observerOptions = {
|
|
5979
|
+
threshold: 0,
|
|
5980
|
+
root: null,
|
|
5981
|
+
rootMargin: '0%'
|
|
5982
|
+
};
|
|
5983
|
+
const observer = new IntersectionObserver(observerCallback, observerOptions);
|
|
5984
|
+
observer.observe(node);
|
|
5985
|
+
return () => observer.disconnect();
|
|
5986
|
+
}, [enabled, frozen]);
|
|
5987
|
+
return {
|
|
5988
|
+
isVisible,
|
|
5989
|
+
containerRef
|
|
5990
|
+
};
|
|
5991
|
+
};
|
|
5992
|
+
|
|
5993
|
+
const useShowInlineView = () => {
|
|
5994
|
+
const dispatch = useStoreDispatch();
|
|
5995
|
+
const {
|
|
5996
|
+
connectWhenInView
|
|
5997
|
+
} = useConfig();
|
|
5998
|
+
const showInlineView = useSelector(Selectors.selectShowInlineView);
|
|
5999
|
+
const {
|
|
6000
|
+
containerRef,
|
|
6001
|
+
isVisible
|
|
6002
|
+
} = useIntersect({
|
|
6003
|
+
enabled: connectWhenInView,
|
|
6004
|
+
freezeOnceVisible: true
|
|
6005
|
+
});
|
|
6006
|
+
useEffect(() => {
|
|
6007
|
+
if (!isVisible) return;
|
|
6008
|
+
dispatch(Actions.setShowInlineView());
|
|
6009
|
+
}, [dispatch, isVisible]);
|
|
6010
|
+
return {
|
|
6011
|
+
containerRef,
|
|
6012
|
+
showInlineView
|
|
6013
|
+
};
|
|
6014
|
+
};
|
|
5956
6015
|
;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/reducer.js
|
|
5957
6016
|
function visibility_reducer_ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
|
|
5958
6017
|
|
|
@@ -5964,7 +6023,8 @@ function visibility_reducer_defineProperty(obj, key, value) { if (key in obj) {
|
|
|
5964
6023
|
|
|
5965
6024
|
|
|
5966
6025
|
const visibility_reducer_initialState = {
|
|
5967
|
-
visibility: constants_visibilityStates.initialize
|
|
6026
|
+
visibility: constants_visibilityStates.initialize,
|
|
6027
|
+
showInlineView: false
|
|
5968
6028
|
};
|
|
5969
6029
|
/* harmony default export */ const visibility_reducer = (visibility_utils_createReducer({
|
|
5970
6030
|
[setFromStorage]: (state, {
|
|
@@ -5976,7 +6036,10 @@ const visibility_reducer_initialState = {
|
|
|
5976
6036
|
payload: visibility
|
|
5977
6037
|
}) => visibility ? visibility_reducer_objectSpread(visibility_reducer_objectSpread({}, state), {}, {
|
|
5978
6038
|
visibility
|
|
5979
|
-
}) : state
|
|
6039
|
+
}) : state,
|
|
6040
|
+
[setShowInlineView]: state => visibility_reducer_objectSpread(visibility_reducer_objectSpread({}, state), {}, {
|
|
6041
|
+
showInlineView: true
|
|
6042
|
+
})
|
|
5980
6043
|
}, visibility_reducer_initialState));
|
|
5981
6044
|
;// CONCATENATED MODULE: ./src/javascripts/domains/visibility/index.js
|
|
5982
6045
|
|
|
@@ -6047,7 +6110,8 @@ const use_seamly_commands_useSeamlyCommands = () => {
|
|
|
6047
6110
|
const hasResponded = useUserHasResponded();
|
|
6048
6111
|
const hasConversation = useSeamlyHasConversation();
|
|
6049
6112
|
const {
|
|
6050
|
-
visible: visibility
|
|
6113
|
+
visible: visibility,
|
|
6114
|
+
setVisibility
|
|
6051
6115
|
} = useVisibility();
|
|
6052
6116
|
const unreadMessageCount = useSeamlyUnreadCount();
|
|
6053
6117
|
const emitEvent = useCallback((...args) => {
|
|
@@ -6105,7 +6169,9 @@ const use_seamly_commands_useSeamlyCommands = () => {
|
|
|
6105
6169
|
type: use_seamly_commands_ADD_EVENT,
|
|
6106
6170
|
event: {
|
|
6107
6171
|
type: 'message',
|
|
6108
|
-
payload: message
|
|
6172
|
+
payload: use_seamly_commands_objectSpread(use_seamly_commands_objectSpread({}, message), {}, {
|
|
6173
|
+
optimisticallyInjected: true
|
|
6174
|
+
})
|
|
6109
6175
|
}
|
|
6110
6176
|
});
|
|
6111
6177
|
}, [api, dispatch, emitEvent, getTextMessageBase]);
|
|
@@ -6203,11 +6269,16 @@ const use_seamly_commands_useSeamlyCommands = () => {
|
|
|
6203
6269
|
type: use_seamly_commands_SET_INITIAL_STATE,
|
|
6204
6270
|
initialState
|
|
6205
6271
|
});
|
|
6272
|
+
|
|
6273
|
+
if (initialState.userResponded) {
|
|
6274
|
+
dispatch(AppActions.setHasResponded(initialState.userResponded));
|
|
6275
|
+
setVisibility(visibilityStates.open);
|
|
6276
|
+
}
|
|
6206
6277
|
}
|
|
6207
6278
|
}).catch(error => {
|
|
6208
6279
|
dispatch(InterruptActions.set(error));
|
|
6209
6280
|
});
|
|
6210
|
-
}, [api, dispatch]);
|
|
6281
|
+
}, [api, dispatch, setVisibility]);
|
|
6211
6282
|
return {
|
|
6212
6283
|
connect,
|
|
6213
6284
|
start,
|
|
@@ -6220,6 +6291,7 @@ const use_seamly_commands_useSeamlyCommands = () => {
|
|
|
6220
6291
|
addMessageBubble,
|
|
6221
6292
|
addUploadBubble,
|
|
6222
6293
|
addDivider,
|
|
6294
|
+
apiConnected: api.connected,
|
|
6223
6295
|
apiConfigReady: api.configReady
|
|
6224
6296
|
};
|
|
6225
6297
|
};
|
|
@@ -6349,11 +6421,12 @@ const useSeamlyEntry = () => {
|
|
|
6349
6421
|
default: defaultEntry,
|
|
6350
6422
|
active,
|
|
6351
6423
|
userSelected,
|
|
6352
|
-
options: entryOptions
|
|
6424
|
+
options: entryOptions,
|
|
6425
|
+
optionsOverride: entryOptionsOverride
|
|
6353
6426
|
} = useSeamlyStateContext().entryMeta;
|
|
6354
6427
|
const dispatch = useSeamlyDispatchContext();
|
|
6355
6428
|
const activeEntry = userSelected || active || defaultEntry;
|
|
6356
|
-
const activeEntryOptions = entryOptions[activeEntry] || {};
|
|
6429
|
+
const activeEntryOptions = entryOptionsOverride[activeEntry] || entryOptions[activeEntry] || {};
|
|
6357
6430
|
const setBlockAutoEntrySwitch = useCallback(value => {
|
|
6358
6431
|
dispatch({
|
|
6359
6432
|
type: seamly_entry_hooks_SET_BLOCK_AUTO_ENTRY_SWITCH,
|
|
@@ -6399,6 +6472,7 @@ const useSeamlyEntry = () => {
|
|
|
6399
6472
|
|
|
6400
6473
|
|
|
6401
6474
|
|
|
6475
|
+
|
|
6402
6476
|
const {
|
|
6403
6477
|
SET_IS_LOADING: use_seamly_chat_SET_IS_LOADING
|
|
6404
6478
|
} = seamly_utils_seamlyActions;
|
|
@@ -6408,28 +6482,31 @@ const useSeamlyChat = () => {
|
|
|
6408
6482
|
t
|
|
6409
6483
|
} = useI18n();
|
|
6410
6484
|
const {
|
|
6411
|
-
|
|
6412
|
-
|
|
6485
|
+
isInline,
|
|
6486
|
+
isWindow
|
|
6487
|
+
} = useSeamlyLayoutMode();
|
|
6413
6488
|
const {
|
|
6414
6489
|
isOpen,
|
|
6415
6490
|
isVisible,
|
|
6416
6491
|
setVisibility
|
|
6417
6492
|
} = useVisibility();
|
|
6493
|
+
const showInlineView = useSelector(selectShowInlineView);
|
|
6418
6494
|
const dispatch = useSeamlyDispatchContext();
|
|
6419
6495
|
const events = useEvents();
|
|
6420
6496
|
const spinnerTimeout = useRef(null);
|
|
6421
6497
|
const {
|
|
6422
6498
|
start,
|
|
6423
6499
|
connect,
|
|
6424
|
-
apiConfigReady
|
|
6500
|
+
apiConfigReady,
|
|
6501
|
+
apiConnected
|
|
6425
6502
|
} = useSeamlyCommands();
|
|
6426
6503
|
const hasConversation = useSeamlyHasConversation();
|
|
6427
6504
|
const prevIsOpen = useRef(null);
|
|
6428
6505
|
const prevIsVisible = useRef(null);
|
|
6506
|
+
const startCalled = useRef(false);
|
|
6429
6507
|
const {
|
|
6430
6508
|
sendAssertive
|
|
6431
6509
|
} = useLiveRegion();
|
|
6432
|
-
const connectCalled = useRef(false);
|
|
6433
6510
|
const hasEvents = events.length > 0;
|
|
6434
6511
|
useEffect(() => {
|
|
6435
6512
|
if (isVisible) {
|
|
@@ -6478,22 +6555,34 @@ const useSeamlyChat = () => {
|
|
|
6478
6555
|
}
|
|
6479
6556
|
}, [hasEvents, dispatch]);
|
|
6480
6557
|
useEffect(() => {
|
|
6481
|
-
// This is needed to reset the ref to allow connect to happen again.
|
|
6558
|
+
// This is needed to reset the ref to allow connect and start to happen again.
|
|
6482
6559
|
// Mostly due to Interrupt situations and a reset being called.
|
|
6483
|
-
if (!
|
|
6484
|
-
|
|
6560
|
+
if (!apiConfigReady || !apiConnected) {
|
|
6561
|
+
startCalled.current = false;
|
|
6485
6562
|
}
|
|
6486
|
-
}, [
|
|
6563
|
+
}, [apiConfigReady, apiConnected]);
|
|
6564
|
+
const connectAndStart = useCallback(async () => {
|
|
6565
|
+
// We don't connect if we are already connected to the api to avoid multiple in-flight connection processes.
|
|
6566
|
+
if (!apiConnected) {
|
|
6567
|
+
await connect();
|
|
6568
|
+
} // We only start a conversation when the chat interface is either 'open' or if using the inline view if it's 'open' or 'minimized'.
|
|
6569
|
+
|
|
6570
|
+
|
|
6571
|
+
if (isOpen || isVisible && isInline) {
|
|
6572
|
+
start();
|
|
6573
|
+
startCalled.current = true;
|
|
6574
|
+
}
|
|
6575
|
+
}, [apiConnected, connect, isInline, isOpen, isVisible, start]);
|
|
6487
6576
|
useEffect(() => {
|
|
6488
|
-
// We
|
|
6489
|
-
//
|
|
6490
|
-
// We
|
|
6491
|
-
//
|
|
6492
|
-
if (
|
|
6577
|
+
// We dont't connect or start when the apiConfig is not ready yet.
|
|
6578
|
+
// We also keep track of whether start has been called to avoid multiple in-flight connection processes.
|
|
6579
|
+
// We check if the window view is not open and no conversation is started yet.
|
|
6580
|
+
// Lastly we check if the inline view is not scrolled in to view.
|
|
6581
|
+
if (!apiConfigReady || startCalled.current || isWindow && !isOpen && !hasConversation || isInline && !showInlineView) {
|
|
6493
6582
|
return;
|
|
6494
6583
|
}
|
|
6495
6584
|
|
|
6496
|
-
if (hasConversation) {
|
|
6585
|
+
if (hasConversation && isOpen) {
|
|
6497
6586
|
// We deactivate the extra startup loading spinner when a conversation is available
|
|
6498
6587
|
// We also stop setting the loading indicator in the first place to avoid a flash.
|
|
6499
6588
|
clearTimeout(spinnerTimeout.current);
|
|
@@ -6503,11 +6592,8 @@ const useSeamlyChat = () => {
|
|
|
6503
6592
|
});
|
|
6504
6593
|
}
|
|
6505
6594
|
|
|
6506
|
-
|
|
6507
|
-
|
|
6508
|
-
});
|
|
6509
|
-
connectCalled.current = true;
|
|
6510
|
-
}, [isOpen, hasConversation, apiConfigReady, start, connect, dispatch, layoutMode]);
|
|
6595
|
+
connectAndStart();
|
|
6596
|
+
}, [apiConfigReady, connectAndStart, dispatch, hasConversation, isInline, isOpen, isWindow, showInlineView]);
|
|
6511
6597
|
|
|
6512
6598
|
const openChat = () => {
|
|
6513
6599
|
setVisibility(visibilityStates.open);
|
|
@@ -7981,7 +8067,7 @@ const app_reducer_initialState = {
|
|
|
7981
8067
|
userHasResponded: false
|
|
7982
8068
|
};
|
|
7983
8069
|
/* harmony default export */ const app_reducer = (app_utils_createReducer({
|
|
7984
|
-
[
|
|
8070
|
+
[actions_setHasResponded]: (state, {
|
|
7985
8071
|
hasResponded
|
|
7986
8072
|
}) => app_reducer_objectSpread(app_reducer_objectSpread({}, state), {}, {
|
|
7987
8073
|
userHasResponded: hasResponded
|
|
@@ -8329,6 +8415,7 @@ const StyleGuideApp = ({
|
|
|
8329
8415
|
|
|
8330
8416
|
const updatedState = app_objectSpread(app_objectSpread({}, bareState), {}, {
|
|
8331
8417
|
config: app_objectSpread(app_objectSpread(app_objectSpread(app_objectSpread({}, bareState.config), config), {}, {
|
|
8418
|
+
showDisclaimer: bareState.config.showDisclaimer || config.showDisclaimer,
|
|
8332
8419
|
layoutMode: bareState.config.layoutMode
|
|
8333
8420
|
}, overrideMessages ? {
|
|
8334
8421
|
messages: overrideMessages
|