simplified embed modal to remove social links

This commit is contained in:
Ben Wheeler 2019-05-02 17:18:13 -04:00
parent fdfa61649f
commit 08f8e1c546
10 changed files with 121 additions and 153 deletions

View file

@ -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])
};

View file

@ -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;

View file

@ -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);

View file

@ -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",

View file

@ -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>';
}

View file

@ -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,

View file

@ -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}

View file

@ -61,7 +61,6 @@ const Subactions = props => (
isOpen
key="social-modal"
projectId={props.projectInfo && props.projectInfo.id}
onCopyProjectLink={props.onCopyProjectLink}
onRequestClose={props.onSocialClosed}
/>
)}

View file

@ -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");
}
}

View 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