add toast component, start to add functionality

This commit is contained in:
catarak 2016-09-07 19:00:52 -04:00
parent f1ead9f124
commit 3352fe9d0d
10 changed files with 126 additions and 4 deletions

View file

@ -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';

View file

@ -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,

View 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
};
}

View 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);

View file

@ -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);
}

View 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;

View file

@ -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;

View file

@ -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;

View 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;
}

View file

@ -25,6 +25,7 @@
@import 'components/about';
@import 'components/github-button';
@import 'components/forms';
@import 'components/toast';
@import 'layout/ide';
@import 'layout/sketch-list';