@gamelearn/arcade-components 2.2.3 → 2.2.5

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 (22) 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 +2 -4
  5. package/dist/components/conversational-pro-component/components/ConversationalProComponent.js +144 -48
  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 +202 -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/useEkho.js +14 -8
  22. package/package.json +1 -1
@@ -20,6 +20,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope
20
20
  var Panels = function Panels(_ref) {
21
21
  var characters = _ref.characters,
22
22
  slots = _ref.slots,
23
+ ttsStarted = _ref.ttsStarted,
23
24
  activeIndex = _ref.activeIndex,
24
25
  flex = _ref.flex,
25
26
  lodSettings = _ref.lodSettings;
@@ -37,7 +38,8 @@ var Panels = function Panels(_ref) {
37
38
  key: "".concat("".concat(currentCharacter.uid, "_").concat(slotPosition), "_", characterPos),
38
39
  character: currentCharacter,
39
40
  active: activeIndex === currentPosition,
40
- lodSettings: lodSettings
41
+ lodSettings: lodSettings,
42
+ ttsStarted: ttsStarted
41
43
  });
42
44
  }
43
45
 
@@ -36,6 +36,7 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
36
36
  var PanelsWrapper = function PanelsWrapper(_ref) {
37
37
  var characters = _ref.characters,
38
38
  slots = _ref.slots,
39
+ ttsStarted = _ref.ttsStarted,
39
40
  slotRefs = _ref.slotRefs,
40
41
  flex = _ref.flex,
41
42
  currentMessage = _ref.currentMessage;
@@ -56,6 +57,7 @@ var PanelsWrapper = function PanelsWrapper(_ref) {
56
57
  finishBuild(true);
57
58
  }, []);
58
59
  return built ? /*#__PURE__*/_react.default.createElement(_Panels.default, {
60
+ ttsStarted: ttsStarted,
59
61
  characters: characters,
60
62
  slots: slots,
61
63
  slotRefs: slotRefs,
@@ -77,8 +79,13 @@ var Scene = function Scene(props) {
77
79
  var gl = _ref3.gl;
78
80
  gl.setClearColor('white', 0);
79
81
  gl.physicallyCorrectLights = true;
82
+ },
83
+ frameloop: "demand"
84
+ }, /*#__PURE__*/_react.default.createElement(_arcadeThreeCore.SettingsController, {
85
+ current: {
86
+ animate: props.pause
80
87
  }
81
- }, /*#__PURE__*/_react.default.createElement(_react.Suspense, {
88
+ }), /*#__PURE__*/_react.default.createElement(_react.Suspense, {
82
89
  fallback: null
83
90
  }, /*#__PURE__*/_react.default.createElement(PanelsWrapper, props)));
84
91
  };
@@ -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[currentLineData - 1] ? lines[currentLineData - 1] : {};
231
+ return currentLineData > 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,31 @@ 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,
542
641
  soundActions: soundActions,
543
642
  emitEvent: emitEvent,
643
+ pauseTTS: pause,
644
+ onStart: function onStart() {
645
+ var _talkingCharacter$emo;
646
+
647
+ if (talkingCharacter !== null && talkingCharacter !== void 0 && (_talkingCharacter$emo = talkingCharacter.emotion) !== null && _talkingCharacter$emo !== void 0 && _talkingCharacter$emo.includes('think')) return;
648
+ startTalking(true);
649
+ },
544
650
  onError: function onError() {
545
651
  setAudioFailed(true);
546
652
  },
547
653
  onFinish: function onFinish() {
548
- if (autoPlayCond) {
654
+ startTalking(false);
655
+
656
+ if (autoPlayCond && !pause) {
549
657
  nextLine();
550
658
  }
551
659
  }
@@ -555,29 +663,40 @@ var DialogComponent = function DialogComponent(_ref) {
555
663
  return function () {
556
664
  stopEkho();
557
665
  };
558
- }, [line, stopEkho]); // Autoplay logic
559
-
666
+ }, [line, stopEkho]);
560
667
  (0, _react.useEffect)(function () {
561
- if (autoPlayCond && currentMessage.show && ((currentLine === null || currentLine === void 0 ? void 0 : currentLine.audioType) === 'none' || audioFailed)) {
668
+ 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
669
  var _currentMessage$text;
563
670
 
671
+ startTalking(true);
564
672
  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);
673
+ setTimeout(function () {
674
+ startTalking(false);
675
+ }, time < minMs ? minMs : time);
676
+ }
677
+ }, [audioFailed, currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType, talkingCharacter === null || talkingCharacter === void 0 ? void 0 : talkingCharacter.emotion, currentMessage]); // Autoplay logic
678
+
679
+ (0, _react.useEffect)(function () {
680
+ if (autoPlayCond && currentMessage.show && ((currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType) === 'none' || audioFailed) && !pause) {
681
+ var _currentMessage$text2;
682
+
683
+ 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
684
+
685
+ if (!isEndNode()) {
686
+ start(nextLine, time < minMs ? minMs : time);
687
+ }
566
688
  }
567
689
 
568
690
  return function () {
569
691
  stop();
570
692
  };
571
- }, [currentMessage, nextLine, start, stop, currentLine === null || currentLine === void 0 ? void 0 : currentLine.audioType, autoPlayCond, audio, voice, audioFailed]); // Positioning Bubble Message logic
693
+ }, [currentMessage, nextLine, start, stop, currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType, autoPlayCond, audio, voice, audioFailed]); // Positioning Bubble Message logic
572
694
 
573
695
  var checkBubbleBounds = (0, _react.useCallback)(function (group, bubble) {
574
696
  groupRef.current = group === null || group === void 0 ? void 0 : group.current;
575
697
  bubbleRef.current = bubble === null || bubble === void 0 ? void 0 : bubble.current;
576
698
 
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
- });
699
+ if (currentLineData !== null && currentLineData !== void 0 && currentLineData.slots && currentMessage.show && bubble !== null && bubble !== void 0 && bubble.current) {
581
700
  var bubbleRect = bubble.current.getBoundingClientRect();
582
701
  var x = bubbleRect.x + bubbleRect.width;
583
702
  var y = bubbleRect.y - bubbleRect.height;
@@ -617,7 +736,7 @@ var DialogComponent = function DialogComponent(_ref) {
617
736
  bubble.current.parentNode.style.transform = '';
618
737
  }
619
738
  }
620
- }, [camera.quaternion, currentLine === null || currentLine === void 0 ? void 0 : currentLine.slots, currentMessage.inScene, getAvatarURL]);
739
+ }, [camera.quaternion, currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.slots, currentMessage.inScene, getAvatarURL]);
621
740
  (0, _react.useEffect)(function () {
622
741
  if (animationRunning) {
623
742
  var cam = camera;
@@ -688,10 +807,10 @@ var DialogComponent = function DialogComponent(_ref) {
688
807
  height: '100vh',
689
808
  position: 'static'
690
809
  };
691
- var disableBackButton = line === 0 || previousLineWasDecision || line > 0 && (lastLine === null || lastLine === void 0 ? void 0 : lastLine.decision);
810
+ var disableBackButton = line === 0 || previousLineWasDecision();
692
811
 
693
812
  if (isDecision) {
694
- var decisionPayload = _objectSpread(_objectSpread({}, currentLine.payload), {}, {
813
+ var decisionPayload = _objectSpread(_objectSpread({}, currentLineData.payload), {}, {
695
814
  inheritProps: {
696
815
  slots: [],
697
816
  disableBackground: true
@@ -700,6 +819,7 @@ var DialogComponent = function DialogComponent(_ref) {
700
819
  branched: isBranched,
701
820
  onFinish: nextLine,
702
821
  emitEvent: emitEvent,
822
+ pause: pause,
703
823
  soundActions: soundActions
704
824
  });
705
825
 
@@ -709,6 +829,7 @@ var DialogComponent = function DialogComponent(_ref) {
709
829
  portal: container ? {
710
830
  current: container
711
831
  } : undefined,
832
+ onOcclude: function onOcclude() {},
712
833
  calculatePosition: function calculatePosition() {
713
834
  return [0, 0];
714
835
  }
@@ -748,7 +869,7 @@ var DialogComponent = function DialogComponent(_ref) {
748
869
  type: "button",
749
870
  onClick: manualNextLine,
750
871
  disabled: animationRunning,
751
- className: "gat--btn__round ".concat(animationRunning ? 'disabled' : '')
872
+ className: "gat--btn__round \n ".concat(animationRunning ? 'disabled' : '', "\n ").concat(automatic && isEndNode() ? 'glowing-animation' : '')
752
873
  }, /*#__PURE__*/_react.default.createElement("span", {
753
874
  className: (0, _LangIsRtl.default)() ? 'icon-back' : 'icon-next'
754
875
  })))));
@@ -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