From 538a41c617ef0c76cce52c598b2bbe0ea12b0cf3 Mon Sep 17 00:00:00 2001
From: siddhant <30566406+siddhant1@users.noreply.github.com>
Date: Thu, 2 May 2019 02:02:39 +0530
Subject: [PATCH] Added Loader to indicate loading of sketches (#880)
* Added Loader to indicate loading of sketches
* Fixed styles
* Changed styles
* remove prefixes
* Issues Fixed:
* added Loader
* Refactor
* Issues Fixed
* clean up loader functions
---
client/constants.js | 3 ++
client/modules/App/components/loader.jsx | 9 +++++
client/modules/IDE/actions/loader.js | 9 +++++
client/modules/IDE/actions/projects.js | 14 +++++--
client/modules/IDE/components/SketchList.jsx | 26 ++++++++++---
client/modules/IDE/reducers/loading.js | 14 +++++++
client/reducers.js | 4 +-
client/styles/components/_loader.scss | 40 ++++++++++++++++++++
client/styles/main.scss | 1 +
9 files changed, 110 insertions(+), 10 deletions(-)
create mode 100644 client/modules/App/components/loader.jsx
create mode 100644 client/modules/IDE/actions/loader.js
create mode 100644 client/modules/IDE/reducers/loading.js
create mode 100644 client/styles/components/_loader.scss
diff --git a/client/constants.js b/client/constants.js
index 38fc467b..9cb3daa4 100644
--- a/client/constants.js
+++ b/client/constants.js
@@ -118,5 +118,8 @@ export const HIDE_RUNTIME_ERROR_WARNING = 'HIDE_RUNTIME_ERROR_WARNING';
export const SHOW_RUNTIME_ERROR_WARNING = 'SHOW_RUNTIME_ERROR_WARNING';
export const SET_ASSETS = 'SET_ASSETS';
+export const START_LOADING = 'START_LOADING';
+export const STOP_LOADING = 'STOP_LOADING';
+
export const START_SAVING_PROJECT = 'START_SAVING_PROJECT';
export const END_SAVING_PROJECT = 'END_SAVING_PROJECT';
diff --git a/client/modules/App/components/loader.jsx b/client/modules/App/components/loader.jsx
new file mode 100644
index 00000000..1561387e
--- /dev/null
+++ b/client/modules/App/components/loader.jsx
@@ -0,0 +1,9 @@
+import React from 'react';
+
+const Loader = () => (
+
+);
+export default Loader;
diff --git a/client/modules/IDE/actions/loader.js b/client/modules/IDE/actions/loader.js
new file mode 100644
index 00000000..f331094c
--- /dev/null
+++ b/client/modules/IDE/actions/loader.js
@@ -0,0 +1,9 @@
+import * as ActionTypes from '../../../constants';
+
+export function startLoader() {
+ return { type: ActionTypes.START_LOADING };
+}
+
+export function stopLoader() {
+ return { type: ActionTypes.STOP_LOADING };
+}
diff --git a/client/modules/IDE/actions/projects.js b/client/modules/IDE/actions/projects.js
index 5419f0fb..77dfbe52 100644
--- a/client/modules/IDE/actions/projects.js
+++ b/client/modules/IDE/actions/projects.js
@@ -2,12 +2,14 @@ import axios from 'axios';
import * as ActionTypes from '../../../constants';
import { showErrorModal, setPreviousPath } from './ide';
import { resetProject } from './project';
+import { startLoader, stopLoader } from './loader';
const __process = (typeof global !== 'undefined' ? global : window).process;
const ROOT_URL = __process.env.API_URL;
export function getProjects(username) {
return (dispatch) => {
+ dispatch(startLoader());
let url;
if (username) {
url = `${ROOT_URL}/${username}/projects`;
@@ -20,11 +22,15 @@ export function getProjects(username) {
type: ActionTypes.SET_PROJECTS,
projects: response.data
});
+ dispatch(stopLoader());
})
- .catch(response => dispatch({
- type: ActionTypes.ERROR,
- error: response.data
- }));
+ .catch((response) => {
+ dispatch({
+ type: ActionTypes.ERROR,
+ error: response.data
+ });
+ dispatch(stopLoader());
+ });
};
}
diff --git a/client/modules/IDE/components/SketchList.jsx b/client/modules/IDE/components/SketchList.jsx
index 75a9b474..c0086ab5 100644
--- a/client/modules/IDE/components/SketchList.jsx
+++ b/client/modules/IDE/components/SketchList.jsx
@@ -9,6 +9,7 @@ import { bindActionCreators } from 'redux';
import * as ProjectActions from '../actions/project';
import * as SketchActions from '../actions/projects';
import * as ToastActions from '../actions/toast';
+import Loader from '../../App/components/loader';
const trashCan = require('../../../images/trash-can.svg');
@@ -25,6 +26,20 @@ class SketchList extends React.Component {
return `p5.js Web Editor | ${this.props.username}'s sketches`;
}
+ hasSketches() {
+ return !this.props.loading && this.props.sketches.length > 0;
+ }
+
+ renderLoader() {
+ if (this.props.loading) return ;
+ return null;
+ }
+
+ renderEmptyTable() {
+ if (!this.props.loading && this.props.sketches.length === 0) return (No sketches.
);
+ return null;
+ }
+
render() {
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
return (
@@ -32,10 +47,9 @@ class SketchList extends React.Component {
{this.getSketchesTitle()}
- { this.props.sketches.length === 0 &&
- No sketches.
- }
- { this.props.sketches.length > 0 &&
+ {this.renderLoader()}
+ {this.renderEmptyTable()}
+ {this.hasSketches() &&
@@ -95,6 +109,7 @@ SketchList.propTypes = {
updatedAt: PropTypes.string.isRequired
})).isRequired,
username: PropTypes.string,
+ loading: PropTypes.bool.isRequired,
deleteProject: PropTypes.func.isRequired
};
@@ -105,7 +120,8 @@ SketchList.defaultProps = {
function mapStateToProps(state) {
return {
user: state.user,
- sketches: state.sketches
+ sketches: state.sketches,
+ loading: state.loading,
};
}
diff --git a/client/modules/IDE/reducers/loading.js b/client/modules/IDE/reducers/loading.js
new file mode 100644
index 00000000..529c5747
--- /dev/null
+++ b/client/modules/IDE/reducers/loading.js
@@ -0,0 +1,14 @@
+import * as ActionTypes from '../../../constants';
+
+const loading = (state = false, action) => {
+ switch (action.type) {
+ case ActionTypes.START_LOADING:
+ return true;
+ case ActionTypes.STOP_LOADING:
+ return false;
+ default:
+ return state;
+ }
+};
+
+export default loading;
diff --git a/client/reducers.js b/client/reducers.js
index c508c8ea..ef4d39c3 100644
--- a/client/reducers.js
+++ b/client/reducers.js
@@ -10,6 +10,7 @@ import sketches from './modules/IDE/reducers/projects';
import toast from './modules/IDE/reducers/toast';
import console from './modules/IDE/reducers/console';
import assets from './modules/IDE/reducers/assets';
+import loading from './modules/IDE/reducers/loading';
const rootReducer = combineReducers({
form,
@@ -22,7 +23,8 @@ const rootReducer = combineReducers({
editorAccessibility,
toast,
console,
- assets
+ assets,
+ loading
});
export default rootReducer;
diff --git a/client/styles/components/_loader.scss b/client/styles/components/_loader.scss
new file mode 100644
index 00000000..ec52410a
--- /dev/null
+++ b/client/styles/components/_loader.scss
@@ -0,0 +1,40 @@
+.loader {
+ width: #{80 / $base-font-size }rem;
+ height: #{80 / $base-font-size}rem;
+
+ position: relative;
+ margin: #{100 / $base-font-size}rem auto;
+}
+
+.loader__circle1,
+.loader__circle2 {
+ width: 100%;
+ height: 100%;
+ border-radius: 80%;
+
+ @include themify() {
+ background-color: getThemifyVariable('logo-color');
+ }
+
+ opacity: 0.6;
+ position: absolute;
+ top: 0;
+ left: 0;
+ animation: sk-bounce 2.0s infinite ease-in-out;
+}
+
+.loader__circle2 {
+ animation-delay: -1.0s;
+}
+
+@keyframes sk-bounce {
+
+ 0%,
+ 100% {
+ transform: scale(0.0);
+ }
+
+ 50% {
+ transform: scale(1.0);
+ }
+}
\ No newline at end of file
diff --git a/client/styles/main.scss b/client/styles/main.scss
index 12df45d3..3d9bf977 100644
--- a/client/styles/main.scss
+++ b/client/styles/main.scss
@@ -41,6 +41,7 @@
@import 'components/keyboard-shortcuts';
@import 'components/copyable-input';
@import 'components/feedback';
+@import 'components/loader';
@import 'components/uploader';
@import 'layout/ide';