improvement (editor): #20 + bugfix

This commit is contained in:
Mickael KERJEAN
2018-04-10 14:51:52 +10:00
parent 050a26e99a
commit 950f56bbdf
10 changed files with 69 additions and 68 deletions
+1 -13
View File
@@ -23,6 +23,7 @@ html {
background: var(--bg-color);
color: var(--color);
}
body {overflow: hidden;}
body, html{
height: 100%;
margin: 0;
@@ -80,19 +81,6 @@ input[type="checkbox"]{position: relative; top: 1px; margin: 0; padding: 0;}
/* I know this looks weird but at least it doesn't rely on javascript to dynamically set element size */
body {overflow: hidden;}
body, body > div, body > div > div, body > div > div > div{ height: 100%;}
/* CONNECTION FORM */
.login-form button.active{
box-shadow: 0px 1px 5px rgba(0,0,0,0.20);
+4 -1
View File
@@ -1,10 +1,13 @@
import React from 'react';
import './fab.scss';
export const Fab = (props) => {
return (
<div className="component_fab" onClick={props.onClick}>
{props.children}
<div className="content">
{props.children}
</div>
</div>
);
}
+10 -8
View File
@@ -1,13 +1,15 @@
.component_fab{
height: 25px;
width: 25px;
padding: 13px;
position: fixed;
bottom: 20px;
right: 20px;
border-radius: 50%;
background: var(--color);
box-shadow: rgba(0, 0, 0, 0.14) 0px 4px 5px 0px, rgba(0, 0, 0, 0.12) 0px 1px 10px 0px, rgba(0, 0, 0, 0.2) 0px 2px 4px -1px;
z-index: 1000;
cursor: pointer;
.content{
height: 25px;
width: 25px;
padding: 13px;
border-radius: 50%;
background: var(--color);
box-shadow: rgba(0, 0, 0, 0.14) 0px 4px 5px 0px, rgba(0, 0, 0, 0.12) 0px 1px 10px 0px, rgba(0, 0, 0, 0.2) 0px 2px 4px -1px;
z-index: 1000;
cursor: pointer;
}
}
+1 -1
View File
@@ -32,6 +32,6 @@
<meta name="description" content="browse your files in the cloud">
</head>
<body>
<div id="main"></div>
<div id="main" style="height: 100%"></div>
</body>
</html>
+10 -20
View File
@@ -28,22 +28,24 @@ export class ViewerPage extends React.Component {
data: '',
needSaving: false,
isSaving: false,
height: null,
loading: true,
error: false
};
this.resetHeight = debounce(this.resetHeight.bind(this), 100);
this.props.subscribe('file.select', this.onPathUpdate.bind(this));
}
componentWillMount(){
this.setState({loading: true, error: false});
this.setState({loading: null, error: false}, () => {
window.setTimeout(() => {
if(this.state.loading === null) this.setState({loading: true});
}, 500);
});
let app = opener(this.state.path);
if(app === 'editor'){
Files.cat(this.state.path).then((content) => {
this.setState({data: content, loading: false, opener: app});
}).catch(err => {
if(err && err.code === 'CANCELLED'){ return }
if(err && err.code === 'CANCELLED'){ return; }
if(err.code === 'BINARY_FILE'){
Files.url(this.state.path).then((url) => {
this.setState({data: url, loading: false, opener: 'download'});
@@ -58,7 +60,7 @@ export class ViewerPage extends React.Component {
Files.url(this.state.path).then((url) => {
this.setState({data: url, loading: false, opener: app});
}).catch(err => {
if(err && err.code === 'CANCELLED'){ return }
if(err && err.code === 'CANCELLED'){ return; }
this.setState({error: err});
});
}
@@ -66,7 +68,6 @@ export class ViewerPage extends React.Component {
componentWillUnmount() {
this.props.unsubscribe('file.select');
window.removeEventListener("resize", this.resetHeight);
}
@@ -96,24 +97,13 @@ export class ViewerPage extends React.Component {
this.setState({needSaving: bool});
}
componentDidMount(){
this.resetHeight();
window.addEventListener("resize", this.resetHeight);
}
resetHeight(){
this.setState({
height: document.body.clientHeight - document.querySelector('.breadcrumb').offsetHeight
});
}
render() {
let style = {height: '100%'};
return (
<div>
<div style={style}>
<BreadCrumb needSaving={this.state.needSaving} className="breadcrumb" path={this.state.path} />
<div style={{height: this.state.height ? this.state.height + 'px' : '100%'}}>
<NgIf cond={this.state.loading === false} style={{height: '100%'}}>
<div style={style}>
<NgIf cond={this.state.loading === false} style={style}>
<NgIf cond={this.state.opener === 'editor'} style={style}>
<IDE needSaving={this.needSaving.bind(this)}
isSaving={this.state.isSaving}
+19 -13
View File
@@ -1,6 +1,8 @@
import React from 'react';
import PropTypes from 'prop-types';
import { NgIf, Loader } from '../../components/';
import CodeMirror from 'codemirror/lib/codemirror';
import 'codemirror/lib/codemirror.css';
import './editor.scss';
@@ -25,6 +27,7 @@ export class Editor extends React.Component {
constructor(props){
super(props);
this.state = {
loading: null,
editor: null,
filename: this.props.filename
};
@@ -34,13 +37,16 @@ export class Editor extends React.Component {
if(this.props.content !== props.content){
this.state.editor.getDoc().setValue(props.content);
}
if(this.props.height !== props.height){
this.updateHeight(props.height);
}
}
componentDidMount(){
this.setState({loading: null, error: false}, () => {
window.setTimeout(() => {
if(this.state.loading === null) this.setState({loading: true});
}, 200);
});
this.loadMode(this.props.filename)
.then((res) => new Promise((done) => this.setState({loading: false}, () => done(res))))
.then(loadCodeMirror.bind(this));
function loadCodeMirror(CodeMirror){
@@ -62,7 +68,6 @@ export class Editor extends React.Component {
}
this.setState({editor: editor});
this.updateHeight(this.props.height);
editor.on('change', (edit) => {
if(this.props.onChange){
@@ -83,13 +88,6 @@ export class Editor extends React.Component {
this.state.editor.clearHistory();
}
updateHeight(height){
if(height){
document.querySelector('.CodeMirror').style.height = height+'px';
}
}
loadMode(file){
let ext = file.split('.').pop(),
mode = null;
@@ -103,7 +101,7 @@ export class Editor extends React.Component {
else if(ext === 'css'){ mode = 'css'; }
else if(ext === 'less' || ext === 'scss' || ext === 'sass'){ mode = 'sass'; }
else if(ext === 'js' || ext === 'json'){ mode = 'javascript'; }
else if(ext === 'jsx'){ mode = 'jsx' }
else if(ext === 'jsx'){ mode = 'jsx'; }
else if(ext === 'php' || ext === 'php5' || ext === 'php4'){ mode = 'php'; }
else if(ext === 'elm'){ mode = 'elm'; }
else if(ext === 'erl'){ mode = 'erlang'; }
@@ -112,7 +110,7 @@ export class Editor extends React.Component {
else if(ext === 'pl' || ext === 'pm'){mode = 'perl'; }
else if(ext === 'clj'){ mode = 'clojure'; }
else if(ext === 'el' || ext === 'lisp' || ext === 'cl' || ext === 'emacs'){ mode = 'lisp'; }
else if(ext === 'Dockerfile'){ mode = 'dockerfile'}
else if(ext === 'Dockerfile'){ mode = 'dockerfile'; }
else if(ext === 'R'){ mode = 'r'; }
else if(ext === 'Makefile'){ mode = 'cmake'; }
else if(ext === 'rb'){ mode = 'ruby'; }
@@ -130,12 +128,20 @@ export class Editor extends React.Component {
}
return import(/* webpackChunkName: "editor" */'./editor/'+mode)
.catch(() => import("./editor/text"))
.then((module) => Promise.resolve(module.default));
}
render() {
return (
<div style={{height: '100%'}}>
<NgIf cond={this.state.loading === true} style={{height: '100%'}}>
<Loader/>
</NgIf>
<NgIf cond={this.state.loading === false} style={{height: '100%'}}>
<div id="editor" style={{height: '100%'}}></div>
</NgIf>
</div>
);
}
}
+14 -9
View File
@@ -1,14 +1,16 @@
import React from 'react';
import ReactCSSTransitionGroup from 'react-addons-css-transition-group';
import { NgIf, Fab, Icon } from '../../components/';
import { MenuBar } from './menubar';
import { Editor } from './editor';
import './ide.scss';
export class IDE extends React.Component {
constructor(props){
super(props);
this.state = {
contentToSave: null
contentToSave: props.content
};
}
@@ -32,13 +34,16 @@ export class IDE extends React.Component {
render(){
return (
<div style={{height: '100%'}}>
<Editor onSave={this.save.bind(this)} filename={this.props.filename} content={this.props.content} onChange={this.onContentUpdate.bind(this)} height={this.state.height}/>
<NgIf cond={!this.props.isSaving}>
<Fab onClick={this.save.bind(this)}><Icon name="save" style={{height: '100%', width: '100%'}}/></Fab>
</NgIf>
<NgIf cond={this.props.isSaving}>
<Fab><Icon name="loading_white" style={{height: '100%', width: '100%'}}/></Fab>
</NgIf>
<Editor onSave={this.save.bind(this)} filename={this.props.filename} content={this.props.content} onChange={this.onContentUpdate.bind(this)} />
<ReactCSSTransitionGroup transitionName="fab" transitionLeave={false} transitionEnter={false} transitionAppear={true} transitionAppearTimeout={25000}>
<NgIf cond={!this.props.isSaving}>
<Fab onClick={this.save.bind(this)}><Icon name="save" style={{height: '100%', width: '100%'}}/></Fab>
</NgIf>
<NgIf cond={this.props.isSaving}>
<Fab><Icon name="loading_white" style={{height: '100%', width: '100%'}}/></Fab>
</NgIf>
</ReactCSSTransitionGroup>
</div>
);
}
+7
View File
@@ -0,0 +1,7 @@
.fab-appear{
opacity: 0;
}
.fab-appear.fab-appear-active{
transition: all 0.2s ease-out;
opacity: 1;
}
+1 -1
View File
@@ -2,6 +2,6 @@ export { AudioPlayer } from './audioplayer';
export { FileDownloader } from './filedownloader';
export { ImageViewer } from './imageviewer';
export { PDFViewer } from './pdfviewer';
export { IDE } from './ide';
// Those are commented because they will be delivered as a separate chunk
//export { VideoPlayer } from './videoplayer';
//export { IDE } from './ide';
+2 -2
View File
@@ -7,9 +7,9 @@ import { Audio, Video } from './components/';
export default class AppRouter extends React.Component {
render() {
return (
<div>
<div style={{height: '100%'}}>
<BrowserRouter>
<div>
<div style={{height: '100%'}}>
<Switch>
<Route exact path="/" component={HomePage} />
<Route path="/login" component={ConnectPage} />