@gamelearn/arcade-components 1.10.1 → 1.11.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.
@@ -9,6 +9,8 @@ exports.default = void 0;
9
9
 
10
10
  var _react = _interopRequireWildcard(require("react"));
11
11
 
12
+ var _useTimeout2 = _interopRequireDefault(require("../../../helpers/useTimeout"));
13
+
12
14
  var _Slide = _interopRequireDefault(require("./Slide"));
13
15
 
14
16
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -29,48 +31,82 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
29
31
 
30
32
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
31
33
 
34
+ var characterMs = 250;
35
+
32
36
  var ComicComponent = function ComicComponent(_ref) {
33
37
  var slides = _ref.slides,
34
38
  emitEvent = _ref.emitEvent,
35
39
  _ref$soundActions = _ref.soundActions,
36
- soundActions = _ref$soundActions === void 0 ? [function () {}, function () {}] : _ref$soundActions;
40
+ soundActions = _ref$soundActions === void 0 ? [function () {}, function () {}] : _ref$soundActions,
41
+ autoPlay = _ref.autoPlay;
37
42
 
38
- var _useState = (0, _react.useState)(0),
43
+ var _useState = (0, _react.useState)(!!autoPlay),
39
44
  _useState2 = _slicedToArray(_useState, 2),
40
- slideCount = _useState2[0],
41
- setCount = _useState2[1];
45
+ automatic = _useState2[0],
46
+ setAutomatic = _useState2[1];
47
+
48
+ var _useTimeout = (0, _useTimeout2.default)(),
49
+ start = _useTimeout.start,
50
+ stop = _useTimeout.stop;
42
51
 
43
- var _useState3 = (0, _react.useState)('slide-animation'),
52
+ var _useState3 = (0, _react.useState)(0),
44
53
  _useState4 = _slicedToArray(_useState3, 2),
45
- slideTransition = _useState4[0],
46
- setTransition = _useState4[1];
54
+ slideCount = _useState4[0],
55
+ setCount = _useState4[1];
56
+
57
+ var _useState5 = (0, _react.useState)('slide-animation'),
58
+ _useState6 = _slicedToArray(_useState5, 2),
59
+ slideTransition = _useState6[0],
60
+ setTransition = _useState6[1];
47
61
 
48
62
  var _soundActions = _slicedToArray(soundActions, 1),
49
63
  play = _soundActions[0];
50
64
 
51
- var close = function close() {
65
+ var close = (0, _react.useCallback)(function () {
52
66
  emitEvent({
53
67
  type: 'success'
54
68
  });
55
- play('click-ui');
56
- };
57
-
58
- var goToNextSlide = function goToNextSlide() {
69
+ }, [emitEvent]);
70
+ var goToNextSlide = (0, _react.useCallback)(function () {
59
71
  if (slideCount + 1 < slides.length) {
60
72
  setTransition('slide-animation');
61
73
  setCount(slideCount + 1);
62
- play('click-ui');
74
+ } else {
75
+ close();
63
76
  }
64
- };
65
-
66
- var goToPreviousSlide = function goToPreviousSlide() {
77
+ }, [close, slideCount, slides.length]);
78
+ var goToPreviousSlide = (0, _react.useCallback)(function () {
67
79
  if (slideCount - 1 >= 0) {
68
80
  setTransition('slide-animation');
69
81
  setCount(slideCount - 1);
70
82
  play('click-ui');
71
83
  }
84
+ }, [play, slideCount]);
85
+
86
+ var handleManualNext = function handleManualNext() {
87
+ play('click-ui');
88
+ setAutomatic(false);
89
+ goToNextSlide();
90
+ };
91
+
92
+ var handleManualBack = function handleManualBack() {
93
+ play('click-ui');
94
+ setAutomatic(false);
95
+ goToPreviousSlide();
72
96
  };
73
97
 
98
+ (0, _react.useEffect)(function () {
99
+ if (automatic) {
100
+ var _slides$slideCount, _slides$slideCount$vi, _slides$slideCount$vi2;
101
+
102
+ var time = characterMs * (((_slides$slideCount = slides[slideCount]) === null || _slides$slideCount === void 0 ? void 0 : (_slides$slideCount$vi = _slides$slideCount.vignettes[0]) === null || _slides$slideCount$vi === void 0 ? void 0 : (_slides$slideCount$vi2 = _slides$slideCount$vi.textData) === null || _slides$slideCount$vi2 === void 0 ? void 0 : _slides$slideCount$vi2.text.length) || 0);
103
+ start(goToNextSlide, time);
104
+ }
105
+
106
+ return function () {
107
+ stop();
108
+ };
109
+ }, [automatic, goToNextSlide, slideCount, slides, start, stop]);
74
110
  if (!(slides !== null && slides !== void 0 && slides.length)) return null;
75
111
  return /*#__PURE__*/_react.default.createElement("div", {
76
112
  className: "comic component growIn-animation"
@@ -85,7 +121,7 @@ var ComicComponent = function ComicComponent(_ref) {
85
121
  }), slideCount > 0 && /*#__PURE__*/_react.default.createElement("button", {
86
122
  type: "button",
87
123
  className: "comic-control comic-control--left gat--btn__round",
88
- onClick: goToPreviousSlide,
124
+ onClick: handleManualBack,
89
125
  "data-testid": "btn-bck"
90
126
  }, /*#__PURE__*/_react.default.createElement("span", {
91
127
  className: "icon-back"
@@ -93,7 +129,7 @@ var ComicComponent = function ComicComponent(_ref) {
93
129
  type: "button",
94
130
  className: "comic-control comic-control--right gat--btn__round",
95
131
  "data-testid": "btn-nxt",
96
- onClick: goToNextSlide
132
+ onClick: handleManualNext
97
133
  }, /*#__PURE__*/_react.default.createElement("span", {
98
134
  className: "icon-next"
99
135
  })), slideCount + 1 >= slides.length && /*#__PURE__*/_react.default.createElement("div", {
@@ -102,7 +138,10 @@ var ComicComponent = function ComicComponent(_ref) {
102
138
  type: "button",
103
139
  className: "gat--btn__round",
104
140
  "data-testid": "btn-cls",
105
- onClick: close
141
+ onClick: function onClick() {
142
+ play('click-ui');
143
+ close();
144
+ }
106
145
  }, /*#__PURE__*/_react.default.createElement("span", {
107
146
  className: "icon-close"
108
147
  })))));
@@ -17,6 +17,8 @@ var _decisionComponent = _interopRequireDefault(require("../../decision-componen
17
17
 
18
18
  var _useEkho = _interopRequireDefault(require("../../../helpers/useEkho"));
19
19
 
20
+ var _useTimeout2 = _interopRequireDefault(require("../../../helpers/useTimeout"));
21
+
20
22
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
21
23
 
22
24
  function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); }
@@ -41,6 +43,9 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
41
43
 
42
44
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
43
45
 
46
+ var characterMs = 75;
47
+ var minMs = 1400;
48
+
44
49
  var ConversationProViewer = function ConversationProViewer(_ref) {
45
50
  var _background$img, _currentLineData$slot;
46
51
 
@@ -51,16 +56,26 @@ var ConversationProViewer = function ConversationProViewer(_ref) {
51
56
  actors = _ref.actors,
52
57
  background = _ref.background,
53
58
  soundActions = _ref.soundActions,
54
- lodSettings = _ref.lodSettings;
59
+ lodSettings = _ref.lodSettings,
60
+ autoPlay = _ref.autoPlay;
55
61
 
56
- var _useState = (0, _react.useState)(0),
62
+ var _useState = (0, _react.useState)(!!autoPlay),
57
63
  _useState2 = _slicedToArray(_useState, 2),
58
- currentLine = _useState2[0],
59
- setCurrentLine = _useState2[1];
64
+ automatic = _useState2[0],
65
+ setAutomatic = _useState2[1];
66
+
67
+ var _useState3 = (0, _react.useState)(0),
68
+ _useState4 = _slicedToArray(_useState3, 2),
69
+ currentLine = _useState4[0],
70
+ setCurrentLine = _useState4[1];
60
71
 
61
72
  var _soundActions = _slicedToArray(soundActions, 1),
62
73
  playSound = _soundActions[0];
63
74
 
75
+ var _useTimeout = (0, _useTimeout2.default)(),
76
+ start = _useTimeout.start,
77
+ stop = _useTimeout.stop;
78
+
64
79
  var backgroundImage = (background === null || background === void 0 ? void 0 : (_background$img = background.img) === null || _background$img === void 0 ? void 0 : _background$img.url) || null;
65
80
  var currentLineData = lines[currentLine];
66
81
  var voiceOverSlots = [];
@@ -202,8 +217,7 @@ var ConversationProViewer = function ConversationProViewer(_ref) {
202
217
  finishConversation();
203
218
  }
204
219
  }, [currentLineData.id, edges, finishConversation, lines]);
205
-
206
- var handleBranchDirection = function handleBranchDirection() {
220
+ var handleBranchDirection = (0, _react.useCallback)(function () {
207
221
  var forward = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : true;
208
222
  var keys = forward ? ['fromId', 'toId'] : ['toId', 'fromId'];
209
223
  var foundEdge = edges.find(function (edge) {
@@ -223,11 +237,8 @@ var ConversationProViewer = function ConversationProViewer(_ref) {
223
237
  finishConversation();
224
238
  }
225
239
  }
226
- };
227
-
228
- var handleClickNext = function handleClickNext(choice, reset) {
229
- playSound('click-ui');
230
-
240
+ }, [currentLineData.id, edges, finishConversation, lines]);
241
+ var handleClickNext = (0, _react.useCallback)(function (choice, reset) {
231
242
  if (isBranched) {
232
243
  if (choice) {
233
244
  handleDecisionBranch(choice, reset);
@@ -244,11 +255,9 @@ var ConversationProViewer = function ConversationProViewer(_ref) {
244
255
  finishConversation();
245
256
  }
246
257
  }
247
- };
258
+ }, [currentLine, finishConversation, handleBranchDirection, handleDecisionBranch, isBranched, lines.length]);
248
259
 
249
260
  var handleClickBack = function handleClickBack() {
250
- playSound('click-ui');
251
-
252
261
  if (isBranched) {
253
262
  handleBranchDirection(false);
254
263
  } else if (currentLine > 0) {
@@ -256,6 +265,18 @@ var ConversationProViewer = function ConversationProViewer(_ref) {
256
265
  }
257
266
  };
258
267
 
268
+ var manualClickNext = function manualClickNext() {
269
+ playSound('click-ui');
270
+ setAutomatic(false);
271
+ handleClickNext();
272
+ };
273
+
274
+ var manualClickBack = function manualClickBack() {
275
+ playSound('click-ui');
276
+ setAutomatic(false);
277
+ handleClickBack();
278
+ };
279
+
259
280
  (0, _useEkho.default)({
260
281
  audioType: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audioType,
261
282
  voice: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.voice,
@@ -263,7 +284,20 @@ var ConversationProViewer = function ConversationProViewer(_ref) {
263
284
  audio: currentLineData === null || currentLineData === void 0 ? void 0 : currentLineData.audio,
264
285
  soundActions: soundActions,
265
286
  emitEvent: emitEvent
266
- });
287
+ }); // Autoplay logic
288
+
289
+ (0, _react.useEffect)(function () {
290
+ if (automatic && !isDecision) {
291
+ var _currentMessage$text;
292
+
293
+ 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);
294
+ start(handleClickNext, time < minMs ? minMs : time);
295
+ }
296
+
297
+ return function () {
298
+ stop();
299
+ };
300
+ }, [currentMessage, automatic, isDecision, start, stop, handleClickNext]);
267
301
 
268
302
  var decisionPayload = _objectSpread(_objectSpread({}, currentLineData.payload), {}, {
269
303
  required: !isBranched,
@@ -301,15 +335,13 @@ var ConversationProViewer = function ConversationProViewer(_ref) {
301
335
  className: "gat--btn__round ".concat(currentLine > 0 && (!lastLine.decision || isBranched) ? '' : 'disabled'),
302
336
  disabled: currentLine > 0 && (!lastLine.decision || isBranched) ? '' : true,
303
337
  type: "button",
304
- onClick: handleClickBack
338
+ onClick: manualClickBack
305
339
  }, /*#__PURE__*/_react.default.createElement("span", {
306
340
  className: "icon-back"
307
341
  })), /*#__PURE__*/_react.default.createElement("button", {
308
342
  className: "gat--btn__round",
309
343
  type: "button",
310
- onClick: function onClick() {
311
- return handleClickNext();
312
- }
344
+ onClick: manualClickNext
313
345
  }, /*#__PURE__*/_react.default.createElement("span", {
314
346
  className: "icon-next"
315
347
  }))))));
@@ -25,6 +25,8 @@ var _helpers = require("../../../helpers");
25
25
 
26
26
  var _deviceDetection = require("../../../helpers/deviceDetection");
27
27
 
28
+ var _useTimeout2 = _interopRequireDefault(require("../../../helpers/useTimeout"));
29
+
28
30
  var _useEkho = _interopRequireDefault(require("../../../helpers/useEkho"));
29
31
 
30
32
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -54,15 +56,15 @@ function _iterableToArrayLimit(arr, i) { var _i = arr == null ? null : typeof Sy
54
56
  function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
55
57
 
56
58
  var isMobile = (0, _deviceDetection.DeviceDetection)();
57
- var crossFadeDuration = 0.5; // Mobile always zoom in?
59
+ var crossFadeDuration = 0.5;
60
+ var characterMs = 75;
61
+ var minMs = 1400; // Mobile always zoom in?
58
62
 
59
63
  var raycast = new _three.Raycaster();
60
64
  var maxCharacterToSwitch = 70;
61
65
  raycast.firstHitOnly = true;
62
66
 
63
67
  var DialogComponent = function DialogComponent(_ref) {
64
- var _currentLine$audio;
65
-
66
68
  var emitEvent = _ref.emitEvent,
67
69
  lines = _ref.lines,
68
70
  actors = _ref.actors,
@@ -76,7 +78,7 @@ var DialogComponent = function DialogComponent(_ref) {
76
78
  line = _useState2[0],
77
79
  changeLine = _useState2[1];
78
80
 
79
- var _useState3 = (0, _react.useState)(true),
81
+ var _useState3 = (0, _react.useState)(!!autoPlay),
80
82
  _useState4 = _slicedToArray(_useState3, 2),
81
83
  automatic = _useState4[0],
82
84
  setAutomatic = _useState4[1];
@@ -104,6 +106,11 @@ var DialogComponent = function DialogComponent(_ref) {
104
106
  scene = _useThree2[1];
105
107
 
106
108
  var changedMats = (0, _react.useRef)([]);
109
+
110
+ var _useTimeout = (0, _useTimeout2.default)(),
111
+ start = _useTimeout.start,
112
+ stop = _useTimeout.stop;
113
+
107
114
  var loader = (0, _react.useMemo)(function () {
108
115
  return new _GLTFLoader.GLTFLoader();
109
116
  }, []);
@@ -285,7 +292,18 @@ var DialogComponent = function DialogComponent(_ref) {
285
292
  } else {
286
293
  finishConversation();
287
294
  }
288
- }, [isBranched, line, lines.length, handleDecisionBranch, handleBranchDirection, finishConversation]); // Position bubble over talking character/and switch emotions
295
+ }, [isBranched, line, lines.length, handleDecisionBranch, handleBranchDirection, finishConversation]);
296
+
297
+ var manualBackLine = function manualBackLine() {
298
+ setAutomatic(false);
299
+ backLine();
300
+ };
301
+
302
+ var manualNextLine = function manualNextLine() {
303
+ setAutomatic(false);
304
+ nextLine();
305
+ }; // Position bubble over talking character/and switch emotions
306
+
289
307
 
290
308
  (0, _react.useEffect)(function () {
291
309
  if (isDecision) {
@@ -431,28 +449,17 @@ var DialogComponent = function DialogComponent(_ref) {
431
449
  }); // Autoplay logic
432
450
 
433
451
  (0, _react.useEffect)(function () {
434
- var timeout;
435
-
436
- if (autoPlay) {
437
- if (line >= lines.length - 1 && automatic) {
438
- setAutomatic(false);
439
- } else if (automatic && currentMessage.show && !currentLine.decision) {
440
- var time = 0;
441
-
442
- if (currentMessage.text) {
443
- time = 75 * (currentMessage === null || currentMessage === void 0 ? void 0 : currentMessage.text.length);
444
- }
452
+ if (automatic && currentMessage.show && !currentLine.decision) {
453
+ var _currentMessage$text;
445
454
 
446
- timeout = setTimeout(function () {
447
- nextLine();
448
- }, time < 1400 ? 1400 : time);
449
- }
455
+ 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);
456
+ start(nextLine, time < minMs ? minMs : time);
450
457
  }
451
458
 
452
459
  return function () {
453
- if (timeout) clearTimeout(timeout);
460
+ stop();
454
461
  };
455
- }, [currentMessage, nextLine, autoPlay, lines.length, automatic, line, currentLine === null || currentLine === void 0 ? void 0 : currentLine.decision, currentLine === null || currentLine === void 0 ? void 0 : currentLine.audioType, currentLine === null || currentLine === void 0 ? void 0 : (_currentLine$audio = currentLine.audio) === null || _currentLine$audio === void 0 ? void 0 : _currentLine$audio.url]); // Positioning logic
462
+ }, [currentMessage, nextLine, automatic, currentLine.decision, start, stop]); // Positioning logic
456
463
 
457
464
  var checkBubblePosition = (0, _react.useCallback)(function () {
458
465
  if (bubbleRef.current && currentLine.slots) {
@@ -611,16 +618,14 @@ var DialogComponent = function DialogComponent(_ref) {
611
618
  }, /*#__PURE__*/_react.default.createElement("button", {
612
619
  disabled: line <= 0 || (lastLine === null || lastLine === void 0 ? void 0 : lastLine.decision) || isBranched,
613
620
  type: "button",
614
- onClick: backLine,
621
+ onClick: manualBackLine,
615
622
  className: "gat--btn__round ".concat(line <= 0 || lastLine !== null && lastLine !== void 0 && lastLine.decision || isBranched ? 'disabled' : '')
616
623
  }, /*#__PURE__*/_react.default.createElement("span", {
617
624
  className: "icon-back"
618
625
  })), /*#__PURE__*/_react.default.createElement("button", {
619
626
  className: "gat--btn__round",
620
627
  type: "button",
621
- onClick: function onClick() {
622
- return nextLine();
623
- }
628
+ onClick: manualNextLine
624
629
  }, /*#__PURE__*/_react.default.createElement("span", {
625
630
  className: "icon-next"
626
631
  })))) : null);
@@ -36,6 +36,8 @@ var useEkho = function useEkho(_ref) {
36
36
  playSound = _soundActions[0],
37
37
  stop = _soundActions[1];
38
38
 
39
+ var noAudio = !audio && !voice;
40
+
39
41
  var _useState = (0, _react.useState)(false),
40
42
  _useState2 = _slicedToArray(_useState, 2),
41
43
  isMounted = _useState2[0],
@@ -111,7 +113,7 @@ var useEkho = function useEkho(_ref) {
111
113
 
112
114
  case 3:
113
115
  url = _context.sent;
114
- setCurrentPlaying(url, 'tts');
116
+ setCurrentPlaying(url);
115
117
 
116
118
  case 5:
117
119
  case "end":
@@ -126,12 +128,10 @@ var useEkho = function useEkho(_ref) {
126
128
  };
127
129
  }(), [emitEvent, setCurrentPlaying]);
128
130
  (0, _react.useEffect)(function () {
129
- var noAudio = !audio && !voice;
130
-
131
131
  if (currentPlaying.current.url && noAudio) {
132
132
  stop(currentPlaying.current.cc);
133
133
  }
134
- }, [stop, audio, voice]);
134
+ }, [noAudio, stop]);
135
135
  (0, _react.useEffect)(function () {
136
136
  if (isMounted) {
137
137
  if (audioType === 'voice' && voice !== null && voice !== void 0 && voice.id) {
@@ -144,7 +144,7 @@ var useEkho = function useEkho(_ref) {
144
144
  setCurrentPlaying(audio === null || audio === void 0 ? void 0 : audio.url);
145
145
  }
146
146
  }
147
- }, [getVoice, playSpeech, isMounted, playSound, stop, voice, text, audioType, audio === null || audio === void 0 ? void 0 : audio.url, audio, setCurrentPlaying]);
147
+ }, [getVoice, playSpeech, isMounted, voice, text, audioType, audio === null || audio === void 0 ? void 0 : audio.url, audio, setCurrentPlaying]);
148
148
  };
149
149
 
150
150
  var _default = useEkho;
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+
8
+ var _react = require("react");
9
+
10
+ var useTimeout = function useTimeout() {
11
+ var timeout = (0, _react.useRef)();
12
+
13
+ var start = function start(fn, ms) {
14
+ timeout.current = setTimeout(fn, ms);
15
+ };
16
+
17
+ var stop = function stop() {
18
+ if (timeout.current) {
19
+ clearTimeout(timeout.current);
20
+ }
21
+ };
22
+
23
+ (0, _react.useEffect)(function () {
24
+ return function () {
25
+ if (timeout.current) {
26
+ clearTimeout(timeout.current);
27
+ }
28
+ };
29
+ }, []);
30
+ return {
31
+ start: start,
32
+ stop: stop,
33
+ running: !!timeout.current
34
+ };
35
+ };
36
+
37
+ var _default = useTimeout;
38
+ exports.default = _default;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@gamelearn/arcade-components",
3
3
  "author": "Gamelearn",
4
4
  "license": "unlicense",
5
- "version": "1.10.1",
5
+ "version": "1.11.0",
6
6
  "main": "dist/index.js",
7
7
  "files": [
8
8
  "dist",