add toast component, start to add functionality
This commit is contained in:
parent
f1ead9f124
commit
3352fe9d0d
10 changed files with 126 additions and 4 deletions
|
@ -78,6 +78,9 @@ export const SHOW_EDITOR_OPTIONS = 'SHOW_EDITOR_OPTIONS';
|
|||
export const CLOSE_EDITOR_OPTIONS = 'CLOSE_EDITOR_OPTIONS';
|
||||
export const SHOW_KEYBOARD_SHORTCUT_MODAL = 'SHOW_KEYBOARD_SHORTCUT_MODAL';
|
||||
export const CLOSE_KEYBOARD_SHORTCUT_MODAL = 'CLOSE_KEYBOARD_SHORTCUT_MODAL';
|
||||
export const SHOW_TOAST = 'SHOW_TOAST';
|
||||
export const HIDE_TOAST = 'HIDE_TOAST';
|
||||
export const SET_TOAST_TEXT = 'SET_TOAST_TEXT';
|
||||
|
||||
// eventually, handle errors more specifically and better
|
||||
export const ERROR = 'ERROR';
|
||||
|
|
|
@ -5,6 +5,7 @@ import JSZip from 'jszip';
|
|||
import JSZipUtils from 'jszip-utils';
|
||||
import { saveAs } from 'file-saver';
|
||||
import { getBlobUrl } from './files';
|
||||
import { showToast, setToastText } from './toast';
|
||||
|
||||
const ROOT_URL = location.href.indexOf('localhost') > 0 ? 'http://localhost:8000/api' : '/api';
|
||||
|
||||
|
@ -60,6 +61,8 @@ export function saveProject() {
|
|||
dispatch({
|
||||
type: ActionTypes.PROJECT_SAVE_SUCCESS
|
||||
});
|
||||
dispatch(showToast());
|
||||
dispatch(setToastText('Project saved.'));
|
||||
})
|
||||
.catch((response) => dispatch({
|
||||
type: ActionTypes.PROJECT_SAVE_FAIL,
|
||||
|
@ -76,6 +79,8 @@ export function saveProject() {
|
|||
owner: response.data.user,
|
||||
files: response.data.files
|
||||
});
|
||||
dispatch(showToast());
|
||||
dispatch(setToastText('Project saved.'));
|
||||
})
|
||||
.catch(response => dispatch({
|
||||
type: ActionTypes.PROJECT_SAVE_FAIL,
|
||||
|
|
23
client/modules/IDE/actions/toast.js
Normal file
23
client/modules/IDE/actions/toast.js
Normal file
|
@ -0,0 +1,23 @@
|
|||
import * as ActionTypes from '../../../constants';
|
||||
|
||||
export function hideToast() {
|
||||
return {
|
||||
type: ActionTypes.HIDE_TOAST
|
||||
};
|
||||
}
|
||||
|
||||
export function showToast() {
|
||||
return (dispatch) => {
|
||||
dispatch({
|
||||
type: ActionTypes.SHOW_TOAST
|
||||
});
|
||||
setTimeout(() => dispatch(hideToast()), 1500);
|
||||
};
|
||||
}
|
||||
|
||||
export function setToastText(text) {
|
||||
return {
|
||||
type: ActionTypes.SET_TOAST_TEXT,
|
||||
text
|
||||
};
|
||||
}
|
34
client/modules/IDE/components/Toast.js
Normal file
34
client/modules/IDE/components/Toast.js
Normal file
|
@ -0,0 +1,34 @@
|
|||
import React, { PropTypes } from 'react';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import InlineSVG from 'react-inlinesvg';
|
||||
const exitUrl = require('../../../images/exit.svg');
|
||||
import * as ToastActions from '../actions/toast';
|
||||
|
||||
function Toast(props) {
|
||||
return (
|
||||
<section className="toast">
|
||||
<p>
|
||||
{props.text}
|
||||
</p>
|
||||
<button className="toast__close" onClick={props.hideToast}>
|
||||
<InlineSVG src={exitUrl} alt="Close Keyboard Shortcuts Overlay" />
|
||||
</button>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
Toast.propTypes = {
|
||||
text: PropTypes.string.isRequired,
|
||||
hideToast: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
return state.toast;
|
||||
}
|
||||
|
||||
function mapDispatchToProps(dispatch) {
|
||||
return bindActionCreators(ToastActions, dispatch);
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Toast);
|
|
@ -11,6 +11,7 @@ import ShareModal from '../components/ShareModal';
|
|||
import KeyboardShortcutModal from '../components/KeyboardShortcutModal';
|
||||
import Nav from '../../../components/Nav';
|
||||
import Console from '../components/Console';
|
||||
import Toast from '../components/Toast';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { connect } from 'react-redux';
|
||||
import * as FileActions from '../actions/files';
|
||||
|
@ -19,6 +20,7 @@ import * as ProjectActions from '../actions/project';
|
|||
import * as EditorAccessibilityActions from '../actions/editorAccessibility';
|
||||
import * as PreferencesActions from '../actions/preferences';
|
||||
import * as UserActions from '../../User/actions';
|
||||
import * as ToastActions from '../actions/toast';
|
||||
import { getHTMLFile, getJSFiles, getCSSFiles } from '../reducers/files';
|
||||
import SplitPane from 'react-split-pane';
|
||||
import Overlay from '../../App/components/Overlay';
|
||||
|
@ -114,6 +116,7 @@ class IDEView extends React.Component {
|
|||
render() {
|
||||
return (
|
||||
<div className="ide">
|
||||
{this.props.toast.isVisible && <Toast />}
|
||||
<Nav
|
||||
user={this.props.user}
|
||||
newProject={this.props.newProject}
|
||||
|
@ -124,6 +127,8 @@ class IDEView extends React.Component {
|
|||
logoutUser={this.props.logoutUser}
|
||||
stopSketch={this.props.stopSketch}
|
||||
showShareModal={this.props.showShareModal}
|
||||
showToast={this.props.showToast}
|
||||
setToastText={this.props.setToastText}
|
||||
/>
|
||||
<Toolbar
|
||||
className="Toolbar"
|
||||
|
@ -434,7 +439,12 @@ IDEView.propTypes = {
|
|||
showEditorOptions: PropTypes.func.isRequired,
|
||||
closeEditorOptions: PropTypes.func.isRequired,
|
||||
showKeyboardShortcutModal: PropTypes.func.isRequired,
|
||||
closeKeyboardShortcutModal: PropTypes.func.isRequired
|
||||
closeKeyboardShortcutModal: PropTypes.func.isRequired,
|
||||
toast: PropTypes.shape({
|
||||
isVisible: PropTypes.bool.isRequired
|
||||
}).isRequired,
|
||||
showToast: PropTypes.func.isRequired,
|
||||
setToastText: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
function mapStateToProps(state) {
|
||||
|
@ -448,7 +458,8 @@ function mapStateToProps(state) {
|
|||
preferences: state.preferences,
|
||||
editorAccessibility: state.editorAccessibility,
|
||||
user: state.user,
|
||||
project: state.project
|
||||
project: state.project,
|
||||
toast: state.toast
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -459,7 +470,8 @@ function mapDispatchToProps(dispatch) {
|
|||
ProjectActions,
|
||||
IDEActions,
|
||||
PreferencesActions,
|
||||
UserActions),
|
||||
UserActions,
|
||||
ToastActions),
|
||||
dispatch);
|
||||
}
|
||||
|
||||
|
|
21
client/modules/IDE/reducers/toast.js
Normal file
21
client/modules/IDE/reducers/toast.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
import * as ActionTypes from '../../../constants';
|
||||
|
||||
const initialState = {
|
||||
isVisible: false,
|
||||
text: ''
|
||||
};
|
||||
|
||||
const toast = (state = initialState, action) => {
|
||||
switch (action.type) {
|
||||
case ActionTypes.SHOW_TOAST:
|
||||
return Object.assign({}, state, { isVisible: true });
|
||||
case ActionTypes.HIDE_TOAST:
|
||||
return Object.assign({}, state, { isVisible: false });
|
||||
case ActionTypes.SET_TOAST_TEXT:
|
||||
return Object.assign({}, state, { text: action.text });
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
||||
|
||||
export default toast;
|
|
@ -6,6 +6,7 @@ import project from './modules/IDE/reducers/project';
|
|||
import editorAccessibility from './modules/IDE/reducers/editorAccessibility';
|
||||
import user from './modules/User/reducers';
|
||||
import sketches from './modules/Sketch/reducers';
|
||||
import toast from './modules/IDE/reducers/toast';
|
||||
import { reducer as form } from 'redux-form';
|
||||
|
||||
const rootReducer = combineReducers({
|
||||
|
@ -16,7 +17,8 @@ const rootReducer = combineReducers({
|
|||
user,
|
||||
project,
|
||||
sketches,
|
||||
editorAccessibility
|
||||
editorAccessibility,
|
||||
toast
|
||||
});
|
||||
|
||||
export default rootReducer;
|
||||
|
|
|
@ -25,6 +25,9 @@ $light-icon-color: #8b8b8b;
|
|||
$light-icon-hover-color: $light-primary-text-color;
|
||||
$light-shadow-color: rgba(0, 0, 0, 0.16);
|
||||
|
||||
$toast-background-color: #979797;
|
||||
$toast-text-color: $white;
|
||||
|
||||
$dark-primary-text-color: $white;
|
||||
$dark-secondary-text-color: #c2c2c2;
|
||||
$dark-inactive-color: #7d7d7d;
|
||||
|
|
18
client/styles/components/_toast.scss
Normal file
18
client/styles/components/_toast.scss
Normal file
|
@ -0,0 +1,18 @@
|
|||
.toast {
|
||||
background-color: $toast-background-color;
|
||||
color: $toast-text-color;
|
||||
padding: #{20 / $base-font-size}rem;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 40%;
|
||||
display: flex;
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.toast__close {
|
||||
@extend %icon;
|
||||
& g {
|
||||
fill: $toast-text-color;
|
||||
}
|
||||
margin-left: #{10 / $base-font-size}rem;
|
||||
}
|
|
@ -25,6 +25,7 @@
|
|||
@import 'components/about';
|
||||
@import 'components/github-button';
|
||||
@import 'components/forms';
|
||||
@import 'components/toast';
|
||||
|
||||
@import 'layout/ide';
|
||||
@import 'layout/sketch-list';
|
||||
|
|
Loading…
Reference in a new issue