1- /* eslint-disable no-bitwise */
2- import React , {
3- memo ,
4- useState ,
5- useEffect ,
6- useCallback ,
7- useMemo ,
8- } from 'react' ;
1+ import React , { memo } from 'react' ;
92
103import MonacoEditor , { loader } from '@monaco-editor/react' ;
11- import cn from 'classnames' ;
124
135import haskellProvider from '../config/editor/haskell' ;
146import sassProvider from '../config/editor/sass' ;
157import stylusProvider from '../config/editor/stylus' ;
16- import GameRoomModes from '../config/gameModes' ;
178import languages from '../config/languages' ;
18- import sound from '../lib/sound' ;
19- import getLanguageTabSize , { shouldReplaceTabsWithSpaces } from '../utils/editor' ;
20- import useRemoteCursor from '../utils/useRemoteCursor' ;
9+ import useEditor from '../utils/useEditor' ;
2110
22- import Loading from './Loading ' ;
11+ import EditorLoading from './EditorLoading ' ;
2312
24- const editorPlaceholder = 'Please! Help me!!!' ;
2513const monacoVersion = '0.52.0' ;
2614
2715loader . config ( {
@@ -41,193 +29,6 @@ loader.init().then(monaco => {
4129 monaco . languages . setMonarchTokensProvider ( 'scss' , sassProvider ) ;
4230} ) ;
4331
44- let editorClipboard = '' ;
45-
46- const useOption = ( {
47- wordWrap = 'off' ,
48- lineNumbers = 'on' ,
49- syntax = 'js' ,
50- fontSize = 16 ,
51- editable = false ,
52- loading = false ,
53- } ) => {
54- const options = useMemo ( ( ) => ( {
55- placeholder : editorPlaceholder ,
56- wordWrap,
57- lineNumbers,
58- tabSize : getLanguageTabSize ( syntax ) ,
59- insertSpaces : shouldReplaceTabsWithSpaces ( syntax ) ,
60- lineNumbersMinChars : 3 ,
61- fontSize,
62- scrollBeyondLastLine : false ,
63- selectOnLineNumbers : true ,
64- minimap : {
65- enabled : false ,
66- } ,
67- parameterHints : {
68- enabled : false ,
69- } ,
70- readOnly : ! editable || loading ,
71- contextmenu : editable && ! loading ,
72- scrollbar : {
73- useShadows : false ,
74- verticalHasArrows : true ,
75- horizontalHasArrows : true ,
76- vertical : 'visible' ,
77- horizontal : 'visible' ,
78- verticalScrollbarSize : 17 ,
79- horizontalScrollbarSize : 17 ,
80- arrowSize : 30 ,
81- } ,
82- } ) , [
83- wordWrap ,
84- lineNumbers ,
85- syntax ,
86- fontSize ,
87- editable ,
88- loading ,
89- ] ) ;
90-
91- return options ;
92- } ;
93-
94- const useEditor = props => {
95- const [ editor , setEditor ] = useState ( ) ;
96- const [ monaco , setMonaco ] = useState ( ) ;
97- // const convertRemToPixels = rem => rem * parseFloat(getComputedStyle(document.documentElement).fontSize);
98- // this.statusBarHeight = lineHeight = current fontSize * 1.5
99- // this.statusBarHeight = convertRemToPixels(1) * 1.5;
100-
101- useRemoteCursor ( editor , monaco , props ) ;
102- const options = useOption ( props ) ;
103-
104- const handleResize = useCallback ( ( ) => {
105- if ( editor ) {
106- editor . layout ( ) ;
107- }
108- } , [ editor ] ) ;
109-
110- // if (editor) {
111- // const model = editor.getModel();
112- //
113- // // fix flickering in editor
114- // model.forceTokenization(model.getLineCount());
115- // }
116-
117- useEffect ( ( ) => {
118- handleResize ( ) ;
119- } , [ props . locked , handleResize ] ) ;
120-
121- useEffect ( ( ) => {
122- const ctrPlusS = e => {
123- if ( e . key === 's' && ( e . metaKey || e . ctrlKey ) ) e . preventDefault ( ) ;
124- } ;
125-
126- window . addEventListener ( 'resize' , handleResize ) ;
127-
128- return ( ) => {
129- window . removeEventListener ( 'resize' , handleResize ) ;
130- window . removeEventListener ( 'keydown' , ctrPlusS ) ;
131- } ;
132- } , [ handleResize ] ) ;
133-
134- const handleEditorWillMount = ( ) => { } ;
135-
136- const handleEditorDidMount = ( newEditor , newMonaco ) => {
137- setEditor ( newEditor ) ;
138- setMonaco ( newMonaco ) ;
139-
140- const {
141- editable,
142- gameMode,
143- checkResult,
144- toggleMuteSound,
145- } = props ;
146-
147- const isBuilder = gameMode === GameRoomModes . builder ;
148-
149- // Handle copy event
150- // editor.onDidCopyText(event => {
151- // // Custom copy logic
152- // const customText = `Custom copied text: ${event.text}`;
153- // navigator.clipboard.writeText(customText);
154- // event.preventDefault();
155- // });
156-
157- newEditor . onKeyDown ( e => {
158- // Custom Copy Event
159- if ( ( e . ctrlKey || e . metaKey ) && e . keyCode === newMonaco . KeyCode . KEY_C ) {
160- const selection = newEditor . getModel ( ) . getValueInRange ( newEditor . getSelection ( ) ) ;
161- editorClipboard = `___CUSTOM_COPIED_TEXT___${ selection } ` ;
162-
163- e . preventDefault ( ) ;
164- }
165-
166- // Custom Paste Event
167- if ( ( e . ctrlKey || e . metaKey ) && e . keyCode === newMonaco . KeyCode . KEY_V ) {
168- if ( editorClipboard . startsWith ( '___CUSTOM_COPIED_TEXT___' ) ) {
169- const customText = editorClipboard . replace ( '___CUSTOM_COPIED_TEXT___' , '' ) ;
170-
171- newEditor . executeEdits ( 'custom-paste' , [
172- {
173- range : newEditor . getSelection ( ) ,
174- text : customText ,
175- forceMoveMarkers : true ,
176- } ,
177- ] ) ;
178- }
179-
180- e . preventDefault ( ) ;
181- }
182- } ) ;
183-
184- if ( editable && ! isBuilder ) {
185- newEditor . focus ( ) ;
186- }
187-
188- newEditor . addCommand (
189- newMonaco . KeyMod . CtrlCmd | newMonaco . KeyCode . Enter ,
190- ( ) => null ,
191- ) ;
192-
193- newEditor . addCommand (
194- newMonaco . KeyMod . CtrlCmd | newMonaco . KeyCode . KEY_M ,
195- ( ) => null ,
196- ) ;
197-
198- if ( checkResult ) {
199- newEditor . addAction ( {
200- id : 'codebattle-check-keys' ,
201- label : 'Codebattle check start' ,
202- keybindings : [ newMonaco . KeyMod . CtrlCmd | newMonaco . KeyCode . Enter ] ,
203- run : ( ) => {
204- if ( options . readOnly ) {
205- checkResult ( ) ;
206- }
207- } ,
208- } ) ;
209- }
210-
211- newEditor . addAction ( {
212- id : 'codebattle-mute-keys' ,
213- label : 'Codebattle mute sound' ,
214- keybindings : [ newMonaco . KeyMod . CtrlCmd | newMonaco . KeyCode . KEY_M ] ,
215- run : ( ) => {
216- const { mute } = props ;
217- // eslint-disable-next-line no-unused-expressions
218- mute ? sound . toggle ( ) : sound . toggle ( 0 ) ;
219- toggleMuteSound ( ) ;
220- } ,
221- } ) ;
222- } ;
223-
224- return {
225- options,
226- handleEditorWillMount,
227- handleEditorDidMount,
228- } ;
229- } ;
230-
23132function Editor ( props ) {
23233 const {
23334 value,
@@ -236,14 +37,8 @@ function Editor(props) {
23637 theme,
23738 loading = false ,
23839 } = props ;
239- // FIXME: move here and apply mapping object
24040 const mappedSyntax = languages [ syntax ] ;
24141
242- const loadingClassName = cn ( 'position-absolute align-items-center justify-content-center w-100 h-100' , {
243- 'd-flex cb-loading-background' : loading ,
244- 'd-none' : ! loading ,
245- } ) ;
246-
24742 const {
24843 options,
24944 handleEditorDidMount,
@@ -264,7 +59,7 @@ function Editor(props) {
26459 onChange = { onChange }
26560 data-guide-id = "Editor"
26661 />
267- < div className = { loadingClassName } > < Loading /> </ div >
62+ < EditorLoading loading = { loading } / >
26863 </ >
26964 ) ;
27065}
0 commit comments