Skip to content

Commit

Permalink
feat(components): component selecting
Browse files Browse the repository at this point in the history
  • Loading branch information
patrickocoffeyo committed Jul 18, 2018
1 parent 234b140 commit 402c4d3
Show file tree
Hide file tree
Showing 17 changed files with 271 additions and 11 deletions.
27 changes: 27 additions & 0 deletions src/actions/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
/**
* @file component.js
* Exports actions related to components.
*/

import { put, takeLatest } from 'redux-saga/effects';

import { COMPONENT_SELECT } from '../constants';

/**
* Sets the currently selected component.
*
* @param {object} payload - Payload for this saga action.
* @param {string} payload.id - ID of the component that should be selected.
*/
export function* componentSelect({ id }) {
yield put({
type: `${COMPONENT_SELECT}_SUCCESS`,
payload: {
id
}
});
}

export function* watchComponentActions() {
yield takeLatest(COMPONENT_SELECT, componentSelect);
}
4 changes: 3 additions & 1 deletion src/actions/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ import { all } from 'redux-saga/effects';
import { watchUserActions } from './user';
import { watchExperiencesActions } from './experiences';
import { watchOpenExperienceActions } from './openExperience';
import { watchComponentActions } from './component';

export default function* rootSaga() {
yield all([
watchUserActions(),
watchExperiencesActions(),
watchOpenExperienceActions()
watchOpenExperienceActions(),
watchComponentActions()
]);
}
48 changes: 48 additions & 0 deletions src/aframe/components/isEditable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/**
* @file isExitable.js
* AFrame component that allows for components to be selected for editing.
*/

/* globals AFRAME */

import { COMPONENT_SELECT, MODE_COMPONENT_SELECTING } from '../../constants';
import connectRedux from '../utils/connectRedux';
import connectRouter from '../utils/connectRouter';

const isEditable = {
multiple: true,
clickHandler() {
const id = this.el.getAttribute('id');
const { dispatch } = this.props;
const {
match: {
params: { editorMode }
}
} = this.router;

if (id && editorMode === MODE_COMPONENT_SELECTING) {
dispatch({
type: COMPONENT_SELECT,
id
});
}
},
init() {
this.el.addEventListener('click', this.clickHandler.bind(this));
},
remove() {
this.el.removeEventListener('click', this.clickHandler.bind(this));
}
};

AFRAME.registerComponent(
'is-editable',
connectRedux(state => ({
experience: state.openExperience.item
}))(
connectRouter(
isEditable,
'/experience/vreditor/:experienceSlug/:sceneSlug/:editorMode?'
)
)
);
1 change: 1 addition & 0 deletions src/aframe/components/spawnDialogs.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ const spawnDialogs = {
const e = document.createElement('a-entity');
e.setAttribute('id', component.id);
e.setAttribute('look-at', '#camera');
e.setAttribute('is-editable', true);
e.setAttribute('position', { x, y, z });
e.setAttribute('dialog-popup', {
title,
Expand Down
1 change: 1 addition & 0 deletions src/aframe/entities/scene.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ require('../components/spawnSky');
require('../components/spawnLinks');
require('../components/spawnDialogs');
require('../components/navLink');
require('../components/isEditable');

export default () => (
<a-scene
Expand Down
19 changes: 19 additions & 0 deletions src/components/ComponentForm/ComponentForm.container.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
/**
* @file ComponentForm.container.js
* Exports a redux-connected ComponentForm component.
*/

import { connect } from 'react-redux';

import ComponentForm from './ComponentForm';

const mapDispatchToProps = dispatch => ({
dispatch
});

const mapState = ({ user, openExperience }) => ({
user,
experience: openExperience
});

export default connect(mapState, mapDispatchToProps)(ComponentForm);
24 changes: 24 additions & 0 deletions src/components/ComponentForm/ComponentForm.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/**
* @file ComponentForm.js
* Exports a component that allows users to operate on scene components.
*/

import React from 'react';
import PropTypes from 'prop-types';
import { withFormik } from 'formik';
import { withStyles } from '@material-ui/core';

import ComponentFormStyles from './ComponentForm.style';

const ComponentForm = ({ id }) => <form>{id}</form>;

ComponentForm.propTypes = {
id: PropTypes.string.isRequired
};

const FormikComponentForm = withFormik({
displayName: 'ComponentForm',
enableReinitialize: true
})(ComponentForm);

export default withStyles(ComponentFormStyles)(FormikComponentForm);
6 changes: 6 additions & 0 deletions src/components/ComponentForm/ComponentForm.style.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @file ComponentForm.style.js
* Exports ComponentForm component styles.
*/

export default () => ({});
4 changes: 3 additions & 1 deletion src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import App from './App/App';
import LoginForm from './LoginForm/LoginForm.container';
import ExperienceForm from './ExperienceForm/ExperienceForm.container';
import SceneForm from './SceneForm/SceneForm.container';
import ComponentForm from './ComponentForm/ComponentForm.container';
import Loading from './Loading/Loading';
import Message from './Message/Message';
import SceneCards from './SceneCards/SceneCards.container';
Expand All @@ -20,5 +21,6 @@ export {
Message,
SceneCards,
ToolsMenu,
SceneForm
SceneForm,
ComponentForm
};
6 changes: 6 additions & 0 deletions src/constants/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/**
* @file component.js
* Exports component-related constants.
*/

export const COMPONENT_SELECT = 'COMPONENT_SELECT';
1 change: 1 addition & 0 deletions src/constants/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from './modes';
export * from './form';
export * from './experiences';
export * from './openExperience';
export * from './component';
3 changes: 2 additions & 1 deletion src/pages/VREditor/VREditor.container.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,9 @@ const mapDispatchToProps = dispatch => ({
dispatch
});

const mapState = ({ openExperience, user }) => ({
const mapState = ({ openExperience, user, component }) => ({
experience: openExperience,
component,
user
});

Expand Down
87 changes: 80 additions & 7 deletions src/pages/VREditor/VREditor.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,26 @@
* Exports a React component that render's EditVR's VREditor interface.
*/

import React, { Component } from 'react';
import React, { Component, Fragment } from 'react';
import PropTypes from 'prop-types';
import { Redirect, Link } from 'react-router-dom';
import { withStyles, Grid, Typography, Button } from '@material-ui/core';
import { AddBox } from '@material-ui/icons';
import { AddBox, OpenWith, TouchApp } from '@material-ui/icons';

import { SceneCards, SceneForm, ToolsMenu } from '../../components';
import {
SceneCards,
SceneForm,
ToolsMenu,
ComponentForm
} from '../../components';
import {
OPEN_EXPERIENCE_FETCH_FOR_USER,
MODE_SCENE_CREATE,
MODE_SCENE_EDIT
MODE_SCENE_EDIT,
MODE_COMPONENT_SELECTING
} from '../../constants';
import parseSceneFromExperience from '../../lib/parseSceneFromExperience';
import parseComponentFromScene from '../../lib/parseComponentFromScene';
import Scene from '../../aframe/entities/scene';
import { VREditorLayout } from '../../layouts';
import VREditorStyles from './VREditor.style';
Expand Down Expand Up @@ -46,14 +53,20 @@ class VREditor extends Component {
experienceSlug: PropTypes.string.isRequired,
editorMode: PropTypes.string
}).isRequired
}).isRequired
}).isRequired,
component: PropTypes.shape({
id: PropTypes.string
})
};

static defaultProps = {
experience: {
item: {
title: false
}
},
component: {
id: null
}
};

Expand Down Expand Up @@ -84,6 +97,7 @@ class VREditor extends Component {
params: { sceneSlug, editorMode }
},
experience: { item: experience },
component: { id: component },
classes
} = this.props;

Expand All @@ -98,6 +112,17 @@ class VREditor extends Component {
field_scenes: scenes
} = experience;

let scene = null;
if (sceneSlug) {
scene = parseSceneFromExperience(experience, sceneSlug);
}

// TODO: The logic for determining what to render in the main and right
// columns should likely be extracted from this file and placed into another
// component, just to make this component less cluttered. This isn't a
// difficult thing to do, and this component isn't yet too messy, so for now
// holding the logic in here will do.

// The main column defaults to showing instructions to create or select a scene
let mainColumn = <Scene />;

Expand All @@ -113,7 +138,6 @@ class VREditor extends Component {

// If the editor mode is scene edit, return the scene form.
if (editorMode === MODE_SCENE_EDIT) {
const scene = parseSceneFromExperience(experience, sceneSlug);
if (scene) {
mainColumn = (
<div className={classes.mainColumn}>
Expand All @@ -136,6 +160,55 @@ class VREditor extends Component {
);
}

// Default right column to a preview message.
let rightColumn = (
<Fragment>
<Typography variant="title" className={classes.columnRightTitle}>
Previewing
<OpenWith className={classes.columnRightIcon} />
</Typography>
<Typography>
You are currently previewing your scene. You can use your mouse to
grab the scene area, and drag it around to view different portions of
your scene.
</Typography>
</Fragment>
);

// If the current mode is selecting, but no component has been selected,
// show selection documentation in the right column.
if (editorMode === MODE_COMPONENT_SELECTING && !component) {
rightColumn = (
<Fragment>
<Typography variant="title" className={classes.columnRightTitle}>
Selecting
<TouchApp className={classes.columnRightIcon} />
</Typography>
<Typography>
You are currently in the selecting mode. You can use your mouse to
select components. Upon being selected, a component will be opened
in this pane and you can edit its properties.
</Typography>
</Fragment>
);
}

// If the current mode is selecting, and a component has been selected,
// show the component editorial form.
if (editorMode === MODE_COMPONENT_SELECTING && component) {
const selected = parseComponentFromScene(scene, component);
if (selected) {
rightColumn = (
<Fragment>
<Typography variant="title" className={classes.columnRightTitle}>
Edit {selected.title}
</Typography>
<ComponentForm id={component} />
</Fragment>
);
}
}

return (
<VREditorLayout
title={experience.title ? `Editing ${title} Experience` : 'Loading...'}
Expand Down Expand Up @@ -173,7 +246,7 @@ class VREditor extends Component {
</Grid>
</Grid>
}
rightAside="Right Sidebar"
rightAside={<div className={classes.columnRight}>{rightColumn}</div>}
>
{mainColumn}
</VREditorLayout>
Expand Down
8 changes: 8 additions & 0 deletions src/pages/VREditor/VREditor.style.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,14 @@ export default theme => ({
padding: theme.spacing.unit * 2,
userSelect: 'none'
},
columnRightTitle: {
marginTop: theme.spacing.unit * 2,
marginBottom: theme.spacing.unit * 2
},
columnRightIcon: {
marginLeft: 6,
marginBottom: -6
},
mainColumn: {
padding: theme.spacing.unit * 4
},
Expand Down
2 changes: 1 addition & 1 deletion src/pages/VREditor/__snapshots__/VREditor.test.js.snap
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`<VREditor /> Matches its snapshot 1`] = `"<div class=\\"MuiGrid-container-11 VREditorLayout-wrapper-6\\" id=\\"editor__wrapper\\" align=\\"stretch\\"><div></div><header class=\\"MuiPaper-root-110 MuiPaper-elevation4-116 MuiAppBar-root-102 MuiAppBar-positionFixed-103 MuiAppBar-colorPrimary-108 mui-fixed VREditorLayout-appBar-9\\"><div class=\\"MuiToolbar-root-137 MuiToolbar-gutters-138\\"><a tabindex=\\"0\\" class=\\"MuiButtonBase-root-145 MuiIconButton-root-139 MuiIconButton-colorInherit-140\\" role=\\"button\\" aria-label=\\"Back to Dashboard\\" href=\\"/dashboard\\"><span class=\\"MuiIconButton-label-144\\"><svg class=\\"MuiSvgIcon-root-148\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\"><g><path d=\\"M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z\\"></path></g></svg></span><span class=\\"MuiTouchRipple-root-154\\"></span></a><img src=\\"editvr-logo.svg\\" alt=\\"EditVR logo\\" class=\\"VREditorLayout-logo-10\\"><h2 class=\\"MuiTypography-root-161 MuiTypography-title-167\\">Editing test Experience</h2></div></header><div class=\\"MuiGrid-item-12 MuiGrid-grid-xs-3-40 VREditorLayout-aside-7\\" id=\\"VREditorLayout--left\\"><div class=\\"MuiGrid-container-11\\" align=\\"stretch\\"><div class=\\"MuiGrid-item-12 MuiGrid-grid-xs-3-40 VREditor-columnLeft-2\\" id=\\"column--left_aside\\"><h2 class=\\"MuiTypography-root-161 MuiTypography-title-167\\">Tools</h2><p class=\\"MuiTypography-root-161 MuiTypography-body1-170\\">You must create or select an existing scene before being able to use scene editing tools.</p></div><div class=\\"MuiGrid-item-12 MuiGrid-grid-xs-9-46 VREditor-columnRight-1\\" id=\\"column--left_aside\\"><h2 class=\\"MuiTypography-root-161 MuiTypography-title-167\\">Scenes</h2><div></div></div></div></div><div class=\\"MuiGrid-item-12 MuiGrid-grid-xs-6-43 VREditorLayout-middle-8\\" id=\\"VREditorLayout--middle\\"><div class=\\"VREditor-mainColumn-3\\"><h1 class=\\"MuiTypography-root-161 MuiTypography-headline-166\\">Select or create a scene to continue.</h1></div></div><div class=\\"MuiGrid-item-12 MuiGrid-grid-xs-3-40 VREditorLayout-aside-7\\" id=\\"VREditorLayout--right\\">Right Sidebar</div></div>"`;
exports[`<VREditor /> Matches its snapshot 1`] = `"<div class=\\"MuiGrid-container-13 VREditorLayout-wrapper-8\\" id=\\"editor__wrapper\\" align=\\"stretch\\"><div></div><header class=\\"MuiPaper-root-112 MuiPaper-elevation4-118 MuiAppBar-root-104 MuiAppBar-positionFixed-105 MuiAppBar-colorPrimary-110 mui-fixed VREditorLayout-appBar-11\\"><div class=\\"MuiToolbar-root-139 MuiToolbar-gutters-140\\"><a tabindex=\\"0\\" class=\\"MuiButtonBase-root-147 MuiIconButton-root-141 MuiIconButton-colorInherit-142\\" role=\\"button\\" aria-label=\\"Back to Dashboard\\" href=\\"/dashboard\\"><span class=\\"MuiIconButton-label-146\\"><svg class=\\"MuiSvgIcon-root-150\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\"><g><path d=\\"M15.41 16.09l-4.58-4.59 4.58-4.59L14 5.5l-6 6 6 6z\\"></path></g></svg></span><span class=\\"MuiTouchRipple-root-156\\"></span></a><img src=\\"editvr-logo.svg\\" alt=\\"EditVR logo\\" class=\\"VREditorLayout-logo-12\\"><h2 class=\\"MuiTypography-root-163 MuiTypography-title-169\\">Editing test Experience</h2></div></header><div class=\\"MuiGrid-item-14 MuiGrid-grid-xs-3-42 VREditorLayout-aside-9\\" id=\\"VREditorLayout--left\\"><div class=\\"MuiGrid-container-13\\" align=\\"stretch\\"><div class=\\"MuiGrid-item-14 MuiGrid-grid-xs-3-42 VREditor-columnLeft-2\\" id=\\"column--left_aside\\"><h2 class=\\"MuiTypography-root-163 MuiTypography-title-169\\">Tools</h2><p class=\\"MuiTypography-root-163 MuiTypography-body1-172\\">You must create or select an existing scene before being able to use scene editing tools.</p></div><div class=\\"MuiGrid-item-14 MuiGrid-grid-xs-9-48 VREditor-columnRight-1\\" id=\\"column--left_aside\\"><h2 class=\\"MuiTypography-root-163 MuiTypography-title-169\\">Scenes</h2><div></div></div></div></div><div class=\\"MuiGrid-item-14 MuiGrid-grid-xs-6-45 VREditorLayout-middle-10\\" id=\\"VREditorLayout--middle\\"><div class=\\"VREditor-mainColumn-5\\"><h1 class=\\"MuiTypography-root-163 MuiTypography-headline-168\\">Select or create a scene to continue.</h1></div></div><div class=\\"MuiGrid-item-14 MuiGrid-grid-xs-3-42 VREditorLayout-aside-9\\" id=\\"VREditorLayout--right\\"><div class=\\"VREditor-columnRight-1\\"><h2 class=\\"MuiTypography-root-163 MuiTypography-title-169 VREditor-columnRightTitle-3\\">Previewing<svg class=\\"MuiSvgIcon-root-150 VREditor-columnRightIcon-4\\" focusable=\\"false\\" viewBox=\\"0 0 24 24\\" aria-hidden=\\"true\\"><g><path d=\\"M10 9h4V6h3l-5-5-5 5h3v3zm-1 1H6V7l-5 5 5 5v-3h3v-4zm14 2l-5-5v3h-3v4h3v3l5-5zm-9 3h-4v3H7l5 5 5-5h-3v-3z\\"></path></g></svg></h2><p class=\\"MuiTypography-root-163 MuiTypography-body1-172\\">You are currently previewing your scene. You can use your mouse to grab the scene area, and drag it around to view different portions of your scene.</p></div></div></div>"`;
Loading

0 comments on commit 402c4d3

Please sign in to comment.