mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-23 23:57:55 -05:00
Merge pull request #5573 from seotts/muted-add-proj-via-proj-page
Muted users can’t add projects to studio via project page
This commit is contained in:
commit
d468072552
6 changed files with 149 additions and 84 deletions
|
@ -145,6 +145,8 @@ module.exports.selectProjectCommentsGloballyEnabled = state =>
|
|||
module.exports.selectMuteStatus = state => get(state, ['session', 'session', 'permissions', 'mute_status'],
|
||||
{muteExpiresAt: 0, offenses: [], showWarning: false});
|
||||
module.exports.selectIsMuted = state => (module.exports.selectMuteStatus(state).muteExpiresAt || 0) * 1000 > Date.now();
|
||||
module.exports.selectNewStudiosLaunched = state => get(state, ['session', 'session', 'flags', 'new_studios_launched'],
|
||||
false);
|
||||
|
||||
module.exports.selectHasFetchedSession = state => state.session.status === module.exports.Status.FETCHED;
|
||||
|
||||
|
|
|
@ -46,5 +46,6 @@
|
|||
"project.cloudVariables": "Cloud Variables",
|
||||
"project.cloudDataLink": "See Data",
|
||||
"project.usernameBlockAlert": "This project can detect who is using it, through the \"username\" block. To hide your identity, sign out before using the project.",
|
||||
"project.inappropriateUpdate": "Hmm...the bad word detector thinks there is a problem with your text. Please change it and remember to be respectful."
|
||||
"project.inappropriateUpdate": "Hmm...the bad word detector thinks there is a problem with your text. Please change it and remember to be respectful.",
|
||||
"project.mutedAddToStudio": "You will be able to add to studios again {inDuration}."
|
||||
}
|
||||
|
|
|
@ -160,7 +160,6 @@ $stage-width: 480px;
|
|||
margin-top: $arrow-border-width;
|
||||
border: 1px solid $active-gray;
|
||||
border-radius: 5px;
|
||||
background-color: $ui-orange;
|
||||
padding: 1rem;
|
||||
max-width: 18.75rem;
|
||||
min-height: 1rem;
|
||||
|
@ -185,7 +184,6 @@ $stage-width: 480px;
|
|||
border-left: 1px solid $active-gray;
|
||||
border-radius: 5px;
|
||||
|
||||
background-color: $ui-orange;
|
||||
width: $arrow-border-width;
|
||||
height: $arrow-border-width;
|
||||
|
||||
|
|
|
@ -8,19 +8,48 @@ const Button = require('../../components/forms/button.jsx');
|
|||
const AddToStudioModal = require('./add-to-studio.jsx');
|
||||
const SocialModal = require('../../components/modal/social/container.jsx');
|
||||
const ReportModal = require('../../components/modal/report/modal.jsx');
|
||||
const {connect} = require('react-redux');
|
||||
const {selectShowProjectMuteError} = require('../../redux/studio-permissions.js');
|
||||
const {useState} = require('react');
|
||||
const projectShape = require('./projectshape.jsx').projectShape;
|
||||
|
||||
import {selectNewStudiosLaunched} from '../../redux/session.js';
|
||||
import StudioMuteEditMessage from '../studio/studio-mute-edit-message.jsx';
|
||||
|
||||
require('./subactions.scss');
|
||||
|
||||
const Subactions = props => (
|
||||
const Subactions = ({
|
||||
addToStudioOpen,
|
||||
canAddToStudio,
|
||||
canReport,
|
||||
isAdmin,
|
||||
isShared,
|
||||
onAddToStudioClicked,
|
||||
onAddToStudioClosed,
|
||||
onReportClicked,
|
||||
onReportClose,
|
||||
onReportSubmit,
|
||||
onSocialClicked,
|
||||
onSocialClosed,
|
||||
onToggleStudio,
|
||||
projectInfo,
|
||||
reportOpen,
|
||||
shareDate,
|
||||
showAddToStudioMuteError,
|
||||
socialOpen,
|
||||
userOwnsProject
|
||||
}) => {
|
||||
const [showMuteMessage, setShowMuteMessage] = useState(false);
|
||||
|
||||
return (
|
||||
<FlexRow className="subactions">
|
||||
<div className="share-date">
|
||||
<div className="copyleft">©</div>
|
||||
{' '}
|
||||
{/* eslint-disable react/jsx-sort-props */}
|
||||
{props.shareDate ? (
|
||||
{shareDate ? (
|
||||
<FormattedDate
|
||||
value={Date.parse(props.shareDate)}
|
||||
value={Date.parse(shareDate)}
|
||||
day="2-digit"
|
||||
month="short"
|
||||
year="numeric"
|
||||
|
@ -29,69 +58,83 @@ const Subactions = props => (
|
|||
{/* eslint-enable react/jsx-sort-props */}
|
||||
</div>
|
||||
<FlexRow className="action-buttons">
|
||||
{(props.canReport) &&
|
||||
{(canReport) &&
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button report-button"
|
||||
key="report-button"
|
||||
onClick={props.onReportClicked}
|
||||
onClick={onReportClicked}
|
||||
>
|
||||
<FormattedMessage id="general.report" />
|
||||
</Button>
|
||||
{props.reportOpen && (
|
||||
{reportOpen && (
|
||||
<ReportModal
|
||||
isOpen
|
||||
key="report-modal"
|
||||
type="project"
|
||||
onReport={props.onReportSubmit}
|
||||
onRequestClose={props.onReportClose}
|
||||
onReport={onReportSubmit}
|
||||
onRequestClose={onReportClose}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
{props.canAddToStudio &&
|
||||
{canAddToStudio &&
|
||||
<React.Fragment>
|
||||
<div
|
||||
style={{position: 'relative'}}
|
||||
/* eslint-disable react/jsx-no-bind */
|
||||
onMouseEnter={() => showAddToStudioMuteError && setShowMuteMessage(true)}
|
||||
onMouseLeave={() => showAddToStudioMuteError && setShowMuteMessage(false)}
|
||||
/* eslint-enable react/jsx-no-bind */
|
||||
>
|
||||
<Button
|
||||
className="action-button studio-button"
|
||||
disabled={showAddToStudioMuteError}
|
||||
key="add-to-studio-button"
|
||||
onClick={props.onAddToStudioClicked}
|
||||
onClick={showMuteMessage ? null : onAddToStudioClicked}
|
||||
>
|
||||
<FormattedMessage id="addToStudio.title" />
|
||||
</Button>
|
||||
{props.addToStudioOpen && (
|
||||
{showMuteMessage && <StudioMuteEditMessage
|
||||
className="studio-button-error"
|
||||
messageId="project.mutedAddToStudio"
|
||||
/>}
|
||||
</div>
|
||||
{addToStudioOpen && (
|
||||
<AddToStudioModal
|
||||
isOpen
|
||||
isAdmin={props.isAdmin}
|
||||
isAdmin={isAdmin}
|
||||
key="add-to-studio-modal"
|
||||
userOwnsProject={props.userOwnsProject}
|
||||
onRequestClose={props.onAddToStudioClosed}
|
||||
onToggleStudio={props.onToggleStudio}
|
||||
userOwnsProject={userOwnsProject}
|
||||
onRequestClose={onAddToStudioClosed}
|
||||
onToggleStudio={onToggleStudio}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
{/* only show copy link button, modal if project is shared */}
|
||||
{props.isShared && props.projectInfo && props.projectInfo.id && (
|
||||
{isShared && projectInfo && projectInfo.id && (
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button copy-link-button"
|
||||
onClick={props.onSocialClicked}
|
||||
onClick={onSocialClicked}
|
||||
>
|
||||
<FormattedMessage id="general.copyLink" />
|
||||
</Button>
|
||||
{props.socialOpen && (
|
||||
{socialOpen && (
|
||||
<SocialModal
|
||||
isOpen
|
||||
key="social-modal"
|
||||
projectId={props.projectInfo && props.projectInfo.id}
|
||||
onRequestClose={props.onSocialClosed}
|
||||
projectId={projectInfo && projectInfo.id}
|
||||
onRequestClose={onSocialClosed}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
);
|
||||
);
|
||||
};
|
||||
|
||||
Subactions.propTypes = {
|
||||
addToStudioOpen: PropTypes.bool,
|
||||
|
@ -110,8 +153,13 @@ Subactions.propTypes = {
|
|||
projectInfo: projectShape,
|
||||
reportOpen: PropTypes.bool,
|
||||
shareDate: PropTypes.string,
|
||||
showAddToStudioMuteError: PropTypes.bool,
|
||||
socialOpen: PropTypes.bool,
|
||||
userOwnsProject: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = Subactions;
|
||||
module.exports = connect(
|
||||
state => ({
|
||||
showAddToStudioMuteError: selectShowProjectMuteError(state) && selectNewStudiosLaunched(state)
|
||||
})
|
||||
)(Subactions);
|
||||
|
|
|
@ -109,3 +109,10 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.studio-button-error {
|
||||
top: auto;
|
||||
transform: none;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
|
|
@ -9,12 +9,15 @@ import {selectMuteStatus} from '../../redux/session';
|
|||
import {formatRelativeTime} from '../../lib/format-time.js';
|
||||
|
||||
const StudioMuteEditMessage = ({
|
||||
className,
|
||||
messageId,
|
||||
muteExpiresAtMs
|
||||
}) => (
|
||||
<ValidationMessage
|
||||
className={className}
|
||||
mode="info"
|
||||
message={<FormattedMessage
|
||||
id="studio.mutedEdit"
|
||||
id={messageId}
|
||||
values={{
|
||||
inDuration: formatRelativeTime(muteExpiresAtMs, window._locale)
|
||||
}}
|
||||
|
@ -24,9 +27,15 @@ const StudioMuteEditMessage = ({
|
|||
|
||||
|
||||
StudioMuteEditMessage.propTypes = {
|
||||
className: PropTypes.string,
|
||||
messageId: PropTypes.string,
|
||||
muteExpiresAtMs: PropTypes.number
|
||||
};
|
||||
|
||||
StudioMuteEditMessage.defaultProps = {
|
||||
messageId: 'studio.mutedEdit'
|
||||
};
|
||||
|
||||
export default connect(
|
||||
state => ({
|
||||
muteExpiresAtMs: (selectMuteStatus(state).muteExpiresAt * 1000 || 0)
|
||||
|
|
Loading…
Reference in a new issue