const injectIntl = require('react-intl').injectIntl; const PropTypes = require('prop-types'); const intlShape = require('react-intl').intlShape; const FormattedMessage = require('react-intl').FormattedMessage; const MediaQuery = require('react-responsive').default; const React = require('react'); const Formsy = require('formsy-react').default; const classNames = require('classnames'); const GUI = require('scratch-gui').default; const IntlGUI = injectIntl(GUI); 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 Banner = require('./banner.jsx'); const ModInfo = require('./mod-info.jsx'); const RemixCredit = require('./remix-credit.jsx'); const RemixList = require('./remix-list.jsx'); const Stats = require('./stats.jsx'); const StudioList = require('./studio-list.jsx'); const Subactions = require('./subactions.jsx'); const InplaceInput = require('../../components/forms/inplace-input.jsx'); const TopLevelComment = require('./comment/top-level-comment.jsx'); const ComposeComment = require('./comment/compose-comment.jsx'); const ExtensionChip = require('./extension-chip.jsx'); const thumbnailUrl = require('../../lib/user-thumbnail'); const projectShape = require('./projectshape.jsx').projectShape; require('./preview.scss'); const frameless = require('../../lib/frameless'); // disable enter key submission on formsy input fields; otherwise formsy thinks // we meant to trigger the "See inside" button. Instead, treat these keypresses // as a blur, which will trigger a save. const onKeyPress = e => { if (e.target.type === 'text' && e.which === 13 /* Enter */) { e.preventDefault(); e.target.blur(); } }; const PreviewPresentation = ({ addToStudioOpen, assetHost, backpackHost, canAddToStudio, canDeleteComments, canRemix, canReport, canRestoreComments, canSave, canShare, canUseBackpack, cloudHost, comments, editable, extensions, faved, favoriteCount, intl, isFullScreen, isLoggedIn, isShared, loveCount, loved, modInfo, moreCommentsToLoad, onAddComment, onAddToStudioClicked, onAddToStudioClosed, onCopyProjectLink, onDeleteComment, onFavoriteClicked, onLoadMore, onLoveClicked, onRemix, onReportClicked, onReportClose, onReportComment, onReportSubmit, onRestoreComment, onSeeAllComments, onSeeInside, onShare, onToggleComments, onToggleStudio, onUpdate, onUpdateProjectId, originalInfo, parentInfo, projectHost, projectId, projectInfo, projectStudios, remixes, replies, reportOpen, showModInfo, singleCommentId, userOwnsProject, visibilityInfo }) => { const shareDate = ((projectInfo.history && projectInfo.history.shared)) ? projectInfo.history.shared : ''; const revisedDate = ((projectInfo.history && projectInfo.history.modified)) ? projectInfo.history.modified : ''; // Allow embedding html in banner messages coming from the server const embedCensorMessage = message => ( // eslint-disable-next-line react/no-danger ); let banner; if (visibilityInfo.deleted) { // If both censored and deleted, prioritize deleted banner banner = (} />); } else if (visibilityInfo.censored) { if (visibilityInfo.reshareable) { banner = (} className="banner-danger" message={embedCensorMessage(visibilityInfo.censorMessage)} onAction={onShare} />); } else { banner = (); } } else if (canShare && !isShared) { banner = (} message={} onAction={onShare} />); } return (
{ projectInfo && projectInfo.author && projectInfo.author.id && ( {banner}
{editable ? :
{projectInfo.title}
{'by '} {projectInfo.author.username}
}
{canRemix && }
{/* eslint-disable max-len */} {extensions && extensions.map(extension => ( ))}
{editable ? :
{decorateText(projectInfo.instructions, { usernames: true, hashtags: true, scratchLinks: false })}
}
{editable ? :
{decorateText(projectInfo.description, { usernames: true, hashtags: true, scratchLinks: false })}
}
{/* eslint-enable max-len */}
{showModInfo &&
} {extensions && extensions.map(extension => ( ))}

{userOwnsProject ? (
) : null}
{/* Do not show the top-level comment form in single comment mode */} {!singleCommentId && ( {projectInfo.comments_allowed ? ( isLoggedIn ? ( ) : ( /* TODO add box for signing in to leave a comment */ null ) ) : (
)}
)} {comments.map(comment => ( ))} {moreCommentsToLoad && } {!!singleCommentId && }
)}
); }; PreviewPresentation.propTypes = { addToStudioOpen: PropTypes.bool, assetHost: PropTypes.string, backpackHost: PropTypes.string, canAddToStudio: PropTypes.bool, canDeleteComments: PropTypes.bool, canRemix: PropTypes.bool, canReport: PropTypes.bool, canRestoreComments: PropTypes.bool, canSave: PropTypes.bool, canShare: PropTypes.bool, canUseBackpack: PropTypes.bool, cloudHost: PropTypes.string, comments: PropTypes.arrayOf(PropTypes.object), editable: PropTypes.bool, extensions: PropTypes.arrayOf(PropTypes.object), faved: PropTypes.bool, favoriteCount: PropTypes.number, intl: intlShape, isFullScreen: PropTypes.bool, isLoggedIn: PropTypes.bool, isShared: PropTypes.bool, loveCount: PropTypes.number, loved: PropTypes.bool, modInfo: PropTypes.shape({ scripts: PropTypes.number, sprites: PropTypes.number }), moreCommentsToLoad: PropTypes.bool, onAddComment: PropTypes.func, onAddToStudioClicked: PropTypes.func, onAddToStudioClosed: PropTypes.func, onCopyProjectLink: PropTypes.func, onDeleteComment: PropTypes.func, onFavoriteClicked: PropTypes.func, onLoadMore: PropTypes.func, onLoveClicked: PropTypes.func, onRemix: PropTypes.func, onReportClicked: PropTypes.func.isRequired, onReportClose: PropTypes.func.isRequired, onReportComment: PropTypes.func.isRequired, onReportSubmit: PropTypes.func.isRequired, onRestoreComment: PropTypes.func, onSeeAllComments: PropTypes.func, onSeeInside: PropTypes.func, onShare: PropTypes.func, onToggleComments: PropTypes.func, onToggleStudio: PropTypes.func, onUpdate: PropTypes.func, onUpdateProjectId: PropTypes.func, originalInfo: projectShape, parentInfo: projectShape, projectHost: PropTypes.string, projectId: PropTypes.string, projectInfo: projectShape, projectStudios: PropTypes.arrayOf(PropTypes.object), remixes: PropTypes.arrayOf(PropTypes.object), replies: PropTypes.objectOf(PropTypes.array), reportOpen: PropTypes.bool, showModInfo: PropTypes.bool, singleCommentId: PropTypes.oneOfType([PropTypes.number, PropTypes.bool]), userOwnsProject: PropTypes.bool, visibilityInfo: PropTypes.shape({ censored: PropTypes.bool, censorMessage: PropTypes.string, deleted: PropTypes.bool, reshareable: PropTypes.bool }) }; module.exports = injectIntl(PreviewPresentation);