From 49ada60824cb4bbeaec6ed3937552cadc285e6ea Mon Sep 17 00:00:00 2001
From: Ben Wheeler <wheeler.benjamin@gmail.com>
Date: Tue, 4 Dec 2018 00:09:54 -0500
Subject: [PATCH] use blue creating screen for new projects; revised alert text
 for copy, remix; saving messages don't dismiss alerts

---
 src/components/gui/gui.jsx       |  7 +++
 src/components/loader/loader.jsx | 30 +++++++++--
 src/lib/alerts/index.jsx         | 86 ++++++++++++++++++++++++++++----
 src/lib/project-saver-hoc.jsx    | 33 +++++++-----
 src/reducers/project-state.js    |  6 +++
 5 files changed, 135 insertions(+), 27 deletions(-)

diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx
index 6326e63fc..04b2da69a 100644
--- a/src/components/gui/gui.jsx
+++ b/src/components/gui/gui.jsx
@@ -81,6 +81,7 @@ const GUIComponent = props => {
         enableCommunity,
         importInfoVisible,
         intl,
+        isCreating,
         isPlayerOnly,
         isRtl,
         isShared,
@@ -152,6 +153,9 @@ const GUIComponent = props => {
                 {loading ? (
                     <Loader />
                 ) : null}
+                {isCreating ? (
+                    <Loader messageId="gui.loader.creating" />
+                ) : null}
                 {importInfoVisible ? (
                     <ImportModal />
                 ) : null}
@@ -357,6 +361,7 @@ GUIComponent.propTypes = {
     enableCommunity: PropTypes.bool,
     importInfoVisible: PropTypes.bool,
     intl: intlShape.isRequired,
+    isCreating: PropTypes.bool,
     isPlayerOnly: PropTypes.bool,
     isRtl: PropTypes.bool,
     isShared: PropTypes.bool,
@@ -397,7 +402,9 @@ GUIComponent.defaultProps = {
     canShare: false,
     canUseCloud: false,
     enableCommunity: false,
+    isCreating: false,
     isShared: false,
+    loading: false,
     onUpdateProjectTitle: () => {},
     showComingSoon: false,
     stageSizeMode: STAGE_SIZE_MODES.large
diff --git a/src/components/loader/loader.jsx b/src/components/loader/loader.jsx
index dea1ff311..e06b8bb35 100644
--- a/src/components/loader/loader.jsx
+++ b/src/components/loader/loader.jsx
@@ -1,6 +1,7 @@
 import React from 'react';
 import {FormattedMessage} from 'react-intl';
 import styles from './loader.css';
+import PropTypes from 'prop-types';
 
 import topBlock from './top-block.svg';
 import middleBlock from './middle-block.svg';
@@ -97,6 +98,22 @@ const messages = [
         weight: 1
     }
 ];
+const mainMessages = {
+    'gui.loader.headline': (
+        <FormattedMessage
+            defaultMessage="Loading Project"
+            description="Main loading message"
+            id="gui.loader.headline"
+        />
+    ),
+    'gui.loader.creating': (
+        <FormattedMessage
+            defaultMessage="Creating Project"
+            description="Main creating message"
+            id="gui.loader.creating"
+        />
+    )
+};
 
 class LoaderComponent extends React.Component {
     constructor (props) {
@@ -148,11 +165,7 @@ class LoaderComponent extends React.Component {
                         />
                     </div>
                     <div className={styles.title}>
-                        <FormattedMessage
-                            defaultMessage="Loading Project"
-                            description="Main loading message"
-                            id="gui.loader.headline"
-                        />
+                        {mainMessages[this.props.messageId]}
                     </div>
                     <div className={styles.messageContainerOuter}>
                         <div
@@ -175,4 +188,11 @@ class LoaderComponent extends React.Component {
     }
 }
 
+LoaderComponent.propTypes = {
+    messageId: PropTypes.string
+};
+LoaderComponent.defaultProps = {
+    messageId: 'gui.loader.headline'
+};
+
 export default LoaderComponent;
diff --git a/src/lib/alerts/index.jsx b/src/lib/alerts/index.jsx
index dda178e1f..67abea3c9 100644
--- a/src/lib/alerts/index.jsx
+++ b/src/lib/alerts/index.jsx
@@ -20,10 +20,11 @@ const alerts = [
     {
         alertId: 'createSuccess',
         alertType: AlertTypes.STANDARD,
-        clearList: ['createSuccess', 'creating', 'saveSuccess', 'saving'],
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
         content: (
             <FormattedMessage
-                defaultMessage="Successfully created."
+                defaultMessage="New project created."
                 description="Message indicating that project was successfully created"
                 id="gui.alerts.createsuccess"
             />
@@ -32,13 +33,46 @@ const alerts = [
         level: AlertLevels.SUCCESS,
         maxDisplaySecs: 5
     },
+    {
+        alertId: 'createCopySuccess',
+        alertType: AlertTypes.STANDARD,
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
+        content: (
+            <FormattedMessage
+                defaultMessage="Project saved as a copy."
+                description="Message indicating that project was successfully created"
+                id="gui.alerts.createcopysuccess"
+            />
+        ),
+        iconURL: successImage,
+        level: AlertLevels.SUCCESS,
+        maxDisplaySecs: 5
+    },
+    {
+        alertId: 'createRemixSuccess',
+        alertType: AlertTypes.STANDARD,
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
+        content: (
+            <FormattedMessage
+                defaultMessage="Project saved as a remix."
+                description="Message indicating that project was successfully created"
+                id="gui.alerts.createremixsuccess"
+            />
+        ),
+        iconURL: successImage,
+        level: AlertLevels.SUCCESS,
+        maxDisplaySecs: 5
+    },
     {
         alertId: 'creating',
         alertType: AlertTypes.STANDARD,
-        clearList: ['createSuccess', 'creating', 'saveSuccess', 'saving'],
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
         content: (
             <FormattedMessage
-                defaultMessage="Creating..."
+                defaultMessage="Creating new…"
                 description="Message indicating that project is in process of creating"
                 id="gui.alerts.creating"
             />
@@ -46,9 +80,40 @@ const alerts = [
         iconSpinner: true,
         level: AlertLevels.SUCCESS
     },
+    {
+        alertId: 'creatingCopy',
+        alertType: AlertTypes.STANDARD,
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
+        content: (
+            <FormattedMessage
+                defaultMessage="Copying project…"
+                description="Message indicating that project is in process of copying"
+                id="gui.alerts.creatingCopy"
+            />
+        ),
+        iconSpinner: true,
+        level: AlertLevels.SUCCESS
+    },
+    {
+        alertId: 'creatingRemix',
+        alertType: AlertTypes.STANDARD,
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
+        content: (
+            <FormattedMessage
+                defaultMessage="Remixing project…"
+                description="Message indicating that project is in process of remixing"
+                id="gui.alerts.creatingRemix"
+            />
+        ),
+        iconSpinner: true,
+        level: AlertLevels.SUCCESS
+    },
     {
         alertId: 'creatingError',
-        clearList: ['creating', 'createSuccess'],
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
         closeButton: true,
         content: (
             <FormattedMessage
@@ -61,7 +126,8 @@ const alerts = [
     },
     {
         alertId: 'savingError',
-        clearList: ['saving', 'saveSuccess', 'savingError'],
+        clearList: ['createSuccess', 'creating', 'createCopySuccess', 'creatingCopy',
+            'createRemixSuccess', 'creatingRemix', 'saveSuccess', 'saving'],
         showDownload: true,
         showSaveNow: true,
         closeButton: false,
@@ -77,10 +143,10 @@ const alerts = [
     {
         alertId: 'saveSuccess',
         alertType: AlertTypes.INLINE,
-        clearList: ['createSuccess', 'creating', 'saveSuccess', 'saving', 'savingError'],
+        clearList: ['saveSuccess', 'saving', 'savingError'],
         content: (
             <FormattedMessage
-                defaultMessage="Successfully saved."
+                defaultMessage="Project saved."
                 description="Message indicating that project was successfully saved"
                 id="gui.alerts.savesuccess"
             />
@@ -92,10 +158,10 @@ const alerts = [
     {
         alertId: 'saving',
         alertType: AlertTypes.INLINE,
-        clearList: ['createSuccess', 'creating', 'saveSuccess', 'saving', 'savingError'],
+        clearList: ['saveSuccess', 'saving', 'savingError'],
         content: (
             <FormattedMessage
-                defaultMessage="Saving..."
+                defaultMessage="Saving project…"
                 description="Message indicating that project is in process of saving"
                 id="gui.alerts.saving"
             />
diff --git a/src/lib/project-saver-hoc.jsx b/src/lib/project-saver-hoc.jsx
index cd6be4ca7..a5956a2d2 100644
--- a/src/lib/project-saver-hoc.jsx
+++ b/src/lib/project-saver-hoc.jsx
@@ -20,6 +20,7 @@ import {
     createProject,
     doneCreatingProject,
     doneUpdatingProject,
+    getIsAnyCreatingNewState,
     getIsCreatingCopy,
     getIsCreatingNew,
     getIsManualUpdating,
@@ -125,11 +126,9 @@ const ProjectSaverHOC = function (WrappedComponent) {
                 });
         }
         createNewProjectToStorage () {
-            this.props.onShowCreatingAlert();
             return this.storeProject(null)
                 .then(response => {
                     this.props.onCreatedProject(response.id.toString(), this.props.loadingState);
-                    this.props.onShowCreateSuccessAlert();
                 })
                 .catch(err => {
                     this.props.onShowAlert('creatingError');
@@ -137,7 +136,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
                 });
         }
         createCopyToStorage () {
-            this.props.onShowCreatingAlert();
+            this.props.onShowCreatingCopyAlert();
             return this.storeProject(null, {
                 original_id: this.props.reduxProjectId,
                 is_copy: 1,
@@ -145,7 +144,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
             })
                 .then(response => {
                     this.props.onCreatedProject(response.id.toString(), this.props.loadingState);
-                    this.props.onShowCreateSuccessAlert();
+                    this.props.onShowCopySuccessAlert();
                 })
                 .catch(err => {
                     this.props.onShowAlert('creatingError');
@@ -153,7 +152,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
                 });
         }
         createRemixToStorage () {
-            this.props.onShowCreatingAlert();
+            this.props.onShowCreatingRemixAlert();
             return this.storeProject(null, {
                 original_id: this.props.reduxProjectId,
                 is_remix: 1,
@@ -161,7 +160,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
             })
                 .then(response => {
                     this.props.onCreatedProject(response.id.toString(), this.props.loadingState);
-                    this.props.onShowCreateSuccessAlert();
+                    this.props.onShowRemixSuccessAlert();
                 })
                 .catch(err => {
                     this.props.onShowAlert('creatingError');
@@ -242,6 +241,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
                 isCreatingCopy,
                 isCreatingNew,
                 projectChanged,
+                isAnyCreatingNewState,
                 isManualUpdating,
                 isRemixing,
                 isShowingSaveable,
@@ -254,8 +254,10 @@ const ProjectSaverHOC = function (WrappedComponent) {
                 onCreateProject,
                 onProjectError,
                 onShowAlert,
-                onShowCreateSuccessAlert,
-                onShowCreatingAlert,
+                onShowCopySuccessAlert,
+                onShowRemixSuccessAlert,
+                onShowCreatingCopyAlert,
+                onShowCreatingRemixAlert,
                 onShowSaveSuccessAlert,
                 onShowSavingAlert,
                 onUpdatedProject,
@@ -268,6 +270,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
             } = this.props;
             return (
                 <WrappedComponent
+                    isCreating={isAnyCreatingNewState}
                     {...componentProps}
                 />
             );
@@ -278,6 +281,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
         autoSaveTimeoutId: PropTypes.number,
         canCreateNew: PropTypes.bool,
         canSave: PropTypes.bool,
+        isAnyCreatingNewState: PropTypes.bool,
         isCreatingCopy: PropTypes.bool,
         isCreatingNew: PropTypes.bool,
         isManualUpdating: PropTypes.bool,
@@ -293,8 +297,10 @@ const ProjectSaverHOC = function (WrappedComponent) {
         onCreatedProject: PropTypes.func,
         onProjectError: PropTypes.func,
         onShowAlert: PropTypes.func,
-        onShowCreateSuccessAlert: PropTypes.func,
-        onShowCreatingAlert: PropTypes.func,
+        onShowCopySuccessAlert: PropTypes.func,
+        onShowCreatingCopyAlert: PropTypes.func,
+        onShowCreatingRemixAlert: PropTypes.func,
+        onShowRemixSuccessAlert: PropTypes.func,
         onShowSaveSuccessAlert: PropTypes.func,
         onShowSavingAlert: PropTypes.func,
         onUpdateProjectThumbnail: PropTypes.func,
@@ -312,6 +318,7 @@ const ProjectSaverHOC = function (WrappedComponent) {
         const isShowingWithId = getIsShowingWithId(loadingState);
         return {
             autoSaveTimeoutId: state.scratchGui.timeout.autoSaveTimeoutId,
+            isAnyCreatingNewState: getIsAnyCreatingNewState(loadingState),
             isCreatingCopy: getIsCreatingCopy(loadingState),
             isCreatingNew: getIsCreatingNew(loadingState),
             isRemixing: getIsRemixing(loadingState),
@@ -334,8 +341,10 @@ const ProjectSaverHOC = function (WrappedComponent) {
         onProjectError: error => dispatch(projectError(error)),
         onSetProjectUnchanged: () => dispatch(setProjectUnchanged()),
         onShowAlert: alertType => dispatch(showStandardAlert(alertType)),
-        onShowCreateSuccessAlert: () => showAlertWithTimeout(dispatch, 'createSuccess'),
-        onShowCreatingAlert: () => showAlertWithTimeout(dispatch, 'creating'),
+        onShowCopySuccessAlert: () => showAlertWithTimeout(dispatch, 'createCopySuccess'),
+        onShowRemixSuccessAlert: () => showAlertWithTimeout(dispatch, 'createRemixSuccess'),
+        onShowCreatingCopyAlert: () => showAlertWithTimeout(dispatch, 'creatingCopy'),
+        onShowCreatingRemixAlert: () => showAlertWithTimeout(dispatch, 'creatingRemix'),
         onShowSaveSuccessAlert: () => showAlertWithTimeout(dispatch, 'saveSuccess'),
         onShowSavingAlert: () => showAlertWithTimeout(dispatch, 'saving'),
         onUpdatedProject: (projectId, loadingState) => dispatch(doneUpdatingProject(projectId, loadingState)),
diff --git a/src/reducers/project-state.js b/src/reducers/project-state.js
index cc4df27f3..1491ac3b1 100644
--- a/src/reducers/project-state.js
+++ b/src/reducers/project-state.js
@@ -61,6 +61,11 @@ const getIsLoadingWithId = loadingState => (
 const getIsCreatingNew = loadingState => (
     loadingState === LoadingState.CREATING_NEW
 );
+const getIsAnyCreatingNewState = loadingState => (
+    loadingState === LoadingState.FETCHING_NEW_DEFAULT ||
+    loadingState === LoadingState.LOADING_VM_NEW_DEFAULT ||
+    loadingState === LoadingState.CREATING_NEW
+);
 const getIsCreatingCopy = loadingState => (
     loadingState === LoadingState.CREATING_COPY
 );
@@ -464,6 +469,7 @@ export {
     defaultProjectId,
     doneCreatingProject,
     doneUpdatingProject,
+    getIsAnyCreatingNewState,
     getIsCreatingCopy,
     getIsCreatingNew,
     getIsError,
-- 
GitLab