diff --git a/frontend/components/Editor/Editor.js b/frontend/components/Editor/Editor.js index 0ba3055f7..ad73209e1 100644 --- a/frontend/components/Editor/Editor.js +++ b/frontend/components/Editor/Editor.js @@ -89,11 +89,12 @@ type KeyData = { case 's': ev.preventDefault(); ev.stopPropagation(); - return this.props.onSave({ redirect: false }); + this.props.onSave(); + return state; case 'enter': ev.preventDefault(); ev.stopPropagation(); - this.props.onSave(); + this.props.onSave({ redirect: false }); return state; case 'escape': return this.props.onCancel(); diff --git a/frontend/components/Icon/CheckIcon.js b/frontend/components/Icon/CheckIcon.js new file mode 100644 index 000000000..ab6ea35e3 --- /dev/null +++ b/frontend/components/Icon/CheckIcon.js @@ -0,0 +1,21 @@ +// @flow +import React from 'react'; +import Icon from './Icon'; +import type { Props } from './Icon'; + +export default function CheckIcon(props: Props) { + return ( + + + + + + + ); +} diff --git a/frontend/components/Layout/components/SaveAction/SaveAction.js b/frontend/components/Layout/components/SaveAction/SaveAction.js index b37cce08a..ff307acb9 100644 --- a/frontend/components/Layout/components/SaveAction/SaveAction.js +++ b/frontend/components/Layout/components/SaveAction/SaveAction.js @@ -1,14 +1,17 @@ // @flow import React from 'react'; -import { observer } from 'mobx-react'; +import styled from 'styled-components'; +import CheckIcon from 'components/Icon/CheckIcon'; +import { fadeAndScaleIn } from 'styles/animations'; type Props = { onClick: Function, + showCheckmark: boolean, disabled?: boolean, isNew?: boolean, }; -@observer class SaveAction extends React.Component { +class SaveAction extends React.Component { props: Props; onClick = (event: MouseEvent) => { @@ -19,21 +22,38 @@ type Props = { }; render() { - const { disabled, isNew } = this.props; + const { showCheckmark, disabled, isNew } = this.props; return ( -
- - {isNew ? 'Publish' : 'Save'} - -
+ + {showCheckmark && } + {isNew ? 'Publish' : 'Save'} + ); } } +const Link = styled.a` + display: flex; + align-items: center; +`; + +const SavedIcon = styled(CheckIcon)` + animation: ${fadeAndScaleIn} 250ms ease; + display: inline-block; + margin-right: 4px; + width: 18px; + height: 18px; + + svg { + width: 18px; + height: 18px; + } +`; + export default SaveAction; diff --git a/frontend/components/Modal/Modal.js b/frontend/components/Modal/Modal.js index ee988528a..50e5bdb02 100644 --- a/frontend/components/Modal/Modal.js +++ b/frontend/components/Modal/Modal.js @@ -2,7 +2,7 @@ import React from 'react'; import styled from 'styled-components'; import ReactModal from 'react-modal'; -import { modalFadeIn } from 'styles/animations'; +import { fadeAndScaleIn } from 'styles/animations'; import CloseIcon from 'components/Icon/CloseIcon'; import Flex from 'components/Flex'; @@ -46,7 +46,7 @@ const Content = styled(Flex)` `; const StyledModal = styled(ReactModal)` - animation: ${modalFadeIn} 250ms ease; + animation: ${fadeAndScaleIn} 250ms ease; position: absolute; top: 0; diff --git a/frontend/scenes/Document/Document.js b/frontend/scenes/Document/Document.js index c82315c5b..7f6d95107 100644 --- a/frontend/scenes/Document/Document.js +++ b/frontend/scenes/Document/Document.js @@ -37,6 +37,7 @@ type Props = { @observer class DocumentScene extends Component { props: Props; + savedTimeout: number; state: { newDocument?: Document, }; @@ -44,6 +45,7 @@ type Props = { isDragging: false, isLoading: false, newDocument: undefined, + showAsSaved: false, }; componentDidMount() { @@ -60,6 +62,7 @@ type Props = { } componentWillUnmount() { + clearTimeout(this.savedTimeout); this.props.ui.clearActiveDocument(); } @@ -108,9 +111,19 @@ type Props = { if (redirect || this.props.newDocument) { this.props.history.push(document.url); + } else { + this.showAsSaved(); } }; + showAsSaved() { + this.setState({ showAsSaved: true }); + this.savedTimeout = setTimeout( + () => this.setState({ showAsSaved: false }), + 2000 + ); + } + onImageUploadStart() { this.setState({ isLoading: true }); } @@ -204,6 +217,7 @@ type Props = { {isEditing ?