@ -10,8 +10,7 @@ const defaultOptions = {
|
|||||||
lineNumbers: false,
|
lineNumbers: false,
|
||||||
lineWrapping: true,
|
lineWrapping: true,
|
||||||
mode: 'javascript',
|
mode: 'javascript',
|
||||||
readOnly: 'nocursor',
|
readOnly: 'nocursor'
|
||||||
theme: 'monokai'
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const propTypes = {
|
const propTypes = {
|
||||||
|
@ -117,6 +117,10 @@
|
|||||||
caret-color:#ABABAB;
|
caret-color:#ABABAB;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
.@{ns}-log .CodeMirror {
|
||||||
|
background-color: #282a36;
|
||||||
|
color: #f8f8f2;
|
||||||
|
}
|
||||||
.refresh-icon {
|
.refresh-icon {
|
||||||
color: @icon-light-gray;
|
color: @icon-light-gray;
|
||||||
}
|
}
|
||||||
|
@ -15,6 +15,8 @@ import {
|
|||||||
challengeMetaSelector
|
challengeMetaSelector
|
||||||
} from '../../redux';
|
} from '../../redux';
|
||||||
|
|
||||||
|
import { themeSelector } from '../../../../redux';
|
||||||
|
|
||||||
import { createFileSelector } from '../../../../files';
|
import { createFileSelector } from '../../../../files';
|
||||||
|
|
||||||
const envProps = typeof window !== 'undefined' ? Object.keys(window) : [];
|
const envProps = typeof window !== 'undefined' ? Object.keys(window) : [];
|
||||||
@ -36,13 +38,16 @@ const options = {
|
|||||||
const mapStateToProps = createSelector(
|
const mapStateToProps = createSelector(
|
||||||
createFileSelector((_, { fileKey }) => fileKey || ''),
|
createFileSelector((_, { fileKey }) => fileKey || ''),
|
||||||
challengeMetaSelector,
|
challengeMetaSelector,
|
||||||
|
themeSelector,
|
||||||
(
|
(
|
||||||
file,
|
file,
|
||||||
{ mode }
|
{ mode },
|
||||||
|
theme
|
||||||
) => ({
|
) => ({
|
||||||
content: file.contents || '// Happy Coding!',
|
content: file.contents || '// Happy Coding!',
|
||||||
file: file,
|
file: file,
|
||||||
mode: file.ext || mode || 'javascript'
|
mode: file.ext || mode || 'javascript',
|
||||||
|
theme
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -56,15 +61,18 @@ const propTypes = {
|
|||||||
executeChallenge: PropTypes.func.isRequired,
|
executeChallenge: PropTypes.func.isRequired,
|
||||||
fileKey: PropTypes.string,
|
fileKey: PropTypes.string,
|
||||||
mode: PropTypes.string,
|
mode: PropTypes.string,
|
||||||
modernEditorUpdated: PropTypes.func.isRequired
|
modernEditorUpdated: PropTypes.func.isRequired,
|
||||||
|
theme: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Editor extends PureComponent {
|
export class Editor extends PureComponent {
|
||||||
createOptions = createSelector(
|
createOptions = createSelector(
|
||||||
state => state.executeChallenge,
|
state => state.executeChallenge,
|
||||||
state => state.mode,
|
state => state.mode,
|
||||||
(executeChallenge, mode) => ({
|
state => state.cmTheme,
|
||||||
|
(executeChallenge, mode, cmTheme) => ({
|
||||||
...options,
|
...options,
|
||||||
|
theme: cmTheme,
|
||||||
mode,
|
mode,
|
||||||
// JSHint only works with javascript
|
// JSHint only works with javascript
|
||||||
// we will need to switch to eslint to make this work with jsx
|
// we will need to switch to eslint to make this work with jsx
|
||||||
@ -119,6 +127,7 @@ export class Editor extends PureComponent {
|
|||||||
fileKey,
|
fileKey,
|
||||||
mode
|
mode
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const cmTheme = this.props.theme === 'default' ? 'default' : 'dracula';
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={ `${ns}-editor` }
|
className={ `${ns}-editor` }
|
||||||
@ -127,7 +136,7 @@ export class Editor extends PureComponent {
|
|||||||
<NoSSR onSSR={ <CodeMirrorSkeleton content={ content } /> }>
|
<NoSSR onSSR={ <CodeMirrorSkeleton content={ content } /> }>
|
||||||
<Codemirror
|
<Codemirror
|
||||||
onChange={ content => modernEditorUpdated(fileKey, content) }
|
onChange={ content => modernEditorUpdated(fileKey, content) }
|
||||||
options={ this.createOptions({ executeChallenge, mode }) }
|
options={ this.createOptions({ executeChallenge, mode, cmTheme }) }
|
||||||
ref='editor'
|
ref='editor'
|
||||||
value={ content }
|
value={ content }
|
||||||
/>
|
/>
|
||||||
|
@ -16,6 +16,8 @@ import {
|
|||||||
keySelector
|
keySelector
|
||||||
} from '../../redux';
|
} from '../../redux';
|
||||||
|
|
||||||
|
import { themeSelector } from '../../../../redux';
|
||||||
|
|
||||||
import { filesSelector } from '../../../../files';
|
import { filesSelector } from '../../../../files';
|
||||||
|
|
||||||
const envProps = typeof window !== 'undefined' ? Object.keys(window) : [];
|
const envProps = typeof window !== 'undefined' ? Object.keys(window) : [];
|
||||||
@ -38,15 +40,18 @@ const mapStateToProps = createSelector(
|
|||||||
filesSelector,
|
filesSelector,
|
||||||
challengeMetaSelector,
|
challengeMetaSelector,
|
||||||
keySelector,
|
keySelector,
|
||||||
|
themeSelector,
|
||||||
(
|
(
|
||||||
files = {},
|
files = {},
|
||||||
{ mode = 'javascript'},
|
{ mode = 'javascript'},
|
||||||
key
|
key,
|
||||||
|
theme
|
||||||
) => ({
|
) => ({
|
||||||
content: files[key] && files[key].contents || '// Happy Coding!',
|
content: files[key] && files[key].contents || '// Happy Coding!',
|
||||||
file: files[key],
|
file: files[key],
|
||||||
fileKey: key,
|
fileKey: key,
|
||||||
mode
|
mode,
|
||||||
|
theme
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -60,15 +65,18 @@ const propTypes = {
|
|||||||
content: PropTypes.string,
|
content: PropTypes.string,
|
||||||
executeChallenge: PropTypes.func.isRequired,
|
executeChallenge: PropTypes.func.isRequired,
|
||||||
fileKey: PropTypes.string.isRequired,
|
fileKey: PropTypes.string.isRequired,
|
||||||
mode: PropTypes.string
|
mode: PropTypes.string,
|
||||||
|
theme: PropTypes.string
|
||||||
};
|
};
|
||||||
|
|
||||||
export class Editor extends PureComponent {
|
export class Editor extends PureComponent {
|
||||||
createOptions = createSelector(
|
createOptions = createSelector(
|
||||||
state => state.executeChallenge,
|
state => state.executeChallenge,
|
||||||
state => state.mode,
|
state => state.mode,
|
||||||
(executeChallenge, mode) => ({
|
state => state.cmTheme,
|
||||||
|
(executeChallenge, mode, cmTheme) => ({
|
||||||
...options,
|
...options,
|
||||||
|
theme: cmTheme,
|
||||||
mode,
|
mode,
|
||||||
extraKeys: {
|
extraKeys: {
|
||||||
Esc() {
|
Esc() {
|
||||||
@ -120,6 +128,7 @@ export class Editor extends PureComponent {
|
|||||||
classicEditorUpdated,
|
classicEditorUpdated,
|
||||||
mode
|
mode
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const cmTheme = this.props.theme === 'default' ? 'default' : 'dracula';
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={ `${ns}-editor` }
|
className={ `${ns}-editor` }
|
||||||
@ -128,7 +137,7 @@ export class Editor extends PureComponent {
|
|||||||
<NoSSR onSSR={ <CodeMirrorSkeleton content={ content } /> }>
|
<NoSSR onSSR={ <CodeMirrorSkeleton content={ content } /> }>
|
||||||
<Codemirror
|
<Codemirror
|
||||||
onChange={ change => classicEditorUpdated(fileKey, change) }
|
onChange={ change => classicEditorUpdated(fileKey, change) }
|
||||||
options={ this.createOptions({ executeChallenge, mode }) }
|
options={ this.createOptions({ executeChallenge, mode, cmTheme }) }
|
||||||
ref='editor'
|
ref='editor'
|
||||||
value={ content }
|
value={ content }
|
||||||
/>
|
/>
|
||||||
|
@ -16,26 +16,6 @@
|
|||||||
padding-right: 5px;
|
padding-right: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.night {
|
|
||||||
.@{ns}-editor .CodeMirror {
|
|
||||||
background-color:#242424;
|
|
||||||
color:#ABABAB;
|
|
||||||
&-gutters {
|
|
||||||
background-color:#242424;
|
|
||||||
color:#ABABAB;
|
|
||||||
}
|
|
||||||
.cm-bracket, .cm-tag {
|
|
||||||
color:#5CAFD6;
|
|
||||||
}
|
|
||||||
.cm-property, .cm-string {
|
|
||||||
color:#B5753A;
|
|
||||||
}
|
|
||||||
.cm-keyword, .cm-attribute {
|
|
||||||
color:#9BBBDC;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.@{ns}-editor {
|
.@{ns}-editor {
|
||||||
.max-element-height();
|
.max-element-height();
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -2,6 +2,7 @@ link(rel='stylesheet', type='text/css' href='/css/lato.css')
|
|||||||
link(rel='stylesheet', type='text/css' href='/css/ubuntu.css')
|
link(rel='stylesheet', type='text/css' href='/css/ubuntu.css')
|
||||||
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css')
|
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css')
|
||||||
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.30.0/codemirror.min.css')
|
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.30.0/codemirror.min.css')
|
||||||
|
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.30.0/theme/dracula.min.css')
|
||||||
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.30.0/addon/lint/lint.min.css')
|
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/codemirror/5.30.0/addon/lint/lint.min.css')
|
||||||
link(rel='stylesheet', href=rev('/css', 'main.css'))
|
link(rel='stylesheet', href=rev('/css', 'main.css'))
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user