@gamelearn/arcade-components 2.2.3 → 2.2.7

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 (23) hide show
  1. package/dist/components/auto-evaluation-component/components/AutoEvaluation.js +4 -2
  2. package/dist/components/cards-selector-puzzle-component/components/CardsSelectorPuzzleComponent.js +6 -3
  3. package/dist/components/chained-image-click-puzzle-component/components/CurrentImagePuzzle.js +20 -8
  4. package/dist/components/comic-component/components/ComicComponent.js +3 -4
  5. package/dist/components/conversational-pro-component/components/ConversationalProComponent.js +148 -49
  6. package/dist/components/conversational-pro-component/components/SlotList.js +6 -2
  7. package/dist/components/conversational-pro-component/components/scene/Panel.js +72 -10
  8. package/dist/components/conversational-pro-component/components/scene/Panels.js +3 -1
  9. package/dist/components/conversational-pro-component/components/scene/index.js +8 -1
  10. package/dist/components/dialog-component/components/DialogComponent.js +206 -81
  11. package/dist/components/feedback-component/components/FeedbackComponent.js +2 -3
  12. package/dist/components/frame-click-puzzle-component/components/CurrentFramePuzzle.js +16 -3
  13. package/dist/components/frame-click-puzzle-component/components/FrameClickPuzzleComponent.js +4 -2
  14. package/dist/components/image-click-wrapper-component/components/ImageClickWrapperComponent.js +9 -1
  15. package/dist/components/lectures-component/components/LecturesComponent.js +1 -1
  16. package/dist/components/survey-component/components/SurveyComponent.js +4 -2
  17. package/dist/components/terminal-puzzle-component/components/Visor/index.js +1 -1
  18. package/dist/components/test-component/components/Container.js +4 -3
  19. package/dist/components/test-component/components/TestComponent.js +11 -4
  20. package/dist/helpers/index.js +70 -4
  21. package/dist/helpers/mocker.js +1 -1
  22. package/dist/helpers/useEkho.js +20 -11
  23. package/package.json +1 -1
@@ -69,7 +69,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
69
69
 
70
70
  // Global
71
71
  var isMobile = (0, _deviceDetection.DeviceDetection)();
72
- var crossFadeDuration = 0.5;
72
+ var crossFadeDuration = 0.2;
73
73
  var characterMs = 75;
74
74
  var minMs = 1400;
75
75
  var headSize = 2; // Mobile always zoom in?
@@ -79,13 +79,16 @@ var maxCharacterToSwitch = 70;
79
79
  raycast.firstHitOnly = true;
80
80
 
81
81
  var DialogComponent = function DialogComponent(_ref) {
82
+ var _currentLineData$slot;
83
+
82
84
  var emitEvent = _ref.emitEvent,
83
85
  lines = _ref.lines,
84
86
  actors = _ref.actors,
85
87
  edges = _ref.edges,
86
88
  soundActions = _ref.soundActions,
87
89
  zoomInActor = _ref.zoomInActor,
88
- autoPlay = _ref.autoPlay;
90
+ autoPlay = _ref.autoPlay,
91
+ pause = _ref.pause;
89
92
 
90
93
  var _useState = (0, _react.useState)(0),
91
94
  _useState2 = _slicedToArray(_useState, 2),
@@ -97,25 +100,15 @@ var DialogComponent = function DialogComponent(_ref) {
97
100
  automatic = _useState4[0],
98
101
  setAutomatic = _useState4[1];
99
102
 
100
- var _useState5 = (0, _react.useState)({
101
- text: '',
102
- name: '',
103
- left: false,
104
- top: false,
105
- inScene: false,
106
- thinkful: false,
107
- voiceOver: false,
108
- avatar: '',
109
- show: false
110
- }),
103
+ var _useState5 = (0, _react.useState)(false),
111
104
  _useState6 = _slicedToArray(_useState5, 2),
112
- currentMessage = _useState6[0],
113
- setCurrentMessage = _useState6[1];
105
+ mounted = _useState6[0],
106
+ setMounted = _useState6[1];
114
107
 
115
108
  var _useState7 = (0, _react.useState)(false),
116
109
  _useState8 = _slicedToArray(_useState7, 2),
117
- mounted = _useState8[0],
118
- setMounted = _useState8[1];
110
+ talking = _useState8[0],
111
+ startTalking = _useState8[1];
119
112
 
120
113
  var _useState9 = (0, _react.useState)(false),
121
114
  _useState10 = _slicedToArray(_useState9, 2),
@@ -154,15 +147,39 @@ var DialogComponent = function DialogComponent(_ref) {
154
147
  setAnimationRunning = _useState12[1];
155
148
 
156
149
  var animationTarget = (0, _react.useRef)(new _three.Object3D());
157
- var currentLine = lines[line];
150
+ var currentLineData = lines[line];
158
151
  var lastLine = lines[line - 1];
159
152
  var lastSet = (0, _react.useRef)(false);
160
153
  var isBranched = !!edges;
161
154
 
162
- var _ref2 = currentLine || {},
155
+ var _ref2 = currentLineData || {},
163
156
  voiceOver = _ref2.voiceOver,
164
157
  decision = _ref2.decision;
165
158
 
159
+ var talkingCharacter = currentLineData === null || currentLineData === void 0 ? void 0 : (_currentLineData$slot = currentLineData.slots) === null || _currentLineData$slot === void 0 ? void 0 : _currentLineData$slot.find(function (slot) {
160
+ return slot.talking;
161
+ });
162
+ var autoPlayCond = automatic && !(currentLineData !== null && currentLineData !== void 0 && currentLineData.decision);
163
+ var audio = Object.keys((currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audio) || {}).length;
164
+ var voice = Object.keys((currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.voice) || {}).length;
165
+ var isVoiceOver = voiceOver || (currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.type) === 'conversationalNarration';
166
+ var isDecision = decision || (currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.type) === 'conversationalDecision';
167
+
168
+ var _useState13 = (0, _react.useState)({
169
+ text: '',
170
+ name: '',
171
+ left: false,
172
+ top: false,
173
+ inScene: false,
174
+ thinkful: false,
175
+ voiceOver: false,
176
+ avatar: '',
177
+ show: false
178
+ }),
179
+ _useState14 = _slicedToArray(_useState13, 2),
180
+ currentMessage = _useState14[0],
181
+ setCurrentMessage = _useState14[1];
182
+
166
183
  var charactersInvolved = (0, _react.useMemo)(function () {
167
184
  return lines.reduce(function (acc, current) {
168
185
  if (current.slots) {
@@ -184,14 +201,37 @@ var DialogComponent = function DialogComponent(_ref) {
184
201
  });
185
202
  }, [emitEvent]);
186
203
 
187
- var _useState13 = (0, _react.useState)(false),
188
- _useState14 = _slicedToArray(_useState13, 2),
189
- previousLineWasDecision = _useState14[0],
190
- setPreviousLineWasDecision = _useState14[1];
204
+ var _useState15 = (0, _react.useState)([]),
205
+ _useState16 = _slicedToArray(_useState15, 2),
206
+ edgesHistory = _useState16[0],
207
+ setEdgesHistory = _useState16[1];
208
+
209
+ var lastNodeId = (0, _react.useMemo)(function () {
210
+ return edgesHistory[edgesHistory.length - 1];
211
+ }, [edgesHistory]);
212
+ var findLastLineBranched = (0, _react.useCallback)(function () {
213
+ var lastEdge = edges.find(function (edge) {
214
+ return edge.fromId === lastNodeId;
215
+ });
216
+ var lastL = lines.find(function (l) {
217
+ return l.id === lastEdge.fromId;
218
+ });
219
+ return lastL;
220
+ }, [edges, lines, lastNodeId]);
221
+ var previousLineWasDecision = (0, _react.useCallback)(function () {
222
+ if (isBranched) {
223
+ // if we have edges, we need to check if the previous line was a decision
224
+ var _lastL = findLastLineBranched();
191
225
 
192
- var isVoiceOver = voiceOver || (currentLine === null || currentLine === void 0 ? void 0 : currentLine.type) === 'conversationalNarration';
193
- var isDecision = decision || (currentLine === null || currentLine === void 0 ? void 0 : currentLine.type) === 'conversationalDecision';
226
+ return _lastL === null || _lastL === void 0 ? void 0 : _lastL.decision;
227
+ } // if there is no branching, the previous line is the previous one
228
+
229
+
230
+ var lastL = lines[line - 1] ? lines[line - 1] : {};
231
+ return line > 0 && (lastL === null || lastL === void 0 ? void 0 : lastL.decision);
232
+ }, [currentLineData, isBranched, lines, lastNodeId, edges]);
194
233
  var getCurrentVisible = (0, _react.useCallback)(function (uid) {
234
+ if (!uid) return null;
195
235
  var object;
196
236
  scene.traverseVisible(function (node) {
197
237
  if (node.uid === uid && !object) {
@@ -240,6 +280,8 @@ var DialogComponent = function DialogComponent(_ref) {
240
280
  }, [loader]); // Force default animation without transition
241
281
 
242
282
  var executeDefaultAnimation = function executeDefaultAnimation(element) {
283
+ if (!talkingCharacter || element.uid === talkingCharacter.uid) return;
284
+
243
285
  if (element.userData.mixer && element.userData.defaultAnim) {
244
286
  var mixer = element.userData.mixer;
245
287
  var defaultAction = mixer.clipAction(element.userData.defaultAnim, element);
@@ -259,6 +301,43 @@ var DialogComponent = function DialogComponent(_ref) {
259
301
  messagePosition.current.parent = null;
260
302
  if (zoomInActor) setAnimationRunning(true);
261
303
  }, [zoomInActor]);
304
+
305
+ var restTalkingAnimation = function restTalkingAnimation() {
306
+ var element = getCurrentVisible(talkingCharacter === null || talkingCharacter === void 0 ? void 0 : talkingCharacter.uid);
307
+
308
+ if (!element) {
309
+ startTalking(false);
310
+ return;
311
+ }
312
+
313
+ var _element$userData = element.userData,
314
+ mixer = _element$userData.mixer,
315
+ defaultAnim = _element$userData.defaultAnim,
316
+ emotionClip = _element$userData.emotionClip;
317
+
318
+ if (defaultAnim && emotionClip) {
319
+ var emotionAction = mixer.clipAction(emotionClip, element);
320
+ var defaultAction = mixer.clipAction(defaultAnim, element);
321
+ mixer.stopAllAction();
322
+ (0, _helpers.executeCrossFade)(emotionAction, defaultAction, crossFadeDuration);
323
+ }
324
+
325
+ startTalking(false);
326
+ };
327
+
328
+ (0, _react.useEffect)(function () {
329
+ var element = getCurrentVisible(talkingCharacter === null || talkingCharacter === void 0 ? void 0 : talkingCharacter.uid);
330
+
331
+ if (element) {
332
+ if (talking) {
333
+ var _talkingCharacter$cha, _talkingCharacter$cha2, _talkingCharacter$cha3, _talkingCharacter$cha4;
334
+
335
+ (0, _helpers.executeTalkingAnimation)(element, talkingCharacter === null || talkingCharacter === void 0 ? void 0 : (_talkingCharacter$cha = talkingCharacter.character) === null || _talkingCharacter$cha === void 0 ? void 0 : (_talkingCharacter$cha2 = _talkingCharacter$cha.resource) === null || _talkingCharacter$cha2 === void 0 ? void 0 : (_talkingCharacter$cha3 = _talkingCharacter$cha2.animations) === null || _talkingCharacter$cha3 === void 0 ? void 0 : (_talkingCharacter$cha4 = _talkingCharacter$cha3.talking) === null || _talkingCharacter$cha4 === void 0 ? void 0 : _talkingCharacter$cha4.url);
336
+ } else {
337
+ restTalkingAnimation();
338
+ }
339
+ }
340
+ }, [talkingCharacter, talking]);
262
341
  var finishConversation = (0, _react.useCallback)(function () {
263
342
  lastSet.current = true;
264
343
  changeLine(0);
@@ -275,31 +354,39 @@ var DialogComponent = function DialogComponent(_ref) {
275
354
  var handleBranchDirection = (0, _react.useCallback)(function () {
276
355
  var forward = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
277
356
  var keys = forward ? ['fromId', 'toId'] : ['toId', 'fromId'];
278
- var foundEdge = edges.find(function (edge) {
279
- return edge[keys[0]] === (currentLine === null || currentLine === void 0 ? void 0 : currentLine.id);
357
+ var foundEdges = edges.filter(function (edge) {
358
+ return edge[keys[0]] === currentLineData.id;
359
+ });
360
+ var foundEdge = foundEdges.length === 1 ? foundEdges[0] : foundEdges.find(function (edge) {
361
+ return edge[keys[1]] === lastNodeId;
280
362
  });
281
363
 
282
364
  if (!(foundEdge !== null && foundEdge !== void 0 && foundEdge[keys[0]])) {
283
- finishConversation();
284
- } else {
285
- var destination = lines.findIndex(function (l) {
286
- return l.id === foundEdge[keys[1]];
287
- });
365
+ return;
366
+ } // if going backwards remove last edge from history
288
367
 
289
- if (destination >= 0) {
290
- setCurrentMessage({
291
- show: false
292
- });
293
- changeLine(destination);
294
- } else {
295
- finishConversation();
296
- }
368
+
369
+ if (!forward) {
370
+ setEdgesHistory(edgesHistory.slice(0, edgesHistory.length - 1));
297
371
  }
298
- }, [currentLine === null || currentLine === void 0 ? void 0 : currentLine.id, edges, finishConversation, lines]);
372
+
373
+ var destination = lines.findIndex(function (l) {
374
+ return l.id === foundEdge[keys[1]];
375
+ });
376
+
377
+ if (destination >= 0) {
378
+ setCurrentMessage({
379
+ show: false
380
+ });
381
+ changeLine(destination);
382
+ } else {
383
+ finishConversation();
384
+ }
385
+ }, [currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.id, edges, finishConversation, lines]);
299
386
  var handleDecisionBranch = (0, _react.useCallback)(function (choice, reset) {
300
387
  var currentId = [3, 2, 1][choice.id];
301
388
  var optionsEdges = edges.filter(function (edge) {
302
- return edge.fromId === (currentLine === null || currentLine === void 0 ? void 0 : currentLine.id);
389
+ return edge.fromId === (currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.id);
303
390
  });
304
391
  var currentEdge = optionsEdges.find(function (edge) {
305
392
  return parseInt(edge.fromPointIndex) === currentId;
@@ -320,13 +407,14 @@ var DialogComponent = function DialogComponent(_ref) {
320
407
  } else {
321
408
  finishConversation();
322
409
  }
323
- }, [currentLine === null || currentLine === void 0 ? void 0 : currentLine.id, edges, finishConversation, lines]);
410
+ }, [currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.id, edges, finishConversation, lines]);
324
411
  var backLine = (0, _react.useCallback)(function () {
412
+ restTalkingAnimation();
325
413
  setAudioFailed(false);
326
414
 
327
415
  if (isBranched) {
328
416
  handleBranchDirection(false);
329
- } else if (lastLine && !(lastLine !== null && lastLine !== void 0 && lastLine.decision) || lastLine.type && !lastLine.type !== 'conversationalDecision') {
417
+ } else if (!previousLineWasDecision()) {
330
418
  setCurrentMessage({
331
419
  show: false
332
420
  });
@@ -334,7 +422,8 @@ var DialogComponent = function DialogComponent(_ref) {
334
422
  }
335
423
  }, [handleBranchDirection, isBranched, lastLine, line]);
336
424
  var nextLine = (0, _react.useCallback)(function (choice, reset) {
337
- setPreviousLineWasDecision(currentLine.decision);
425
+ restTalkingAnimation();
426
+ setEdgesHistory([].concat(_toConsumableArray(edgesHistory), [currentLineData.id]));
338
427
  setAudioFailed(false);
339
428
 
340
429
  if (isBranched) {
@@ -348,19 +437,34 @@ var DialogComponent = function DialogComponent(_ref) {
348
437
  show: false
349
438
  });
350
439
  changeLine(line + 1);
351
- } else {
440
+ } else if (currentLineData.decision) {
352
441
  finishConversation();
353
442
  }
354
- }, [currentLine === null || currentLine === void 0 ? void 0 : currentLine.decision, isBranched, line, lines.length, handleDecisionBranch, handleBranchDirection, finishConversation]);
443
+ }, [currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.decision, isBranched, line, lines.length, handleDecisionBranch, handleBranchDirection, finishConversation]);
355
444
 
356
445
  var manualBackLine = function manualBackLine() {
357
446
  setAutomatic(false);
358
447
  backLine();
359
448
  };
360
449
 
450
+ var isEndNode = function isEndNode() {
451
+ if (isBranched) {
452
+ return currentLineData && currentLineData.type !== 'conversationalDecision' && !edges.find(function (edge) {
453
+ return edge.fromId === currentLineData.id;
454
+ });
455
+ }
456
+
457
+ return line === lines.length - 1;
458
+ };
459
+
361
460
  var manualNextLine = function manualNextLine() {
362
- setAutomatic(false);
363
- nextLine();
461
+ if (isEndNode()) {
462
+ startTalking(false);
463
+ finishConversation();
464
+ } else {
465
+ setAutomatic(false);
466
+ nextLine();
467
+ }
364
468
  }; // Calculate start node
365
469
 
366
470
 
@@ -421,8 +525,8 @@ var DialogComponent = function DialogComponent(_ref) {
421
525
  } else if (isVoiceOver) {
422
526
  resetCameraView();
423
527
  setCurrentMessage({
424
- text: currentLine === null || currentLine === void 0 ? void 0 : currentLine.text,
425
- name: (currentLine === null || currentLine === void 0 ? void 0 : currentLine.alias) || (currentLine === null || currentLine === void 0 ? void 0 : currentLine.name) || "[ ".concat(translate('storylines.misc.voiceOver'), " ]"),
528
+ text: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.text,
529
+ name: (currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.alias) || (currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.name) || "[ ".concat(translate('storylines.misc.voiceOver'), " ]"),
426
530
  left: false,
427
531
  inScene: false,
428
532
  voiceOver: true,
@@ -432,10 +536,7 @@ var DialogComponent = function DialogComponent(_ref) {
432
536
  show: true
433
537
  });
434
538
  } else if (!lastSet.current) {
435
- var talkingCharacter = currentLine === null || currentLine === void 0 ? void 0 : currentLine.slots.find(function (slot) {
436
- return slot.talking;
437
- });
438
- var slottedCharacters = currentLine === null || currentLine === void 0 ? void 0 : currentLine.slots.filter(function (slot) {
539
+ var slottedCharacters = currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.slots.filter(function (slot) {
439
540
  return slot.uid && !slot.talking;
440
541
  });
441
542
  var currentParticipants = [].concat(_toConsumableArray(slottedCharacters.map(function (slot) {
@@ -476,6 +577,7 @@ var DialogComponent = function DialogComponent(_ref) {
476
577
  if (startAction && action && startAction !== action) {
477
578
  mixer.stopAllAction();
478
579
  (0, _helpers.executeCrossFade)(startAction, action, crossFadeDuration);
580
+ element.userData.defaultAnim = action.getClip();
479
581
  }
480
582
 
481
583
  if (talkingCharacter.uid === element.uid) {
@@ -487,14 +589,14 @@ var DialogComponent = function DialogComponent(_ref) {
487
589
  }
488
590
 
489
591
  setTimeout(function () {
490
- var _talkingCharacter$cha;
592
+ var _talkingCharacter$cha5;
491
593
 
492
594
  var _moveBubble = moveBubble(element, showArrowTop),
493
595
  distance = _moveBubble.distance;
494
596
 
495
597
  setCurrentMessage({
496
598
  text: talkingCharacter.text,
497
- name: talkingCharacter.alias || ((_talkingCharacter$cha = talkingCharacter.character) === null || _talkingCharacter$cha === void 0 ? void 0 : _talkingCharacter$cha.name),
599
+ name: talkingCharacter.alias || ((_talkingCharacter$cha5 = talkingCharacter.character) === null || _talkingCharacter$cha5 === void 0 ? void 0 : _talkingCharacter$cha5.name),
498
600
  left: true,
499
601
  top: showArrowTop || distance > 70,
500
602
  inScene: true,
@@ -506,12 +608,12 @@ var DialogComponent = function DialogComponent(_ref) {
506
608
  }
507
609
  });
508
610
  } else {
509
- var _talkingCharacter$cha2;
611
+ var _talkingCharacter$cha6;
510
612
 
511
613
  resetCameraView();
512
614
  setCurrentMessage({
513
615
  text: talkingCharacter.text,
514
- name: talkingCharacter.alias || ((_talkingCharacter$cha2 = talkingCharacter.character) === null || _talkingCharacter$cha2 === void 0 ? void 0 : _talkingCharacter$cha2.name) || (object === null || object === void 0 ? void 0 : object.name),
616
+ name: talkingCharacter.alias || ((_talkingCharacter$cha6 = talkingCharacter.character) === null || _talkingCharacter$cha6 === void 0 ? void 0 : _talkingCharacter$cha6.name) || (object === null || object === void 0 ? void 0 : object.name),
515
617
  left: false,
516
618
  top: talkingCharacter.text.length > maxCharacterToSwitch,
517
619
  inScene: false,
@@ -527,25 +629,32 @@ var DialogComponent = function DialogComponent(_ref) {
527
629
  });
528
630
  }
529
631
  }
530
- }, [actors, camera, currentLine, zoomInActor, getCurrentVisible, translate, getAvatarURL, loadEmotion, resetCameraView, isDecision, isVoiceOver, charactersInvolved]);
531
- var autoPlayCond = automatic && !(currentLine !== null && currentLine !== void 0 && currentLine.decision);
532
- var audio = Object.keys((currentLine === null || currentLine === void 0 ? void 0 : currentLine.audio) || {}).length;
533
- var voice = Object.keys((currentLine === null || currentLine === void 0 ? void 0 : currentLine.voice) || {}).length; // Sound logic
632
+ }, [actors, camera, currentLineData, zoomInActor, getCurrentVisible, translate, getAvatarURL, loadEmotion, resetCameraView, isDecision, isVoiceOver, charactersInvolved]); // Sound logic
534
633
 
535
634
  var stopEkho = (0, _useEkho.default)({
536
- audioType: currentLine === null || currentLine === void 0 ? void 0 : currentLine.audioType,
537
- volume: currentLine === null || currentLine === void 0 ? void 0 : currentLine.audioVolume,
538
- voice: currentLine === null || currentLine === void 0 ? void 0 : currentLine.voice,
635
+ audioType: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType,
636
+ volume: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioVolume,
637
+ voice: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.voice,
539
638
  started: currentMessage.show,
540
639
  text: currentMessage === null || currentMessage === void 0 ? void 0 : currentMessage.text,
541
- audio: currentLine === null || currentLine === void 0 ? void 0 : currentLine.audio,
640
+ audio: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audio,
641
+ slide: line,
542
642
  soundActions: soundActions,
543
643
  emitEvent: emitEvent,
644
+ pauseTTS: pause,
645
+ onStart: function onStart() {
646
+ var _talkingCharacter$emo;
647
+
648
+ if (talkingCharacter !== null && talkingCharacter !== void 0 && (_talkingCharacter$emo = talkingCharacter.emotion) !== null && _talkingCharacter$emo !== void 0 && _talkingCharacter$emo.includes('think')) return;
649
+ startTalking(true);
650
+ },
544
651
  onError: function onError() {
545
652
  setAudioFailed(true);
546
653
  },
547
654
  onFinish: function onFinish() {
548
- if (autoPlayCond) {
655
+ startTalking(false);
656
+
657
+ if (autoPlayCond && !pause) {
549
658
  nextLine();
550
659
  }
551
660
  }
@@ -555,29 +664,40 @@ var DialogComponent = function DialogComponent(_ref) {
555
664
  return function () {
556
665
  stopEkho();
557
666
  };
558
- }, [line, stopEkho]); // Autoplay logic
559
-
667
+ }, [line, stopEkho]);
560
668
  (0, _react.useEffect)(function () {
561
- if (autoPlayCond && currentMessage.show && ((currentLine === null || currentLine === void 0 ? void 0 : currentLine.audioType) === 'none' || audioFailed)) {
669
+ if (((currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType) === 'none' || audioFailed) && currentMessage !== null && currentMessage !== void 0 && currentMessage.show && (talkingCharacter === null || talkingCharacter === void 0 ? void 0 : talkingCharacter.emotion) !== 'thinkful') {
562
670
  var _currentMessage$text;
563
671
 
672
+ startTalking(true);
564
673
  var time = characterMs * ((currentMessage === null || currentMessage === void 0 ? void 0 : (_currentMessage$text = currentMessage.text) === null || _currentMessage$text === void 0 ? void 0 : _currentMessage$text.length) || 0);
565
- start(nextLine, time < minMs ? minMs : time);
674
+ setTimeout(function () {
675
+ startTalking(false);
676
+ }, time < minMs ? minMs : time);
677
+ }
678
+ }, [audioFailed, currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType, talkingCharacter === null || talkingCharacter === void 0 ? void 0 : talkingCharacter.emotion, currentMessage]); // Autoplay logic
679
+
680
+ (0, _react.useEffect)(function () {
681
+ if (autoPlayCond && currentMessage.show && ((currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType) === 'none' || audioFailed) && !pause) {
682
+ var _currentMessage$text2;
683
+
684
+ var time = characterMs * ((currentMessage === null || currentMessage === void 0 ? void 0 : (_currentMessage$text2 = currentMessage.text) === null || _currentMessage$text2 === void 0 ? void 0 : _currentMessage$text2.length) || 0); // if it's not last node
685
+
686
+ if (!isEndNode()) {
687
+ start(nextLine, time < minMs ? minMs : time);
688
+ }
566
689
  }
567
690
 
568
691
  return function () {
569
692
  stop();
570
693
  };
571
- }, [currentMessage, nextLine, start, stop, currentLine === null || currentLine === void 0 ? void 0 : currentLine.audioType, autoPlayCond, audio, voice, audioFailed]); // Positioning Bubble Message logic
694
+ }, [currentMessage, nextLine, start, stop, currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType, autoPlayCond, audio, voice, audioFailed]); // Positioning Bubble Message logic
572
695
 
573
696
  var checkBubbleBounds = (0, _react.useCallback)(function (group, bubble) {
574
697
  groupRef.current = group === null || group === void 0 ? void 0 : group.current;
575
698
  bubbleRef.current = bubble === null || bubble === void 0 ? void 0 : bubble.current;
576
699
 
577
- if (currentLine !== null && currentLine !== void 0 && currentLine.slots && currentMessage.show && bubble !== null && bubble !== void 0 && bubble.current) {
578
- var talkingCharacter = currentLine === null || currentLine === void 0 ? void 0 : currentLine.slots.find(function (slot) {
579
- return slot.talking;
580
- });
700
+ if (currentLineData !== null && currentLineData !== void 0 && currentLineData.slots && currentMessage.show && bubble !== null && bubble !== void 0 && bubble.current) {
581
701
  var bubbleRect = bubble.current.getBoundingClientRect();
582
702
  var x = bubbleRect.x + bubbleRect.width;
583
703
  var y = bubbleRect.y - bubbleRect.height;
@@ -617,7 +737,7 @@ var DialogComponent = function DialogComponent(_ref) {
617
737
  bubble.current.parentNode.style.transform = '';
618
738
  }
619
739
  }
620
- }, [camera.quaternion, currentLine === null || currentLine === void 0 ? void 0 : currentLine.slots, currentMessage.inScene, getAvatarURL]);
740
+ }, [camera.quaternion, currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.slots, currentMessage.inScene, getAvatarURL]);
621
741
  (0, _react.useEffect)(function () {
622
742
  if (animationRunning) {
623
743
  var cam = camera;
@@ -688,10 +808,13 @@ var DialogComponent = function DialogComponent(_ref) {
688
808
  height: '100vh',
689
809
  position: 'static'
690
810
  };
691
- var disableBackButton = line === 0 || previousLineWasDecision || line > 0 && (lastLine === null || lastLine === void 0 ? void 0 : lastLine.decision);
811
+ var disableBackButton = (0, _react.useMemo)(function () {
812
+ var disabled = line === 0 || previousLineWasDecision();
813
+ return disabled;
814
+ }, [line, previousLineWasDecision]);
692
815
 
693
816
  if (isDecision) {
694
- var decisionPayload = _objectSpread(_objectSpread({}, currentLine.payload), {}, {
817
+ var decisionPayload = _objectSpread(_objectSpread({}, currentLineData.payload), {}, {
695
818
  inheritProps: {
696
819
  slots: [],
697
820
  disableBackground: true
@@ -700,6 +823,7 @@ var DialogComponent = function DialogComponent(_ref) {
700
823
  branched: isBranched,
701
824
  onFinish: nextLine,
702
825
  emitEvent: emitEvent,
826
+ pause: pause,
703
827
  soundActions: soundActions
704
828
  });
705
829
 
@@ -709,6 +833,7 @@ var DialogComponent = function DialogComponent(_ref) {
709
833
  portal: container ? {
710
834
  current: container
711
835
  } : undefined,
836
+ onOcclude: function onOcclude() {},
712
837
  calculatePosition: function calculatePosition() {
713
838
  return [0, 0];
714
839
  }
@@ -748,7 +873,7 @@ var DialogComponent = function DialogComponent(_ref) {
748
873
  type: "button",
749
874
  onClick: manualNextLine,
750
875
  disabled: animationRunning,
751
- className: "gat--btn__round ".concat(animationRunning ? 'disabled' : '')
876
+ className: "gat--btn__round \n ".concat(animationRunning ? 'disabled' : '', "\n ").concat(automatic && isEndNode() ? 'glowing-animation' : '')
752
877
  }, /*#__PURE__*/_react.default.createElement("span", {
753
878
  className: (0, _LangIsRtl.default)() ? 'icon-back' : 'icon-next'
754
879
  })))));
@@ -95,15 +95,14 @@ var FeedbackComponent = function FeedbackComponent(_ref) {
95
95
  return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement("div", {
96
96
  className: "feedback-layer ".concat(explain ? 'feedback-layer--withexplain' : '')
97
97
  }, /*#__PURE__*/_react.default.createElement("div", {
98
- // eslint-disable-next-line prettier/prettier
99
- className: "feedback-layer__header ".concat(additionalStyle || '', " ").concat(statusColor())
98
+ className: "feedback-layer__header ".concat(shortText ? 'feedback-layer__header--in-shortText' : '', " ").concat(additionalStyle || '', " ").concat(statusColor())
100
99
  }, secondText && /*#__PURE__*/_react.default.createElement("span", {
101
100
  className: "puzzle--terminal__visor--file"
102
101
  }, /*#__PURE__*/_react.default.createElement("span", {
103
102
  className: "puzzle--terminal__icon ".concat(additionalStyle || '')
104
103
  }), /*#__PURE__*/_react.default.createElement("span", null, secondText)), /*#__PURE__*/_react.default.createElement("span", {
105
104
  className: "feedback-layer__maintitle"
106
- }, !shortText ? /*#__PURE__*/_react.default.createElement("div", {
105
+ }, !text || !shortText ? /*#__PURE__*/_react.default.createElement("div", {
107
106
  title: translate("tooltip.".concat(success ? 'correct' : 'incorrect')),
108
107
  className: "".concat(statusIcon())
109
108
  }) : text), text && functionOnClose && explain && /*#__PURE__*/_react.default.createElement("button", {
@@ -61,7 +61,8 @@ var CurrentFramePuzzle = function CurrentFramePuzzle(_ref) {
61
61
  firstTryForFrame = _ref.firstTryForFrame,
62
62
  setPuzzlesAutoCompleted = _ref.setPuzzlesAutoCompleted,
63
63
  puzzlesAutoCompleted = _ref.puzzlesAutoCompleted,
64
- emitOpenPopupCounterInfo = _ref.emitOpenPopupCounterInfo;
64
+ emitOpenPopupCounterInfo = _ref.emitOpenPopupCounterInfo,
65
+ pause = _ref.pause;
65
66
 
66
67
  var _soundActions = _slicedToArray(soundActions, 1),
67
68
  playSound = _soundActions[0];
@@ -70,6 +71,7 @@ var CurrentFramePuzzle = function CurrentFramePuzzle(_ref) {
70
71
  var info = props.info,
71
72
  specificFeedbacks = props.specificFeedbacks;
72
73
  info.description = description;
74
+ var currentSelected = (0, _react.useRef)(0);
73
75
  var correctClicked = (0, _react.useRef)(0);
74
76
  var puzzleId = "frame-image-click-puzzle_".concat(index, "_").concat(nodeId);
75
77
  (0, _react.useEffect)(function () {
@@ -82,6 +84,7 @@ var CurrentFramePuzzle = function CurrentFramePuzzle(_ref) {
82
84
  }, [setInfo, info, puzzleId]);
83
85
  (0, _react.useEffect)(function () {
84
86
  correctClicked.current = 0;
87
+ currentSelected.current = 0;
85
88
  }, [index]);
86
89
  var onComplete = (0, _react.useCallback)(function (rw) {
87
90
  var correct = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
@@ -95,7 +98,14 @@ var CurrentFramePuzzle = function CurrentFramePuzzle(_ref) {
95
98
  if (specificFeedbacks !== null && specificFeedbacks !== void 0 && (_specificFeedbacks$co = specificFeedbacks.correctFeedbacks) !== null && _specificFeedbacks$co !== void 0 && _specificFeedbacks$co.length && !props.hasClickOnce && !finish) {
96
99
  correctClicked.current += 1;
97
100
  } else {
98
- correctClicked.current += props.areas.length;
101
+ var total = selected;
102
+
103
+ if (currentSelected.current) {
104
+ total -= currentSelected.current;
105
+ }
106
+
107
+ correctClicked.current = props.areas.length;
108
+ setSelected(total + correctClicked.current);
99
109
  }
100
110
 
101
111
  if (correctClicked.current === props.areas.length) {
@@ -146,6 +156,7 @@ var CurrentFramePuzzle = function CurrentFramePuzzle(_ref) {
146
156
  var handleResetPuzzle = (0, _react.useCallback)(function () {
147
157
  setFramesCompleted({});
148
158
  correctClicked.current = 0;
159
+ currentSelected.current = 0;
149
160
  emitResetPuzzle();
150
161
  }, [emitResetPuzzle, setFramesCompleted]);
151
162
  (0, _react.useEffect)(function () {
@@ -156,6 +167,7 @@ var CurrentFramePuzzle = function CurrentFramePuzzle(_ref) {
156
167
 
157
168
  var checkSelectedAreas = function checkSelectedAreas() {
158
169
  var areasSelected = props.hasClickOnce ? props.areas.length : 1;
170
+ currentSelected.current += areasSelected;
159
171
  setSelected(selected + areasSelected);
160
172
  };
161
173
 
@@ -183,7 +195,8 @@ var CurrentFramePuzzle = function CurrentFramePuzzle(_ref) {
183
195
  emitResetPuzzle: handleResetPuzzle,
184
196
  firstTryForFrame: firstTryForFrame,
185
197
  puzzlesAutoCompleted: puzzlesAutoCompleted,
186
- emitOpenPopupCounterInfo: emitOpenPopupCounterInfo
198
+ emitOpenPopupCounterInfo: emitOpenPopupCounterInfo,
199
+ pause: pause
187
200
  }));
188
201
  };
189
202
 
@@ -48,7 +48,8 @@ var FrameImageClickComponent = function FrameImageClickComponent(_ref) {
48
48
  soundActions = _ref.soundActions,
49
49
  disableExit = _ref.disableExit,
50
50
  setResolveAction = _ref.setResolveAction,
51
- setInfo = _ref.setInfo;
51
+ setInfo = _ref.setInfo,
52
+ pause = _ref.pause;
52
53
 
53
54
  var _useState = (0, _react.useState)({}),
54
55
  _useState2 = _slicedToArray(_useState, 2),
@@ -161,7 +162,8 @@ var FrameImageClickComponent = function FrameImageClickComponent(_ref) {
161
162
  emitResetPuzzle: resetPuzzle,
162
163
  setPuzzlesAutoCompleted: setPuzzlesAutoCompleted,
163
164
  puzzlesAutoCompleted: puzzlesAutoCompleted,
164
- emitOpenPopupCounterInfo: onInitPuzzle
165
+ emitOpenPopupCounterInfo: onInitPuzzle,
166
+ pause: pause
165
167
  };
166
168
  return /*#__PURE__*/_react.default.createElement("div", {
167
169
  className: "puzzle-frame"
@@ -88,7 +88,8 @@ var ImageClickWrapperComponent = function ImageClickWrapperComponent(props) {
88
88
  emitResetPuzzle = props.emitResetPuzzle,
89
89
  firstTryForFrame = props.firstTryForFrame,
90
90
  puzzlesAutoCompleted = props.puzzlesAutoCompleted,
91
- emitOpenPopupCounterInfo = props.emitOpenPopupCounterInfo;
91
+ emitOpenPopupCounterInfo = props.emitOpenPopupCounterInfo,
92
+ pause = props.pause;
92
93
 
93
94
  var _useState = (0, _react.useState)([]),
94
95
  _useState2 = _slicedToArray(_useState, 2),
@@ -175,6 +176,13 @@ var ImageClickWrapperComponent = function ImageClickWrapperComponent(props) {
175
176
  }, 1000);
176
177
  intervalForCountDown.current = timeout;
177
178
  }, []);
179
+ (0, _react.useEffect)(function () {
180
+ if (pause) {
181
+ clearInterval(intervalForCountDown.current);
182
+ } else {
183
+ startCountDown();
184
+ }
185
+ }, [pause, startCountDown]);
178
186
  var handleFinish = (0, _react.useCallback)(function (rewards, success) {
179
187
  if (emitFinish) {
180
188
  emitFinish(rewards, success);
@@ -121,7 +121,7 @@ var LecturesComponent = function LecturesComponent(_ref) {
121
121
  return visible ? /*#__PURE__*/_react.default.createElement("div", {
122
122
  className: "".concat(viewed ? 'notes--results' : 'readings--container', " ").concat(!viewed && backgroundImage !== null && backgroundImage !== void 0 && backgroundImage.url ? 'readings--container--with-custom-bg' : ''),
123
123
  style: !viewed && backgroundImage !== null && backgroundImage !== void 0 && backgroundImage.url ? {
124
- backgroundImage: "url(".concat(backgroundImage.url, ")")
124
+ backgroundImage: "url('".concat(backgroundImage.url, "')")
125
125
  } : {}
126
126
  }, /*#__PURE__*/_react.default.createElement("div", {
127
127
  className: viewed ? 'notes--results__text' : 'readings'