put social links section, copy project link button inside social share modal

This commit is contained in:
Ben Wheeler 2019-04-22 22:36:26 -04:00
parent 1e63b51565
commit 5d12f0f781
8 changed files with 95 additions and 119 deletions

View file

@ -54,7 +54,6 @@
"bowser": "1.9.4", "bowser": "1.9.4",
"cheerio": "1.0.0-rc.2", "cheerio": "1.0.0-rc.2",
"classnames": "2.2.5", "classnames": "2.2.5",
"clipboard-copy": "3.0.0",
"cookie": "0.2.2", "cookie": "0.2.2",
"copy-webpack-plugin": "0.2.0", "copy-webpack-plugin": "0.2.0",
"create-react-class": "15.6.2", "create-react-class": "15.6.2",

View file

@ -10,12 +10,15 @@ class ExternalShareModal extends React.Component {
super(props); super(props);
this.embedTextarea = {}; this.embedTextarea = {};
bindAll(this, [ bindAll(this, [
'handleClickCopyEmbed', 'handleCopyEmbed',
'setEmbedTextarea' 'setEmbedTextarea'
]); ]);
} }
// componentDidMount () { // componentDidMount () {
// if (this.embedTextarea) this.embedTextarea.select(); // if (this.embedTextarea) {
// console.log('selecting on mount');
// this.embedTextarea.select();
// }
// } // }
componentDidUpdate () { componentDidUpdate () {
if (this.embedTextarea) { if (this.embedTextarea) {
@ -25,23 +28,26 @@ class ExternalShareModal extends React.Component {
console.log('NOT selecting'); console.log('NOT selecting');
} }
} }
handleClickCopyEmbed () { handleCopyEmbed () {
if (this.embedTextarea) this.embedTextarea.select(); if (this.embedTextarea) this.embedTextarea.select();
clipboardCopy(this.embedTextarea.value); clipboardCopy(this.embedTextarea.value);
} }
setEmbedTextarea (textarea) { setEmbedTextarea (textarea) {
this.embedTextarea = textarea; this.embedTextarea = textarea;
return textarea;
} }
render () { render () {
const projectId = this.props.projectId; const projectId = this.props.projectId;
return ( return (
<ExternalShareModalPresentation <ExternalShareModalPresentation
embedHtml={externalShare.embedHtml(projectId)}
fbUrl={externalShare.facebookIntentLink(projectId)} fbUrl={externalShare.facebookIntentLink(projectId)}
googUrl={externalShare.googleClassroomIntentLink(projectId)} googUrl={externalShare.googleClassroomIntentLink(projectId)}
isOpen={this.props.isOpen} isOpen={this.props.isOpen}
setEmbedTextarea={this.setEmbedTextarea} setEmbedTextarea={this.setEmbedTextarea}
twitterUrl={externalShare.twitterIntentLink(projectId)} twitterUrl={externalShare.twitterIntentLink(projectId)}
onClickCopyEmbed={this.handleClickCopyEmbed} onCopyEmbed={this.handleCopyEmbed}
onCopyProjectLink={this.props.onCopyProjectLink}
onRequestClose={this.props.onRequestClose} onRequestClose={this.props.onRequestClose}
/> />
); );
@ -50,8 +56,9 @@ class ExternalShareModal extends React.Component {
ExternalShareModal.propTypes = { ExternalShareModal.propTypes = {
isOpen: PropTypes.bool, isOpen: PropTypes.bool,
onCopyProjectLink: PropTypes.func,
onRequestClose: PropTypes.func, onRequestClose: PropTypes.func,
projectId: PropTypes.string projectId: PropTypes.oneOfType([PropTypes.number, PropTypes.string])
}; };
module.exports = ExternalShareModal; module.exports = ExternalShareModal;

View file

@ -29,11 +29,17 @@
margin: 1rem auto; margin: 1rem auto;
} }
.externalShare-label {
font-weight: bold;
width: 100%;
}
.externalShare-embed-row { .externalShare-embed-row {
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
margin-top: .5rem; margin-top: .5rem;
margin-bottom: .5rem; margin-bottom: .5rem;
align-items: start;
} }
.externalShare-embed-textarea { .externalShare-embed-textarea {

View file

@ -5,6 +5,7 @@ const FormattedMessage = require('react-intl').FormattedMessage;
const injectIntl = require('react-intl').injectIntl; const injectIntl = require('react-intl').injectIntl;
const intlShape = require('react-intl').intlShape; const intlShape = require('react-intl').intlShape;
const Button = require('../../forms/button.jsx');
const Modal = require('../base/modal.jsx'); const Modal = require('../base/modal.jsx');
// const Form = require('../../forms/form.jsx'); // const Form = require('../../forms/form.jsx');
// const Button = require('../../forms/button.jsx'); // const Button = require('../../forms/button.jsx');
@ -16,56 +17,57 @@ require('../../forms/button.scss');
require('./modal.scss'); require('./modal.scss');
const ExternalShareModalPresentation = ({ const ExternalShareModalPresentation = ({
embedHtml,
fbUrl, fbUrl,
googUrl, googUrl,
intl, intl,
isOpen, isOpen,
onCopyEmbed,
onCopyProjectLink,
onRequestClose, onRequestClose,
projectId, setEmbedTextarea,
twitterUrl twitterUrl
}) => { }) => {
const contentLabel = intl.formatMessage({id: 'externalshare.title'}); const title = intl.formatMessage({id: 'externalshare.title'});
return ( return (
<Modal <Modal
useStandardSizes useStandardSizes
className="mod-externalShare" className="mod-externalShare"
contentLabel={contentLabel} contentLabel={title}
isOpen={isOpen} isOpen={isOpen}
onRequestClose={onRequestClose} onRequestClose={onRequestClose}
> >
<div className="externalShare-modal-header modal-header"> <div className="externalShare-modal-header modal-header">
<div className="externalShare-content-label content-label"> <div className="externalShare-content-label content-label">
Send outside Scratch <FormattedMessage id="externalShare.title" />
</div> </div>
</div> </div>
<div className="externalShare-modal-content modal-content"> <div className="externalShare-modal-content modal-content">
{/*
<div className="external-target-outer-scrollbox">
<div className="external-target-inner-scrollbox">
<div className="external-target-container">
*/}
<div className="username-label">
<b>
{this.props.intl.formatMessage({id: 'externalShare.embedHtmlContent'})}
</b>
<div className="externalShare-label">
{intl.formatMessage({id: 'externalShare.embedHtmlLabel'})}
</div> </div>
<FlexRow className="externalShare-embed-row"> <FlexRow className="externalShare-embed-row">
<textarea <textarea
readOnly readOnly
className="externalShare-embed-textarea" className="externalShare-embed-textarea"
name="embed" name="embed"
ref={textarea => this.embedTextarea = textarea} ref={textarea => setEmbedTextarea(textarea)}
value={externalShare.embedHtml(projectId)} value={embedHtml}
onClick={this.onClickCopyEmbed} onClick={onCopyEmbed}
/> />
<div <div
className="externalShare-copy-icon" className="externalShare-copy-icon"
onClick={this.onClickCopyEmbed} onClick={onCopyEmbed}
/> />
</FlexRow> </FlexRow>
<FlexRow className="externalShare-embed-row">
<div>
<div className="externalShare-label">
{intl.formatMessage({id: 'externalShare.embedHtmlLabel'})}
</div>
<FlexRow className="externalShare-embed-row"> <FlexRow className="externalShare-embed-row">
<a <a
href={twitterUrl} href={twitterUrl}
@ -86,82 +88,39 @@ const ExternalShareModalPresentation = ({
G classroom G classroom
</a> </a>
</FlexRow> </FlexRow>
{/*
</div>
</div>
</div> </div>
<Form <div>
// className="external-share" <div className="externalShare-label">
onSubmit={onSubmit} {intl.formatMessage({id: 'externalShare.linkLabel'})}
> </div>
<FlexRow className="action-buttons"> <FlexRow className="externalShare-embed-row">
<Button <Button
className="action-button submit-button" className="action-button copy-link-button"
key="submitButton" onClick={onCopyProjectLink}
type="submit"
> >
<div className="action-button-text"> <FormattedMessage id="general.copyLink" />
<FormattedMessage id="general.done" />
</div>
</Button> </Button>
</FlexRow> </FlexRow>
</Form> </div>
*/} </FlexRow>
</div> </div>
</Modal> </Modal>
); );
} }
ExternalShareModalPresentation.propTypes = { ExternalShareModalPresentation.propTypes = {
embedHtml: PropTypes.string,
fbUrl: PropTypes.string, fbUrl: PropTypes.string,
googUrl: PropTypes.string, googUrl: PropTypes.string,
intl: intlShape, intl: intlShape,
isOpen: PropTypes.bool, isOpen: PropTypes.bool,
onClickCopyEmbed: PropTypes.func, onCopyEmbed: PropTypes.func,
onCopyProjectLink: PropTypes.func,
onRequestClose: PropTypes.func, onRequestClose: PropTypes.func,
projectId: PropTypes.string, setEmbedTextarea: PropTypes.func,
setEmbedTextarea: PropTypes.string, twitterUrl: PropTypes.string
twitterUrl: PropTypes.string,
}; };
module.exports = injectIntl(ExternalShareModalPresentation); module.exports = injectIntl(ExternalShareModalPresentation);
//
// {/*
// <Form
// className="externalShare-form"
// ref={form => {
// this.form = form;
// }}
// onSubmit={onSubmit}
// onValidSubmit={this.handleValidSubmit}
// >
// */}
// {/*
// <FlexRow className="action-buttons">
// <Button
// className="action-button close-button white"
// key="closeButton"
// name="closeButton"
// type="button"
// onClick={onRequestClose}
// >
// <div className="action-button-text">
// <FormattedMessage id="general.close" />
// </div>
// </Button>
// </FlexRow>
// */}
//
//
// {/*
// {this.props.usernameHelp ? (
// <p className="help-text">{this.props.usernameHelp}</p>
// ) : (
// null
// )}
// */}
//

View file

@ -91,7 +91,7 @@
"general.whatsHappening": "What's Happening?", "general.whatsHappening": "What's Happening?",
"general.wiki": "Scratch Wiki", "general.wiki": "Scratch Wiki",
"general.copyLink": "Copy Link", "general.copyLink": "Copy Link",
"general.externalShareButton": "Share outside Scratch", "general.externalShareButton": "Social",
"general.report": "Report", "general.report": "Report",
"general.notAvailableHeadline": "Whoops! Our server is Scratch'ing its head", "general.notAvailableHeadline": "Whoops! Our server is Scratch'ing its head",
"general.notAvailableSubtitle": "We couldn't find the page you're looking for. Check to make sure you've typed the URL correctly.", "general.notAvailableSubtitle": "We couldn't find the page you're looking for. Check to make sure you've typed the URL correctly.",
@ -259,6 +259,8 @@
"comments.status.deleted": "Deleted", "comments.status.deleted": "Deleted",
"comments.status.reported": "Reported", "comments.status.reported": "Reported",
"externalShare.title": "Share outside Scratch", "externalShare.title": "Social",
"externalShare.embedHtmlContent": "Embed this html yo" "externalShare.embedHtmlLabel": "Embed",
"externalShare.linkLabel": "Link",
"externalShare.socialMediaLabel": "Share"
} }

View file

@ -1,11 +1,12 @@
module.exports = {}; module.exports = {};
module.exports.embedHtml = projectId => { module.exports.embedHtml = projectId => {
return ( if (projectId) {
'<iframe allowtransparency="true" width="485" height="402" ' + return `<iframe src="https://scratch.mit.edu/projects/${projectId}/embed?autostart=false" ` +
`src="//scratch.mit.edu/projects/${projectId}/embed?autostart=false" ` + 'allowtransparency="true" width="485" height="402" ' +
'frameborder="0" allowfullscreen></iframe>' 'frameborder="0" scrolling="no" allowfullscreen></iframe>';
); }
return '';
}; };
module.exports.twitterIntentLink = projectId => { module.exports.twitterIntentLink = projectId => {
@ -16,6 +17,12 @@ module.exports.twitterIntentLink = projectId => {
return `${baseUrl}url=${escapedScratchUrl}&text=${escapedTweetText}&hashtags=${escapedHashtags}`; return `${baseUrl}url=${escapedScratchUrl}&text=${escapedTweetText}&hashtags=${escapedHashtags}`;
}; };
module.exports.googleClassroomIntentLink = projectId => {
const baseUrl = 'https://classroom.google.com/share?';
const escapedScratchUrl = `https%3A%2F%2Fscratch.mit.edu%2Fprojects%2F${projectId}`;
return (`${baseUrl}url=${escapedScratchUrl}`);
};
module.exports.facebookIntentLink = projectId => { module.exports.facebookIntentLink = projectId => {
const baseUrl = 'https://www.facebook.com/sharer.php?'; const baseUrl = 'https://www.facebook.com/sharer.php?';
const escapedScratchUrl = `https%3A%2F%2Fscratch.mit.edu%2Fprojects%2F${projectId}`; const escapedScratchUrl = `https%3A%2F%2Fscratch.mit.edu%2Fprojects%2F${projectId}`;
@ -29,9 +36,3 @@ module.exports.facebookIntentDialog = (scratchFBAppId, projectId) => {
const escapedHashtag = '%23creativecode'; const escapedHashtag = '%23creativecode';
return `${baseUrl}app_id=${scratchFBAppId}href=${escapedScratchUrl}&hashtag=${escapedHashtag}`; return `${baseUrl}app_id=${scratchFBAppId}href=${escapedScratchUrl}&hashtag=${escapedHashtag}`;
}; };
module.exports.googleClassroomIntentLink = projectId => {
const baseUrl = 'https://classroom.google.com/share?';
const escapedScratchUrl = `https%3A%2F%2Fscratch.mit.edu%2Fprojects%2F${projectId}`;
return (`${baseUrl}url=${escapedScratchUrl}`);
};

View file

@ -67,6 +67,7 @@ const Subactions = props => (
isOpen isOpen
key="external-share-modal" key="external-share-modal"
projectId={props.projectInfo && props.projectInfo.id} projectId={props.projectInfo && props.projectInfo.id}
onCopyProjectLink={props.onCopyProjectLink}
onRequestClose={props.onExternalShareClosed} onRequestClose={props.onExternalShareClosed}
/> />
)} )}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="699.428" height="699.428"><path d="M502.714 0H240.428C194.178 0 153 42.425 153 87.429l-25.267.59c-46.228 0-84.019 41.834-84.019 86.838V612c0 45.004 41.179 87.428 87.429 87.428H459c46.249 0 87.428-42.424 87.428-87.428h21.857c46.25 0 87.429-42.424 87.429-87.428v-349.19L502.714 0zM459 655.715H131.143c-22.95 0-43.714-21.441-43.714-43.715V174.857c0-22.272 18.688-42.993 41.638-42.993l23.933-.721v393.429C153 569.576 194.178 612 240.428 612h262.286c0 22.273-20.765 43.715-43.714 43.715zm153-131.143c0 22.271-20.765 43.713-43.715 43.713H240.428c-22.95 0-43.714-21.441-43.714-43.713V87.429c0-22.272 20.764-43.714 43.714-43.714H459c-.351 50.337 0 87.975 0 87.975 0 45.419 40.872 86.882 87.428 86.882H612v306zm-65.572-349.715c-23.277 0-43.714-42.293-43.714-64.981V44.348L612 174.857h-65.572zm-43.714 131.537H306c-12.065 0-21.857 9.77-21.857 21.835 0 12.065 9.792 21.835 21.857 21.835h196.714c12.065 0 21.857-9.771 21.857-21.835 0-12.065-9.792-21.835-21.857-21.835zm0 109.176H306c-12.065 0-21.857 9.77-21.857 21.834 0 12.066 9.792 21.836 21.857 21.836h196.714c12.065 0 21.857-9.77 21.857-21.836 0-12.064-9.792-21.834-21.857-21.834z"/></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB