mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-27 01:25:52 -05:00
Merge pull request #2924 from benjiwheeler/embed-modal
Embed/social sharing modal
This commit is contained in:
commit
d97f5b9d7a
8 changed files with 444 additions and 15 deletions
114
src/components/modal/social/container.jsx
Normal file
114
src/components/modal/social/container.jsx
Normal file
|
@ -0,0 +1,114 @@
|
|||
const bindAll = require('lodash.bindall');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
const SocialModalPresentation = require('./presentation.jsx');
|
||||
const clipboardCopy = require('clipboard-copy');
|
||||
const social = require('../../../lib/social');
|
||||
|
||||
class SocialModal extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
this.embedTextarea = {};
|
||||
this.embedCopyTimeoutId = null;
|
||||
this.linkCopyTimeoutId = null;
|
||||
this.linkTextarea = {};
|
||||
this.showCopyResultTimeout = 2000;
|
||||
this.state = {
|
||||
showEmbedResult: false,
|
||||
showLinkResult: false
|
||||
};
|
||||
bindAll(this, [
|
||||
'handleCopyEmbed',
|
||||
'handleCopyProjectLink',
|
||||
'hideEmbedResult',
|
||||
'hideLinkResult',
|
||||
'setEmbedTextarea',
|
||||
'setLinkTextarea'
|
||||
]);
|
||||
}
|
||||
componentWillUnmount () {
|
||||
this.clearEmbedCopyResultTimeout();
|
||||
this.clearLinkCopyResultTimeout();
|
||||
}
|
||||
handleCopyEmbed () {
|
||||
if (this.embedTextarea) {
|
||||
this.embedTextarea.select();
|
||||
clipboardCopy(this.embedTextarea.value);
|
||||
if (this.state.showEmbedResult === false && this.embedCopyTimeoutId === null) {
|
||||
this.setState({showEmbedResult: true}, () => {
|
||||
this.embedCopyTimeoutId = setTimeout(
|
||||
this.hideEmbedResult,
|
||||
this.showCopyResultTimeout
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
handleCopyProjectLink () {
|
||||
if (this.linkTextarea) {
|
||||
this.linkTextarea.select();
|
||||
clipboardCopy(this.linkTextarea.value);
|
||||
if (this.state.showLinkResult === false && this.linkCopyTimeoutId === null) {
|
||||
this.setState({showLinkResult: true}, () => {
|
||||
this.linkCopyTimeoutId = setTimeout(
|
||||
this.hideLinkResult,
|
||||
this.showCopyResultTimeout
|
||||
);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
hideEmbedResult () {
|
||||
this.setState({showEmbedResult: false});
|
||||
this.embedCopyTimeoutId = null;
|
||||
}
|
||||
hideLinkResult () {
|
||||
this.setState({showLinkResult: false});
|
||||
this.linkCopyTimeoutId = null;
|
||||
}
|
||||
setEmbedTextarea (textarea) {
|
||||
this.embedTextarea = textarea;
|
||||
return textarea;
|
||||
}
|
||||
setLinkTextarea (textarea) {
|
||||
this.linkTextarea = textarea;
|
||||
return textarea;
|
||||
}
|
||||
clearEmbedCopyResultTimeout () {
|
||||
if (this.embedCopyTimeoutId !== null) {
|
||||
clearTimeout(this.embedCopyTimeoutId);
|
||||
this.embedCopyTimeoutId = null;
|
||||
}
|
||||
}
|
||||
clearLinkCopyResultTimeout () {
|
||||
if (this.linkCopyTimeoutId !== null) {
|
||||
clearTimeout(this.linkCopyTimeoutId);
|
||||
this.linkCopyTimeoutId = null;
|
||||
}
|
||||
}
|
||||
render () {
|
||||
const projectId = this.props.projectId;
|
||||
return (
|
||||
<SocialModalPresentation
|
||||
embedHtml={social.embedHtml(projectId)}
|
||||
isOpen={this.props.isOpen}
|
||||
projectUrl={social.projectUrl(projectId)}
|
||||
setEmbedTextarea={this.setEmbedTextarea}
|
||||
setLinkTextarea={this.setLinkTextarea}
|
||||
showEmbedResult={this.state.showEmbedResult}
|
||||
showLinkResult={this.state.showLinkResult}
|
||||
onCopyEmbed={this.handleCopyEmbed}
|
||||
onCopyProjectLink={this.handleCopyProjectLink}
|
||||
onRequestClose={this.props.onRequestClose}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
SocialModal.propTypes = {
|
||||
isOpen: PropTypes.bool,
|
||||
onRequestClose: PropTypes.func,
|
||||
projectId: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
|
||||
};
|
||||
|
||||
module.exports = SocialModal;
|
132
src/components/modal/social/modal.scss
Normal file
132
src/components/modal/social/modal.scss
Normal file
|
@ -0,0 +1,132 @@
|
|||
@import "../../../colors";
|
||||
@import "../../../frameless";
|
||||
|
||||
.mod-social {
|
||||
min-height: 15rem;
|
||||
max-height: calc(100% - 8rem);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.social-modal-header {
|
||||
border-radius: 1rem 1rem 0 0;
|
||||
box-shadow: inset 0 -1px 0 0 $ui-blue-dark;
|
||||
background-color: $ui-blue;
|
||||
}
|
||||
|
||||
.social-modal-content {
|
||||
box-shadow: none;
|
||||
width: 92%;
|
||||
height: calc(100% - 0rem);
|
||||
margin: 1rem auto 1.625rem;
|
||||
font-size: .9375rem;
|
||||
}
|
||||
|
||||
.social-row {
|
||||
width: 100%;
|
||||
margin-top: .5rem;
|
||||
margin-bottom: .5rem;
|
||||
align-items: start;
|
||||
}
|
||||
|
||||
.social-spaced-row {
|
||||
// width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.social-row-right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.social-label-row {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
margin-bottom: .5rem;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.social-label-title {
|
||||
font-size: 1rem;
|
||||
margin-right: 1.5rem;
|
||||
}
|
||||
|
||||
.social-label-item {
|
||||
margin-left: 1.5rem;
|
||||
margin-right: .25rem;
|
||||
}
|
||||
|
||||
.social-label-result {
|
||||
color: $type-gray-75percent;
|
||||
transition: opacity 100ms linear;
|
||||
}
|
||||
|
||||
.link-section {
|
||||
margin-top: .5rem;
|
||||
}
|
||||
|
||||
.embed-section {
|
||||
margin-top: 1rem;
|
||||
}
|
||||
|
||||
.social-social-icon {
|
||||
width: 2.75rem;
|
||||
height: 2.75rem;
|
||||
margin-right: .75rem;
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
.social-twitter-icon {
|
||||
background-image: url("/images/social/twitter.png");
|
||||
}
|
||||
|
||||
.social-facebook-icon {
|
||||
background-image: url("/images/social/facebook.png");
|
||||
}
|
||||
|
||||
.social-google-classroom-icon {
|
||||
background-image: url("/images/social/google-classroom.png");
|
||||
}
|
||||
|
||||
.social-wechat-icon {
|
||||
background-image: url("/images/social/wechat.png");
|
||||
}
|
||||
|
||||
.social-form {
|
||||
transition: all .2s ease;
|
||||
border: 2px solid $box-shadow-light-gray;
|
||||
border-radius: 8px;
|
||||
background-color: $ui-blue-10percent;
|
||||
color: $type-gray;
|
||||
padding: .75rem .875rem;
|
||||
line-height: 1.25rem;
|
||||
font-size: .875rem;
|
||||
box-sizing: border-box;
|
||||
resize: none;
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
|
||||
&:focus {
|
||||
transition: all .2s ease;
|
||||
outline: none;
|
||||
border: 2px solid $ui-blue;
|
||||
box-shadow: 0 0 0 4px $ui-blue-25percent;
|
||||
}
|
||||
|
||||
&.social-textarea {
|
||||
height: 6rem;
|
||||
}
|
||||
|
||||
&.social-input {
|
||||
height: 2.75rem;
|
||||
}
|
||||
|
||||
textarea {
|
||||
min-height: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
.social-hidden {
|
||||
opacity: 0.0;
|
||||
}
|
135
src/components/modal/social/presentation.jsx
Normal file
135
src/components/modal/social/presentation.jsx
Normal file
|
@ -0,0 +1,135 @@
|
|||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
const FormattedMessage = require('react-intl').FormattedMessage;
|
||||
const injectIntl = require('react-intl').injectIntl;
|
||||
const intlShape = require('react-intl').intlShape;
|
||||
const classNames = require('classnames');
|
||||
|
||||
const Modal = require('../base/modal.jsx');
|
||||
const FlexRow = require('../../flex-row/flex-row.jsx');
|
||||
|
||||
require('../../forms/button.scss');
|
||||
require('./modal.scss');
|
||||
|
||||
const SocialModalPresentation = ({
|
||||
embedHtml,
|
||||
intl,
|
||||
isOpen,
|
||||
onCopyEmbed,
|
||||
onCopyProjectLink,
|
||||
onRequestClose,
|
||||
projectUrl,
|
||||
setEmbedTextarea,
|
||||
setLinkTextarea,
|
||||
showEmbedResult,
|
||||
showLinkResult
|
||||
}) => {
|
||||
const title = intl.formatMessage({id: 'general.copyLink'});
|
||||
|
||||
return (
|
||||
<Modal
|
||||
useStandardSizes
|
||||
className="mod-social"
|
||||
contentLabel={title}
|
||||
isOpen={isOpen}
|
||||
onRequestClose={onRequestClose}
|
||||
>
|
||||
<div className="social-modal-header modal-header">
|
||||
<div className="social-content-label content-label">
|
||||
<FormattedMessage id="general.copyLink" />
|
||||
</div>
|
||||
</div>
|
||||
<div className="modal-content social-modal-content">
|
||||
|
||||
{/* top row: link */}
|
||||
<div className="link-section">
|
||||
<FlexRow className="social-row social-spaced-row">
|
||||
<FlexRow className="social-label-row">
|
||||
<div className="social-label-title">
|
||||
{intl.formatMessage({id: 'social.linkLabel'})}
|
||||
</div>
|
||||
<FlexRow className="social-spaced-row social-row-right">
|
||||
<div
|
||||
className={classNames(
|
||||
'social-label-item',
|
||||
'social-label-result',
|
||||
{'social-hidden': !showLinkResult}
|
||||
)}
|
||||
>
|
||||
{intl.formatMessage({id: 'social.embedCopiedResultText'})}
|
||||
</div>
|
||||
<div className="social-label-item">
|
||||
<a
|
||||
onClick={onCopyProjectLink}
|
||||
>
|
||||
{intl.formatMessage({id: 'social.copyLinkLinkText'})}
|
||||
</a>
|
||||
</div>
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
<input
|
||||
readOnly
|
||||
className="social-form social-input"
|
||||
name="link"
|
||||
ref={textarea => setLinkTextarea(textarea)}
|
||||
value={projectUrl}
|
||||
/>
|
||||
</FlexRow>
|
||||
</div>
|
||||
|
||||
{/* bottom row: embed */}
|
||||
<div className="embed-section">
|
||||
<FlexRow className="social-row social-spaced-row">
|
||||
<FlexRow className="social-label-row">
|
||||
<div className="social-label-title">
|
||||
{intl.formatMessage({id: 'social.embedLabel'})}
|
||||
</div>
|
||||
<FlexRow className="social-spaced-row social-row-right">
|
||||
<div
|
||||
className={classNames(
|
||||
'social-label-item',
|
||||
'social-label-result',
|
||||
{'social-hidden': !showEmbedResult}
|
||||
)}
|
||||
>
|
||||
{intl.formatMessage({id: 'social.embedCopiedResultText'})}
|
||||
</div>
|
||||
<div className="social-label-item">
|
||||
<a
|
||||
onClick={onCopyEmbed}
|
||||
>
|
||||
{intl.formatMessage({id: 'social.copyEmbedLinkText'})}
|
||||
</a>
|
||||
</div>
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
<textarea
|
||||
readOnly
|
||||
className="social-form social-textarea"
|
||||
name="embed"
|
||||
ref={textarea => setEmbedTextarea(textarea)}
|
||||
value={embedHtml}
|
||||
/>
|
||||
</FlexRow>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
};
|
||||
|
||||
SocialModalPresentation.propTypes = {
|
||||
embedHtml: PropTypes.string,
|
||||
intl: intlShape,
|
||||
isOpen: PropTypes.bool,
|
||||
onCopyEmbed: PropTypes.func,
|
||||
onCopyProjectLink: PropTypes.func,
|
||||
onRequestClose: PropTypes.func,
|
||||
projectUrl: PropTypes.string,
|
||||
setEmbedTextarea: PropTypes.func,
|
||||
setLinkTextarea: PropTypes.func,
|
||||
showEmbedResult: PropTypes.bool,
|
||||
showLinkResult: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = injectIntl(SocialModalPresentation);
|
|
@ -256,5 +256,11 @@
|
|||
"comments.status.suspended": "Suspended",
|
||||
"comments.status.acctdel": "Account deleted",
|
||||
"comments.status.deleted": "Deleted",
|
||||
"comments.status.reported": "Reported"
|
||||
"comments.status.reported": "Reported",
|
||||
|
||||
"social.embedLabel": "Embed",
|
||||
"social.copyEmbedLinkText": "Copy embed",
|
||||
"social.linkLabel": "Link",
|
||||
"social.copyLinkLinkText": "Copy link",
|
||||
"social.embedCopiedResultText": "Copied"
|
||||
}
|
||||
|
|
17
src/lib/social.js
Normal file
17
src/lib/social.js
Normal file
|
@ -0,0 +1,17 @@
|
|||
module.exports = {};
|
||||
|
||||
module.exports.projectUrl = projectId => {
|
||||
if (projectId) {
|
||||
return `https://scratch.mit.edu/projects/${projectId}`;
|
||||
}
|
||||
return '';
|
||||
};
|
||||
|
||||
module.exports.embedHtml = projectId => {
|
||||
if (projectId) {
|
||||
return `<iframe src="https://scratch.mit.edu/projects/${projectId}/embed" ` +
|
||||
'allowtransparency="true" width="485" height="402" ' +
|
||||
'frameborder="0" scrolling="no" allowfullscreen></iframe>';
|
||||
}
|
||||
return '';
|
||||
};
|
|
@ -88,7 +88,6 @@ const PreviewPresentation = ({
|
|||
onAddToStudioClicked,
|
||||
onAddToStudioClosed,
|
||||
onCloseAdminPanel,
|
||||
onCopyProjectLink,
|
||||
onDeleteComment,
|
||||
onFavoriteClicked,
|
||||
onGreenFlag,
|
||||
|
@ -108,6 +107,8 @@ const PreviewPresentation = ({
|
|||
onSeeInside,
|
||||
onSetProjectThumbnailer,
|
||||
onShare,
|
||||
onSocialClicked,
|
||||
onSocialClosed,
|
||||
onToggleComments,
|
||||
onToggleStudio,
|
||||
onUpdateProjectId,
|
||||
|
@ -126,6 +127,7 @@ const PreviewPresentation = ({
|
|||
showAdminPanel,
|
||||
showModInfo,
|
||||
singleCommentId,
|
||||
socialOpen,
|
||||
userOwnsProject,
|
||||
visibilityInfo
|
||||
}) => {
|
||||
|
@ -368,13 +370,15 @@ const PreviewPresentation = ({
|
|||
projectInfo={projectInfo}
|
||||
reportOpen={reportOpen}
|
||||
shareDate={shareDate}
|
||||
socialOpen={socialOpen}
|
||||
userOwnsProject={userOwnsProject}
|
||||
onAddToStudioClicked={onAddToStudioClicked}
|
||||
onAddToStudioClosed={onAddToStudioClosed}
|
||||
onCopyProjectLink={onCopyProjectLink}
|
||||
onReportClicked={onReportClicked}
|
||||
onReportClose={onReportClose}
|
||||
onReportSubmit={onReportSubmit}
|
||||
onSocialClicked={onSocialClicked}
|
||||
onSocialClosed={onSocialClosed}
|
||||
onToggleStudio={onToggleStudio}
|
||||
/>
|
||||
</div>
|
||||
|
@ -514,13 +518,15 @@ const PreviewPresentation = ({
|
|||
projectInfo={projectInfo}
|
||||
reportOpen={reportOpen}
|
||||
shareDate={shareDate}
|
||||
socialOpen={socialOpen}
|
||||
userOwnsProject={userOwnsProject}
|
||||
onAddToStudioClicked={onAddToStudioClicked}
|
||||
onAddToStudioClosed={onAddToStudioClosed}
|
||||
onCopyProjectLink={onCopyProjectLink}
|
||||
onReportClicked={onReportClicked}
|
||||
onReportClose={onReportClose}
|
||||
onReportSubmit={onReportSubmit}
|
||||
onSocialClicked={onSocialClicked}
|
||||
onSocialClosed={onSocialClosed}
|
||||
onToggleStudio={onToggleStudio}
|
||||
/>
|
||||
</FlexRow>
|
||||
|
@ -693,7 +699,6 @@ PreviewPresentation.propTypes = {
|
|||
onAddToStudioClicked: PropTypes.func,
|
||||
onAddToStudioClosed: PropTypes.func,
|
||||
onCloseAdminPanel: PropTypes.func,
|
||||
onCopyProjectLink: PropTypes.func,
|
||||
onDeleteComment: PropTypes.func,
|
||||
onFavoriteClicked: PropTypes.func,
|
||||
onGreenFlag: PropTypes.func,
|
||||
|
@ -713,6 +718,8 @@ PreviewPresentation.propTypes = {
|
|||
onSeeInside: PropTypes.func,
|
||||
onSetProjectThumbnailer: PropTypes.func,
|
||||
onShare: PropTypes.func,
|
||||
onSocialClicked: PropTypes.func,
|
||||
onSocialClosed: PropTypes.func,
|
||||
onToggleComments: PropTypes.func,
|
||||
onToggleStudio: PropTypes.func,
|
||||
onUpdateProjectId: PropTypes.func,
|
||||
|
@ -731,6 +738,7 @@ PreviewPresentation.propTypes = {
|
|||
showModInfo: PropTypes.bool,
|
||||
showUsernameBlockAlert: PropTypes.bool,
|
||||
singleCommentId: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),
|
||||
socialOpen: PropTypes.bool,
|
||||
userOwnsProject: PropTypes.bool,
|
||||
visibilityInfo: PropTypes.shape({
|
||||
censored: PropTypes.bool,
|
||||
|
|
|
@ -8,7 +8,6 @@ const PropTypes = require('prop-types');
|
|||
const connect = require('react-redux').connect;
|
||||
const injectIntl = require('react-intl').injectIntl;
|
||||
const parser = require('scratch-parser');
|
||||
const copy = require('clipboard-copy');
|
||||
|
||||
const Page = require('../../components/page/www/page.jsx');
|
||||
const storage = require('../../lib/storage.js').default;
|
||||
|
@ -55,8 +54,9 @@ class Preview extends React.Component {
|
|||
'fetchCommunityData',
|
||||
'handleAddComment',
|
||||
'handleClickLogo',
|
||||
'handleCopyProjectLink',
|
||||
'handleDeleteComment',
|
||||
'handleSocialClick',
|
||||
'handleSocialClose',
|
||||
'handleToggleStudio',
|
||||
'handleFavoriteToggle',
|
||||
'handleLoadMore',
|
||||
|
@ -109,6 +109,7 @@ class Preview extends React.Component {
|
|||
clientFaved: false,
|
||||
clientLoved: false,
|
||||
extensions: [],
|
||||
socialOpen: false,
|
||||
favoriteCount: 0,
|
||||
isProjectLoaded: false,
|
||||
isRemixing: false,
|
||||
|
@ -381,6 +382,12 @@ class Preview extends React.Component {
|
|||
handleAddToStudioClose () {
|
||||
this.setState({addToStudioOpen: false});
|
||||
}
|
||||
handleSocialClick () {
|
||||
this.setState({socialOpen: true});
|
||||
}
|
||||
handleSocialClose () {
|
||||
this.setState({socialOpen: false});
|
||||
}
|
||||
handleReportSubmit (formData) {
|
||||
const submit = data => this.props.reportProject(this.state.projectId, data, this.props.user.token);
|
||||
if (this.getProjectThumbnail) {
|
||||
|
@ -579,11 +586,6 @@ class Preview extends React.Component {
|
|||
this.props.user.token
|
||||
);
|
||||
}
|
||||
handleCopyProjectLink () {
|
||||
// Use the pathname so we do not have to update this if path changes
|
||||
// Also do not include hash or query params
|
||||
copy(`${window.location.origin}${window.location.pathname}`);
|
||||
}
|
||||
initCounts (favorites, loves) {
|
||||
this.setState({
|
||||
favoriteCount: favorites,
|
||||
|
@ -678,13 +680,13 @@ class Preview extends React.Component {
|
|||
showModInfo={this.props.isAdmin}
|
||||
showUsernameBlockAlert={this.state.showUsernameBlockAlert}
|
||||
singleCommentId={this.state.singleCommentId}
|
||||
socialOpen={this.state.socialOpen}
|
||||
userOwnsProject={this.props.userOwnsProject}
|
||||
visibilityInfo={this.props.visibilityInfo}
|
||||
onAddComment={this.handleAddComment}
|
||||
onAddToStudioClicked={this.handleAddToStudioClick}
|
||||
onAddToStudioClosed={this.handleAddToStudioClose}
|
||||
onCloseAdminPanel={this.handleCloseAdminPanel}
|
||||
onCopyProjectLink={this.handleCopyProjectLink}
|
||||
onDeleteComment={this.handleDeleteComment}
|
||||
onFavoriteClicked={this.handleFavoriteToggle}
|
||||
onGreenFlag={this.handleGreenFlag}
|
||||
|
@ -704,6 +706,8 @@ class Preview extends React.Component {
|
|||
onSeeInside={this.handleSeeInside}
|
||||
onSetProjectThumbnailer={this.handleSetProjectThumbnailer}
|
||||
onShare={this.handleShare}
|
||||
onSocialClicked={this.handleSocialClick}
|
||||
onSocialClosed={this.handleSocialClose}
|
||||
onToggleComments={this.handleToggleComments}
|
||||
onToggleStudio={this.handleToggleStudio}
|
||||
onUpdateProjectId={this.handleUpdateProjectId}
|
||||
|
|
|
@ -6,7 +6,9 @@ const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
|||
|
||||
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 projectShape = require('./projectshape.jsx').projectShape;
|
||||
|
||||
require('./subactions.scss');
|
||||
|
||||
|
@ -50,10 +52,18 @@ const Subactions = props => (
|
|||
}
|
||||
<Button
|
||||
className="action-button copy-link-button"
|
||||
onClick={props.onCopyProjectLink}
|
||||
onClick={props.onSocialClicked}
|
||||
>
|
||||
<FormattedMessage id="general.copyLink" />
|
||||
</Button>
|
||||
{props.socialOpen && props.projectInfo && props.projectInfo.id && (
|
||||
<SocialModal
|
||||
isOpen
|
||||
key="social-modal"
|
||||
projectId={props.projectInfo && props.projectInfo.id}
|
||||
onRequestClose={props.onSocialClosed}
|
||||
/>
|
||||
)}
|
||||
{(props.canReport) &&
|
||||
<React.Fragment>
|
||||
<Button
|
||||
|
@ -85,13 +95,16 @@ Subactions.propTypes = {
|
|||
isAdmin: PropTypes.bool,
|
||||
onAddToStudioClicked: PropTypes.func,
|
||||
onAddToStudioClosed: PropTypes.func,
|
||||
onCopyProjectLink: PropTypes.func,
|
||||
onReportClicked: PropTypes.func.isRequired,
|
||||
onReportClose: PropTypes.func.isRequired,
|
||||
onReportSubmit: PropTypes.func.isRequired,
|
||||
onSocialClicked: PropTypes.func,
|
||||
onSocialClosed: PropTypes.func,
|
||||
onToggleStudio: PropTypes.func,
|
||||
projectInfo: projectShape,
|
||||
reportOpen: PropTypes.bool,
|
||||
shareDate: PropTypes.string,
|
||||
socialOpen: PropTypes.bool,
|
||||
userOwnsProject: PropTypes.bool
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue