@elice/material-exercise 1.251120.0 → 1.251125.0-coloso.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.
Files changed (69) hide show
  1. package/cjs/components/material-exercise/context/index.js +1 -2
  2. package/cjs/components/material-exercise/context/recoil.d.ts +4 -4
  3. package/cjs/components/material-exercise/context/recoil.js +30 -36
  4. package/cjs/components/material-exercise/context/subjects.d.ts +0 -5
  5. package/cjs/components/material-exercise/context/subjects.js +0 -5
  6. package/cjs/components/material-exercise/context/types.d.ts +1 -5
  7. package/cjs/components/material-exercise/exercise-file-editor/ExerciseFileEditor.d.ts +5 -3
  8. package/cjs/components/material-exercise/exercise-file-editor/ExerciseFileEditor.js +24 -100
  9. package/cjs/components/material-exercise/exercise-file-editor/ExerciseFileReadOnlyBanner.d.ts +2 -5
  10. package/cjs/components/material-exercise/exercise-file-editor/ExerciseFileReadOnlyBanner.js +8 -1
  11. package/cjs/components/material-exercise/exercise-file-editor/locales/en.json.js +1 -1
  12. package/cjs/components/material-exercise/exercise-file-editor/locales/ja.json.js +1 -1
  13. package/cjs/components/material-exercise/exercise-file-editor/locales/ko.json.js +1 -1
  14. package/cjs/components/material-exercise/exercise-file-editor/locales/th.json.js +1 -1
  15. package/cjs/components/material-exercise/exercise-runner/ExerciseRunner.js +23 -78
  16. package/cjs/components/material-exercise/exercise-runner/ExerciseRunnerController.js +2 -16
  17. package/cjs/components/material-exercise/exercise-runner/ExerciseRunnerControllerArduinoAgentModal.js +18 -31
  18. package/cjs/components/material-exercise/exercise-runner/ExerciseRunnerControllerButtonGroup.js +1 -5
  19. package/cjs/components/material-exercise/exercise-runner/ExerciseRunnerControllerRunningInfo.js +5 -30
  20. package/cjs/components/material-exercise/exercise-runner/ExerciseRunnerControllerStatusMessage.js +11 -35
  21. package/cjs/components/material-exercise/exercise-runner/locales/en.json.js +1 -1
  22. package/cjs/components/material-exercise/exercise-runner/locales/ja.json.js +1 -1
  23. package/cjs/components/material-exercise/exercise-runner/locales/ko.json.js +1 -1
  24. package/cjs/components/material-exercise/exercise-runner/locales/th.json.js +1 -1
  25. package/cjs/hooks/useRunnerRoomWebSocket.js +2 -1
  26. package/cjs/hooks/useStdioWebSocket.js +3 -2
  27. package/cjs/hooks/useUsercodeEditWebSocket.d.ts +1 -14
  28. package/cjs/hooks/useUsercodeEditWebSocket.js +6 -16
  29. package/cjs/utils/index.d.ts +0 -1
  30. package/cjs/utils/index.js +0 -2
  31. package/es/components/material-exercise/context/index.js +2 -2
  32. package/es/components/material-exercise/context/recoil.d.ts +4 -4
  33. package/es/components/material-exercise/context/recoil.js +31 -37
  34. package/es/components/material-exercise/context/subjects.d.ts +0 -5
  35. package/es/components/material-exercise/context/subjects.js +1 -5
  36. package/es/components/material-exercise/context/types.d.ts +1 -5
  37. package/es/components/material-exercise/exercise-file-editor/ExerciseFileEditor.d.ts +5 -3
  38. package/es/components/material-exercise/exercise-file-editor/ExerciseFileEditor.js +26 -102
  39. package/es/components/material-exercise/exercise-file-editor/ExerciseFileReadOnlyBanner.d.ts +2 -5
  40. package/es/components/material-exercise/exercise-file-editor/ExerciseFileReadOnlyBanner.js +8 -1
  41. package/es/components/material-exercise/exercise-file-editor/locales/en.json.js +1 -1
  42. package/es/components/material-exercise/exercise-file-editor/locales/ja.json.js +1 -1
  43. package/es/components/material-exercise/exercise-file-editor/locales/ko.json.js +1 -1
  44. package/es/components/material-exercise/exercise-file-editor/locales/th.json.js +1 -1
  45. package/es/components/material-exercise/exercise-runner/ExerciseRunner.js +23 -78
  46. package/es/components/material-exercise/exercise-runner/ExerciseRunnerController.js +3 -17
  47. package/es/components/material-exercise/exercise-runner/ExerciseRunnerControllerArduinoAgentModal.js +17 -31
  48. package/es/components/material-exercise/exercise-runner/ExerciseRunnerControllerButtonGroup.js +2 -6
  49. package/es/components/material-exercise/exercise-runner/ExerciseRunnerControllerRunningInfo.js +7 -32
  50. package/es/components/material-exercise/exercise-runner/ExerciseRunnerControllerStatusMessage.js +14 -38
  51. package/es/components/material-exercise/exercise-runner/locales/en.json.js +1 -1
  52. package/es/components/material-exercise/exercise-runner/locales/ja.json.js +1 -1
  53. package/es/components/material-exercise/exercise-runner/locales/ko.json.js +1 -1
  54. package/es/components/material-exercise/exercise-runner/locales/th.json.js +1 -1
  55. package/es/hooks/useRunnerRoomWebSocket.js +2 -1
  56. package/es/hooks/useStdioWebSocket.js +3 -2
  57. package/es/hooks/useUsercodeEditWebSocket.d.ts +1 -14
  58. package/es/hooks/useUsercodeEditWebSocket.js +6 -16
  59. package/es/utils/index.d.ts +0 -1
  60. package/es/utils/index.js +0 -1
  61. package/package.json +7 -7
  62. package/cjs/components/material-exercise/exercise-runner/ExerciseRunnerControllerCodeHelpRequestButton.d.ts +0 -6
  63. package/cjs/components/material-exercise/exercise-runner/ExerciseRunnerControllerCodeHelpRequestButton.js +0 -47
  64. package/cjs/utils/async.d.ts +0 -4
  65. package/cjs/utils/async.js +0 -15
  66. package/es/components/material-exercise/exercise-runner/ExerciseRunnerControllerCodeHelpRequestButton.d.ts +0 -6
  67. package/es/components/material-exercise/exercise-runner/ExerciseRunnerControllerCodeHelpRequestButton.js +0 -43
  68. package/es/utils/async.d.ts +0 -4
  69. package/es/utils/async.js +0 -13
@@ -36,9 +36,9 @@ exports.exerciseRunnerRunTypeState = recoil.exerciseRunnerRunTypeState;
36
36
  exports.exerciseRunnerRunningState = recoil.exerciseRunnerRunningState;
37
37
  exports.exerciseRunnerStdioFilesState = recoil.exerciseRunnerStdioFilesState;
38
38
  exports.exerciseRunnerSubmittingState = recoil.exerciseRunnerSubmittingState;
39
+ exports.exerciseRunnerWebSocketStatusQuery = recoil.exerciseRunnerWebSocketStatusQuery;
39
40
  exports.exerciseState = recoil.exerciseState;
40
41
  exports.exerciseUserState = recoil.exerciseUserState;
41
- exports.exerciseWebSocketTotalStatusQuery = recoil.exerciseWebSocketTotalStatusQuery;
42
42
  exports.exerciseWebsocketQuery = recoil.exerciseWebsocketQuery;
43
43
  exports.exerciseWebsocketStates = recoil.exerciseWebsocketStates;
44
44
  exports.ExerciseContext = context.ExerciseContext;
@@ -52,7 +52,6 @@ Object.defineProperty(exports, "ExercisePreviewType", {
52
52
  });
53
53
  exports.exerciseFileEditorContentChange$ = subjects.exerciseFileEditorContentChange$;
54
54
  exports.exerciseFileEditorSaveAction$ = subjects.exerciseFileEditorSaveAction$;
55
- exports.exerciseFileEditorSyncRequestAction$ = subjects.exerciseFileEditorSyncRequestAction$;
56
55
  exports.exerciseRunnerRoomsOpen$ = subjects.exerciseRunnerRoomsOpen$;
57
56
  exports.exerciseRunnerTextSend$ = subjects.exerciseRunnerTextSend$;
58
57
  exports.ExerciseProvider = ExerciseProvider.default;
@@ -64,15 +64,15 @@ export declare const exerciseRunnerStdioFilesState: import("recoil").RecoilState
64
64
  /**
65
65
  *
66
66
  */
67
- export declare const exerciseWebsocketStates: import("recoil").RecoilState<AtomWebSocketStates>;
67
+ export declare const exerciseRunnerWebSocketStatusQuery: import("recoil").RecoilValueReadOnly<number>;
68
68
  /**
69
69
  *
70
70
  */
71
- export declare const exerciseWebsocketQuery: (param: AtomWebSocketStateKey) => import("recoil").RecoilState<number>;
71
+ export declare const exerciseWebsocketStates: import("recoil").RecoilState<AtomWebSocketStates>;
72
72
  /**
73
- * Check all necessary websockets and return the status.
73
+ *
74
74
  */
75
- export declare const exerciseWebSocketTotalStatusQuery: (param: AtomWebSocketStateKey[]) => import("recoil").RecoilValueReadOnly<number>;
75
+ export declare const exerciseWebsocketQuery: (param: AtomWebSocketStateKey) => import("recoil").RecoilState<number>;
76
76
  /**
77
77
  *
78
78
  */
@@ -455,6 +455,30 @@ var exerciseRunnerStdioFilesState = recoil.atom({
455
455
  key: "".concat(KEY_PREFIX, "/Runner/StdioFiles"),
456
456
  default: []
457
457
  });
458
+ /**
459
+ *
460
+ */
461
+ var exerciseRunnerWebSocketStatusQuery = recoil.selector({
462
+ key: "".concat(KEY_PREFIX, "/Runner/WebsocketState"),
463
+ get: function get(_ref19) {
464
+ var _get = _ref19.get;
465
+ var states = Object.freeze([_get(exerciseWebsocketStates).runnerRoom, _get(exerciseWebsocketStates).stdio]);
466
+ // connecting
467
+ if (states.includes(websocket.EliceWebSocket.CLOSED) || states.includes(websocket.EliceWebSocket.CONNECTING)) {
468
+ return websocket.EliceWebSocket.CONNECTING;
469
+ }
470
+ // connected
471
+ else if (states.every(function (state) {
472
+ return state === WebSocket.OPEN;
473
+ })) {
474
+ return websocket.EliceWebSocket.OPEN;
475
+ }
476
+ // reconnecting
477
+ else {
478
+ return websocket.EliceWebSocket.CONNECTING;
479
+ }
480
+ }
481
+ });
458
482
  //
459
483
  // =============== websocket ===============
460
484
  //
@@ -475,49 +499,19 @@ var exerciseWebsocketStates = recoil.atom({
475
499
  var exerciseWebsocketQuery = recoil.selectorFamily({
476
500
  key: "".concat(KEY_PREFIX, "/Websocket/State"),
477
501
  get: function get(key) {
478
- return function (_ref19) {
479
- var get = _ref19.get;
502
+ return function (_ref20) {
503
+ var get = _ref20.get;
480
504
  return get(exerciseWebsocketStates)[key];
481
505
  };
482
506
  },
483
507
  set: function set(key) {
484
- return function (_ref20, newWebSocketState) {
485
- var get = _ref20.get,
486
- set = _ref20.set;
508
+ return function (_ref21, newWebSocketState) {
509
+ var get = _ref21.get,
510
+ set = _ref21.set;
487
511
  set(exerciseWebsocketStates, Object.assign(Object.assign({}, get(exerciseWebsocketStates)), _rollupPluginBabelHelpers.defineProperty({}, key, newWebSocketState)));
488
512
  };
489
513
  }
490
514
  });
491
- /**
492
- * Check all necessary websockets and return the status.
493
- */
494
- var exerciseWebSocketTotalStatusQuery = recoil.selectorFamily({
495
- key: "".concat(KEY_PREFIX, "/Websocket/TotalStatus"),
496
- get: function get(keys) {
497
- return function (_ref21) {
498
- var get = _ref21.get;
499
- var states = Object.freeze(keys.map(function (key) {
500
- return get(exerciseWebsocketStates)[key];
501
- }));
502
- switch (true) {
503
- case states.every(function (state) {
504
- return state === websocket.EliceWebSocket.OPEN;
505
- }):
506
- return websocket.EliceWebSocket.OPEN;
507
- case states.every(function (state) {
508
- return state === websocket.EliceWebSocket.CLOSED;
509
- }):
510
- return websocket.EliceWebSocket.CLOSED;
511
- case states.every(function (state) {
512
- return state === websocket.EliceWebSocket.CLOSING;
513
- }):
514
- return websocket.EliceWebSocket.CLOSING;
515
- default:
516
- return websocket.EliceWebSocket.CONNECTING;
517
- }
518
- };
519
- }
520
- });
521
515
  //
522
516
  // =============== multi language ===============
523
517
  //
@@ -859,8 +853,8 @@ exports.exerciseRunnerRunTypeState = exerciseRunnerRunTypeState;
859
853
  exports.exerciseRunnerRunningState = exerciseRunnerRunningState;
860
854
  exports.exerciseRunnerStdioFilesState = exerciseRunnerStdioFilesState;
861
855
  exports.exerciseRunnerSubmittingState = exerciseRunnerSubmittingState;
856
+ exports.exerciseRunnerWebSocketStatusQuery = exerciseRunnerWebSocketStatusQuery;
862
857
  exports.exerciseState = exerciseState;
863
858
  exports.exerciseUserState = exerciseUserState;
864
- exports.exerciseWebSocketTotalStatusQuery = exerciseWebSocketTotalStatusQuery;
865
859
  exports.exerciseWebsocketQuery = exerciseWebsocketQuery;
866
860
  exports.exerciseWebsocketStates = exerciseWebsocketStates;
@@ -1,5 +1,4 @@
1
1
  import { Subject } from 'rxjs';
2
- import type { MaterialExerciseCodeEditorSyncRequest } from "./types";
3
2
  /**
4
3
  * Content change request to code editor.
5
4
  */
@@ -8,10 +7,6 @@ export declare const exerciseFileEditorContentChange$: Subject<string | null>;
8
7
  * Save action emitted by file editor.
9
8
  */
10
9
  export declare const exerciseFileEditorSaveAction$: Subject<void>;
11
- /**
12
- * Request file editor to sync full code.
13
- */
14
- export declare const exerciseFileEditorSyncRequestAction$: Subject<MaterialExerciseCodeEditorSyncRequest>;
15
10
  /**
16
11
  * Send text request to runner stdio.
17
12
  */
@@ -10,10 +10,6 @@ var exerciseFileEditorContentChange$ = new rxjs.Subject();
10
10
  * Save action emitted by file editor.
11
11
  */
12
12
  var exerciseFileEditorSaveAction$ = new rxjs.Subject();
13
- /**
14
- * Request file editor to sync full code.
15
- */
16
- var exerciseFileEditorSyncRequestAction$ = new rxjs.Subject();
17
13
  /**
18
14
  * Send text request to runner stdio.
19
15
  */
@@ -25,6 +21,5 @@ var exerciseRunnerRoomsOpen$ = new rxjs.Subject();
25
21
 
26
22
  exports.exerciseFileEditorContentChange$ = exerciseFileEditorContentChange$;
27
23
  exports.exerciseFileEditorSaveAction$ = exerciseFileEditorSaveAction$;
28
- exports.exerciseFileEditorSyncRequestAction$ = exerciseFileEditorSyncRequestAction$;
29
24
  exports.exerciseRunnerRoomsOpen$ = exerciseRunnerRoomsOpen$;
30
25
  exports.exerciseRunnerTextSend$ = exerciseRunnerTextSend$;
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { GetOrgMaterialExerciseExerciseRunningListResponses, PostOrgMaterialExerciseExerciseRunningSubmitResponses, WebsocketUsercodeMessageWriteFailed, WebsocketUsercodeMessageWriteSucceed } from '@elice/types';
2
+ import type { GetOrgMaterialExerciseExerciseRunningListResponses, PostOrgMaterialExerciseExerciseRunningSubmitResponses } from '@elice/types';
3
3
  import type { MonacoEditorApis } from "../../shared/monaco-editor";
4
4
  import type { CodeHelperError } from "../../../utils";
5
5
  import type { ExerciseProviderNoImageProps } from './ExerciseProviderNoImage';
@@ -133,7 +133,3 @@ export interface ExerciseProviderDedicatedProps {
133
133
  */
134
134
  readOnlyActiveFile: boolean;
135
135
  }
136
- export interface MaterialExerciseCodeEditorSyncRequest {
137
- onSucceed: (msg: WebsocketUsercodeMessageWriteSucceed) => void;
138
- onFailed: (msg: WebsocketUsercodeMessageWriteFailed) => void;
139
- }
@@ -1,4 +1,6 @@
1
1
  import React from 'react';
2
- import type { WithIntlComponentBuilderProps } from '@elice/intl';
3
- declare const _default: React.ForwardRefExoticComponent<Omit<import("@elice/intl").IntlComponentExtraProps & Omit<WithIntlComponentBuilderProps, keyof import("@elice/intl").IntlComponentExtraProps | "__intl">, "ref"> & React.RefAttributes<any>>;
4
- export default _default;
2
+ /**
3
+ * Exercise file (code) editor for editable files
4
+ */
5
+ declare const ExerciseFileEditor: React.VFC;
6
+ export default ExerciseFileEditor;
@@ -8,11 +8,9 @@ var React = require('react');
8
8
  var reactUse = require('react-use');
9
9
  var apiClient = require('@elice/api-client');
10
10
  var blocks = require('@elice/blocks');
11
- var intl = require('@elice/intl');
12
11
  var types = require('@elice/types');
13
12
  var utils = require('@elice/utils');
14
13
  var recoil = require('recoil');
15
- var unicount = require('unicount');
16
14
  var ExerciseFileShimmer = require('../../shared/exercise-shimmer/ExerciseFileShimmer.js');
17
15
  require('../../shared/exercise-shimmer/ExerciseFileTabsShimmer.js');
18
16
  require('../../shared/exercise-shimmer/ExerciseFileTabShimmer.js');
@@ -36,8 +34,6 @@ require('humps');
36
34
  require('ot-text-unicode');
37
35
  var useUsercodeEditWebSocket = require('../../../hooks/useUsercodeEditWebSocket.js');
38
36
  var ExerciseFileReadOnlyBanner = require('./ExerciseFileReadOnlyBanner.js');
39
- var en = require('./locales/en.json.js');
40
- var ko = require('./locales/ko.json.js');
41
37
 
42
38
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
43
39
 
@@ -49,8 +45,7 @@ var React__default = /*#__PURE__*/_interopDefaultCompat(React);
49
45
  /**
50
46
  * Exercise file (code) editor for editable files
51
47
  */
52
- var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
53
- var __intl = _ref.__intl;
48
+ var ExerciseFileEditor = function ExerciseFileEditor() {
54
49
  var _React$useContext = React__default.default.useContext(context.ExerciseContext),
55
50
  materialExerciseId = _React$useContext.materialExerciseId,
56
51
  exerciseRoomId = _React$useContext.exerciseRoomId,
@@ -95,8 +90,6 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
95
90
  _React$useState8 = _rollupPluginBabelHelpers.slicedToArray(_React$useState7, 2),
96
91
  isFileResettable = _React$useState8[0],
97
92
  setFileResettable = _React$useState8[1];
98
- // requests to editor
99
- var usercodeSyncRequestsRef = React__default.default.useRef(new Map());
100
93
  var setExerciseMonacoEditorApisState = recoil.useSetRecoilState(recoil$1.exerciseMonacoEditorApisState);
101
94
  React__default.default.useEffect(function () {
102
95
  if (editorApis.current) {
@@ -108,7 +101,7 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
108
101
  * Set value of current file.
109
102
  */
110
103
  var setValue = /*#__PURE__*/function () {
111
- var _ref2 = _rollupPluginBabelHelpers.asyncToGenerator( /*#__PURE__*/_rollupPluginBabelHelpers.regeneratorRuntime().mark(function _callee(content) {
104
+ var _ref = _rollupPluginBabelHelpers.asyncToGenerator( /*#__PURE__*/_rollupPluginBabelHelpers.regeneratorRuntime().mark(function _callee(content) {
112
105
  var _a, readyExerciseImage;
113
106
  return _rollupPluginBabelHelpers.regeneratorRuntime().wrap(function _callee$(_context) {
114
107
  while (1) switch (_context.prev = _context.next) {
@@ -166,7 +159,7 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
166
159
  }, _callee);
167
160
  }));
168
161
  return function setValue(_x) {
169
- return _ref2.apply(this, arguments);
162
+ return _ref.apply(this, arguments);
170
163
  };
171
164
  }();
172
165
  /**
@@ -228,26 +221,6 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
228
221
  _iterator.f();
229
222
  }
230
223
  };
231
- /**
232
- * Handle `WRITE_SUCCEED` event.
233
- */
234
- var handleWebsocketUsercodeWriteSucceed = function handleWebsocketUsercodeWriteSucceed(msg, requestId) {
235
- var request = usercodeSyncRequestsRef.current.get(requestId);
236
- if (request) {
237
- usercodeSyncRequestsRef.current.delete(requestId);
238
- request.onSucceed(msg);
239
- }
240
- };
241
- /**
242
- * Handle `WRITE_FAILED` event.
243
- */
244
- var handleWebsocketUsercodeWriteFailedAndReset = function handleWebsocketUsercodeWriteFailedAndReset(msg) {
245
- blocks.Notification.error(__intl.formatMessage({
246
- id: 'materialExercise.websocket.writeFailedAndReset'
247
- }), {
248
- duration: 5000
249
- });
250
- };
251
224
  /**
252
225
  * Usercode edit web socket.
253
226
  */
@@ -255,24 +228,16 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
255
228
  exerciseRoomId: exerciseRoomId,
256
229
  filename: activeFilename,
257
230
  onInit: function onInit() {
258
- setWebSocketReady(false);
259
- serverInitiatedVersions.current = [];
260
- editorDocHistories.current = {};
261
- setTimeout(function () {
262
- return setWebSocketReady(true);
263
- }, 100);
231
+ return setWebSocketReady(true);
264
232
  },
265
- onWriteNoti: handleWebsocketUsercodeWriteNoti,
266
- onWriteSucceed: handleWebsocketUsercodeWriteSucceed,
267
- onWriteFailedAndReset: handleWebsocketUsercodeWriteFailedAndReset
233
+ onWriteNoti: handleWebsocketUsercodeWriteNoti
268
234
  });
269
235
  /**
270
236
  *
271
237
  */
272
238
  var handleChange = function handleChange(e) {
273
239
  var _a, _b;
274
- var rawContent = (_b = (_a = editorApis.current) === null || _a === void 0 ? void 0 : _a.getValue()) !== null && _b !== void 0 ? _b : '';
275
- setFileEditorContent(rawContent);
240
+ setFileEditorContent((_b = (_a = editorApis.current) === null || _a === void 0 ? void 0 : _a.getValue()) !== null && _b !== void 0 ? _b : '');
276
241
  // === server initiated ===
277
242
  var index = serverInitiatedVersions.current.indexOf(e.versionId - 1);
278
243
  if (index !== -1) {
@@ -287,23 +252,20 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
287
252
  try {
288
253
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
289
254
  var change = _step2.value;
290
- // the offset calculates a 32bit unicode(ex: emoji) to 1 but vanila JS calculates to 2
291
- var utf32Offset = unicount.uniCount(rawContent.slice(0, change.rangeOffset));
292
255
  // insertion
293
256
  if (change.rangeLength === 0 && !readOnly) {
294
- wsUsercode.sendOTs(utf32Offset > 0 ? [utf32Offset, change.text] : [change.text]);
257
+ wsUsercode.sendOTs(change.rangeOffset > 0 ? [change.rangeOffset, change.text] : [change.text]);
295
258
  }
296
259
  // deletion
297
260
  else {
298
261
  if (prevDoc && !readOnly) {
299
- wsUsercode.sendOTs([utf32Offset || null, {
300
- // when using slice do not use utf32Offset (because it's vanila JS's method)
262
+ wsUsercode.sendOTs([change.rangeOffset || null, {
301
263
  d: prevDoc.slice(change.rangeOffset, change.rangeOffset + change.rangeLength)
302
264
  }].filter(Boolean));
303
265
  }
304
266
  // replace
305
267
  if (change.text.length > 0 && !readOnly) {
306
- wsUsercode.sendOTs(utf32Offset > 0 ? [utf32Offset, change.text] : [change.text]);
268
+ wsUsercode.sendOTs(change.rangeOffset > 0 ? [change.rangeOffset, change.text] : [change.text]);
307
269
  }
308
270
  }
309
271
  }
@@ -335,6 +297,7 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
335
297
  // Handle editor content change.
336
298
  //
337
299
  React__default.default.useEffect(function () {
300
+ var _a, _b;
338
301
  var _editorApis = editorApis.current;
339
302
  if (!_editorApis || !isReady) {
340
303
  return;
@@ -342,24 +305,19 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
342
305
  _editorApis.setValue(wsUsercode.doc);
343
306
  pushEditorDocHistories();
344
307
  var subscription = undefined;
345
- var __subscribe = function __subscribe() {
346
- var _a, _b;
347
- if (utils.FlutterApp.checkWebview()) {
348
- subscription = (_a = _editorApis.editor) === null || _a === void 0 ? void 0 : _a.onDidChangeModelContent(function (e) {
349
- pushEditorDocHistories();
350
- handleChange(e);
351
- utils.FlutterApp.onDidChangeContent();
352
- });
353
- } else {
354
- subscription = (_b = _editorApis.editor) === null || _b === void 0 ? void 0 : _b.onDidChangeModelContent(function (e) {
355
- pushEditorDocHistories();
356
- handleChange(e);
357
- });
358
- }
359
- };
360
- var timeout = window.setTimeout(__subscribe, 10); // need to wait for editor to be ready.
308
+ if (utils.FlutterApp.checkWebview()) {
309
+ subscription = (_a = _editorApis.editor) === null || _a === void 0 ? void 0 : _a.onDidChangeModelContent(function (e) {
310
+ pushEditorDocHistories();
311
+ handleChange(e);
312
+ utils.FlutterApp.onDidChangeContent();
313
+ });
314
+ } else {
315
+ subscription = (_b = _editorApis.editor) === null || _b === void 0 ? void 0 : _b.onDidChangeModelContent(function (e) {
316
+ pushEditorDocHistories();
317
+ handleChange(e);
318
+ });
319
+ }
361
320
  return function () {
362
- window.clearTimeout(timeout);
363
321
  if (subscription) {
364
322
  subscription.dispose();
365
323
  }
@@ -391,29 +349,6 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
391
349
  // eslint-disable-next-line react-hooks/exhaustive-deps
392
350
  []);
393
351
  //
394
- // Sync full usercode before submitting/running the code.
395
- //
396
- React__default.default.useEffect(function () {
397
- var syncRequestSub = subjects.exerciseFileEditorSyncRequestAction$.subscribe(function (request) {
398
- var _a;
399
- var model = (_a = editorApis === null || editorApis === void 0 ? void 0 : editorApis.current) === null || _a === void 0 ? void 0 : _a.getMonacoModel();
400
- if (!model) {
401
- return;
402
- }
403
- var content = model.getValue();
404
- var _wsUsercode$sendOTs = wsUsercode.sendOTs(
405
- // ot-text-unicode doesn't accept empty deletion. So we fallback to no-op when content = "".
406
- content.length > 0 ? [{
407
- d: content
408
- }, content] : []),
409
- requestId = _wsUsercode$sendOTs.requestId;
410
- usercodeSyncRequestsRef.current.set(requestId, request);
411
- });
412
- return function () {
413
- syncRequestSub.unsubscribe();
414
- };
415
- }, [wsUsercode]);
416
- //
417
352
  // Emit editor change event to parent component.
418
353
  //
419
354
  reactUse.useDebounce(function () {
@@ -464,14 +399,7 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
464
399
  column: true,
465
400
  width: "100%",
466
401
  height: "100%",
467
- style: {
468
- // When the user focuses out and in again,
469
- // Monaco editor can't restore focus well in Safari when parent's user-select is none.
470
- WebkitUserSelect: !readOnly ? 'text' : undefined
471
- },
472
- children: [jsxRuntime.jsx(ExerciseFileReadOnlyBanner.default, {
473
- __intl: __intl
474
- }), jsxRuntime.jsx(MonacoEditorLazy.default, {
402
+ children: [jsxRuntime.jsx(ExerciseFileReadOnlyBanner.default, {}), jsxRuntime.jsx(MonacoEditorLazy.default, {
475
403
  defaultValue: "",
476
404
  filename: editorFilename,
477
405
  markers: wsUsercode.markers,
@@ -489,9 +417,5 @@ var ExerciseFileEditor = function ExerciseFileEditor(_ref) {
489
417
  }, editorFilename)]
490
418
  });
491
419
  };
492
- //
493
- //
494
- //
495
- var ExerciseFileEditor$1 = new intl.IntlComponentBuilder(ExerciseFileEditor).add('ko', ko.default).add('en', en.default).addAsync('th', Promise.resolve().then(function () { return require('./locales/th.json.js'); })).addAsync('ja', Promise.resolve().then(function () { return require('./locales/ja.json.js'); })).build();
496
420
 
497
- exports.default = ExerciseFileEditor$1;
421
+ exports.default = ExerciseFileEditor;
@@ -1,7 +1,4 @@
1
1
  import React from 'react';
2
2
  import type { WithIntlComponentBuilderProps as EliceIntlProps } from '@elice/intl';
3
- /**
4
- * Banner for readonly exercise file.
5
- */
6
- declare const ExerciseFileReadOnlyBanner: React.FC<EliceIntlProps>;
7
- export default ExerciseFileReadOnlyBanner;
3
+ declare const _default: React.ForwardRefExoticComponent<Omit<import("@elice/intl").IntlComponentExtraProps & Omit<EliceIntlProps, keyof import("@elice/intl").IntlComponentExtraProps | "__intl">, "ref"> & React.RefAttributes<any>>;
4
+ export default _default;
@@ -6,12 +6,15 @@ var jsxRuntime = require('react/jsx-runtime');
6
6
  var React = require('react');
7
7
  var blocks = require('@elice/blocks');
8
8
  var designTokens = require('@elice/design-tokens');
9
+ var intl = require('@elice/intl');
9
10
  var styled = require('styled-components');
10
11
  require('../context/recoil.js');
11
12
  var context = require('../context/context.js');
12
13
  require('../context/recoilTypes.js');
13
14
  require('../context/subjects.js');
14
15
  require('../context/ExerciseProvider.js');
16
+ var en = require('./locales/en.json.js');
17
+ var ko = require('./locales/ko.json.js');
15
18
 
16
19
  function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
17
20
 
@@ -41,5 +44,9 @@ var ExerciseFileReadOnlyBanner = function ExerciseFileReadOnlyBanner(_ref) {
41
44
  })
42
45
  });
43
46
  };
47
+ //
48
+ //
49
+ //
50
+ var ExerciseFileReadOnlyBanner$1 = new intl.IntlComponentBuilder(ExerciseFileReadOnlyBanner).add('ko', ko.default).add('en', en.default).addAsync('th', Promise.resolve().then(function () { return require('./locales/th.json.js'); })).addAsync('ja', Promise.resolve().then(function () { return require('./locales/ja.json.js'); })).build();
44
51
 
45
- exports.default = ExerciseFileReadOnlyBanner;
52
+ exports.default = ExerciseFileReadOnlyBanner$1;
@@ -2,6 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var messageEn = {"materialExercise.text.readOnlyBanner":"[Read-Only] This file is read-only.","materialExercise.websocket.writeFailedAndReset":"Failed to save the code and the content has been reset. Please try again shortly."};
5
+ var messageEn = {"materialExercise.text.readOnlyBanner":"[Read-Only] This file is read-only."};
6
6
 
7
7
  exports.default = messageEn;
@@ -2,6 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var ja = {"materialExercise.text.readOnlyBanner":"[読み取り専用] このファイルは読み取り専用です。","materialExercise.websocket.writeFailedAndReset":"コードの保存に失敗し、内容が初期化されました。しばらくしてから再度お試しください。"};
5
+ var ja = {"materialExercise.text.readOnlyBanner":"[読み取り専用] このファイルは読み取り専用です。"};
6
6
 
7
7
  exports.default = ja;
@@ -2,6 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var messageKo = {"materialExercise.text.readOnlyBanner":"[읽기전용] 이 파일은 읽기전용 입니다.","materialExercise.websocket.writeFailedAndReset":"코드 저장에 실패하여 내용이 초기화되었습니다. 잠시 후 다시 시도해주세요."};
5
+ var messageKo = {"materialExercise.text.readOnlyBanner":"[읽기전용] 이 파일은 읽기전용 입니다."};
6
6
 
7
7
  exports.default = messageKo;
@@ -2,6 +2,6 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var th = {"materialExercise.text.readOnlyBanner":"[อ่านเท่านั้น] ไฟล์นี้เป็นแบบอ่านเท่านั้น","materialExercise.websocket.writeFailedAndReset":"ไม่สามารถบันทึกรหัสได้ เนื้อหาได้ถูกรีเซ็ต กรุณาลองใหม่อีกครั้งในภายหลัง"};
5
+ var th = {"materialExercise.text.readOnlyBanner":"[อ่านเท่านั้น] ไฟล์นี้เป็นแบบอ่านเท่านั้น"};
6
6
 
7
7
  exports.default = th;