feat: add multi file capabillity
This commit is contained in:
parent
b25089d7c8
commit
7bd6e77b0f
@ -15,10 +15,13 @@ import {
|
||||
import { userSelector, isDonationModalOpenSelector } from '../../../redux';
|
||||
import { Loader } from '../../../components/helpers';
|
||||
|
||||
import './editor.css';
|
||||
|
||||
const MonacoEditor = React.lazy(() => import('react-monaco-editor'));
|
||||
|
||||
const propTypes = {
|
||||
canFocus: PropTypes.bool,
|
||||
challengeFiles: PropTypes.object,
|
||||
containerRef: PropTypes.any.isRequired,
|
||||
contents: PropTypes.string,
|
||||
dimensions: PropTypes.object,
|
||||
@ -26,6 +29,8 @@ const propTypes = {
|
||||
ext: PropTypes.string,
|
||||
fileKey: PropTypes.string,
|
||||
inAccessibilityMode: PropTypes.bool.isRequired,
|
||||
initialEditorContent: PropTypes.string,
|
||||
initialExt: PropTypes.string,
|
||||
saveEditorContent: PropTypes.func.isRequired,
|
||||
setAccessibilityMode: PropTypes.func.isRequired,
|
||||
setEditorFocusability: PropTypes.func,
|
||||
@ -93,6 +98,12 @@ class Editor extends Component {
|
||||
constructor(...props) {
|
||||
super(...props);
|
||||
|
||||
this.state = {
|
||||
code: '',
|
||||
ext: '',
|
||||
fileKey: ''
|
||||
};
|
||||
|
||||
this.options = {
|
||||
fontSize: '18px',
|
||||
scrollBeyondLastLine: false,
|
||||
@ -133,6 +144,11 @@ class Editor extends Component {
|
||||
};
|
||||
|
||||
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;
|
||||
editor.updateOptions({
|
||||
accessibilitySupport: this.props.inAccessibilityMode ? 'on' : 'auto'
|
||||
@ -206,8 +222,12 @@ class Editor extends Component {
|
||||
}
|
||||
|
||||
onChange = editorValue => {
|
||||
const { updateFile, fileKey } = this.props;
|
||||
const { updateFile } = this.props;
|
||||
const { fileKey } = this.state;
|
||||
updateFile({ key: fileKey, editorValue });
|
||||
this.setState({
|
||||
code: editorValue
|
||||
});
|
||||
};
|
||||
|
||||
componentDidUpdate(prevProps) {
|
||||
@ -217,11 +237,18 @@ class Editor extends Component {
|
||||
}
|
||||
|
||||
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';
|
||||
|
||||
return (
|
||||
<Suspense fallback={<Loader timeout={600} />}>
|
||||
<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
|
||||
editorDidMount={this.editorDidMount}
|
||||
editorWillMount={this.editorWillMount}
|
||||
@ -230,7 +257,7 @@ class Editor extends Component {
|
||||
onChange={this.onChange}
|
||||
options={this.options}
|
||||
theme={editorTheme}
|
||||
value={contents}
|
||||
value={code}
|
||||
/>
|
||||
</span>
|
||||
</Suspense>
|
||||
|
@ -222,14 +222,12 @@ class ShowClassic extends Component {
|
||||
renderEditor() {
|
||||
const { files } = this.props;
|
||||
|
||||
const challengeFile = first(Object.keys(files).map(key => files[key]));
|
||||
return (
|
||||
challengeFile && (
|
||||
files && (
|
||||
<Editor
|
||||
challengeFiles={files}
|
||||
containerRef={this.containerRef}
|
||||
ref={this.editorRef}
|
||||
{...challengeFile}
|
||||
fileKey={challengeFile.key}
|
||||
/>
|
||||
)
|
||||
);
|
||||
@ -346,6 +344,14 @@ export const query = graphql`
|
||||
src
|
||||
}
|
||||
files {
|
||||
indexcss {
|
||||
key
|
||||
ext
|
||||
name
|
||||
contents
|
||||
head
|
||||
tail
|
||||
}
|
||||
indexhtml {
|
||||
key
|
||||
ext
|
||||
|
24
client/src/templates/Challenges/classic/editor.css
Normal file
24
client/src/templates/Challenges/classic/editor.css
Normal 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);
|
||||
}
|
@ -16,13 +16,16 @@ import {
|
||||
|
||||
const htmlCatch = '\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;'>
|
||||
<!-- fcc-start-source -->
|
||||
${source}
|
||||
<!-- fcc-end-source -->
|
||||
</body>`;
|
||||
};
|
||||
|
||||
const wrapInScript = partial(
|
||||
transformContents,
|
||||
@ -30,11 +33,12 @@ const wrapInScript = partial(
|
||||
);
|
||||
const wrapInStyle = partial(
|
||||
transformContents,
|
||||
content => `${htmlCatch}<style>${content}</style>`
|
||||
content => `${htmlCatch}<style>${content}${cssCatch}</style>`
|
||||
);
|
||||
const setExtToHTML = partial(setExt, 'html');
|
||||
const padContentWithJsCatch = partial(compileHeadTail, jsCatch);
|
||||
const padContentWithHTMLCatch = partial(compileHeadTail, htmlCatch);
|
||||
const padContentWithCssCatch = partial(compileHeadTail, cssCatch);
|
||||
// const padContentWithHTMLCatch = partial(compileHeadTail, htmlCatch);
|
||||
|
||||
export const jsToHtml = cond([
|
||||
[
|
||||
@ -52,7 +56,7 @@ export const cssToHtml = cond([
|
||||
[
|
||||
matchesProperty('ext', 'css'),
|
||||
flow(
|
||||
padContentWithHTMLCatch,
|
||||
padContentWithCssCatch,
|
||||
wrapInStyle,
|
||||
setExtToHTML
|
||||
)
|
||||
|
@ -20,6 +20,8 @@ function defaultFile(lang) {
|
||||
};
|
||||
}
|
||||
function createCodeGetter(key, regEx, seeds) {
|
||||
console.log('seeds');
|
||||
console.log(seeds);
|
||||
return container => {
|
||||
const {
|
||||
properties: { id }
|
||||
|
Loading…
x
Reference in New Issue
Block a user