feat: add multi file capabillity

This commit is contained in:
moT01
2020-05-05 07:48:51 -05:00
committed by Mrugesh Mohapatra
parent b25089d7c8
commit 7bd6e77b0f
5 changed files with 74 additions and 11 deletions

View File

@ -15,10 +15,13 @@ import {
import { userSelector, isDonationModalOpenSelector } from '../../../redux'; import { userSelector, isDonationModalOpenSelector } from '../../../redux';
import { Loader } from '../../../components/helpers'; import { Loader } from '../../../components/helpers';
import './editor.css';
const MonacoEditor = React.lazy(() => import('react-monaco-editor')); const MonacoEditor = React.lazy(() => import('react-monaco-editor'));
const propTypes = { const propTypes = {
canFocus: PropTypes.bool, canFocus: PropTypes.bool,
challengeFiles: PropTypes.object,
containerRef: PropTypes.any.isRequired, containerRef: PropTypes.any.isRequired,
contents: PropTypes.string, contents: PropTypes.string,
dimensions: PropTypes.object, dimensions: PropTypes.object,
@ -26,6 +29,8 @@ const propTypes = {
ext: PropTypes.string, ext: PropTypes.string,
fileKey: PropTypes.string, fileKey: PropTypes.string,
inAccessibilityMode: PropTypes.bool.isRequired, inAccessibilityMode: PropTypes.bool.isRequired,
initialEditorContent: PropTypes.string,
initialExt: PropTypes.string,
saveEditorContent: PropTypes.func.isRequired, saveEditorContent: PropTypes.func.isRequired,
setAccessibilityMode: PropTypes.func.isRequired, setAccessibilityMode: PropTypes.func.isRequired,
setEditorFocusability: PropTypes.func, setEditorFocusability: PropTypes.func,
@ -93,6 +98,12 @@ class Editor extends Component {
constructor(...props) { constructor(...props) {
super(...props); super(...props);
this.state = {
code: '',
ext: '',
fileKey: ''
};
this.options = { this.options = {
fontSize: '18px', fontSize: '18px',
scrollBeyondLastLine: false, scrollBeyondLastLine: false,
@ -133,6 +144,11 @@ class Editor extends Component {
}; };
editorDidMount = (editor, monaco) => { editorDidMount = (editor, monaco) => {
this.setState({
code: this.props.challengeFiles.indexcss.contents,
ext: this.props.challengeFiles.indexcss.ext,
fileKey: this.props.challengeFiles.indexcss.key
});
this._editor = editor; this._editor = editor;
editor.updateOptions({ editor.updateOptions({
accessibilitySupport: this.props.inAccessibilityMode ? 'on' : 'auto' accessibilitySupport: this.props.inAccessibilityMode ? 'on' : 'auto'
@ -206,8 +222,12 @@ class Editor extends Component {
} }
onChange = editorValue => { onChange = editorValue => {
const { updateFile, fileKey } = this.props; const { updateFile } = this.props;
const { fileKey } = this.state;
updateFile({ key: fileKey, editorValue }); updateFile({ key: fileKey, editorValue });
this.setState({
code: editorValue
});
}; };
componentDidUpdate(prevProps) { componentDidUpdate(prevProps) {
@ -217,11 +237,18 @@ class Editor extends Component {
} }
render() { render() {
const { contents, ext, theme, fileKey } = this.props; const { code, ext, fileKey } = this.state;
const { theme } = this.props;
const editorTheme = theme === 'night' ? 'vs-dark-custom' : 'vs-custom'; const editorTheme = theme === 'night' ? 'vs-dark-custom' : 'vs-custom';
return ( return (
<Suspense fallback={<Loader timeout={600} />}> <Suspense fallback={<Loader timeout={600} />}>
<span className='notranslate'> <span className='notranslate'>
<div className='monaco-editor-tabs'>
<div className='monaco-editor-tab'>index.html</div>
<div className='monaco-editor-tab'>script.js</div>
<div className='monaco-editor-tab'>styles.css</div>
</div>
<MonacoEditor <MonacoEditor
editorDidMount={this.editorDidMount} editorDidMount={this.editorDidMount}
editorWillMount={this.editorWillMount} editorWillMount={this.editorWillMount}
@ -230,7 +257,7 @@ class Editor extends Component {
onChange={this.onChange} onChange={this.onChange}
options={this.options} options={this.options}
theme={editorTheme} theme={editorTheme}
value={contents} value={code}
/> />
</span> </span>
</Suspense> </Suspense>

View File

@ -222,14 +222,12 @@ class ShowClassic extends Component {
renderEditor() { renderEditor() {
const { files } = this.props; const { files } = this.props;
const challengeFile = first(Object.keys(files).map(key => files[key]));
return ( return (
challengeFile && ( files && (
<Editor <Editor
challengeFiles={files}
containerRef={this.containerRef} containerRef={this.containerRef}
ref={this.editorRef} ref={this.editorRef}
{...challengeFile}
fileKey={challengeFile.key}
/> />
) )
); );
@ -346,6 +344,14 @@ export const query = graphql`
src src
} }
files { files {
indexcss {
key
ext
name
contents
head
tail
}
indexhtml { indexhtml {
key key
ext ext

View File

@ -0,0 +1,24 @@
.monaco-editor-tabs {
display: flex;
padding: 0px 10px;
background-color: var(--primary-background);
border-bottom: 2px solid var(--primary-color);
}
.monaco-editor-tab {
position: relative;
top: 2px;
padding: 4px 16px;
border: 2px solid var(--primary-color);
border-left: none;
background-color: var(--secondary-background);
}
.monaco-editor-tab:first-child {
border-left: 2px solid var(--primary-color);
}
.monaco-editor-tab-selected {
background-color: var(--primary-background);
border-bottom: 2px solid var(--primary-background);
}

View File

@ -16,13 +16,16 @@ import {
const htmlCatch = '\n<!--fcc-->\n'; const htmlCatch = '\n<!--fcc-->\n';
const jsCatch = '\n;/*fcc*/\n'; const jsCatch = '\n;/*fcc*/\n';
const cssCatch = '\n/*fcc*/\n';
const defaultTemplate = ({ source }) => ` const defaultTemplate = ({ source }) => {
return `
<body id='display-body'style='margin:8px;'> <body id='display-body'style='margin:8px;'>
<!-- fcc-start-source --> <!-- fcc-start-source -->
${source} ${source}
<!-- fcc-end-source --> <!-- fcc-end-source -->
</body>`; </body>`;
};
const wrapInScript = partial( const wrapInScript = partial(
transformContents, transformContents,
@ -30,11 +33,12 @@ const wrapInScript = partial(
); );
const wrapInStyle = partial( const wrapInStyle = partial(
transformContents, transformContents,
content => `${htmlCatch}<style>${content}</style>` content => `${htmlCatch}<style>${content}${cssCatch}</style>`
); );
const setExtToHTML = partial(setExt, 'html'); const setExtToHTML = partial(setExt, 'html');
const padContentWithJsCatch = partial(compileHeadTail, jsCatch); const padContentWithJsCatch = partial(compileHeadTail, jsCatch);
const padContentWithHTMLCatch = partial(compileHeadTail, htmlCatch); const padContentWithCssCatch = partial(compileHeadTail, cssCatch);
// const padContentWithHTMLCatch = partial(compileHeadTail, htmlCatch);
export const jsToHtml = cond([ export const jsToHtml = cond([
[ [
@ -52,7 +56,7 @@ export const cssToHtml = cond([
[ [
matchesProperty('ext', 'css'), matchesProperty('ext', 'css'),
flow( flow(
padContentWithHTMLCatch, padContentWithCssCatch,
wrapInStyle, wrapInStyle,
setExtToHTML setExtToHTML
) )

View File

@ -20,6 +20,8 @@ function defaultFile(lang) {
}; };
} }
function createCodeGetter(key, regEx, seeds) { function createCodeGetter(key, regEx, seeds) {
console.log('seeds');
console.log(seeds);
return container => { return container => {
const { const {
properties: { id } properties: { id }