1+ // TODO: convert to functional component
2+
13import PropTypes from 'prop-types' ;
24import React from 'react' ;
35import CodeMirror from 'codemirror' ;
@@ -40,33 +42,36 @@ import classNames from 'classnames';
4042import { debounce } from 'lodash' ;
4143import { connect } from 'react-redux' ;
4244import { bindActionCreators } from 'redux' ;
45+ import MediaQuery from 'react-responsive' ;
4346import '../../../../utils/htmlmixed' ;
4447import '../../../../utils/p5-javascript' ;
45- import Timer from '../Timer' ;
46- import EditorAccessibility from '../EditorAccessibility' ;
47- import { selectActiveFile } from '../../selectors/files' ;
48- import AssetPreview from '../AssetPreview' ;
4948import { metaKey } from '../../../../utils/metaKey' ;
5049import '../show-hint' ;
5150import * as hinter from '../../../../utils/p5-hinter' ;
52-
5351import '../../../../utils/codemirror-search' ;
5452
5553import beepUrl from '../../../../sounds/audioAlert.mp3' ;
56- import UnsavedChangesDotIcon from '../../../../images/unsaved-changes-dot.svg' ;
5754import RightArrowIcon from '../../../../images/right-arrow.svg' ;
5855import LeftArrowIcon from '../../../../images/left-arrow.svg' ;
5956import { getHTMLFile } from '../../reducers/files' ;
57+ import { selectActiveFile } from '../../selectors/files' ;
6058
6159import * as FileActions from '../../actions/files' ;
6260import * as IDEActions from '../../actions/ide' ;
6361import * as ProjectActions from '../../actions/project' ;
6462import * as EditorAccessibilityActions from '../../actions/editorAccessibility' ;
6563import * as PreferencesActions from '../../actions/preferences' ;
6664import * as UserActions from '../../../User/actions' ;
67- import * as ToastActions from '../../actions/toast' ;
6865import * as ConsoleActions from '../../actions/console' ;
6966
67+ import AssetPreview from '../AssetPreview' ;
68+ import Timer from '../Timer' ;
69+ import EditorAccessibility from '../EditorAccessibility' ;
70+ import UnsavedChangesIndicator from '../UnsavedChangesIndicator' ;
71+ import { EditorContainer , EditorHolder } from './MobileEditor' ;
72+ import { FolderIcon } from '../../../../common/icons' ;
73+ import IconButton from '../../../../components/mobile/IconButton' ;
74+
7075emmet ( CodeMirror ) ;
7176
7277window . JSHINT = JSHINT ;
@@ -75,7 +80,7 @@ window.HTMLHint = HTMLHint;
7580
7681const INDENTATION_AMOUNT = 2 ;
7782
78- class Editor extends React . Component {
83+ class EditorV2 extends React . Component {
7984 constructor ( props ) {
8085 super ( props ) ;
8186 this . tidyCode = this . tidyCode . bind ( this ) ;
@@ -98,7 +103,7 @@ class Editor extends React.Component {
98103
99104 componentDidMount ( ) {
100105 this . beep = new Audio ( beepUrl ) ;
101- this . widgets = [ ] ;
106+ // this.widgets = [];
102107 this . _cm = CodeMirror ( this . codemirrorContainer , {
103108 theme : `p5-${ this . props . theme } ` ,
104109 lineNumbers : this . props . lineNumbers ,
@@ -161,7 +166,6 @@ class Editor extends React.Component {
161166 [ `${ metaKey } -Enter` ] : ( ) => null ,
162167 [ `Shift-${ metaKey } -Enter` ] : ( ) => null ,
163168 [ `${ metaKey } -F` ] : 'findPersistent' ,
164- [ `Shift-${ metaKey } -F` ] : this . tidyCode ,
165169 [ `${ metaKey } -G` ] : 'findPersistentNext' ,
166170 [ `Shift-${ metaKey } -G` ] : 'findPersistentPrev' ,
167171 [ replaceCommand ] : 'replace' ,
@@ -197,6 +201,16 @@ class Editor extends React.Component {
197201 } ) ;
198202
199203 this . _cm . on ( 'keydown' , ( _cm , e ) => {
204+ if (
205+ ( ( metaKey === 'Cmd' && e . metaKey ) ||
206+ ( metaKey === 'Ctrl' && e . ctrlKey ) ) &&
207+ e . shiftKey &&
208+ e . key === 'f'
209+ ) {
210+ e . preventDefault ( ) ;
211+ this . tidyCode ( ) ;
212+ }
213+
200214 // Show hint
201215 const mode = this . _cm . getOption ( 'mode' ) ;
202216 if ( / ^ [ a - z ] $ / i. test ( e . key ) && ( mode === 'css' || mode === 'javascript' ) ) {
@@ -306,6 +320,13 @@ class Editor extends React.Component {
306320 this . _cm . removeLineClass ( i , 'background' , 'line-runtime-error' ) ;
307321 }
308322 }
323+
324+ this . props . provideController ( {
325+ tidyCode : this . tidyCode ,
326+ showFind : this . showFind ,
327+ showReplace : this . showReplace ,
328+ getContent : this . getContent
329+ } ) ;
309330 }
310331
311332 componentWillUnmount ( ) {
@@ -496,57 +517,82 @@ class Editor extends React.Component {
496517 } ) ;
497518
498519 return (
499- < section className = { editorSectionClass } >
500- < header className = "editor__header" >
501- < button
502- aria-label = { this . props . t ( 'Editor.OpenSketchARIA' ) }
503- className = "sidebar__contract"
504- onClick = { ( ) => {
505- this . props . collapseSidebar ( ) ;
506- this . props . closeProjectOptions ( ) ;
507- } }
508- >
509- < LeftArrowIcon focusable = "false" aria-hidden = "true" />
510- </ button >
511- < button
512- aria-label = { this . props . t ( 'Editor.CloseSketchARIA' ) }
513- className = "sidebar__expand"
514- onClick = { this . props . expandSidebar }
515- >
516- < RightArrowIcon focusable = "false" aria-hidden = "true" />
517- </ button >
518- < div className = "editor__file-name" >
519- < span >
520- { this . props . file . name }
521- < span className = "editor__unsaved-changes" >
522- { this . props . unsavedChanges ? (
523- < UnsavedChangesDotIcon
524- role = "img"
525- aria-label = { this . props . t ( 'Editor.UnsavedChangesARIA' ) }
526- focusable = "false"
520+ < MediaQuery minWidth = { 770 } >
521+ { ( matches ) =>
522+ matches ? (
523+ < section className = { editorSectionClass } >
524+ < header className = "editor__header" >
525+ < button
526+ aria-label = { this . props . t ( 'Editor.OpenSketchARIA' ) }
527+ className = "sidebar__contract"
528+ onClick = { this . props . collapseSidebar }
529+ >
530+ < LeftArrowIcon focusable = "false" aria-hidden = "true" />
531+ </ button >
532+ < button
533+ aria-label = { this . props . t ( 'Editor.CloseSketchARIA' ) }
534+ className = "sidebar__expand"
535+ onClick = { this . props . expandSidebar }
536+ >
537+ < RightArrowIcon focusable = "false" aria-hidden = "true" />
538+ </ button >
539+ < div className = "editor__file-name" >
540+ < span >
541+ { this . props . file . name }
542+ < UnsavedChangesIndicator />
543+ </ span >
544+ < Timer />
545+ </ div >
546+ </ header >
547+ < article
548+ ref = { ( element ) => {
549+ this . codemirrorContainer = element ;
550+ } }
551+ className = { editorHolderClass }
552+ />
553+ { this . props . file . url ? (
554+ < AssetPreview
555+ url = { this . props . file . url }
556+ name = { this . props . file . name }
557+ />
558+ ) : null }
559+ < EditorAccessibility lintMessages = { this . props . lintMessages } />
560+ </ section >
561+ ) : (
562+ < EditorContainer expanded = { this . props . isExpanded } >
563+ < header >
564+ < IconButton
565+ onClick = { this . props . expandSidebar }
566+ icon = { FolderIcon }
567+ />
568+ < span >
569+ { this . props . file . name }
570+ < UnsavedChangesIndicator />
571+ </ span >
572+ </ header >
573+ < section >
574+ < EditorHolder
575+ ref = { ( element ) => {
576+ this . codemirrorContainer = element ;
577+ } }
578+ />
579+ { this . props . file . url ? (
580+ < AssetPreview
581+ url = { this . props . file . url }
582+ name = { this . props . file . name }
527583 />
528584 ) : null }
529- </ span >
530- </ span >
531- < Timer />
532- </ div >
533- </ header >
534- < article
535- ref = { ( element ) => {
536- this . codemirrorContainer = element ;
537- } }
538- className = { editorHolderClass }
539- />
540- { this . props . file . url ? (
541- < AssetPreview url = { this . props . file . url } name = { this . props . file . name } />
542- ) : null }
543- < EditorAccessibility lintMessages = { this . props . lintMessages } />
544- </ section >
585+ < EditorAccessibility lintMessages = { this . props . lintMessages } />
586+ </ section >
587+ </ EditorContainer >
588+ )
589+ }
590+ </ MediaQuery >
545591 ) ;
546592 }
547593}
548594
549- Editor . propTypes = {
595+ EditorV2 . propTypes = {
550596 autocloseBracketsQuotes : PropTypes . bool . isRequired ,
551597 autocompleteHinter : PropTypes . bool . isRequired ,
552598 lineNumbers : PropTypes . bool . isRequired ,
@@ -592,7 +638,6 @@ Editor.propTypes = {
592638 ) . isRequired ,
593639 isExpanded : PropTypes . bool . isRequired ,
594640 collapseSidebar : PropTypes . func . isRequired ,
595- closeProjectOptions : PropTypes . func . isRequired ,
596641 expandSidebar : PropTypes . func . isRequired ,
597642 clearConsole : PropTypes . func . isRequired ,
598643 hideRuntimeErrorWarning : PropTypes . func . isRequired ,
@@ -613,7 +658,6 @@ function mapStateToProps(state) {
613658 editorAccessibility : state . editorAccessibility ,
614659 user : state . user ,
615660 project : state . project ,
616- toast : state . toast ,
617661 consoleEvents : state . console ,
618662
619663 ...state . preferences ,
@@ -634,13 +678,12 @@ function mapDispatchToProps(dispatch) {
634678 IDEActions ,
635679 PreferencesActions ,
636680 UserActions ,
637- ToastActions ,
638681 ConsoleActions
639682 ) ,
640683 dispatch
641684 ) ;
642685}
643686
644687export default withTranslation ( ) (
645- connect ( mapStateToProps , mapDispatchToProps ) ( Editor )
688+ connect ( mapStateToProps , mapDispatchToProps ) ( EditorV2 )
646689) ;
0 commit comments