mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 00:21:20 -05:00
Merge branch 'develop' into studio-comments-off
This commit is contained in:
commit
d3e368bce2
13 changed files with 483 additions and 391 deletions
43
package-lock.json
generated
43
package-lock.json
generated
|
@ -61,20 +61,20 @@
|
|||
}
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.5.1",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz",
|
||||
"integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==",
|
||||
"version": "3.5.2",
|
||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.2.tgz",
|
||||
"integrity": "sha512-ekGhOnNVPgT77r4K/U3GDhu+FQ2S8TnK/s2KbIGXi0SZWuwkZ2QNyfWdZW+TVfn84DpEP7rLeCt2UI6bJ8GwbQ==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
"anymatch": "~3.1.1",
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
"fsevents": "~2.3.1",
|
||||
"glob-parent": "~5.1.0",
|
||||
"fsevents": "~2.3.2",
|
||||
"glob-parent": "~5.1.2",
|
||||
"is-binary-path": "~2.1.0",
|
||||
"is-glob": "~4.0.1",
|
||||
"normalize-path": "~3.0.0",
|
||||
"readdirp": "~3.5.0"
|
||||
"readdirp": "~3.6.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
|
@ -176,9 +176,9 @@
|
|||
"optional": true
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz",
|
||||
"integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==",
|
||||
"version": "3.6.0",
|
||||
"resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
|
||||
"integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"requires": {
|
||||
|
@ -20873,9 +20873,9 @@
|
|||
}
|
||||
},
|
||||
"scratch-blocks": {
|
||||
"version": "0.1.0-prerelease.20210615035054",
|
||||
"resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.20210615035054.tgz",
|
||||
"integrity": "sha512-/YGZN3QiMa41gtcyHUUUVTfhztoT7zEb0+N+FeBmtbkZfeESOtEugJ0y0ftttUY7WJRga35TTDp1UdEyo7sxAg==",
|
||||
"version": "0.1.0-prerelease.20210616144308",
|
||||
"resolved": "https://registry.npmjs.org/scratch-blocks/-/scratch-blocks-0.1.0-prerelease.20210616144308.tgz",
|
||||
"integrity": "sha512-ahYux5Xn0EfkQpBtcwJ641Idu/oQutrpVTqLGf92cVyRqJp3LR/end6HshCCc4l6YFJBGOZV9bKjnsRkktnJRw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"exports-loader": "0.6.3",
|
||||
|
@ -20883,9 +20883,9 @@
|
|||
}
|
||||
},
|
||||
"scratch-gui": {
|
||||
"version": "0.1.0-prerelease.20210615041617",
|
||||
"resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20210615041617.tgz",
|
||||
"integrity": "sha512-HVmqbo9MLfV5tvc5owt7BT+fJKj5QRrz+c4S2vc8WyAsxMEerAYKfaNCHI89LmA5CRb42sgb0Z6YnwlsNVsaiw==",
|
||||
"version": "0.1.0-prerelease.20210617035831",
|
||||
"resolved": "https://registry.npmjs.org/scratch-gui/-/scratch-gui-0.1.0-prerelease.20210617035831.tgz",
|
||||
"integrity": "sha512-JldjubVfCWtT69H8/0eidMNUOnUxNAtuP62p92yhmwXsOHlgh/BSbns9BUaWZaryDYWuEOM0NodSWuiw+xO/9w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"arraybuffer-loader": "^1.0.6",
|
||||
|
@ -20936,8 +20936,8 @@
|
|||
"redux": "3.7.2",
|
||||
"redux-throttle": "0.1.1",
|
||||
"scratch-audio": "0.1.0-prerelease.20200528195344",
|
||||
"scratch-blocks": "0.1.0-prerelease.20210615035054",
|
||||
"scratch-l10n": "3.12.20210615031544",
|
||||
"scratch-blocks": "0.1.0-prerelease.20210616144308",
|
||||
"scratch-l10n": "3.13.20210617031540",
|
||||
"scratch-paint": "0.2.0-prerelease.20210615011117",
|
||||
"scratch-render": "0.1.0-prerelease.20210325231800",
|
||||
"scratch-render-fonts": "1.0.0-prerelease.20210401210003",
|
||||
|
@ -21394,15 +21394,14 @@
|
|||
}
|
||||
},
|
||||
"scratch-l10n": {
|
||||
"version": "3.12.20210615031544",
|
||||
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.12.20210615031544.tgz",
|
||||
"integrity": "sha512-8U2y0wu+xy29ayND5bY4odklo9D/5mVW1XQ+YrBx7rykUPHiJOzPUYHvTUQVXC0CI8khAtW98Lt3SI9m4MxBuw==",
|
||||
"version": "3.13.20210617031540",
|
||||
"resolved": "https://registry.npmjs.org/scratch-l10n/-/scratch-l10n-3.13.20210617031540.tgz",
|
||||
"integrity": "sha512-DPHqWiRnHv7Rp7s3EeESPpFgnHODboZyeRmR133vRj0j7DBnfwtzodzm659J8j4vyudcQblGbtcJYeRHbnYvpA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/cli": "^7.1.2",
|
||||
"@babel/core": "^7.1.2",
|
||||
"babel-plugin-react-intl": "^3.0.1",
|
||||
"react-intl": "^2.8.0",
|
||||
"transifex": "1.6.6"
|
||||
}
|
||||
},
|
||||
|
|
|
@ -126,8 +126,8 @@
|
|||
"redux-mock-store": "^1.2.3",
|
||||
"redux-thunk": "2.0.1",
|
||||
"sass-loader": "6.0.6",
|
||||
"scratch-gui": "0.1.0-prerelease.20210615041617",
|
||||
"scratch-l10n": "3.12.20210615031544",
|
||||
"scratch-gui": "0.1.0-prerelease.20210617035831",
|
||||
"scratch-l10n": "3.13.20210617031540",
|
||||
"selenium-webdriver": "3.6.0",
|
||||
"slick-carousel": "1.6.0",
|
||||
"style-loader": "0.12.3",
|
||||
|
|
|
@ -147,8 +147,6 @@ module.exports.selectStudioCommentsGloballyEnabled = 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;
|
||||
|
||||
|
|
|
@ -21,9 +21,11 @@ const selectShowCommentComposer = state => selectIsSocial(state);
|
|||
const selectCanReportComment = state => selectIsSocial(state);
|
||||
const selectCanRestoreComment = state => selectIsAdmin(state);
|
||||
// On the project page, project owners can delete comments with a confirmation,
|
||||
// and admins can delete comments without a confirmation. For now, only admins
|
||||
// can delete studio comments, so the following two are the same.
|
||||
const selectCanDeleteComment = state => selectIsAdmin(state);
|
||||
// and admins can delete comments without a confirmation.
|
||||
// On the studio page, studio creators and managers have the ability to delete *their own* comments with confirmation.
|
||||
// Admins can delete comments without a confirmation.
|
||||
const selectCanDeleteAnyComment = state => selectIsAdmin(state);
|
||||
const selectCanDeleteOwnComment = state => isCreator(state) || isManager(state);
|
||||
const selectCanDeleteCommentWithoutConfirm = state => selectIsAdmin(state);
|
||||
|
||||
const selectCanFollowStudio = state => selectIsLoggedIn(state);
|
||||
|
@ -80,7 +82,8 @@ export {
|
|||
selectCanAddProjects,
|
||||
selectCanFollowStudio,
|
||||
selectShowCommentComposer,
|
||||
selectCanDeleteComment,
|
||||
selectCanDeleteAnyComment,
|
||||
selectCanDeleteOwnComment,
|
||||
selectCanDeleteCommentWithoutConfirm,
|
||||
selectCanReportComment,
|
||||
selectCanRestoreComment,
|
||||
|
|
|
@ -46,6 +46,5 @@
|
|||
"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.mutedAddToStudio": "You will be able to add to studios again {inDuration}."
|
||||
"project.inappropriateUpdate": "Hmm...the bad word detector thinks there is a problem with your text. Please change it and remember to be respectful."
|
||||
}
|
||||
|
|
|
@ -160,6 +160,7 @@ $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;
|
||||
|
@ -184,6 +185,7 @@ $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,133 +8,90 @@ 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 = ({
|
||||
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 */}
|
||||
{shareDate ? (
|
||||
<FormattedDate
|
||||
value={Date.parse(shareDate)}
|
||||
day="2-digit"
|
||||
month="short"
|
||||
year="numeric"
|
||||
/>
|
||||
) : 'Unshared'}
|
||||
{/* eslint-enable react/jsx-sort-props */}
|
||||
</div>
|
||||
<FlexRow className="action-buttons">
|
||||
{(canReport) &&
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button report-button"
|
||||
key="report-button"
|
||||
onClick={onReportClicked}
|
||||
>
|
||||
<FormattedMessage id="general.report" />
|
||||
</Button>
|
||||
{reportOpen && (
|
||||
<ReportModal
|
||||
isOpen
|
||||
key="report-modal"
|
||||
type="project"
|
||||
onReport={onReportSubmit}
|
||||
onRequestClose={onReportClose}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
{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={showMuteMessage ? null : onAddToStudioClicked}
|
||||
>
|
||||
<FormattedMessage id="addToStudio.title" />
|
||||
</Button>
|
||||
{showMuteMessage && <StudioMuteEditMessage
|
||||
className="studio-button-error"
|
||||
messageId="project.mutedAddToStudio"
|
||||
/>}
|
||||
</div>
|
||||
{addToStudioOpen && (
|
||||
<AddToStudioModal
|
||||
isOpen
|
||||
isAdmin={isAdmin}
|
||||
key="add-to-studio-modal"
|
||||
userOwnsProject={userOwnsProject}
|
||||
onRequestClose={onAddToStudioClosed}
|
||||
onToggleStudio={onToggleStudio}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
{/* only show copy link button, modal if project is shared */}
|
||||
{isShared && projectInfo && projectInfo.id && (
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button copy-link-button"
|
||||
onClick={onSocialClicked}
|
||||
>
|
||||
<FormattedMessage id="general.copyLink" />
|
||||
</Button>
|
||||
{socialOpen && (
|
||||
<SocialModal
|
||||
isOpen
|
||||
key="social-modal"
|
||||
projectId={projectInfo && projectInfo.id}
|
||||
onRequestClose={onSocialClosed}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
</FlexRow>
|
||||
const Subactions = props => (
|
||||
<FlexRow className="subactions">
|
||||
<div className="share-date">
|
||||
<div className="copyleft">©</div>
|
||||
{' '}
|
||||
{/* eslint-disable react/jsx-sort-props */}
|
||||
{props.shareDate ? (
|
||||
<FormattedDate
|
||||
value={Date.parse(props.shareDate)}
|
||||
day="2-digit"
|
||||
month="short"
|
||||
year="numeric"
|
||||
/>
|
||||
) : 'Unshared'}
|
||||
{/* eslint-enable react/jsx-sort-props */}
|
||||
</div>
|
||||
<FlexRow className="action-buttons">
|
||||
{(props.canReport) &&
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button report-button"
|
||||
key="report-button"
|
||||
onClick={props.onReportClicked}
|
||||
>
|
||||
<FormattedMessage id="general.report" />
|
||||
</Button>
|
||||
{props.reportOpen && (
|
||||
<ReportModal
|
||||
isOpen
|
||||
key="report-modal"
|
||||
type="project"
|
||||
onReport={props.onReportSubmit}
|
||||
onRequestClose={props.onReportClose}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
{props.canAddToStudio &&
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button studio-button"
|
||||
key="add-to-studio-button"
|
||||
onClick={props.onAddToStudioClicked}
|
||||
>
|
||||
<FormattedMessage id="addToStudio.title" />
|
||||
</Button>
|
||||
{props.addToStudioOpen && (
|
||||
<AddToStudioModal
|
||||
isOpen
|
||||
isAdmin={props.isAdmin}
|
||||
key="add-to-studio-modal"
|
||||
userOwnsProject={props.userOwnsProject}
|
||||
onRequestClose={props.onAddToStudioClosed}
|
||||
onToggleStudio={props.onToggleStudio}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
}
|
||||
{/* only show copy link button, modal if project is shared */}
|
||||
{props.isShared && props.projectInfo && props.projectInfo.id && (
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button copy-link-button"
|
||||
onClick={props.onSocialClicked}
|
||||
>
|
||||
<FormattedMessage id="general.copyLink" />
|
||||
</Button>
|
||||
{props.socialOpen && (
|
||||
<SocialModal
|
||||
isOpen
|
||||
key="social-modal"
|
||||
projectId={props.projectInfo && props.projectInfo.id}
|
||||
onRequestClose={props.onSocialClosed}
|
||||
/>
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
</FlexRow>
|
||||
);
|
||||
};
|
||||
</FlexRow>
|
||||
);
|
||||
|
||||
Subactions.propTypes = {
|
||||
addToStudioOpen: PropTypes.bool,
|
||||
|
@ -153,13 +110,8 @@ Subactions.propTypes = {
|
|||
projectInfo: projectShape,
|
||||
reportOpen: PropTypes.bool,
|
||||
shareDate: PropTypes.string,
|
||||
showAddToStudioMuteError: PropTypes.bool,
|
||||
socialOpen: PropTypes.bool,
|
||||
userOwnsProject: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = connect(
|
||||
state => ({
|
||||
showAddToStudioMuteError: selectShowProjectMuteError(state) && selectNewStudiosLaunched(state)
|
||||
})
|
||||
)(Subactions);
|
||||
module.exports = Subactions;
|
||||
|
|
|
@ -109,10 +109,3 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.studio-button-error {
|
||||
top: auto;
|
||||
transform: none;
|
||||
width: 100%;
|
||||
margin-left: 0;
|
||||
}
|
||||
|
|
|
@ -10,10 +10,11 @@ import TopLevelComment from '../preview/comment/top-level-comment.jsx';
|
|||
import studioCommentActions from '../../redux/studio-comment-actions.js';
|
||||
import StudioCommentsAllowed from './studio-comments-allowed.jsx';
|
||||
import StudioCommentsNotAllowed from './studio-comments-not-allowed.jsx';
|
||||
import {selectIsAdmin, selectHasFetchedSession} from '../../redux/session';
|
||||
import {selectIsAdmin, selectHasFetchedSession, selectUsername} from '../../redux/session';
|
||||
import {
|
||||
selectShowCommentComposer,
|
||||
selectCanDeleteComment,
|
||||
selectCanDeleteAnyComment,
|
||||
selectCanDeleteOwnComment,
|
||||
selectCanDeleteCommentWithoutConfirm,
|
||||
selectCanReportComment,
|
||||
selectCanRestoreComment,
|
||||
|
@ -36,7 +37,9 @@ const StudioComments = ({
|
|||
shouldShowCommentComposer,
|
||||
shouldShowCommentsList,
|
||||
shouldShowCommentsGloballyOffError,
|
||||
canDeleteComment,
|
||||
username,
|
||||
canDeleteAnyComment,
|
||||
canDeleteOwnComment,
|
||||
canDeleteCommentWithoutConfirm,
|
||||
canEditCommentsAllowed,
|
||||
canReportComment,
|
||||
|
@ -106,7 +109,7 @@ const StudioComments = ({
|
|||
<TopLevelComment
|
||||
hasThreadLimit
|
||||
author={comment.author}
|
||||
canDelete={canDeleteComment}
|
||||
canDelete={canDeleteAnyComment || (canDeleteOwnComment && comment.author.username === username)}
|
||||
canDeleteWithoutConfirm={canDeleteCommentWithoutConfirm}
|
||||
canReply={shouldShowCommentComposer}
|
||||
canReport={canReportComment}
|
||||
|
@ -141,6 +144,7 @@ const StudioComments = ({
|
|||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
@ -157,7 +161,9 @@ StudioComments.propTypes = {
|
|||
shouldShowCommentComposer: PropTypes.bool,
|
||||
shouldShowCommentsGloballyOffError: PropTypes.bool,
|
||||
shouldShowCommentsList: PropTypes.bool,
|
||||
canDeleteComment: PropTypes.bool,
|
||||
username: PropTypes.string,
|
||||
canDeleteAnyComment: PropTypes.bool,
|
||||
canDeleteOwnComment: PropTypes.bool,
|
||||
canDeleteCommentWithoutConfirm: PropTypes.bool,
|
||||
canEditCommentsAllowed: PropTypes.bool,
|
||||
canReportComment: PropTypes.bool,
|
||||
|
@ -181,11 +187,13 @@ export default connect(
|
|||
isAdmin: selectIsAdmin(state),
|
||||
moreCommentsToLoad: state.comments.moreCommentsToLoad,
|
||||
replies: state.comments.replies,
|
||||
username: selectUsername(state),
|
||||
commentsAllowed: selectStudioCommentsAllowed(state),
|
||||
shouldShowCommentComposer: selectShowCommentComposer(state),
|
||||
shouldShowCommentsGloballyOffError: selectShowCommentsGloballyOffError(state),
|
||||
shouldShowCommentsList: selectShowCommentsList(state),
|
||||
canDeleteComment: selectCanDeleteComment(state),
|
||||
canDeleteAnyComment: selectCanDeleteAnyComment(state),
|
||||
canDeleteOwnComment: selectCanDeleteOwnComment(state),
|
||||
canDeleteCommentWithoutConfirm: selectCanDeleteCommentWithoutConfirm(state),
|
||||
canEditCommentsAllowed: selectCanEditCommentsAllowed(state),
|
||||
canReportComment: selectCanReportComment(state),
|
||||
|
|
|
@ -9,15 +9,12 @@ 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={messageId}
|
||||
id="studio.mutedEdit"
|
||||
values={{
|
||||
inDuration: formatRelativeTime(muteExpiresAtMs, window._locale)
|
||||
}}
|
||||
|
@ -27,15 +24,9 @@ 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)
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
.header-wrapper {
|
||||
width: 100%;
|
||||
height: 100px;
|
||||
height: 10vh;
|
||||
}
|
||||
.header-content {
|
||||
width: calc(100% - 2rem);
|
||||
|
@ -40,7 +40,6 @@
|
|||
width: 90vw;
|
||||
max-width: 45rem;
|
||||
margin: 0 auto;
|
||||
padding-top: 4vw;
|
||||
text-align: center;
|
||||
font-family: "Helvetica Neue", "Helvetica", Arial, sans-serif;
|
||||
color: white;
|
||||
|
@ -59,9 +58,13 @@
|
|||
opacity: 25%;
|
||||
margin: 2rem 0;
|
||||
}
|
||||
img.main-img {
|
||||
width: 300px;
|
||||
height: 200px;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2rem;
|
||||
margin: 1rem 1rem 2.5rem 1rem;
|
||||
margin: 1.5rem 1rem 2.5rem 1rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 1.125rem;
|
||||
|
@ -239,12 +242,12 @@
|
|||
</div>
|
||||
<div class="main">
|
||||
<div class="content">
|
||||
<h1>The Scratch Team is working hard to fix an issue with the Scratch website</h1>
|
||||
<h2 class="reload" onclick="location.reload()">Try reloading the page in a few minutes</h2>
|
||||
<img src="http://scratch-maintenance.s3.amazonaws.com/cairn.svg" />
|
||||
<h1>The Scratch Team is working on some planned updates to the website</h1>
|
||||
<h2 class="comment">Check <a href="https://twitter.com/scratch">@Scratch</a> for updates</h2>
|
||||
<hr>
|
||||
<div class="narrow">
|
||||
<p>While the website is being fixed, you can use the Scratch app to make projects offline</p>
|
||||
<p>While the website is being worked on, you can use the Scratch app to make projects offline</p>
|
||||
</div>
|
||||
<button class="toggleShowing showing"><span>Download Scratch app</span></button>
|
||||
<div class="grid-wrapper hidden">
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -2,7 +2,8 @@ import {
|
|||
selectCanEditInfo,
|
||||
selectCanAddProjects,
|
||||
selectShowCommentComposer,
|
||||
selectCanDeleteComment,
|
||||
selectCanDeleteAnyComment,
|
||||
selectCanDeleteOwnComment,
|
||||
selectCanDeleteCommentWithoutConfirm,
|
||||
selectCanReportComment,
|
||||
selectCanRestoreComment,
|
||||
|
@ -198,7 +199,7 @@ describe('studio comments', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('can delete comment', () => {
|
||||
describe('can delete any comment', () => {
|
||||
test.each([
|
||||
['admin', true],
|
||||
['curator', false],
|
||||
|
@ -211,7 +212,26 @@ describe('studio comments', () => {
|
|||
['muted logged in', false]
|
||||
])('%s: %s', (role, expected) => {
|
||||
setStateByRole(role);
|
||||
expect(selectCanDeleteComment(state)).toBe(expected);
|
||||
expect(selectCanDeleteAnyComment(state)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
describe('can delete own comment', () => {
|
||||
test.each([
|
||||
['admin', false], // This is false here because we check for `canDeleteAnyComment` separately
|
||||
['curator', false],
|
||||
['manager', true],
|
||||
['creator', true],
|
||||
['logged in', false],
|
||||
['unconfirmed', false],
|
||||
['logged out', false],
|
||||
['muted creator', true],
|
||||
['muted manager', true],
|
||||
['muted curator', false],
|
||||
['muted logged in', false]
|
||||
])('%s: %s', (role, expected) => {
|
||||
setStateByRole(role);
|
||||
expect(selectCanDeleteOwnComment(state)).toBe(expected);
|
||||
});
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue