mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-07-07 09:15:04 -04: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
src
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.suspended": "Suspended",
|
||||||
"comments.status.acctdel": "Account deleted",
|
"comments.status.acctdel": "Account deleted",
|
||||||
"comments.status.deleted": "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,
|
onAddToStudioClicked,
|
||||||
onAddToStudioClosed,
|
onAddToStudioClosed,
|
||||||
onCloseAdminPanel,
|
onCloseAdminPanel,
|
||||||
onCopyProjectLink,
|
|
||||||
onDeleteComment,
|
onDeleteComment,
|
||||||
onFavoriteClicked,
|
onFavoriteClicked,
|
||||||
onGreenFlag,
|
onGreenFlag,
|
||||||
|
@ -108,6 +107,8 @@ const PreviewPresentation = ({
|
||||||
onSeeInside,
|
onSeeInside,
|
||||||
onSetProjectThumbnailer,
|
onSetProjectThumbnailer,
|
||||||
onShare,
|
onShare,
|
||||||
|
onSocialClicked,
|
||||||
|
onSocialClosed,
|
||||||
onToggleComments,
|
onToggleComments,
|
||||||
onToggleStudio,
|
onToggleStudio,
|
||||||
onUpdateProjectId,
|
onUpdateProjectId,
|
||||||
|
@ -126,6 +127,7 @@ const PreviewPresentation = ({
|
||||||
showAdminPanel,
|
showAdminPanel,
|
||||||
showModInfo,
|
showModInfo,
|
||||||
singleCommentId,
|
singleCommentId,
|
||||||
|
socialOpen,
|
||||||
userOwnsProject,
|
userOwnsProject,
|
||||||
visibilityInfo
|
visibilityInfo
|
||||||
}) => {
|
}) => {
|
||||||
|
@ -368,13 +370,15 @@ const PreviewPresentation = ({
|
||||||
projectInfo={projectInfo}
|
projectInfo={projectInfo}
|
||||||
reportOpen={reportOpen}
|
reportOpen={reportOpen}
|
||||||
shareDate={shareDate}
|
shareDate={shareDate}
|
||||||
|
socialOpen={socialOpen}
|
||||||
userOwnsProject={userOwnsProject}
|
userOwnsProject={userOwnsProject}
|
||||||
onAddToStudioClicked={onAddToStudioClicked}
|
onAddToStudioClicked={onAddToStudioClicked}
|
||||||
onAddToStudioClosed={onAddToStudioClosed}
|
onAddToStudioClosed={onAddToStudioClosed}
|
||||||
onCopyProjectLink={onCopyProjectLink}
|
|
||||||
onReportClicked={onReportClicked}
|
onReportClicked={onReportClicked}
|
||||||
onReportClose={onReportClose}
|
onReportClose={onReportClose}
|
||||||
onReportSubmit={onReportSubmit}
|
onReportSubmit={onReportSubmit}
|
||||||
|
onSocialClicked={onSocialClicked}
|
||||||
|
onSocialClosed={onSocialClosed}
|
||||||
onToggleStudio={onToggleStudio}
|
onToggleStudio={onToggleStudio}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -514,13 +518,15 @@ const PreviewPresentation = ({
|
||||||
projectInfo={projectInfo}
|
projectInfo={projectInfo}
|
||||||
reportOpen={reportOpen}
|
reportOpen={reportOpen}
|
||||||
shareDate={shareDate}
|
shareDate={shareDate}
|
||||||
|
socialOpen={socialOpen}
|
||||||
userOwnsProject={userOwnsProject}
|
userOwnsProject={userOwnsProject}
|
||||||
onAddToStudioClicked={onAddToStudioClicked}
|
onAddToStudioClicked={onAddToStudioClicked}
|
||||||
onAddToStudioClosed={onAddToStudioClosed}
|
onAddToStudioClosed={onAddToStudioClosed}
|
||||||
onCopyProjectLink={onCopyProjectLink}
|
|
||||||
onReportClicked={onReportClicked}
|
onReportClicked={onReportClicked}
|
||||||
onReportClose={onReportClose}
|
onReportClose={onReportClose}
|
||||||
onReportSubmit={onReportSubmit}
|
onReportSubmit={onReportSubmit}
|
||||||
|
onSocialClicked={onSocialClicked}
|
||||||
|
onSocialClosed={onSocialClosed}
|
||||||
onToggleStudio={onToggleStudio}
|
onToggleStudio={onToggleStudio}
|
||||||
/>
|
/>
|
||||||
</FlexRow>
|
</FlexRow>
|
||||||
|
@ -693,7 +699,6 @@ PreviewPresentation.propTypes = {
|
||||||
onAddToStudioClicked: PropTypes.func,
|
onAddToStudioClicked: PropTypes.func,
|
||||||
onAddToStudioClosed: PropTypes.func,
|
onAddToStudioClosed: PropTypes.func,
|
||||||
onCloseAdminPanel: PropTypes.func,
|
onCloseAdminPanel: PropTypes.func,
|
||||||
onCopyProjectLink: PropTypes.func,
|
|
||||||
onDeleteComment: PropTypes.func,
|
onDeleteComment: PropTypes.func,
|
||||||
onFavoriteClicked: PropTypes.func,
|
onFavoriteClicked: PropTypes.func,
|
||||||
onGreenFlag: PropTypes.func,
|
onGreenFlag: PropTypes.func,
|
||||||
|
@ -713,6 +718,8 @@ PreviewPresentation.propTypes = {
|
||||||
onSeeInside: PropTypes.func,
|
onSeeInside: PropTypes.func,
|
||||||
onSetProjectThumbnailer: PropTypes.func,
|
onSetProjectThumbnailer: PropTypes.func,
|
||||||
onShare: PropTypes.func,
|
onShare: PropTypes.func,
|
||||||
|
onSocialClicked: PropTypes.func,
|
||||||
|
onSocialClosed: PropTypes.func,
|
||||||
onToggleComments: PropTypes.func,
|
onToggleComments: PropTypes.func,
|
||||||
onToggleStudio: PropTypes.func,
|
onToggleStudio: PropTypes.func,
|
||||||
onUpdateProjectId: PropTypes.func,
|
onUpdateProjectId: PropTypes.func,
|
||||||
|
@ -731,6 +738,7 @@ PreviewPresentation.propTypes = {
|
||||||
showModInfo: PropTypes.bool,
|
showModInfo: PropTypes.bool,
|
||||||
showUsernameBlockAlert: PropTypes.bool,
|
showUsernameBlockAlert: PropTypes.bool,
|
||||||
singleCommentId: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),
|
singleCommentId: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]),
|
||||||
|
socialOpen: PropTypes.bool,
|
||||||
userOwnsProject: PropTypes.bool,
|
userOwnsProject: PropTypes.bool,
|
||||||
visibilityInfo: PropTypes.shape({
|
visibilityInfo: PropTypes.shape({
|
||||||
censored: PropTypes.bool,
|
censored: PropTypes.bool,
|
||||||
|
|
|
@ -8,7 +8,6 @@ const PropTypes = require('prop-types');
|
||||||
const connect = require('react-redux').connect;
|
const connect = require('react-redux').connect;
|
||||||
const injectIntl = require('react-intl').injectIntl;
|
const injectIntl = require('react-intl').injectIntl;
|
||||||
const parser = require('scratch-parser');
|
const parser = require('scratch-parser');
|
||||||
const copy = require('clipboard-copy');
|
|
||||||
|
|
||||||
const Page = require('../../components/page/www/page.jsx');
|
const Page = require('../../components/page/www/page.jsx');
|
||||||
const storage = require('../../lib/storage.js').default;
|
const storage = require('../../lib/storage.js').default;
|
||||||
|
@ -55,8 +54,9 @@ class Preview extends React.Component {
|
||||||
'fetchCommunityData',
|
'fetchCommunityData',
|
||||||
'handleAddComment',
|
'handleAddComment',
|
||||||
'handleClickLogo',
|
'handleClickLogo',
|
||||||
'handleCopyProjectLink',
|
|
||||||
'handleDeleteComment',
|
'handleDeleteComment',
|
||||||
|
'handleSocialClick',
|
||||||
|
'handleSocialClose',
|
||||||
'handleToggleStudio',
|
'handleToggleStudio',
|
||||||
'handleFavoriteToggle',
|
'handleFavoriteToggle',
|
||||||
'handleLoadMore',
|
'handleLoadMore',
|
||||||
|
@ -109,6 +109,7 @@ class Preview extends React.Component {
|
||||||
clientFaved: false,
|
clientFaved: false,
|
||||||
clientLoved: false,
|
clientLoved: false,
|
||||||
extensions: [],
|
extensions: [],
|
||||||
|
socialOpen: false,
|
||||||
favoriteCount: 0,
|
favoriteCount: 0,
|
||||||
isProjectLoaded: false,
|
isProjectLoaded: false,
|
||||||
isRemixing: false,
|
isRemixing: false,
|
||||||
|
@ -381,6 +382,12 @@ class Preview extends React.Component {
|
||||||
handleAddToStudioClose () {
|
handleAddToStudioClose () {
|
||||||
this.setState({addToStudioOpen: false});
|
this.setState({addToStudioOpen: false});
|
||||||
}
|
}
|
||||||
|
handleSocialClick () {
|
||||||
|
this.setState({socialOpen: true});
|
||||||
|
}
|
||||||
|
handleSocialClose () {
|
||||||
|
this.setState({socialOpen: false});
|
||||||
|
}
|
||||||
handleReportSubmit (formData) {
|
handleReportSubmit (formData) {
|
||||||
const submit = data => this.props.reportProject(this.state.projectId, data, this.props.user.token);
|
const submit = data => this.props.reportProject(this.state.projectId, data, this.props.user.token);
|
||||||
if (this.getProjectThumbnail) {
|
if (this.getProjectThumbnail) {
|
||||||
|
@ -579,11 +586,6 @@ class Preview extends React.Component {
|
||||||
this.props.user.token
|
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) {
|
initCounts (favorites, loves) {
|
||||||
this.setState({
|
this.setState({
|
||||||
favoriteCount: favorites,
|
favoriteCount: favorites,
|
||||||
|
@ -678,13 +680,13 @@ class Preview extends React.Component {
|
||||||
showModInfo={this.props.isAdmin}
|
showModInfo={this.props.isAdmin}
|
||||||
showUsernameBlockAlert={this.state.showUsernameBlockAlert}
|
showUsernameBlockAlert={this.state.showUsernameBlockAlert}
|
||||||
singleCommentId={this.state.singleCommentId}
|
singleCommentId={this.state.singleCommentId}
|
||||||
|
socialOpen={this.state.socialOpen}
|
||||||
userOwnsProject={this.props.userOwnsProject}
|
userOwnsProject={this.props.userOwnsProject}
|
||||||
visibilityInfo={this.props.visibilityInfo}
|
visibilityInfo={this.props.visibilityInfo}
|
||||||
onAddComment={this.handleAddComment}
|
onAddComment={this.handleAddComment}
|
||||||
onAddToStudioClicked={this.handleAddToStudioClick}
|
onAddToStudioClicked={this.handleAddToStudioClick}
|
||||||
onAddToStudioClosed={this.handleAddToStudioClose}
|
onAddToStudioClosed={this.handleAddToStudioClose}
|
||||||
onCloseAdminPanel={this.handleCloseAdminPanel}
|
onCloseAdminPanel={this.handleCloseAdminPanel}
|
||||||
onCopyProjectLink={this.handleCopyProjectLink}
|
|
||||||
onDeleteComment={this.handleDeleteComment}
|
onDeleteComment={this.handleDeleteComment}
|
||||||
onFavoriteClicked={this.handleFavoriteToggle}
|
onFavoriteClicked={this.handleFavoriteToggle}
|
||||||
onGreenFlag={this.handleGreenFlag}
|
onGreenFlag={this.handleGreenFlag}
|
||||||
|
@ -704,6 +706,8 @@ class Preview extends React.Component {
|
||||||
onSeeInside={this.handleSeeInside}
|
onSeeInside={this.handleSeeInside}
|
||||||
onSetProjectThumbnailer={this.handleSetProjectThumbnailer}
|
onSetProjectThumbnailer={this.handleSetProjectThumbnailer}
|
||||||
onShare={this.handleShare}
|
onShare={this.handleShare}
|
||||||
|
onSocialClicked={this.handleSocialClick}
|
||||||
|
onSocialClosed={this.handleSocialClose}
|
||||||
onToggleComments={this.handleToggleComments}
|
onToggleComments={this.handleToggleComments}
|
||||||
onToggleStudio={this.handleToggleStudio}
|
onToggleStudio={this.handleToggleStudio}
|
||||||
onUpdateProjectId={this.handleUpdateProjectId}
|
onUpdateProjectId={this.handleUpdateProjectId}
|
||||||
|
|
|
@ -6,7 +6,9 @@ const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||||
|
|
||||||
const Button = require('../../components/forms/button.jsx');
|
const Button = require('../../components/forms/button.jsx');
|
||||||
const AddToStudioModal = require('./add-to-studio.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 ReportModal = require('../../components/modal/report/modal.jsx');
|
||||||
|
const projectShape = require('./projectshape.jsx').projectShape;
|
||||||
|
|
||||||
require('./subactions.scss');
|
require('./subactions.scss');
|
||||||
|
|
||||||
|
@ -50,10 +52,18 @@ const Subactions = props => (
|
||||||
}
|
}
|
||||||
<Button
|
<Button
|
||||||
className="action-button copy-link-button"
|
className="action-button copy-link-button"
|
||||||
onClick={props.onCopyProjectLink}
|
onClick={props.onSocialClicked}
|
||||||
>
|
>
|
||||||
<FormattedMessage id="general.copyLink" />
|
<FormattedMessage id="general.copyLink" />
|
||||||
</Button>
|
</Button>
|
||||||
|
{props.socialOpen && props.projectInfo && props.projectInfo.id && (
|
||||||
|
<SocialModal
|
||||||
|
isOpen
|
||||||
|
key="social-modal"
|
||||||
|
projectId={props.projectInfo && props.projectInfo.id}
|
||||||
|
onRequestClose={props.onSocialClosed}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{(props.canReport) &&
|
{(props.canReport) &&
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<Button
|
<Button
|
||||||
|
@ -85,13 +95,16 @@ Subactions.propTypes = {
|
||||||
isAdmin: PropTypes.bool,
|
isAdmin: PropTypes.bool,
|
||||||
onAddToStudioClicked: PropTypes.func,
|
onAddToStudioClicked: PropTypes.func,
|
||||||
onAddToStudioClosed: PropTypes.func,
|
onAddToStudioClosed: PropTypes.func,
|
||||||
onCopyProjectLink: PropTypes.func,
|
|
||||||
onReportClicked: PropTypes.func.isRequired,
|
onReportClicked: PropTypes.func.isRequired,
|
||||||
onReportClose: PropTypes.func.isRequired,
|
onReportClose: PropTypes.func.isRequired,
|
||||||
onReportSubmit: PropTypes.func.isRequired,
|
onReportSubmit: PropTypes.func.isRequired,
|
||||||
|
onSocialClicked: PropTypes.func,
|
||||||
|
onSocialClosed: PropTypes.func,
|
||||||
onToggleStudio: PropTypes.func,
|
onToggleStudio: PropTypes.func,
|
||||||
|
projectInfo: projectShape,
|
||||||
reportOpen: PropTypes.bool,
|
reportOpen: PropTypes.bool,
|
||||||
shareDate: PropTypes.string,
|
shareDate: PropTypes.string,
|
||||||
|
socialOpen: PropTypes.bool,
|
||||||
userOwnsProject: PropTypes.bool
|
userOwnsProject: PropTypes.bool
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue