mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-27 09:35:56 -05:00
got addtostudio modal state changes to work, though not updating to server yet
This commit is contained in:
parent
bc0a5f64f7
commit
16190f1147
3 changed files with 152 additions and 24 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
// NOTE: next questions:
|
||||||
|
// * should i make these buttons actual select/checkbox elements?
|
||||||
|
// then i could just submit the form or something, right?
|
||||||
|
|
||||||
const bindAll = require('lodash.bindall');
|
const bindAll = require('lodash.bindall');
|
||||||
const truncate = require('lodash.truncate');
|
const truncate = require('lodash.truncate');
|
||||||
const PropTypes = require('prop-types');
|
const PropTypes = require('prop-types');
|
||||||
|
@ -22,6 +26,7 @@ class AddToStudioModal extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
super(props);
|
super(props);
|
||||||
bindAll(this, [ // NOTE: will need to add and bind callback fn to handle addind and removing studios
|
bindAll(this, [ // NOTE: will need to add and bind callback fn to handle addind and removing studios
|
||||||
|
'handleToggleAdded',
|
||||||
'handleRequestClose',
|
'handleRequestClose',
|
||||||
'handleSubmit'
|
'handleSubmit'
|
||||||
]);
|
]);
|
||||||
|
@ -47,16 +52,95 @@ class AddToStudioModal extends React.Component {
|
||||||
// maybe i should calculate delta here? if studio was
|
// maybe i should calculate delta here? if studio was
|
||||||
// left elsewhere and that status was not changed here,
|
// left elsewhere and that status was not changed here,
|
||||||
// prolly didn't want to be changed!
|
// prolly didn't want to be changed!
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
waiting: false
|
waiting: false,
|
||||||
|
onOrDirty: {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
this.updateOnOrDirty(this.props.projectStudios, this.props.myStudios);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillReceiveProps(nextProps) {
|
||||||
|
this.updateOnOrDirty(nextProps.projectStudios, nextProps.myStudios);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateOnOrDirty(projectStudios, myStudios) {
|
||||||
|
// NOTE: in theory, myStudios could have dropped some studios in
|
||||||
|
// onOrDirty, so we should check all existing onOrDirty and drop
|
||||||
|
// them too; otherwise we might retain a dirty change for a studio
|
||||||
|
// we no longer have permission for. In theory.
|
||||||
|
|
||||||
|
let onOrDirty = this.state.onOrDirty;
|
||||||
|
projectStudios.forEach((studio) => {
|
||||||
|
onOrDirty[studio.id] = {added: true, dirty: false};
|
||||||
|
});
|
||||||
|
console.log(projectStudios);
|
||||||
|
console.log(myStudios);
|
||||||
|
console.log(onOrDirty);
|
||||||
|
this.setState({onOrDirty: Object.assign({}, onOrDirty)});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleToggleAdded(studioId) {
|
||||||
|
let onOrDirty = this.state.onOrDirty;
|
||||||
|
if (studioId in onOrDirty) {
|
||||||
|
if (onOrDirty[studioId].added === true) {
|
||||||
|
if (onOrDirty[studioId].dirty === true) {
|
||||||
|
// let's untrack the status of this studio, so it's
|
||||||
|
// un-added, and un-dirty again
|
||||||
|
delete onOrDirty[studioId];
|
||||||
|
} else { // it started off added, so it's dirty now
|
||||||
|
onOrDirty[studioId].added = false;
|
||||||
|
onOrDirty[studioId].dirty = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (onOrDirty[studioId].dirty === true) {
|
||||||
|
// it was previously set to unadded. so let's set it to
|
||||||
|
// added, and NOT dirty. This is how it started out
|
||||||
|
onOrDirty[studioId].added = true;
|
||||||
|
onOrDirty[studioId].dirty = false;
|
||||||
|
}
|
||||||
|
// should never be added == false AND dirty == false
|
||||||
|
}
|
||||||
|
} else { // was not in onOrDirty; add it as added!
|
||||||
|
onOrDirty[studioId] = {added: true, dirty: true};
|
||||||
|
}
|
||||||
|
this.setState({onOrDirty: Object.assign({}, onOrDirty)});
|
||||||
|
}
|
||||||
|
|
||||||
handleRequestClose () {
|
handleRequestClose () {
|
||||||
|
// NOTE that we do NOT clear onOrDirty, so we don't lose
|
||||||
|
// user's work from a stray click outside the modal...
|
||||||
|
// but maybe this should be different?
|
||||||
this.baseModal.handleRequestClose();
|
this.baseModal.handleRequestClose();
|
||||||
}
|
}
|
||||||
handleSubmit (formData) {
|
handleSubmit (formData) {
|
||||||
|
// NOTE: ignoring formData for now...
|
||||||
this.setState({waiting: true});
|
this.setState({waiting: true});
|
||||||
this.props.onAddToStudio(formData, err => {
|
const onOrDirty = this.state.onOrDirty;
|
||||||
|
const studiosToAdd = Object.keys(onOrDirty)
|
||||||
|
.reduce(function(accumulator, key) {
|
||||||
|
if (onOrDirty[key].dirty === true &&
|
||||||
|
onOrDirty[key].added === true) {
|
||||||
|
accumulator.push(key);
|
||||||
|
}
|
||||||
|
return accumulator;
|
||||||
|
}, []);
|
||||||
|
const studiosToDelete = Object.keys(onOrDirty)
|
||||||
|
.reduce(function(accumulator, key) {
|
||||||
|
if (onOrDirty[key].dirty === true &&
|
||||||
|
onOrDirty[key].added === false) {
|
||||||
|
accumulator.push(key);
|
||||||
|
}
|
||||||
|
return accumulator;
|
||||||
|
}, []);
|
||||||
|
// When this modal is opened, and isOpen becomes true,
|
||||||
|
// onOrDirty should start with a clean slate
|
||||||
|
// NOTE: this doesn't seem to be working
|
||||||
|
this.setState({onOrDirty: {}});
|
||||||
|
this.props.onAddToStudio(studiosToAdd, studiosToDelete, err => {
|
||||||
if (err) log.error(err);
|
if (err) log.error(err);
|
||||||
this.setState({
|
this.setState({
|
||||||
waiting: false
|
waiting: false
|
||||||
|
@ -72,19 +156,26 @@ class AddToStudioModal extends React.Component {
|
||||||
type,
|
type,
|
||||||
...modalProps
|
...modalProps
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
const onOrDirty = this.state.onOrDirty;
|
||||||
const contentLabel = intl.formatMessage({id: `addToStudio.${type}`});
|
const contentLabel = intl.formatMessage({id: `addToStudio.${type}`});
|
||||||
const projectStudioButtons = projectStudios.map((studio, index) => (
|
const studioButtons = myStudios.map((studio, index) => {
|
||||||
<div className="studio-selector-button" key={studio.id}>
|
const isAdded = (studio.id in onOrDirty &&
|
||||||
|
onOrDirty[studio.id].added === true);
|
||||||
|
return (
|
||||||
|
<div className={"studio-selector-button" +
|
||||||
|
(isAdded ? " studio-selector-button-selected" : "")}
|
||||||
|
key={studio.id}
|
||||||
|
onClick={() => this.handleToggleAdded(studio.id)}
|
||||||
|
>
|
||||||
{truncate(studio.title, {'length': 20, 'separator': /[,:\.;]*\s+/})}
|
{truncate(studio.title, {'length': 20, 'separator': /[,:\.;]*\s+/})}
|
||||||
✓
|
<div className={".studio-status-icon" +
|
||||||
|
(isAdded ? " .studio-status-icon-selected" : "")}
|
||||||
|
>
|
||||||
|
{isAdded ? "✓" : "+"}
|
||||||
</div>
|
</div>
|
||||||
));
|
|
||||||
const myStudioButtons = myStudios.map((studio, index) => (
|
|
||||||
<div className="studio-selector-button" key={studio.id}>
|
|
||||||
{truncate(studio.title, {'length': 20, 'separator': /[,:\.;]*\s+/})}
|
|
||||||
+
|
|
||||||
</div>
|
</div>
|
||||||
));
|
);
|
||||||
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
|
@ -105,8 +196,7 @@ class AddToStudioModal extends React.Component {
|
||||||
<div className="studio-list-outer-scrollbox">
|
<div className="studio-list-outer-scrollbox">
|
||||||
<div className="studio-list-inner-scrollbox">
|
<div className="studio-list-inner-scrollbox">
|
||||||
<div className="studio-list-container">
|
<div className="studio-list-container">
|
||||||
{[...projectStudioButtons,
|
{studioButtons}
|
||||||
...myStudioButtons]}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -67,9 +67,11 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-start;
|
justify-content: flex-start;
|
||||||
flex-flow: row wrap;
|
flex-flow: row wrap;
|
||||||
min-height: 30rem; /* NOTE: remove this, this is just to force scrolling */
|
|
||||||
padding: 1rem 3rem;
|
padding: 1rem 3rem;
|
||||||
}
|
}
|
||||||
|
/* NOTE: force scrolling: add to above:
|
||||||
|
min-height: 30rem;
|
||||||
|
*/
|
||||||
|
|
||||||
.studio-selector-button {
|
.studio-selector-button {
|
||||||
background-color: $ui-white;
|
background-color: $ui-white;
|
||||||
|
@ -82,3 +84,25 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
width: 40%;
|
width: 40%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.studio-selector-button-selected {
|
||||||
|
background-color: $ui-green;
|
||||||
|
color: $ui-white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.studio-status-icon {
|
||||||
|
background-color: $ui-blue;
|
||||||
|
color: $type-gray;
|
||||||
|
font-weight: 800;
|
||||||
|
height: 1.5rem;
|
||||||
|
margin: 0.5rem 0.5rem;
|
||||||
|
padding: 0.5rem 0.5rem;
|
||||||
|
border-radius: 0.75rem;
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 1.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.studio-status-icon-selected {
|
||||||
|
background-color: $ui-green;
|
||||||
|
color: $ui-white;
|
||||||
|
}
|
||||||
|
|
|
@ -43,6 +43,16 @@ class PreviewPresentation extends React.Component {
|
||||||
reportOpen: false
|
reportOpen: false
|
||||||
};
|
};
|
||||||
this.mockedMyStudios = [
|
this.mockedMyStudios = [
|
||||||
|
{
|
||||||
|
id: 1702295,
|
||||||
|
description: "Real open studio",
|
||||||
|
history: {created: "2015-11-15T00:24:35.000Z",
|
||||||
|
modified: "2018-05-01T00:14:48.000Z"},
|
||||||
|
image: "https://cdn2.scratch.mit.edu/get_image/gallery/1702295_170x100.png",
|
||||||
|
owner: 10689298,
|
||||||
|
stats: {followers: 0},
|
||||||
|
title: "Real open studio"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: 0,
|
id: 0,
|
||||||
description: "Wow, studio A rocks",
|
description: "Wow, studio A rocks",
|
||||||
|
@ -84,13 +94,17 @@ class PreviewPresentation extends React.Component {
|
||||||
handleAddToStudioClose () {
|
handleAddToStudioClose () {
|
||||||
this.setState({addToStudioOpen: false});
|
this.setState({addToStudioOpen: false});
|
||||||
}
|
}
|
||||||
handleAddToStudioSubmit (formData, callback) {
|
handleAddToStudioSubmit (studiosToAdd, studiosToDelete, callback) {
|
||||||
const data = {
|
console.log('studios to add: ');
|
||||||
...formData,
|
console.log(studiosToAdd);
|
||||||
id: this.props.projectId,
|
console.log('studios to delete: ');
|
||||||
username: this.props.user.username
|
console.log(studiosToDelete);
|
||||||
};
|
// const data = {
|
||||||
console.log('submit addToStudio data', data); // eslint-disable-line no-console
|
// ...formData,
|
||||||
|
// id: this.props.projectId,
|
||||||
|
// username: this.props.user.username
|
||||||
|
// };
|
||||||
|
//console.log('submit addToStudio data', data); // eslint-disable-line no-console
|
||||||
// TODO: pass error to modal via callback.
|
// TODO: pass error to modal via callback.
|
||||||
callback();
|
callback();
|
||||||
this.setState({addToStudioOpen: false});
|
this.setState({addToStudioOpen: false});
|
||||||
|
|
Loading…
Reference in a new issue