mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2025-02-17 00:21:20 -05:00
FIxing PR #1900 comments
addresses most comments except modal refactor, and error response from sumitting report. * restore gui as a dev dependency * better separation of view container/presentation * replace absolute heights for textareas with making all sub components `display: flex` * start to make presentation more modular added subcomponents to the view folder: * share-banner (moved from components) * remix-credit * remix-list * studio-list
This commit is contained in:
parent
5124c613db
commit
6872cfc51f
13 changed files with 274 additions and 221 deletions
|
@ -29,8 +29,7 @@
|
|||
"express-http-proxy": "1.1.0",
|
||||
"lodash.defaults": "4.0.1",
|
||||
"newrelic": "1.25.4",
|
||||
"raven": "0.10.0",
|
||||
"scratch-gui": "0.1.0-prerelease.20180529181946"
|
||||
"raven": "0.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"ajv": "6.4.0",
|
||||
|
@ -97,6 +96,7 @@
|
|||
"redux-thunk": "2.0.1",
|
||||
"sass-lint": "1.5.1",
|
||||
"sass-loader": "6.0.6",
|
||||
"scratch-gui": "0.1.0-prerelease.20180529181946",
|
||||
"scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master",
|
||||
"slick-carousel": "1.6.0",
|
||||
"source-map-support": "0.3.2",
|
||||
|
|
|
@ -38,6 +38,8 @@ class InplaceInput extends React.Component {
|
|||
<FRCTextarea
|
||||
className="inplace-textarea"
|
||||
componentRef={this.setRef}
|
||||
elementWrapperClassName="grow"
|
||||
label={null}
|
||||
rowClassName={classNames('textarea-row no-label', className)}
|
||||
onBlur={this.handleBlur}
|
||||
{...props}
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
const classNames = require('classnames');
|
||||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
|
||||
require('./share-banner.scss');
|
||||
|
||||
const ShareBanner = props => (
|
||||
<div className={classNames('shareBanner', props.className)}>
|
||||
<div className="inner">
|
||||
{props.children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
ShareBanner.propTypes = {
|
||||
children: PropTypes.node,
|
||||
className: PropTypes.string
|
||||
};
|
||||
|
||||
module.exports = ShareBanner;
|
|
@ -1,10 +0,0 @@
|
|||
@import "../../colors";
|
||||
|
||||
$navigation-height: 50px;
|
||||
|
||||
.shareBanner {
|
||||
background-color: $ui-orange-25percent;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
color: $ui-orange;
|
||||
}
|
|
@ -14,7 +14,7 @@ const ThumbnailColumn = props => (
|
|||
if (props.itemType === 'preview') {
|
||||
return (
|
||||
<Thumbnail
|
||||
avatar={`https://cdn2.scratch.mit.edu/get_image/user/${item.author.i}_32x32.png`}
|
||||
avatar={`https://cdn2.scratch.mit.edu/get_image/user/${item.author.id}_32x32.png`}
|
||||
creator={item.author.username}
|
||||
favorites={item.stats.favorites}
|
||||
href={href}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
const bindAll = require('lodash.bindall');
|
||||
const FormattedDate = require('react-intl').FormattedDate;
|
||||
const injectIntl = require('react-intl').injectIntl;
|
||||
const PropTypes = require('prop-types');
|
||||
|
@ -10,14 +9,15 @@ const approx = require('approximate-number');
|
|||
const GUI = require('scratch-gui').default;
|
||||
const IntlGUI = injectIntl(GUI);
|
||||
|
||||
const sessionActions = require('../../redux/session.js');
|
||||
const decorateText = require('../../lib/decorate-text.jsx');
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const Button = require('../../components/forms/button.jsx');
|
||||
const Avatar = require('../../components/avatar/avatar.jsx');
|
||||
const CappedNumber = require('../../components/cappednumber/cappednumber.jsx');
|
||||
const ShareBanner = require('../../components/share-banner/share-banner.jsx');
|
||||
const ThumbnailColumn = require('../../components/thumbnailcolumn/thumbnailcolumn.jsx');
|
||||
const ShareBanner = require('./share-banner.jsx');
|
||||
const RemixCredit = require('./remix-credit.jsx');
|
||||
const RemixList = require('./remix-list.jsx');
|
||||
const StudioList = require('./studio-list.jsx');
|
||||
const InplaceInput = require('../../components/forms/inplace-input.jsx');
|
||||
const ReportModal = require('../../components/modal/report/modal.jsx');
|
||||
|
||||
|
@ -25,42 +25,15 @@ const projectShape = require('./projectshape.jsx').projectShape;
|
|||
require('./preview.scss');
|
||||
|
||||
class PreviewPresentation extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
bindAll(this, [
|
||||
'handleReportClick',
|
||||
'handleReportClose',
|
||||
'handleReportSubmit'
|
||||
]);
|
||||
this.state = {
|
||||
reportOpen: false
|
||||
};
|
||||
}
|
||||
handleReportClick (e) {
|
||||
e.preventDefault();
|
||||
this.setState({reportOpen: true});
|
||||
}
|
||||
handleReportClose () {
|
||||
this.setState({reportOpen: false});
|
||||
}
|
||||
|
||||
handleReportSubmit (formData, callback) {
|
||||
const data = {
|
||||
...formData,
|
||||
id: this.props.projectId,
|
||||
username: this.props.user.username
|
||||
};
|
||||
console.log('submit report data', data); // eslint-disable-line no-console
|
||||
// TODO: pass error to modal via callback.
|
||||
callback();
|
||||
this.setState({reportOpen: false});
|
||||
}
|
||||
userOwnsProject
|
||||
render () {
|
||||
const {
|
||||
editable,
|
||||
faved,
|
||||
favoriteCount,
|
||||
isFullScreen,
|
||||
isReportOpen,
|
||||
isShared,
|
||||
loved,
|
||||
loveCount,
|
||||
originalInfo,
|
||||
|
@ -68,30 +41,21 @@ class PreviewPresentation extends React.Component {
|
|||
projectId,
|
||||
projectInfo,
|
||||
remixes,
|
||||
sessionStatus,
|
||||
studios,
|
||||
user,
|
||||
userOwnsProject,
|
||||
onFavoriteClicked,
|
||||
onLoveClicked,
|
||||
onReportClicked,
|
||||
onReportClose,
|
||||
onReportSubmit,
|
||||
onSeeInside,
|
||||
onUpdate
|
||||
// ...otherProps TBD
|
||||
} = this.props;
|
||||
const shareDate = (projectInfo.history && projectInfo.history.shared) ? projectInfo.history.shared : '';
|
||||
const shareDate = ((projectInfo.history && projectInfo.history.shared)) ? projectInfo.history.shared : '';
|
||||
return (
|
||||
<div className="preview">
|
||||
{projectInfo.history && shareDate === '' &&
|
||||
<ShareBanner>
|
||||
<FlexRow className="preview-row">
|
||||
<span className="share-text">
|
||||
This project is not shared — so only you can see it. Click share to let everyone see it!
|
||||
</span>
|
||||
<Button className="button share-button">
|
||||
Share
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</ShareBanner>
|
||||
}
|
||||
<ShareBanner shared={isShared} />
|
||||
|
||||
{ projectInfo && projectInfo.author && projectInfo.author.id && (
|
||||
<div className="inner">
|
||||
|
@ -122,14 +86,19 @@ class PreviewPresentation extends React.Component {
|
|||
}}
|
||||
value={projectInfo.title}
|
||||
/> :
|
||||
<div className="project-title">{projectInfo.title}</div>
|
||||
<React.Fragment>
|
||||
<div className="project-title">{projectInfo.title}</div>
|
||||
{'by '}
|
||||
<a href={`/users/${projectInfo.author.username}`}>
|
||||
{projectInfo.author.username}
|
||||
</a>
|
||||
</React.Fragment>
|
||||
}
|
||||
</div>
|
||||
</FlexRow>
|
||||
<div className="project-buttons">
|
||||
{sessionStatus === sessionActions.Status.FETCHED &&
|
||||
Object.keys(user).length > 0 &&
|
||||
user.id !== projectInfo.author.id &&
|
||||
{/* TODO: Hide Remix button for now until implemented */}
|
||||
{(!userOwnsProject && false) &&
|
||||
<Button className="button remix-button">
|
||||
Remix
|
||||
</Button>
|
||||
|
@ -154,44 +123,8 @@ class PreviewPresentation extends React.Component {
|
|||
/>
|
||||
</div>
|
||||
<FlexRow className="project-notes">
|
||||
{parentInfo && parentInfo.author && parentInfo.id && (
|
||||
<FlexRow className="remix-credit">
|
||||
<Avatar
|
||||
className="remix"
|
||||
src={`https://cdn2.scratch.mit.edu/get_image/user/${parentInfo.author.id}_48x48.png`}
|
||||
/>
|
||||
<div className="credit-text">
|
||||
Thanks to <a
|
||||
href={`/users/${parentInfo.author.username}`}
|
||||
>
|
||||
{parentInfo.author.username}
|
||||
</a> for the original project <a
|
||||
href={`/preview/${parentInfo.id}`}
|
||||
>
|
||||
{parentInfo.title}
|
||||
</a>.
|
||||
</div>
|
||||
</FlexRow>
|
||||
)}
|
||||
{originalInfo && originalInfo.author && originalInfo.id && (
|
||||
<FlexRow className="remix-credit">
|
||||
<Avatar
|
||||
className="remix"
|
||||
src={`https://cdn2.scratch.mit.edu/get_image/user/${originalInfo.author.id}_48x48.png`}
|
||||
/>
|
||||
<div className="credit-text">
|
||||
Thanks to <a
|
||||
href={`/users/${originalInfo.author.username}`}
|
||||
>
|
||||
{originalInfo.author.username}
|
||||
</a> for the original project <a
|
||||
href={`/preview/${originalInfo.id}`}
|
||||
>
|
||||
{originalInfo.title}
|
||||
</a>.
|
||||
</div>
|
||||
</FlexRow>
|
||||
)}
|
||||
<RemixCredit projectInfo={parentInfo} />
|
||||
<RemixCredit projectInfo={originalInfo} />
|
||||
{/* eslint-disable max-len */}
|
||||
<FlexRow className="description-block">
|
||||
<div className="project-textlabel">
|
||||
|
@ -311,80 +244,34 @@ class PreviewPresentation extends React.Component {
|
|||
<Button className="action-button copy-link-button">
|
||||
Copy Link
|
||||
</Button>
|
||||
{
|
||||
sessionStatus === sessionActions.Status.FETCHED &&
|
||||
Object.keys(user).length > 0 &&
|
||||
user.id !== projectInfo.author.id && [
|
||||
{(!userOwnsProject) &&
|
||||
<React.Fragment>
|
||||
<Button
|
||||
className="action-button report-button"
|
||||
key="report-button"
|
||||
onClick={this.handleReportClick}
|
||||
onClick={onReportClicked}
|
||||
>
|
||||
Report
|
||||
</Button>,
|
||||
<ReportModal
|
||||
isOpen={this.state.reportOpen}
|
||||
isOpen={isReportOpen}
|
||||
key="report-modal"
|
||||
type="project"
|
||||
onReport={this.handleReportSubmit}
|
||||
onRequestClose={this.handleReportClose}
|
||||
onReport={onReportSubmit}
|
||||
onRequestClose={onReportClose}
|
||||
/>
|
||||
]
|
||||
</React.Fragment>
|
||||
}
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
<FlexRow className="preview-row">
|
||||
<div className="comments-container">
|
||||
<div className="project-title">
|
||||
Comments go here
|
||||
</div>
|
||||
<div className="project-title" />
|
||||
</div>
|
||||
<FlexRow className="column">
|
||||
{/* hide remixes if there aren't any */}
|
||||
{remixes && remixes.length !== 0 && (
|
||||
<FlexRow className="remix-list">
|
||||
<div className="project-title">
|
||||
Remixes
|
||||
</div>
|
||||
{remixes && remixes.length === 0 ? (
|
||||
// TODO: style remix invitation
|
||||
<span>Invite user to remix</span>
|
||||
) : (
|
||||
<ThumbnailColumn
|
||||
cards
|
||||
showAvatar
|
||||
itemType="preview"
|
||||
items={remixes.slice(0, 5)}
|
||||
showFavorites={false}
|
||||
showLoves={false}
|
||||
showViews={false}
|
||||
/>
|
||||
)}
|
||||
</FlexRow>
|
||||
)}
|
||||
{/* hide studios if there aren't any */}
|
||||
{studios && studios.length !== 0 && (
|
||||
<FlexRow className="studio-list">
|
||||
<div className="project-title">
|
||||
Studios
|
||||
</div>
|
||||
{studios && studios.length === 0 ? (
|
||||
// TODO: invite user to add to studio?
|
||||
<span>None </span>
|
||||
) : (
|
||||
<ThumbnailColumn
|
||||
cards
|
||||
showAvatar
|
||||
itemType="gallery"
|
||||
items={studios.slice(0, 5)}
|
||||
showFavorites={false}
|
||||
showLoves={false}
|
||||
showViews={false}
|
||||
/>
|
||||
)}
|
||||
</FlexRow>
|
||||
)}
|
||||
<RemixList remixes={remixes} />
|
||||
<StudioList studios={studios} />
|
||||
</FlexRow>
|
||||
</FlexRow>
|
||||
</Formsy>
|
||||
|
@ -401,10 +288,15 @@ PreviewPresentation.propTypes = {
|
|||
faved: PropTypes.bool,
|
||||
favoriteCount: PropTypes.number,
|
||||
isFullScreen: PropTypes.bool,
|
||||
isReportOpen: PropTypes.bool,
|
||||
isShared: PropTypes.bool,
|
||||
loveCount: PropTypes.number,
|
||||
loved: PropTypes.bool,
|
||||
onFavoriteClicked: PropTypes.func,
|
||||
onLoveClicked: PropTypes.func,
|
||||
onReportClicked: PropTypes.func.isRequired,
|
||||
onReportClose: PropTypes.func.isRequired,
|
||||
onReportSubmit: PropTypes.func.isRequired,
|
||||
onSeeInside: PropTypes.func,
|
||||
onUpdate: PropTypes.func,
|
||||
originalInfo: projectShape,
|
||||
|
@ -412,18 +304,8 @@ PreviewPresentation.propTypes = {
|
|||
projectId: PropTypes.string,
|
||||
projectInfo: projectShape,
|
||||
remixes: PropTypes.arrayOf(PropTypes.object),
|
||||
sessionStatus: PropTypes.string.isRequired,
|
||||
studios: PropTypes.arrayOf(PropTypes.object),
|
||||
user: PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
banned: PropTypes.bool,
|
||||
username: PropTypes.string,
|
||||
token: PropTypes.string,
|
||||
thumbnailUrl: PropTypes.string,
|
||||
dateJoined: PropTypes.string,
|
||||
email: PropTypes.string,
|
||||
classroomId: PropTypes.string
|
||||
}).isRequired
|
||||
userOwnsProject: PropTypes.bool
|
||||
};
|
||||
|
||||
module.exports = injectIntl(PreviewPresentation);
|
||||
|
|
|
@ -24,12 +24,28 @@ class Preview extends React.Component {
|
|||
'handleLoveToggle',
|
||||
'handlePermissions',
|
||||
'handlePopState',
|
||||
'handleReportClick',
|
||||
'handleReportClose',
|
||||
'handleReportSubmit',
|
||||
'handleSeeInside',
|
||||
'handleUpdate',
|
||||
'initCounts',
|
||||
'pushHistory'
|
||||
'isShared',
|
||||
'pushHistory',
|
||||
'userOwnsProject'
|
||||
]);
|
||||
this.state = this.initState();
|
||||
const pathname = window.location.pathname.toLowerCase();
|
||||
const parts = pathname.split('/').filter(Boolean);
|
||||
// parts[0]: 'preview'
|
||||
// parts[1]: either :id or 'editor'
|
||||
// parts[2]: undefined if no :id, otherwise either 'editor' or 'fullscreen'
|
||||
this.state = {
|
||||
editable: false,
|
||||
favoriteCount: 0,
|
||||
loveCount: 0,
|
||||
projectId: parts[1] === 'editor' ? 0 : parts[1],
|
||||
reportOpen: false
|
||||
};
|
||||
this.addEventListeners();
|
||||
}
|
||||
componentDidUpdate (prevProps) {
|
||||
|
@ -89,6 +105,21 @@ class Preview extends React.Component {
|
|||
removeEventListeners () {
|
||||
window.removeEventListener('popstate', this.handlePopState);
|
||||
}
|
||||
handleReportClick () {
|
||||
this.setState({reportOpen: true});
|
||||
}
|
||||
handleReportClose () {
|
||||
this.setState({reportOpen: false});
|
||||
}
|
||||
handleReportSubmit (formData) {
|
||||
const data = {
|
||||
...formData,
|
||||
id: this.state.projectId,
|
||||
username: this.props.user.username
|
||||
};
|
||||
console.log('submit report data', data); // eslint-disable-line no-console
|
||||
this.setState({reportOpen: false});
|
||||
}
|
||||
handlePopState () {
|
||||
const path = window.location.pathname.toLowerCase();
|
||||
const playerMode = path.indexOf('editor') === -1;
|
||||
|
@ -179,6 +210,23 @@ class Preview extends React.Component {
|
|||
loveCount: loves
|
||||
});
|
||||
}
|
||||
isShared () {
|
||||
return (
|
||||
// if we don't have projectInfo assume shared until we know otherwise
|
||||
Object.keys(this.props.projectInfo).length === 0 || (
|
||||
this.props.projectInfo.history &&
|
||||
this.props.projectInfo.history.shared.length > 0
|
||||
)
|
||||
);
|
||||
}
|
||||
userOwnsProject () {
|
||||
return (
|
||||
this.props.sessionStatus === sessionActions.Status.FETCHED &&
|
||||
Object.keys(this.props.user).length > 0 &&
|
||||
Object.keys(this.props.projectInfo).length > 0 &&
|
||||
this.props.user.id === this.props.projectInfo.author.id
|
||||
);
|
||||
}
|
||||
render () {
|
||||
return (
|
||||
this.props.playerMode ?
|
||||
|
@ -189,6 +237,8 @@ class Preview extends React.Component {
|
|||
faved={this.props.faved}
|
||||
favoriteCount={this.state.favoriteCount}
|
||||
isFullScreen={this.state.isFullScreen}
|
||||
isReportOpen={this.state.reportOpen}
|
||||
isShared={this.isShared()}
|
||||
loveCount={this.state.loveCount}
|
||||
loved={this.props.loved}
|
||||
originalInfo={this.props.original}
|
||||
|
@ -196,11 +246,14 @@ class Preview extends React.Component {
|
|||
projectId={this.state.projectId}
|
||||
projectInfo={this.props.projectInfo}
|
||||
remixes={this.props.remixes}
|
||||
sessionStatus={this.props.sessionStatus}
|
||||
studios={this.props.studios}
|
||||
user={this.props.user}
|
||||
userOwnsProject={this.userOwnsProject()}
|
||||
onFavoriteClicked={this.handleFavoriteToggle}
|
||||
onLoveClicked={this.handleLoveToggle}
|
||||
onReportClicked={this.handleReportClick}
|
||||
onReportClose={this.handleReportClose}
|
||||
onReportSubmit={this.handleReportSubmit}
|
||||
onSeeInside={this.handleSeeInside}
|
||||
onUpdate={this.handleUpdate}
|
||||
/>
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
@import "../../colors";
|
||||
@import "../../frameless";
|
||||
|
||||
/* stage size contants
|
||||
/* stage size constants
|
||||
* this is a hack right now - stage includes padding of .5rem (8px) for alignment in gui
|
||||
* in www the player is placed with margin -.5rem to align the edge.
|
||||
* the height is calculated from the actual height on the page (404)
|
||||
|
@ -10,13 +10,6 @@ $gui-width: 496px;
|
|||
$stage-width: 480px;
|
||||
$stage-height: 404px;
|
||||
|
||||
|
||||
// remix credit height: 52px
|
||||
// project text label line-height + margin-bottom .5rem: 19px + 8px = 27px
|
||||
// Formsy wrapper adds 3px to the input height for
|
||||
$description-input: 166px; // $stage-height / 2 - $project-label - $wrapper - margin
|
||||
$description-input-small: 120px; // normal $description-input - $remix-credit
|
||||
|
||||
/* override view padding for share banner */
|
||||
#view {
|
||||
padding: 0 0 20px 0;
|
||||
|
@ -138,7 +131,6 @@ $description-input-small: 120px; // normal $description-input - $remix-credit
|
|||
width: 60%;
|
||||
}
|
||||
|
||||
.share-button,
|
||||
.remix-button,
|
||||
.see-inside-button {
|
||||
margin-top: 0;
|
||||
|
@ -158,18 +150,6 @@ $description-input-small: 120px; // normal $description-input - $remix-credit
|
|||
}
|
||||
}
|
||||
|
||||
.shareText {
|
||||
align-self: center;
|
||||
}
|
||||
|
||||
.share-button {
|
||||
background-color: $ui-orange;
|
||||
|
||||
&:before {
|
||||
background-image: url("/svgs/project/share-white.svg");
|
||||
}
|
||||
}
|
||||
|
||||
.remix-button {
|
||||
background-color: $ui-green;
|
||||
|
||||
|
@ -267,6 +247,7 @@ $description-input-small: 120px; // normal $description-input - $remix-credit
|
|||
}
|
||||
|
||||
.project-description-edit {
|
||||
display: flex;
|
||||
margin-bottom: .75rem;
|
||||
border: 1px solid $ui-blue-10percent;
|
||||
border-radius: 8px;
|
||||
|
@ -293,15 +274,12 @@ $description-input-small: 120px; // normal $description-input - $remix-credit
|
|||
}
|
||||
}
|
||||
|
||||
.inplace-textarea {
|
||||
height: $description-input;
|
||||
& > .grow {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.project-description-edit.remixes .inplace-textarea {
|
||||
height: $description-input-small;
|
||||
}
|
||||
|
||||
.copyleft {
|
||||
display: inline-block;
|
||||
transform: scale(-1, 1);
|
||||
|
|
34
src/views/preview/remix-credit.jsx
Normal file
34
src/views/preview/remix-credit.jsx
Normal file
|
@ -0,0 +1,34 @@
|
|||
const React = require('react');
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const Avatar = require('../../components/avatar/avatar.jsx');
|
||||
const projectShape = require('./projectshape.jsx').projectShape;
|
||||
|
||||
const RemixCredit = props => {
|
||||
const projectInfo = props.projectInfo;
|
||||
if (Object.keys(projectInfo).length === 0) return null;
|
||||
return (
|
||||
<FlexRow className="remix-credit">
|
||||
<Avatar
|
||||
className="remix"
|
||||
src={`https://cdn2.scratch.mit.edu/get_image/user/${projectInfo.author.id}_48x48.png`}
|
||||
/>
|
||||
<div className="credit-text">
|
||||
Thanks to <a
|
||||
href={`/users/${projectInfo.author.username}`}
|
||||
>
|
||||
{projectInfo.author.username}
|
||||
</a> for the original project <a
|
||||
href={`/preview/${projectInfo.id}`}
|
||||
>
|
||||
{projectInfo.title}
|
||||
</a>.
|
||||
</div>
|
||||
</FlexRow>
|
||||
);
|
||||
};
|
||||
|
||||
RemixCredit.propTypes = {
|
||||
projectInfo: projectShape
|
||||
};
|
||||
|
||||
module.exports = RemixCredit;
|
37
src/views/preview/remix-list.jsx
Normal file
37
src/views/preview/remix-list.jsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const ThumbnailColumn = require('../../components/thumbnailcolumn/thumbnailcolumn.jsx');
|
||||
const projectShape = require('./projectshape.jsx').projectShape;
|
||||
|
||||
const RemixList = props => {
|
||||
const remixes = props.remixes;
|
||||
if (remixes.length === 0) return null;
|
||||
return (
|
||||
<FlexRow className="remix-list">
|
||||
<div className="project-title">
|
||||
Remixes
|
||||
</div>
|
||||
{remixes.length === 0 ? (
|
||||
// TODO: style remix invitation
|
||||
<span>Invite user to remix</span>
|
||||
) : (
|
||||
<ThumbnailColumn
|
||||
cards
|
||||
showAvatar
|
||||
itemType="preview"
|
||||
items={remixes.slice(0, 5)}
|
||||
showFavorites={false}
|
||||
showLoves={false}
|
||||
showViews={false}
|
||||
/>
|
||||
)}
|
||||
</FlexRow>
|
||||
);
|
||||
};
|
||||
|
||||
RemixList.propTypes = {
|
||||
remixes: PropTypes.arrayOf(projectShape)
|
||||
};
|
||||
|
||||
module.exports = RemixList;
|
30
src/views/preview/share-banner.jsx
Normal file
30
src/views/preview/share-banner.jsx
Normal file
|
@ -0,0 +1,30 @@
|
|||
const PropTypes = require('prop-types');
|
||||
const React = require('react');
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const Button = require('../../components/forms/button.jsx');
|
||||
|
||||
require('./share-banner.scss');
|
||||
|
||||
const ShareBanner = props => {
|
||||
if (props.shared) return null;
|
||||
return (
|
||||
<div className="shareBanner">
|
||||
<div className="inner">
|
||||
<FlexRow className="preview-row">
|
||||
<span className="share-text">
|
||||
This project is not shared — so only you can see it. Click share to let everyone see it!
|
||||
</span>
|
||||
<Button className="button share-button">
|
||||
Share
|
||||
</Button>
|
||||
</FlexRow>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
ShareBanner.propTypes = {
|
||||
shared: PropTypes.bool.isRequired
|
||||
};
|
||||
|
||||
module.exports = ShareBanner;
|
30
src/views/preview/share-banner.scss
Normal file
30
src/views/preview/share-banner.scss
Normal file
|
@ -0,0 +1,30 @@
|
|||
@import "../../colors";
|
||||
|
||||
$navigation-height: 50px;
|
||||
|
||||
.shareBanner {
|
||||
background-color: $ui-orange-25percent;
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
color: $ui-orange;
|
||||
}
|
||||
|
||||
.share-button {
|
||||
margin-top: 0;
|
||||
background-color: $ui-orange;
|
||||
font-size: .875rem;
|
||||
font-weight: normal;
|
||||
|
||||
&:before {
|
||||
display: inline-block;
|
||||
margin-right: .5rem;
|
||||
background-image: url("/svgs/project/share-white.svg");
|
||||
background-repeat: no-repeat;
|
||||
background-position: center center;
|
||||
background-size: contain;
|
||||
width: 1.25rem;
|
||||
height: 1.25rem;
|
||||
vertical-align: middle;
|
||||
content: "";
|
||||
}
|
||||
}
|
37
src/views/preview/studio-list.jsx
Normal file
37
src/views/preview/studio-list.jsx
Normal file
|
@ -0,0 +1,37 @@
|
|||
const React = require('react');
|
||||
const PropTypes = require('prop-types');
|
||||
const FlexRow = require('../../components/flex-row/flex-row.jsx');
|
||||
const ThumbnailColumn = require('../../components/thumbnailcolumn/thumbnailcolumn.jsx');
|
||||
const projectShape = require('./projectshape.jsx').projectShape;
|
||||
|
||||
const StudioList = props => {
|
||||
const studios = props.studios;
|
||||
if (studios.length === 0) return null;
|
||||
return (
|
||||
<FlexRow className="remix-list">
|
||||
<div className="project-title">
|
||||
Studios
|
||||
</div>
|
||||
{studios.length === 0 ? (
|
||||
// TODO: style remix invitation
|
||||
<span>Invite user to add to studio</span>
|
||||
) : (
|
||||
<ThumbnailColumn
|
||||
cards
|
||||
showAvatar
|
||||
itemType="studio"
|
||||
items={studios.slice(0, 5)}
|
||||
showFavorites={false}
|
||||
showLoves={false}
|
||||
showViews={false}
|
||||
/>
|
||||
)}
|
||||
</FlexRow>
|
||||
);
|
||||
};
|
||||
|
||||
StudioList.propTypes = {
|
||||
studios: PropTypes.arrayOf(projectShape)
|
||||
};
|
||||
|
||||
module.exports = StudioList;
|
Loading…
Reference in a new issue