1
1
/* eslint-disable react-hooks/exhaustive-deps */
2
2
import "../../../assets/stylesheets/EditorPanel.scss" ;
3
- import React , { useRef , useEffect , useContext } from "react" ;
3
+ import React , { useRef , useEffect , useContext , useState } from "react" ;
4
4
import { useSelector , useDispatch } from "react-redux" ;
5
5
import { updateProjectComponent } from "../../../redux/EditorSlice" ;
6
6
import { useCookies } from "react-cookie" ;
@@ -11,16 +11,20 @@ import { EditorState } from "@codemirror/state";
11
11
import { defaultKeymap , indentWithTab } from "@codemirror/commands" ;
12
12
import { indentationMarkers } from "@replit/codemirror-indentation-markers" ;
13
13
import { indentUnit } from "@codemirror/language" ;
14
+ import "material-symbols" ;
14
15
15
16
import { html } from "@codemirror/lang-html" ;
16
17
import { css } from "@codemirror/lang-css" ;
17
18
import { python } from "@codemirror/lang-python" ;
18
19
import { javascript } from "@codemirror/lang-javascript" ;
19
20
21
+ import { Alert } from "@raspberrypifoundation/design-system-react" ;
20
22
import { editorLightTheme } from "../../../assets/themes/editorLightTheme" ;
21
23
import { editorDarkTheme } from "../../../assets/themes/editorDarkTheme" ;
22
24
import { SettingsContext } from "../../../utils/settings" ;
23
25
26
+ const MAX_CHARACTERS = 8500000 ;
27
+
24
28
const EditorPanel = ( { extension = "html" , fileName = "index" } ) => {
25
29
const editor = useRef ( ) ;
26
30
const project = useSelector ( ( state ) => state . editor . project ) ;
@@ -29,6 +33,7 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
29
33
const dispatch = useDispatch ( ) ;
30
34
const { t } = useTranslation ( ) ;
31
35
const settings = useContext ( SettingsContext ) ;
36
+ const [ characterLimitExceeded , setCharacterLimitExceeded ] = useState ( false ) ;
32
37
33
38
const updateStoredProject = ( content ) => {
34
39
dispatch (
@@ -86,6 +91,16 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
86
91
customIndentUnit = " " ;
87
92
}
88
93
94
+ const limitCharacters = EditorState . transactionFilter . of ( ( transaction ) => {
95
+ const newDoc = transaction . newDoc ;
96
+ if ( newDoc . length > MAX_CHARACTERS ) {
97
+ setCharacterLimitExceeded ( true ) ;
98
+ return [ ] ;
99
+ }
100
+ setCharacterLimitExceeded ( false ) ;
101
+ return transaction ;
102
+ } ) ;
103
+
89
104
const startState = EditorState . create ( {
90
105
doc : code ,
91
106
extensions : [
@@ -98,6 +113,7 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
98
113
indentationMarkers ( ) ,
99
114
indentUnit . of ( customIndentUnit ) ,
100
115
EditorView . editable . of ( ! readOnly ) ,
116
+ limitCharacters ,
101
117
] ,
102
118
} ) ;
103
119
@@ -123,7 +139,18 @@ const EditorPanel = ({ extension = "html", fileName = "index" }) => {
123
139
} , [ cookies ] ) ;
124
140
125
141
return (
126
- < div className = { `editor editor--${ settings . fontSize } ` } ref = { editor } > </ div >
142
+ < >
143
+ < div className = { `editor editor--${ settings . fontSize } ` } ref = { editor } > </ div >
144
+ { characterLimitExceeded && (
145
+ < Alert
146
+ title = { t ( "editorPanel.characterLimitError" ) }
147
+ type = "error"
148
+ text = { t ( "editorPanel.characterLimitExplanation" , {
149
+ maxCharacters : MAX_CHARACTERS ,
150
+ } ) }
151
+ />
152
+ ) }
153
+ </ >
127
154
) ;
128
155
} ;
129
156
0 commit comments