mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-23 07:38:07 -05:00
Revert "Revert "Add to studio modal should only show studios user can actually change""
This commit is contained in:
parent
ecad945ead
commit
4d3e46e40b
7 changed files with 83 additions and 19 deletions
|
@ -134,6 +134,14 @@
|
|||
color: $type-gray;
|
||||
}
|
||||
|
||||
.studio-selector-button-enabled {
|
||||
pointer-events: auto;
|
||||
}
|
||||
|
||||
.studio-selector-button-disabled {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.studio-status-icon {
|
||||
position: absolute;
|
||||
right: .625rem;
|
||||
|
|
|
@ -26,6 +26,8 @@ const AddToStudioModalPresentation = ({
|
|||
const contentLabel = intl.formatMessage({id: 'addToStudio.title'});
|
||||
const studioButtons = studios.map(studio => (
|
||||
<StudioButton
|
||||
canAdd={studio.canAdd}
|
||||
canRemove={studio.canRemove}
|
||||
hasRequestOutstanding={studio.hasRequestOutstanding}
|
||||
id={studio.id}
|
||||
includesProject={studio.includesProject}
|
||||
|
|
|
@ -8,6 +8,8 @@ const AnimateHOC = require('./animate-hoc.jsx');
|
|||
require('./modal.scss');
|
||||
|
||||
const StudioButton = ({
|
||||
canAdd,
|
||||
canRemove,
|
||||
hasRequestOutstanding,
|
||||
includesProject,
|
||||
title,
|
||||
|
@ -38,9 +40,12 @@ const StudioButton = ({
|
|||
<div
|
||||
className={classNames(
|
||||
'studio-selector-button',
|
||||
{'studio-selector-button-waiting': hasRequestOutstanding},
|
||||
{'studio-selector-button-selected':
|
||||
includesProject && !hasRequestOutstanding}
|
||||
{
|
||||
'studio-selector-button-waiting': hasRequestOutstanding,
|
||||
'studio-selector-button-selected': includesProject && !hasRequestOutstanding,
|
||||
'studio-selector-button-enabled': includesProject ? canRemove : canAdd,
|
||||
'studio-selector-button-disabled': includesProject ? !canRemove : !canAdd
|
||||
}
|
||||
)}
|
||||
onClick={onClick}
|
||||
>
|
||||
|
@ -69,6 +74,8 @@ const StudioButton = ({
|
|||
};
|
||||
|
||||
StudioButton.propTypes = {
|
||||
canAdd: PropTypes.bool,
|
||||
canRemove: PropTypes.bool,
|
||||
hasRequestOutstanding: PropTypes.bool,
|
||||
includesProject: PropTypes.bool,
|
||||
onClick: PropTypes.func,
|
||||
|
|
|
@ -3,26 +3,59 @@ const connect = require('react-redux').connect;
|
|||
const previewActions = require('../../redux/preview.js');
|
||||
const AddToStudioModal = require('../../components/modal/addtostudio/container.jsx');
|
||||
|
||||
// user can add project to studio if studio is open to all, or user is a curator of studio
|
||||
const canAdd = (studio, userIsCurator) => (
|
||||
studio.open_to_all || userIsCurator
|
||||
);
|
||||
|
||||
// user can remove project from studio if user owns project or is admin or user is a curator of studio
|
||||
const canRemove = (userOwnsProject, isAdmin, userIsCurator) => (
|
||||
userOwnsProject || isAdmin || userIsCurator
|
||||
);
|
||||
|
||||
// include a given studio in the list to show in add to studio modal.
|
||||
// only include it if user has the ability to remove the project from this studio.
|
||||
const showStudio = (studio, currentStudioIds, userIsCurator, userOwnsProject, isAdmin) => {
|
||||
const includesProject = (currentStudioIds.indexOf(studio.id) !== -1);
|
||||
const canAddToThisStudio = canAdd(studio, userIsCurator);
|
||||
const canRemoveFromThisStudio = canRemove(userOwnsProject, isAdmin, userIsCurator);
|
||||
if (canRemoveFromThisStudio) { // power to remove matches set of studios we want to show
|
||||
// include the current status of whether the project is in the studio,
|
||||
// and what privileges the user has to change that.
|
||||
const consolidatedStudio = Object.assign({}, studio, {
|
||||
includesProject: includesProject,
|
||||
canAdd: canAddToThisStudio,
|
||||
canRemove: canRemoveFromThisStudio
|
||||
});
|
||||
return consolidatedStudio;
|
||||
}
|
||||
return null;
|
||||
};
|
||||
|
||||
// Build consolidated curatedStudios object from all studio info.
|
||||
// We add flags to indicate whether the project is currently in the studio,
|
||||
// and the status of requests to join/leave studios.
|
||||
const consolidateStudiosInfo = (curatedStudios, projectStudios, currentStudioIds, studioRequests) => {
|
||||
const consolidateStudiosInfo = (userOwnsProject, isAdmin, curatedStudios, projectStudios,
|
||||
currentStudioIds, studioRequests) => {
|
||||
|
||||
const consolidatedStudios = [];
|
||||
|
||||
// for each studio the project is in, include it if user can add or remove project from it.
|
||||
projectStudios.forEach(projectStudio => {
|
||||
const includesProject = (currentStudioIds.indexOf(projectStudio.id) !== -1);
|
||||
const consolidatedStudio =
|
||||
Object.assign({}, projectStudio, {includesProject: includesProject});
|
||||
consolidatedStudios.push(consolidatedStudio);
|
||||
const userIsCurator = curatedStudios.some(curatedStudio => (curatedStudio.id === projectStudio.id));
|
||||
const studioToShow = showStudio(projectStudio, currentStudioIds, userIsCurator, userOwnsProject, isAdmin);
|
||||
if (studioToShow) {
|
||||
consolidatedStudios.push(studioToShow);
|
||||
}
|
||||
});
|
||||
|
||||
// copy the curated studios that project is not in
|
||||
// for each curated studio, if it was not already added to consolidatedStudios above, add it now.
|
||||
curatedStudios.forEach(curatedStudio => {
|
||||
if (!projectStudios.some(projectStudio => (projectStudio.id === curatedStudio.id))) {
|
||||
const includesProject = (currentStudioIds.indexOf(curatedStudio.id) !== -1);
|
||||
const consolidatedStudio =
|
||||
Object.assign({}, curatedStudio, {includesProject: includesProject});
|
||||
consolidatedStudios.push(consolidatedStudio);
|
||||
const studioToShow = showStudio(curatedStudio, currentStudioIds, true, userOwnsProject, isAdmin);
|
||||
if (studioToShow) {
|
||||
consolidatedStudios.push(studioToShow);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -32,16 +65,16 @@ const consolidateStudiosInfo = (curatedStudios, projectStudios, currentStudioIds
|
|||
const id = consolidatedStudio.id;
|
||||
consolidatedStudio.hasRequestOutstanding =
|
||||
((id in studioRequests) &&
|
||||
(studioRequests[id] === previewActions.Status.FETCHING));
|
||||
(studioRequests[id] === previewActions.Status.FETCHING));
|
||||
});
|
||||
|
||||
return consolidatedStudios;
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
studios: consolidateStudiosInfo(state.preview.curatedStudios,
|
||||
state.preview.projectStudios, state.preview.currentStudioIds,
|
||||
state.preview.status.studioRequests)
|
||||
const mapStateToProps = (state, ownProps) => ({
|
||||
studios: consolidateStudiosInfo(ownProps.userOwnsProject, ownProps.isAdmin,
|
||||
state.preview.curatedStudios, state.preview.projectStudios,
|
||||
state.preview.currentStudioIds, state.preview.status.studioRequests)
|
||||
});
|
||||
|
||||
const mapDispatchToProps = () => ({});
|
||||
|
|
|
@ -67,6 +67,7 @@ const PreviewPresentation = ({
|
|||
faved,
|
||||
favoriteCount,
|
||||
intl,
|
||||
isAdmin,
|
||||
isFullScreen,
|
||||
isLoggedIn,
|
||||
isNewScratcher,
|
||||
|
@ -122,6 +123,7 @@ const PreviewPresentation = ({
|
|||
showAdminPanel,
|
||||
showModInfo,
|
||||
singleCommentId,
|
||||
userOwnsProject,
|
||||
visibilityInfo
|
||||
}) => {
|
||||
const shareDate = ((projectInfo.history && projectInfo.history.shared)) ? projectInfo.history.shared : '';
|
||||
|
@ -344,9 +346,11 @@ const PreviewPresentation = ({
|
|||
<Subactions
|
||||
addToStudioOpen={addToStudioOpen}
|
||||
canReport={canReport}
|
||||
isAdmin={isAdmin}
|
||||
projectInfo={projectInfo}
|
||||
reportOpen={reportOpen}
|
||||
shareDate={shareDate}
|
||||
userOwnsProject={userOwnsProject}
|
||||
onAddToStudioClicked={onAddToStudioClicked}
|
||||
onAddToStudioClosed={onAddToStudioClosed}
|
||||
onCopyProjectLink={onCopyProjectLink}
|
||||
|
@ -469,9 +473,11 @@ const PreviewPresentation = ({
|
|||
addToStudioOpen={addToStudioOpen}
|
||||
canAddToStudio={canAddToStudio}
|
||||
canReport={canReport}
|
||||
isAdmin={isAdmin}
|
||||
projectInfo={projectInfo}
|
||||
reportOpen={reportOpen}
|
||||
shareDate={shareDate}
|
||||
userOwnsProject={userOwnsProject}
|
||||
onAddToStudioClicked={onAddToStudioClicked}
|
||||
onAddToStudioClosed={onAddToStudioClosed}
|
||||
onCopyProjectLink={onCopyProjectLink}
|
||||
|
@ -626,6 +632,7 @@ PreviewPresentation.propTypes = {
|
|||
faved: PropTypes.bool,
|
||||
favoriteCount: PropTypes.number,
|
||||
intl: intlShape,
|
||||
isAdmin: PropTypes.bool,
|
||||
isFullScreen: PropTypes.bool,
|
||||
isLoggedIn: PropTypes.bool,
|
||||
isNewScratcher: PropTypes.bool,
|
||||
|
@ -684,6 +691,7 @@ PreviewPresentation.propTypes = {
|
|||
showModInfo: PropTypes.bool,
|
||||
showUsernameBlockAlert: PropTypes.bool,
|
||||
singleCommentId: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),
|
||||
userOwnsProject: PropTypes.bool,
|
||||
visibilityInfo: PropTypes.shape({
|
||||
censored: PropTypes.bool,
|
||||
message: PropTypes.string,
|
||||
|
|
|
@ -641,6 +641,7 @@ class Preview extends React.Component {
|
|||
extensions={this.state.extensions}
|
||||
faved={this.state.clientFaved}
|
||||
favoriteCount={this.state.favoriteCount}
|
||||
isAdmin={this.props.isAdmin}
|
||||
isFullScreen={this.props.fullScreen}
|
||||
isLoggedIn={this.props.isLoggedIn}
|
||||
isNewScratcher={this.props.isNewScratcher}
|
||||
|
@ -668,6 +669,7 @@ class Preview extends React.Component {
|
|||
showModInfo={this.props.isAdmin}
|
||||
showUsernameBlockAlert={this.state.showUsernameBlockAlert}
|
||||
singleCommentId={this.state.singleCommentId}
|
||||
userOwnsProject={this.props.userOwnsProject}
|
||||
visibilityInfo={this.props.visibilityInfo}
|
||||
onAddComment={this.handleAddComment}
|
||||
onAddToStudioClicked={this.handleAddToStudioClick}
|
||||
|
|
|
@ -39,7 +39,9 @@ const Subactions = props => (
|
|||
{props.addToStudioOpen && (
|
||||
<AddToStudioModal
|
||||
isOpen
|
||||
isAdmin={props.isAdmin}
|
||||
key="add-to-studio-modal"
|
||||
userOwnsProject={props.userOwnsProject}
|
||||
onRequestClose={props.onAddToStudioClosed}
|
||||
onToggleStudio={props.onToggleStudio}
|
||||
/>
|
||||
|
@ -80,6 +82,7 @@ Subactions.propTypes = {
|
|||
addToStudioOpen: PropTypes.bool,
|
||||
canAddToStudio: PropTypes.bool,
|
||||
canReport: PropTypes.bool,
|
||||
isAdmin: PropTypes.bool,
|
||||
onAddToStudioClicked: PropTypes.func,
|
||||
onAddToStudioClosed: PropTypes.func,
|
||||
onCopyProjectLink: PropTypes.func,
|
||||
|
@ -88,7 +91,8 @@ Subactions.propTypes = {
|
|||
onReportSubmit: PropTypes.func.isRequired,
|
||||
onToggleStudio: PropTypes.func,
|
||||
reportOpen: PropTypes.bool,
|
||||
shareDate: PropTypes.string
|
||||
shareDate: PropTypes.string,
|
||||
userOwnsProject: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = Subactions;
|
||||
|
|
Loading…
Reference in a new issue