MobX based editing

This commit is contained in:
Jori Lallo
2016-06-02 22:04:33 -07:00
parent aac20341f7
commit e6c7e95115
26 changed files with 436 additions and 185 deletions

View File

@@ -1,73 +1,45 @@
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { observer } from 'mobx-react';
import {
resetEditor,
updateText,
updateTitle,
replaceText,
} from 'actions/EditorActions';
import {
resetDocument,
fetchDocumentAsync,
saveDocumentAsync,
} from 'actions/DocumentActions';
import state from './DocumentEditState';
import Layout, { Title } from 'components/Layout';
import Switch from 'components/Switch';
import Layout, { Title, HeaderAction } from 'components/Layout';
import Flex from 'components/Flex';
import MarkdownEditor from 'components/MarkdownEditor';
import AtlasPreviewLoading from 'components/AtlasPreviewLoading';
import CenteredContent from 'components/CenteredContent';
import DropdownMenu, { MenuItem } from 'components/DropdownMenu';
import SaveAction from './components/SaveAction';
import Preview from './components/Preview';
import EditorPane from './components/EditorPane';
import styles from './DocumentEdit.scss';
import classNames from 'classnames/bind';
const cx = classNames.bind(styles);
@observer
class DocumentEdit extends Component {
static propTypes = {
updateText: React.PropTypes.func.isRequired,
updateTitle: React.PropTypes.func.isRequired,
replaceText: React.PropTypes.func.isRequired,
resetDocument: React.PropTypes.func.isRequired,
saveDocumentAsync: React.PropTypes.func.isRequired,
text: React.PropTypes.string,
title: React.PropTypes.string,
isSaving: React.PropTypes.bool,
}
state = {
loadingDocument: false,
}
componentWillMount = () => {
this.props.resetEditor();
this.props.resetDocument();
}
componentDidMount = () => {
const id = this.props.routeParams.id;
this.props.fetchDocumentAsync(id);
}
componentWillReceiveProps = (nextProps) => {
if (!this.props.document && nextProps.document) {
const doc = nextProps.document;
this.props.updateText(doc.text);
this.props.updateTitle(doc.title);
}
state.documentId = this.props.params.id;
state.fetchDocument();
}
onSave = () => {
if (this.props.title.length === 0) {
alert("Please add a title before saving (hint: Write a markdown header)");
return
}
// if (this.props.title.length === 0) {
// alert("Please add a title before saving (hint: Write a markdown header)");
// return
// }
state.updateDocument();
}
this.props.saveDocumentAsync(
null,
this.props.document.id,
this.props.title,
this.props.text,
)
state = {}
onScroll = (scrollTop) => {
this.setState({
scrollTop: scrollTop,
})
}
render() {
@@ -76,62 +48,60 @@ class DocumentEdit extends Component {
truncate={ 60 }
placeholder={ "Untitle document" }
>
{ this.props.title }
{ state.title }
</Title>
);
const actions = (
<Flex direction="row">
<HeaderAction>
<SaveAction
onClick={ this.onSave }
disabled={ state.isSaving }
/>
</HeaderAction>
<DropdownMenu label="More">
<MenuItem onClick={ state.togglePreview }>
Preview <Switch checked={ state.preview } />
</MenuItem>
</DropdownMenu>
</Flex>
);
return (
<Layout
actions={(
<Flex direction="row" align="center">
<SaveAction onClick={ this.onSave } />
</Flex>
)}
actions={ actions }
title={ title }
fixed={ true }
loading={ this.props.isSaving }
loading={ state.isSaving }
>
{ (this.props.isLoading && !this.props.document) ? (
{ (state.isFetching) ? (
<CenteredContent>
<AtlasPreviewLoading />
</CenteredContent>
) : (
<MarkdownEditor
onChange={ this.props.updateText }
text={ this.props.text }
replaceText={this.props.replaceText}
/>
<div className={ styles.container }>
<EditorPane
fullWidth={ !state.preview }
onScroll={ this.onScroll }
>
<MarkdownEditor
onChange={ state.updateText }
text={ state.text }
replaceText={ state.replaceText }
/>
</EditorPane>
{ state.preview ? (
<EditorPane
scrollTop={ this.state.scrollTop }
>
<Preview html={ state.htmlPreview } />
</EditorPane>
) : null }
</div>
) }
</Layout>
);
}
}
const mapStateToProps = (state) => {
return {
document: state.document.data,
text: state.editor.text,
title: state.editor.title,
isLoading: state.document.isLoading,
isSaving: state.document.isSaving,
};
};
const mapDispatchToProps = (dispatch) => {
return bindActionCreators({
resetEditor,
updateText,
updateTitle,
replaceText,
resetDocument,
fetchDocumentAsync,
saveDocumentAsync,
}, dispatch)
};
DocumentEdit = connect(
mapStateToProps,
mapDispatchToProps,
)(DocumentEdit);
export default DocumentEdit;