mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-23 07:38:07 -05:00
simplified embed modal to remove social links
This commit is contained in:
parent
fdfa61649f
commit
08f8e1c546
10 changed files with 121 additions and 153 deletions
|
@ -11,6 +11,7 @@ class SocialModal extends React.Component {
|
|||
this.embedTextarea = {};
|
||||
this.embedCopyTimeoutId = null;
|
||||
this.linkCopyTimeoutId = null;
|
||||
this.linkTextarea = {};
|
||||
this.showCopyResultTimeout = 2000;
|
||||
this.state = {
|
||||
showEmbedResult: false,
|
||||
|
@ -21,11 +22,14 @@ class SocialModal extends React.Component {
|
|||
'handleCopyProjectLink',
|
||||
'hideEmbedResult',
|
||||
'hideLinkResult',
|
||||
'setEmbedTextarea'
|
||||
'linkUrl',
|
||||
'setEmbedTextarea',
|
||||
'setLinkTextarea'
|
||||
]);
|
||||
}
|
||||
componentWillUnmount () {
|
||||
this.clearEmbedCopyResultTimeout();
|
||||
this.clearLinkCopyResultTimeout();
|
||||
}
|
||||
handleCopyEmbed () {
|
||||
if (this.embedTextarea) {
|
||||
|
@ -42,14 +46,17 @@ class SocialModal extends React.Component {
|
|||
}
|
||||
}
|
||||
handleCopyProjectLink () {
|
||||
this.props.onCopyProjectLink();
|
||||
if (this.state.showLinkResult === false && this.linkCopyTimeoutId === null) {
|
||||
this.setState({showLinkResult: true}, () => {
|
||||
this.linkCopyTimeoutId = setTimeout(
|
||||
this.hideLinkResult,
|
||||
this.showCopyResultTimeout
|
||||
);
|
||||
});
|
||||
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 () {
|
||||
|
@ -60,16 +67,29 @@ class SocialModal extends React.Component {
|
|||
this.setState({showLinkResult: false});
|
||||
this.linkCopyTimeoutId = null;
|
||||
}
|
||||
linkUrl () {
|
||||
return `${window.location.origin}${window.location.pathname}`;
|
||||
}
|
||||
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 (
|
||||
|
@ -78,7 +98,9 @@ class SocialModal extends React.Component {
|
|||
fbUrl={social.facebookIntentLink(projectId)}
|
||||
googleClassroomUrl={social.googleClassroomIntentLink(projectId)}
|
||||
isOpen={this.props.isOpen}
|
||||
linkUrl={this.linkUrl()}
|
||||
setEmbedTextarea={this.setEmbedTextarea}
|
||||
setLinkTextarea={this.setLinkTextarea}
|
||||
showEmbedResult={this.state.showEmbedResult}
|
||||
showLinkResult={this.state.showLinkResult}
|
||||
twitterUrl={social.twitterIntentLink(projectId)}
|
||||
|
@ -93,7 +115,6 @@ class SocialModal extends React.Component {
|
|||
|
||||
SocialModal.propTypes = {
|
||||
isOpen: PropTypes.bool,
|
||||
onCopyProjectLink: PropTypes.func,
|
||||
onRequestClose: PropTypes.func,
|
||||
projectId: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
|
||||
};
|
||||
|
|
|
@ -30,28 +30,39 @@
|
|||
}
|
||||
|
||||
.social-spaced-row {
|
||||
width: 100%;
|
||||
// width: 100%;
|
||||
justify-content: space-between;
|
||||
align-items: start;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.social-row-right {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
.social-label-row {
|
||||
width: 100%;
|
||||
font-weight: bold;
|
||||
margin-bottom: .5rem;
|
||||
justify-content: start;
|
||||
align-items: start;
|
||||
justify-content: space-between;
|
||||
align-items: flex-end;
|
||||
}
|
||||
|
||||
.social-label {
|
||||
.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;
|
||||
}
|
||||
|
||||
.embed-section {
|
||||
.embed-section, .link-section {
|
||||
margin-top: 2rem;
|
||||
}
|
||||
|
||||
|
@ -115,7 +126,7 @@
|
|||
|
||||
// NOTE: copied from inplace-input.scss. We should refactor to put this style in
|
||||
// only one place.
|
||||
.social-embed-textarea {
|
||||
.social-embed-textarea, .social-link-textarea {
|
||||
transition: all .2s ease;
|
||||
border: 2px dashed $ui-blue-25percent;
|
||||
border-radius: 8px;
|
||||
|
@ -128,6 +139,13 @@
|
|||
resize: none;
|
||||
overflow: hidden;
|
||||
|
||||
width: 100%;
|
||||
height: 6rem;
|
||||
|
||||
textarea {
|
||||
min-height: 4rem;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
transition: all .2s ease;
|
||||
outline: none;
|
||||
|
@ -136,15 +154,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.social-embed-textarea {
|
||||
width: 100%;
|
||||
height: 6rem;
|
||||
|
||||
textarea {
|
||||
min-height: 4rem;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: should probably be put in a shared css location
|
||||
.social-hidden {
|
||||
opacity: 0.0;
|
||||
|
|
|
@ -14,18 +14,17 @@ require('./modal.scss');
|
|||
|
||||
const SocialModalPresentation = ({
|
||||
embedHtml,
|
||||
fbUrl,
|
||||
googleClassroomUrl,
|
||||
intl,
|
||||
isOpen,
|
||||
linkUrl,
|
||||
onClickEmbedText,
|
||||
onCopyEmbed,
|
||||
onCopyProjectLink,
|
||||
onRequestClose,
|
||||
setEmbedTextarea,
|
||||
setLinkTextarea,
|
||||
showEmbedResult,
|
||||
showLinkResult,
|
||||
twitterUrl,
|
||||
weChatUrl
|
||||
showLinkResult
|
||||
}) => {
|
||||
const title = intl.formatMessage({id: 'social.title'});
|
||||
|
||||
|
@ -44,117 +43,68 @@ const SocialModalPresentation = ({
|
|||
</div>
|
||||
<div className="modal-content social-modal-content">
|
||||
|
||||
{/* top row: social links and copy link button */}
|
||||
<FlexRow className="social-row social-spaced-row">
|
||||
|
||||
{/* social links */}
|
||||
<div>
|
||||
{/* top row: link */}
|
||||
<div className="link-section">
|
||||
<FlexRow className="social-row social-spaced-row">
|
||||
<FlexRow className="social-label-row">
|
||||
{intl.formatMessage({id: 'social.socialMediaLabel'})}
|
||||
</FlexRow>
|
||||
<FlexRow className="social-spaced-row">
|
||||
<a
|
||||
alt="Google Classroom"
|
||||
href={googleClassroomUrl}
|
||||
target="_blank"
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'social-social-icon',
|
||||
'social-google-classroom-icon'
|
||||
)}
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
alt="WeChat"
|
||||
href={weChatUrl}
|
||||
target="_blank"
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'social-social-icon',
|
||||
'social-wechat-icon'
|
||||
)}
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
alt="Facebook"
|
||||
href={fbUrl}
|
||||
target="_blank"
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'social-social-icon',
|
||||
'social-facebook-icon'
|
||||
)}
|
||||
/>
|
||||
</a>
|
||||
<a
|
||||
alt="Twitter"
|
||||
href={twitterUrl}
|
||||
target="_blank"
|
||||
>
|
||||
<div
|
||||
className={classNames(
|
||||
'social-social-icon',
|
||||
'social-twitter-icon'
|
||||
)}
|
||||
/>
|
||||
</a>
|
||||
</FlexRow>
|
||||
</div>
|
||||
|
||||
{/* copy link button */}
|
||||
<div>
|
||||
<FlexRow className="social-label-row">
|
||||
<div className="social-label">
|
||||
<div className="social-label-title">
|
||||
{intl.formatMessage({id: 'social.linkLabel'})}
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
'social-label',
|
||||
'social-label-result',
|
||||
{'social-hidden': !showLinkResult}
|
||||
)}
|
||||
>
|
||||
{intl.formatMessage({id: 'social.embedCopiedResultText'})}
|
||||
</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: 'general.copyLink'})}
|
||||
</a>
|
||||
</div>
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
<FlexRow className="social-spaced-row">
|
||||
<Button
|
||||
className="social-copy-link-button social-copy-link-button-large"
|
||||
onClick={onCopyProjectLink}
|
||||
>
|
||||
<FormattedMessage id="general.copyLink" />
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</div>
|
||||
|
||||
</FlexRow>
|
||||
<textarea
|
||||
readOnly
|
||||
className="social-link-textarea"
|
||||
name="link"
|
||||
ref={textarea => setLinkTextarea(textarea)}
|
||||
value={linkUrl}
|
||||
onClick={onClickProjectLinkText}
|
||||
/>
|
||||
</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">
|
||||
<div className="social-label-title">
|
||||
{intl.formatMessage({id: 'social.embedHtmlLabel'})}
|
||||
</div>
|
||||
<div className="social-label">
|
||||
<a
|
||||
onClick={onCopyEmbed}
|
||||
<FlexRow className="social-spaced-row social-row-right">
|
||||
<div
|
||||
className={classNames(
|
||||
'social-label-item',
|
||||
'social-label-result',
|
||||
{'social-hidden': !showEmbedResult}
|
||||
)}
|
||||
>
|
||||
{intl.formatMessage({id: 'social.copyEmbedLinkText'})}
|
||||
</a>
|
||||
</div>
|
||||
<div
|
||||
className={classNames(
|
||||
'social-label',
|
||||
'social-label-result',
|
||||
{'social-hidden': !showEmbedResult}
|
||||
)}
|
||||
>
|
||||
{intl.formatMessage({id: 'social.embedCopiedResultText'})}
|
||||
</div>
|
||||
{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
|
||||
|
@ -162,7 +112,7 @@ const SocialModalPresentation = ({
|
|||
name="embed"
|
||||
ref={textarea => setEmbedTextarea(textarea)}
|
||||
value={embedHtml}
|
||||
onClick={onCopyEmbed}
|
||||
onClick={onClickEmbedText}
|
||||
/>
|
||||
</FlexRow>
|
||||
</div>
|
||||
|
@ -174,18 +124,17 @@ const SocialModalPresentation = ({
|
|||
|
||||
SocialModalPresentation.propTypes = {
|
||||
embedHtml: PropTypes.string,
|
||||
fbUrl: PropTypes.string,
|
||||
googleClassroomUrl: PropTypes.string,
|
||||
intl: intlShape,
|
||||
isOpen: PropTypes.bool,
|
||||
linkUrl: PropTypes.string,
|
||||
onClickEmbedText: PropTypes.func,
|
||||
onCopyEmbed: PropTypes.func,
|
||||
onCopyProjectLink: PropTypes.func,
|
||||
onRequestClose: PropTypes.func,
|
||||
setEmbedTextarea: PropTypes.func,
|
||||
setLinkTextarea: PropTypes.func,
|
||||
showEmbedResult: PropTypes.bool,
|
||||
showLinkResult: PropTypes.bool,
|
||||
twitterUrl: PropTypes.string,
|
||||
weChatUrl: PropTypes.string
|
||||
showLinkResult: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = injectIntl(SocialModalPresentation);
|
||||
|
|
|
@ -258,7 +258,7 @@
|
|||
"comments.status.deleted": "Deleted",
|
||||
"comments.status.reported": "Reported",
|
||||
|
||||
"social.title": "Social",
|
||||
"social.title": "Embed",
|
||||
"social.embedHtmlLabel": "Embed",
|
||||
"social.copyEmbedLinkText": "Copy embed",
|
||||
"social.linkLabel": "Link",
|
||||
|
|
|
@ -2,7 +2,7 @@ module.exports = {};
|
|||
|
||||
module.exports.embedHtml = projectId => {
|
||||
if (projectId) {
|
||||
return `<iframe src="https://scratch.mit.edu/projects/${projectId}/embed?autostart=false" ` +
|
||||
return `<iframe src="https://scratch.mit.edu/projects/${projectId}/embed" ` +
|
||||
'allowtransparency="true" width="485" height="402" ' +
|
||||
'frameborder="0" scrolling="no" allowfullscreen></iframe>';
|
||||
}
|
||||
|
|
|
@ -88,7 +88,6 @@ const PreviewPresentation = ({
|
|||
onAddToStudioClicked,
|
||||
onAddToStudioClosed,
|
||||
onCloseAdminPanel,
|
||||
onCopyProjectLink,
|
||||
onDeleteComment,
|
||||
onFavoriteClicked,
|
||||
onGreenFlag,
|
||||
|
@ -375,7 +374,6 @@ const PreviewPresentation = ({
|
|||
userOwnsProject={userOwnsProject}
|
||||
onAddToStudioClicked={onAddToStudioClicked}
|
||||
onAddToStudioClosed={onAddToStudioClosed}
|
||||
onCopyProjectLink={onCopyProjectLink}
|
||||
onReportClicked={onReportClicked}
|
||||
onReportClose={onReportClose}
|
||||
onReportSubmit={onReportSubmit}
|
||||
|
@ -524,7 +522,6 @@ const PreviewPresentation = ({
|
|||
userOwnsProject={userOwnsProject}
|
||||
onAddToStudioClicked={onAddToStudioClicked}
|
||||
onAddToStudioClosed={onAddToStudioClosed}
|
||||
onCopyProjectLink={onCopyProjectLink}
|
||||
onReportClicked={onReportClicked}
|
||||
onReportClose={onReportClose}
|
||||
onReportSubmit={onReportSubmit}
|
||||
|
@ -702,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,
|
||||
|
|
|
@ -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,7 +54,6 @@ class Preview extends React.Component {
|
|||
'fetchCommunityData',
|
||||
'handleAddComment',
|
||||
'handleClickLogo',
|
||||
'handleCopyProjectLink',
|
||||
'handleDeleteComment',
|
||||
'handleSocialClick',
|
||||
'handleSocialClose',
|
||||
|
@ -582,11 +580,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}`);
|
||||
}
|
||||
handleSocialClick () {
|
||||
this.setState({socialOpen: true});
|
||||
}
|
||||
|
@ -694,7 +687,6 @@ class Preview extends React.Component {
|
|||
onAddToStudioClicked={this.handleAddToStudioClick}
|
||||
onAddToStudioClosed={this.handleAddToStudioClose}
|
||||
onCloseAdminPanel={this.handleCloseAdminPanel}
|
||||
onCopyProjectLink={this.handleCopyProjectLink}
|
||||
onDeleteComment={this.handleDeleteComment}
|
||||
onFavoriteClicked={this.handleFavoriteToggle}
|
||||
onGreenFlag={this.handleGreenFlag}
|
||||
|
|
|
@ -61,7 +61,6 @@ const Subactions = props => (
|
|||
isOpen
|
||||
key="social-modal"
|
||||
projectId={props.projectInfo && props.projectInfo.id}
|
||||
onCopyProjectLink={props.onCopyProjectLink}
|
||||
onRequestClose={props.onSocialClosed}
|
||||
/>
|
||||
)}
|
||||
|
|
|
@ -61,7 +61,8 @@
|
|||
}
|
||||
&.studio-button,
|
||||
&.copy-link-button,
|
||||
&.report-button {
|
||||
&.report-button,
|
||||
&.social-button {
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: .25rem;
|
||||
|
@ -89,7 +90,7 @@
|
|||
|
||||
&.social-button {
|
||||
&:before {
|
||||
background-image: url("/svgs/project/copy-link-white.svg");
|
||||
background-image: url("/svgs/project/embed-icon.svg");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
1
static/svgs/project/embed-icon.svg
Normal file
1
static/svgs/project/embed-icon.svg
Normal file
|
@ -0,0 +1 @@
|
|||
<svg width="20" height="20" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"><defs><path d="M10.049 6.474a7.627 7.627 0 0 1 3.35 1.485 7.743 7.743 0 0 1 .89.826c.244.27.504.614.717.941a6.65 6.65 0 0 1 .872 2.11 6.32 6.32 0 0 1 .11 1.911c-.056.554-.165.98-.271 1.313-.05.163-.091.238-.118.314l-.042.106a.81.81 0 0 1-.834.492c-.443-.043-.765-.423-.72-.848l.013-.111c.003-.066.027-.196.024-.3a4.307 4.307 0 0 0-.51-2.145 4.2 4.2 0 0 0-.886-1.107 5.127 5.127 0 0 0-.581-.427c-.138-.092-.166-.089-.283-.151-.098-.052-.2-.092-.296-.134a3.93 3.93 0 0 0-1.095-.257 4.049 4.049 0 0 0-.34-.011v1.307c0 .522-.325.99-.828 1.19a1.38 1.38 0 0 1-1.463-.279L4.383 9.457a1.253 1.253 0 0 1 0-1.821l3.375-3.242c.385-.37.96-.48 1.463-.279.503.2.828.668.828 1.19v1.17z" id="a"/></defs><g transform="matrix(-1 0 0 1 20 0)" fill="none" fill-rule="evenodd"><mask id="b" fill="#fff"><use xlink:href="#a"/></mask><use fill="#4C97FF" xlink:href="#a"/><g mask="url(#b)" fill="#FFF"><path d="M0 0h20v20H0z"/></g></g></svg>
|
After Width: | Height: | Size: 1,022 B |
Loading…
Reference in a new issue