first attempt at external share modal

This commit is contained in:
Ben Wheeler 2019-04-18 11:29:00 -04:00
parent db4c81fbec
commit 9587de480c
7 changed files with 380 additions and 0 deletions

View file

@ -0,0 +1,27 @@
const bindAll = require('lodash.bindall');
const PropTypes = require('prop-types');
const React = require('react');
const ExternalShareModalPresentation = require('./presentation.jsx');
class ExternalShareModal extends React.Component {
constructor (props) {
super(props);
}
render () {
return (
<ExternalShareModalPresentation
isOpen={this.props.isOpen}
onRequestClose={this.props.onRequestClose}
onSubmit={this.props.onRequestClose}
/>
);
}
}
ExternalShareModal.propTypes = {
isOpen: PropTypes.bool,
onRequestClose: PropTypes.func
};
module.exports = ExternalShareModal;

View file

@ -0,0 +1,194 @@
@import "../../../colors";
@import "../../../frameless";
.mod-externalShare {
min-height: 15rem;
max-height: calc(100% - 8rem);
/* Some value for height must be set for scrolling to work */
height: 100%;
overflow: hidden;
@media #{$small}, #{$small-height} {
overflow: hidden;
}
}
.externalShare-modal-header {
box-shadow: inset 0 -1px 0 0 $ui-blue-dark;
background-color: $ui-blue;
}
.externalShare-modal-content {
margin: 0 auto;
box-shadow: none;
width: 100%;
height: calc(100% - 3rem);
}
.external-target-outer-scrollbox {
position: relative;
background-color: $ui-blue-10percent;
flex: 1;
height: calc(100% - 5rem);
@media #{$small-height} {
min-height: 0;
}
}
.external-target-inner-scrollbox {
margin-right: .5rem;
padding-right: .5rem;
height: 100%;
overflow: scroll;
overflow-x: hidden;
&::-webkit-scrollbar {
width: 8px;
}
&::-webkit-scrollbar-thumb {
border-radius: 4px;
background-color: $active-dark-gray;
height: 92px;
}
&::-webkit-scrollbar-track {
margin-top: 8px;
margin-bottom: 10px;
}
}
.external-target-container {
display: flex;
padding: .40625rem 0 0 1.46875rem;
justify-content: flex-start;
flex-flow: row wrap;
}
/* NOTE: force scrolling: add to above:
min-height: 30rem;
*/
.external-target-bottom-gradient {
position: absolute;
right: 1rem;
bottom: 0;
left: 0;
background: linear-gradient(
$transparent-light-blue,
$ui-light-primary
);
height: 32px;
pointer-events: none; /* pass clicks through to buttons underneath */
}
.studio-selector-button {
display: flex;
position: relative;
transition: all .5s;
margin: .21875rem;
border-radius: .5rem;
background-color: $ui-white;
cursor: pointer;
padding: 0;
width: 48%;
height: 2.5rem;
justify-content: space-between;
align-items: center;
@media #{$small} {
min-width: 98%;
flex-shrink: 1;
}
}
.studio-selector-button-text {
margin: auto 2.18375rem auto .6875rem;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
font-size: .875rem;
font-weight: regular;
flex-shrink: 1;
}
.studio-selector-button-selected {
background-color: $ui-mint-green;
color: $ui-white;
}
.studio-selector-button-waiting {
background-color: $ui-light-mint;
color: $ui-white;
}
.studio-selector-button-text-selected {
color: $ui-white;
}
.studio-selector-button-text-unselected {
color: $type-gray;
}
.studio-selector-button-enabled {
pointer-events: auto;
}
.studio-selector-button-disabled {
pointer-events: none;
}
.studio-status-icon {
position: absolute;
right: .625rem;
border-radius: .75rem;
padding: .0625rem .075rem;
width: 1.5rem;
height: 1.5rem;
color: $ui-white;
box-sizing: border-box;
}
.studio-status-icon-unselected {
background-color: $ui-blue;
}
.submit-button {
background-color: $ui-blue;
}
.submit-button-waiting {
background-color: $ui-blue;
}
.studio-status-icon-plus-img,
.studio-status-icon-checkmark-img {
animation-direction: normal;
width: 1.4rem;
height: 1.4rem;
transform-origin: center;
}
.studio-status-icon-with-animation {
animation-name: bump;
animation-duration: .25s;
animation-timing-function: cubic-bezier(.3, -3, .6, 3);
animation-iteration-count: 1;
}
@keyframes bump {
0% {
transform: scale(0);
opacity: 0;
-webkit-transform: scale(0);
}
100% {
transform: scale(1);
opacity: 1;
-webkit-transform: scale(1);
}
}

View file

@ -0,0 +1,113 @@
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 Modal = require('../base/modal.jsx');
const Form = require('../../forms/form.jsx');
const Button = require('../../forms/button.jsx');
const FlexRow = require('../../flex-row/flex-row.jsx');
const Input = require('../../components/forms/input.jsx');
const TextArea = require('../../components/forms/textarea.jsx');
require('../../forms/button.scss');
require('./modal.scss');
const ExternalShareModalPresentation = ({
intl,
isOpen,
studios,
waitingToClose,
onToggleStudio,
onRequestClose,
onSubmit
}) => {
const contentLabel = intl.formatMessage({id: 'externalshare.title'});
return (
<Modal
useStandardSizes
className="mod-externalShare"
contentLabel={contentLabel}
isOpen={isOpen}
onRequestClose={onRequestClose}
>
<div className="externalShare-modal-header modal-header">
<div className="externalShare-content-label content-label">
{contentLabel}
</div>
</div>
<div className="externalShare-modal-content modal-content">
<div className="external-target-outer-scrollbox">
<div className="external-target-inner-scrollbox">
<div className="external-target-container">
<Form
ref={form => {
this.form = form;
}}
onValidSubmit={this.handleValidSubmit}
>
<div>
<div className="username-label">
<b>
{this.props.intl.formatMessage({id: 'registration.createUsername'})}
</b>
{this.props.usernameHelp ? (
<p className="help-text">{this.props.usernameHelp}</p>
) : (
null
)}
</div>
<Input
name="user.username"
type="text"
onBlur={this.handleUsernameBlur}
/>
<TextArea
required
className="report-text"
elementWrapperClassName="report-modal-field"
label={null}
name="notes"
placeholder={this.lookupPrompt(this.state.category)}
value={this.state.notes}
/>
</div>
</Form>
</div>
<div className="external-target-bottom-gradient" />
</div>
</div>
<Form
// className="external-share"
onSubmit={onSubmit}
>
<FlexRow className="action-buttons">
<Button
className="action-button submit-button"
key="submitButton"
type="submit"
>
<div className="action-button-text">
<FormattedMessage id="general.done" />
</div>
</Button>
</FlexRow>
</Form>
</div>
</Modal>
);
};
ExternalShareModalPresentation.propTypes = {
intl: intlShape,
isOpen: PropTypes.bool,
onRequestClose: PropTypes.func,
onSubmit: PropTypes.func
};
module.exports = injectIntl(ExternalShareModalPresentation);

View file

@ -67,6 +67,7 @@ const PreviewPresentation = ({
comments,
editable,
extensions,
externalShareOpen,
faved,
favoriteCount,
intl,
@ -90,6 +91,8 @@ const PreviewPresentation = ({
onCloseAdminPanel,
onCopyProjectLink,
onDeleteComment,
onExternalShareClicked,
onExternalShareClosed,
onFavoriteClicked,
onGreenFlag,
onLoadMore,
@ -364,6 +367,7 @@ const PreviewPresentation = ({
<Subactions
addToStudioOpen={addToStudioOpen}
canReport={canReport}
externalShareOpen={externalShareOpen}
isAdmin={isAdmin}
projectInfo={projectInfo}
reportOpen={reportOpen}
@ -372,6 +376,8 @@ const PreviewPresentation = ({
onAddToStudioClicked={onAddToStudioClicked}
onAddToStudioClosed={onAddToStudioClosed}
onCopyProjectLink={onCopyProjectLink}
onExternalShareClicked={onExternalShareClicked}
onExternalShareClosed={onExternalShareClosed}
onReportClicked={onReportClicked}
onReportClose={onReportClose}
onReportSubmit={onReportSubmit}
@ -510,6 +516,7 @@ const PreviewPresentation = ({
addToStudioOpen={addToStudioOpen}
canAddToStudio={canAddToStudio}
canReport={canReport}
externalShareOpen={externalShareOpen}
isAdmin={isAdmin}
projectInfo={projectInfo}
reportOpen={reportOpen}
@ -518,6 +525,8 @@ const PreviewPresentation = ({
onAddToStudioClicked={onAddToStudioClicked}
onAddToStudioClosed={onAddToStudioClosed}
onCopyProjectLink={onCopyProjectLink}
onExternalShareClicked={onExternalShareClicked}
onExternalShareClosed={onExternalShareClosed}
onReportClicked={onReportClicked}
onReportClose={onReportClose}
onReportSubmit={onReportSubmit}
@ -695,6 +704,8 @@ PreviewPresentation.propTypes = {
onCloseAdminPanel: PropTypes.func,
onCopyProjectLink: PropTypes.func,
onDeleteComment: PropTypes.func,
onExternalShareClicked: PropTypes.func,
onExternalShareClosed: PropTypes.func,
onFavoriteClicked: PropTypes.func,
onGreenFlag: PropTypes.func,
onLoadMore: PropTypes.func,

View file

@ -57,6 +57,8 @@ class Preview extends React.Component {
'handleClickLogo',
'handleCopyProjectLink',
'handleDeleteComment',
'handleExternalShareClick',
'handleExternalShareClose',
'handleToggleStudio',
'handleFavoriteToggle',
'handleLoadMore',
@ -109,6 +111,7 @@ class Preview extends React.Component {
clientFaved: false,
clientLoved: false,
extensions: [],
externalShareOpen: false,
favoriteCount: 0,
isProjectLoaded: false,
isRemixing: false,
@ -584,6 +587,12 @@ class Preview extends React.Component {
// Also do not include hash or query params
copy(`${window.location.origin}${window.location.pathname}`);
}
handleExternalShareClick () {
this.setState({externalShareOpen: true});
}
handleExternalShareClose () {
this.setState({externalShareOpen: false});
}
initCounts (favorites, loves) {
this.setState({
favoriteCount: favorites,
@ -648,6 +657,7 @@ class Preview extends React.Component {
comments={this.props.comments}
editable={this.props.isEditable}
extensions={this.state.extensions}
externalShareOpen={this.state.externalShareOpen}
faved={this.state.clientFaved}
favoriteCount={this.state.favoriteCount}
isAdmin={this.props.isAdmin}
@ -686,6 +696,8 @@ class Preview extends React.Component {
onCloseAdminPanel={this.handleCloseAdminPanel}
onCopyProjectLink={this.handleCopyProjectLink}
onDeleteComment={this.handleDeleteComment}
onExternalShareClicked={this.handleExternalShareClick}
onExternalShareClosed={this.handleExternalShareClose}
onFavoriteClicked={this.handleFavoriteToggle}
onGreenFlag={this.handleGreenFlag}
onLoadMore={this.handleLoadMore}

View file

@ -6,6 +6,7 @@ const FlexRow = require('../../components/flex-row/flex-row.jsx');
const Button = require('../../components/forms/button.jsx');
const AddToStudioModal = require('./add-to-studio.jsx');
const ExternalShareModal = require('../../components/modal/externalshare/container.jsx');
const ReportModal = require('../../components/modal/report/modal.jsx');
require('./subactions.scss');
@ -54,6 +55,19 @@ const Subactions = props => (
>
<FormattedMessage id="general.copyLink" />
</Button>
<Button
className="action-button external-share-button"
onClick={props.onExternalShareClicked}
>
<FormattedMessage id="general.externalShare" />
</Button>
{props.externalShareOpen && (
<ExternalShareModal
isOpen
key="external-share-modal"
onRequestClose={props.onExternalShareClosed}
/>
)}
{(props.canReport) &&
<React.Fragment>
<Button
@ -82,10 +96,13 @@ Subactions.propTypes = {
addToStudioOpen: PropTypes.bool,
canAddToStudio: PropTypes.bool,
canReport: PropTypes.bool,
externalShareOpen: PropTypes.bool,
isAdmin: PropTypes.bool,
onAddToStudioClicked: PropTypes.func,
onAddToStudioClosed: PropTypes.func,
onCopyProjectLink: PropTypes.func,
onExternalShareClicked: PropTypes.func,
onExternalShareClosed: PropTypes.func,
onReportClicked: PropTypes.func.isRequired,
onReportClose: PropTypes.func.isRequired,
onReportSubmit: PropTypes.func.isRequired,

View file

@ -87,6 +87,12 @@
}
}
&.external-share-button {
&:before {
background-image: url("/svgs/project/copy-link-white.svg");
}
}
&.report-button {
background-color: $ui-coral;