@@ -6,7 +6,7 @@ import Preview from 'app/components/sandbox/Preview';
66import CodeEditor from 'app/components/sandbox/CodeEditor' ;
77import { getModulePath } from 'app/store/entities/sandboxes/modules/selectors' ;
88
9- import type { Sandbox , Module } from 'common/types' ;
9+ import type { Sandbox , Module , ModuleError } from 'common/types' ;
1010import fetchBundle from 'app/store/entities/sandboxes/bundler' ;
1111
1212const Container = styled . div `
@@ -26,7 +26,7 @@ const Split = styled.div`
2626
2727type Props = {
2828 sandbox : Sandbox ,
29- currentModule : string ,
29+ currentModule : ? string ,
3030 showEditor : boolean ,
3131 showPreview : boolean ,
3232 isInProjectView : boolean ,
@@ -37,11 +37,18 @@ type Props = {
3737type State = {
3838 bundle : Object ,
3939 isInProjectView : boolean ,
40+ codes : { [ id : string ] : string } ,
41+ errors : Array < ModuleError > ,
4042} ;
4143
42- export default class Content extends React . Component {
44+ export default class Content extends React . PureComponent {
4345 state : State = {
44- bundle : { processing : true } ,
46+ bundle : {
47+ processing : true ,
48+ } ,
49+ inInProjectView : false ,
50+ codes : { } ,
51+ errors : [ ] ,
4552 } ;
4653
4754 componentDidMount ( ) {
@@ -86,6 +93,63 @@ export default class Content extends React.Component {
8693 }
8794 } ;
8895
96+ setCode = ( moduleId : string , code : string ) => {
97+ this . setState ( {
98+ ...this . state ,
99+ codes : {
100+ ...this . state . codes ,
101+ [ moduleId ] : code ,
102+ } ,
103+ } ) ;
104+ } ;
105+
106+ addError = ( moduleId : string , error : ModuleError ) => {
107+ if ( ! this . state . errors . find ( e => e . moduleId === error . moduleId ) ) {
108+ this . setState ( {
109+ errors : [ ...this . state . errors , error ] ,
110+ } ) ;
111+ }
112+ } ;
113+
114+ clearErrors = ( ) => {
115+ if ( this . state . errors . length > 0 ) {
116+ this . setState ( {
117+ errors : [ ] ,
118+ } ) ;
119+ }
120+ } ;
121+
122+ lastCodes = { } ;
123+ lastAlteredModules = [ ] ;
124+ /**
125+ * This is a bit of a hack, we utilize custom memoization so we don't return
126+ * a new array of new modules on each render, because map creates a new array
127+ */
128+ getAlteredModules = ( ) => {
129+ const { sandbox } = this . props ;
130+ const { codes } = this . state ;
131+ const codeChanged = this . lastCodes !== codes ;
132+
133+ if ( ! codeChanged ) {
134+ return this . lastAlteredModules ;
135+ }
136+
137+ this . lastCodes = codes ;
138+
139+ // $FlowIssue
140+ const alteredModules = sandbox . modules . map ( ( m : Module ) => ( {
141+ ...m ,
142+ code : codes [ m . id ] || m . code ,
143+ } ) ) ;
144+
145+ this . lastAlteredModules = alteredModules ;
146+ return alteredModules ;
147+ } ;
148+
149+ preferences = {
150+ livePreviewEnabled : true ,
151+ } ;
152+
89153 props : Props ;
90154 state : State ;
91155 render ( ) {
@@ -98,7 +162,10 @@ export default class Content extends React.Component {
98162 hideNavigation,
99163 } = this . props ;
100164
101- const preferences = { livePreviewEnabled : true } ;
165+ const { errors } = this . state ;
166+
167+ const alteredModules = this . getAlteredModules ( ) ;
168+
102169 // $FlowIssue
103170 const mainModule : Module =
104171 sandbox . modules . find ( ( m : Module ) => m . shortid === currentModule ) ||
@@ -121,8 +188,8 @@ export default class Content extends React.Component {
121188 sandbox . directories ,
122189 mainModule . id ,
123190 ) }
124- preferences = { preferences }
125- onlyViewMode
191+ changeCode = { this . setCode }
192+ preferences = { this . preferences }
126193 />
127194 </ Split > }
128195
@@ -131,19 +198,19 @@ export default class Content extends React.Component {
131198 < Preview
132199 sandboxId = { sandbox . id }
133200 isInProjectView = { isInProjectView }
134- modules = { sandbox . modules }
201+ modules = { alteredModules }
135202 directories = { sandbox . directories }
136203 bundle = { this . state . bundle }
137204 externalResources = { sandbox . externalResources }
138205 module = { mainModule }
139206 fetchBundle = { this . fetchBundle }
140- addError = { ( ) => { } }
141- clearErrors = { ( ) => { } }
142- preferences = { preferences }
207+ addError = { this . addError }
208+ clearErrors = { this . clearErrors }
209+ preferences = { this . preferences }
143210 setProjectView = { this . props . setProjectView }
144211 hideNavigation = { hideNavigation }
145- noDelay
146212 setFrameHeight = { this . handleResize }
213+ errors = { errors }
147214 />
148215 </ Split > }
149216 </ Container >
0 commit comments