mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-26 17:16:11 -05:00
Merge pull request #3377 from benjiwheeler/embed-view
embed view with minimal functionality, route
This commit is contained in:
commit
18fd960a6a
5 changed files with 158 additions and 17 deletions
18
src/lib/sentry.js
Normal file
18
src/lib/sentry.js
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
const initSentry = () => {
|
||||||
|
// initialize Sentry instance, making sure it hasn't been initialized already
|
||||||
|
if (!window.Sentry && `${process.env.SENTRY_DSN}` !== '') {
|
||||||
|
const Sentry = require('@sentry/browser');
|
||||||
|
|
||||||
|
Sentry.init({
|
||||||
|
dsn: `${process.env.SENTRY_DSN}`,
|
||||||
|
// Do not collect global onerror, only collect specifically from React error boundaries.
|
||||||
|
// TryCatch plugin also includes errors from setTimeouts (i.e. the VM)
|
||||||
|
integrations: integrations => integrations.filter(i =>
|
||||||
|
!(i.name === 'GlobalHandlers' || i.name === 'TryCatch'))
|
||||||
|
});
|
||||||
|
|
||||||
|
window.Sentry = Sentry; // Allow GUI access to Sentry via window
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = initSentry;
|
|
@ -177,12 +177,20 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "projects",
|
"name": "projects",
|
||||||
"pattern": "^/projects(/editor|(/\\d+(/editor|/fullscreen|/embed)?)?)?/?(\\?.*)?$",
|
"pattern": "^/projects(/editor|(/\\d+(/editor|/fullscreen)?)?)?/?(\\?.*)?$",
|
||||||
"routeAlias": "/projects/?$",
|
"routeAlias": "/projects/?$",
|
||||||
"view": "preview/preview",
|
"view": "preview/preview",
|
||||||
"title": "Scratch Project",
|
"title": "Scratch Project",
|
||||||
"dynamicMetaTags": true
|
"dynamicMetaTags": true
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "embed",
|
||||||
|
"pattern": "^/projects/\\d+/embed/?(\\?.*)?$",
|
||||||
|
"routeAlias": "/projects/?$",
|
||||||
|
"view": "preview/embed",
|
||||||
|
"title": "Scratch Project",
|
||||||
|
"dynamicMetaTags": true
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "parents",
|
"name": "parents",
|
||||||
"pattern": "^/parents/?(\\?.*)?$",
|
"pattern": "^/parents/?(\\?.*)?$",
|
||||||
|
|
97
src/views/preview/embed-view.jsx
Normal file
97
src/views/preview/embed-view.jsx
Normal file
|
@ -0,0 +1,97 @@
|
||||||
|
// embed view
|
||||||
|
|
||||||
|
const React = require('react');
|
||||||
|
const PropTypes = require('prop-types');
|
||||||
|
const connect = require('react-redux').connect;
|
||||||
|
const injectIntl = require('react-intl').injectIntl;
|
||||||
|
|
||||||
|
const ErrorBoundary = require('../../components/errorboundary/errorboundary.jsx');
|
||||||
|
const projectShape = require('./projectshape.jsx').projectShape;
|
||||||
|
const NotAvailable = require('../../components/not-available/not-available.jsx');
|
||||||
|
const Meta = require('./meta.jsx');
|
||||||
|
|
||||||
|
const previewActions = require('../../redux/preview.js');
|
||||||
|
|
||||||
|
const GUI = require('scratch-gui');
|
||||||
|
const IntlGUI = injectIntl(GUI.default);
|
||||||
|
|
||||||
|
const initSentry = require('../../lib/sentry.js');
|
||||||
|
initSentry();
|
||||||
|
|
||||||
|
class EmbedView extends React.Component {
|
||||||
|
constructor (props) {
|
||||||
|
super(props);
|
||||||
|
const pathname = window.location.pathname.toLowerCase();
|
||||||
|
const parts = pathname.split('/').filter(Boolean);
|
||||||
|
this.state = {
|
||||||
|
extensions: [],
|
||||||
|
invalidProject: parts.length === 1,
|
||||||
|
projectId: parts[1]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
componentDidMount () {
|
||||||
|
this.props.getProjectInfo(this.state.projectId);
|
||||||
|
}
|
||||||
|
render () {
|
||||||
|
if (this.props.projectNotAvailable || this.state.invalidProject) {
|
||||||
|
return (
|
||||||
|
<ErrorBoundary>
|
||||||
|
<div className="preview">
|
||||||
|
<NotAvailable />
|
||||||
|
</div>
|
||||||
|
</ErrorBoundary>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<React.Fragment>
|
||||||
|
<Meta projectInfo={this.props.projectInfo} />
|
||||||
|
<IntlGUI
|
||||||
|
assetHost={this.props.assetHost}
|
||||||
|
basePath="/"
|
||||||
|
className="gui"
|
||||||
|
projectHost={this.props.projectHost}
|
||||||
|
projectId={this.state.projectId}
|
||||||
|
projectTitle={this.props.projectInfo.title}
|
||||||
|
/>
|
||||||
|
</React.Fragment>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EmbedView.propTypes = {
|
||||||
|
assetHost: PropTypes.string.isRequired,
|
||||||
|
getProjectInfo: PropTypes.func.isRequired,
|
||||||
|
projectHost: PropTypes.string.isRequired,
|
||||||
|
projectInfo: projectShape,
|
||||||
|
projectNotAvailable: PropTypes.bool
|
||||||
|
};
|
||||||
|
|
||||||
|
EmbedView.defaultProps = {
|
||||||
|
assetHost: process.env.ASSET_HOST,
|
||||||
|
projectHost: process.env.PROJECT_HOST
|
||||||
|
};
|
||||||
|
|
||||||
|
const mapStateToProps = state => ({
|
||||||
|
projectInfo: state.preview.projectInfo,
|
||||||
|
projectNotAvailable: state.preview.projectNotAvailable
|
||||||
|
});
|
||||||
|
|
||||||
|
const mapDispatchToProps = dispatch => ({
|
||||||
|
getProjectInfo: (id, token) => {
|
||||||
|
dispatch(previewActions.getProjectInfo(id, token));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
module.exports.View = connect(
|
||||||
|
mapStateToProps,
|
||||||
|
mapDispatchToProps
|
||||||
|
)(EmbedView);
|
||||||
|
|
||||||
|
GUI.setAppElement(document.getElementById('app'));
|
||||||
|
module.exports.initGuiState = GUI.initEmbedded;
|
||||||
|
module.exports.guiReducers = GUI.guiReducers;
|
||||||
|
module.exports.guiInitialState = GUI.guiInitialState;
|
||||||
|
module.exports.guiMiddleware = GUI.guiMiddleware;
|
||||||
|
module.exports.initLocale = GUI.initLocale;
|
||||||
|
module.exports.localesInitialState = GUI.localesInitialState;
|
30
src/views/preview/embed.jsx
Normal file
30
src/views/preview/embed.jsx
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
const React = require('react');
|
||||||
|
const ErrorBoundary = require('../../components/errorboundary/errorboundary.jsx');
|
||||||
|
const render = require('../../lib/render.jsx');
|
||||||
|
|
||||||
|
// Require this even though we don't use it because, without it, webpack runs out of memory...
|
||||||
|
const Page = require('../../components/page/www/page.jsx'); // eslint-disable-line no-unused-vars
|
||||||
|
|
||||||
|
const previewActions = require('../../redux/preview.js');
|
||||||
|
|
||||||
|
const isSupportedBrowser = require('../../lib/supported-browser').default;
|
||||||
|
const UnsupportedBrowser = require('./unsupported-browser.jsx');
|
||||||
|
|
||||||
|
if (isSupportedBrowser()) {
|
||||||
|
const EmbedView = require('./embed-view.jsx');
|
||||||
|
render(
|
||||||
|
<EmbedView.View />,
|
||||||
|
document.getElementById('app'),
|
||||||
|
{
|
||||||
|
preview: previewActions.previewReducer,
|
||||||
|
...EmbedView.guiReducers
|
||||||
|
},
|
||||||
|
{
|
||||||
|
locales: EmbedView.initLocale(EmbedView.localesInitialState, window._locale),
|
||||||
|
scratchGui: EmbedView.initGuiState(EmbedView.guiInitialState)
|
||||||
|
},
|
||||||
|
EmbedView.guiMiddleware
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
render(<ErrorBoundary><UnsupportedBrowser /></ErrorBoundary>, document.getElementById('app'));
|
||||||
|
}
|
|
@ -35,17 +35,8 @@ const IntlGUI = injectIntl(GUI.default);
|
||||||
|
|
||||||
const localStorageAvailable = 'localStorage' in window && window.localStorage !== null;
|
const localStorageAvailable = 'localStorage' in window && window.localStorage !== null;
|
||||||
|
|
||||||
const Sentry = require('@sentry/browser');
|
const initSentry = require('../../lib/sentry.js');
|
||||||
if (`${process.env.SENTRY_DSN}` !== '') {
|
initSentry();
|
||||||
Sentry.init({
|
|
||||||
dsn: `${process.env.SENTRY_DSN}`,
|
|
||||||
// Do not collect global onerror, only collect specifically from React error boundaries.
|
|
||||||
// TryCatch plugin also includes errors from setTimeouts (i.e. the VM)
|
|
||||||
integrations: integrations => integrations.filter(i =>
|
|
||||||
!(i.name === 'GlobalHandlers' || i.name === 'TryCatch'))
|
|
||||||
});
|
|
||||||
window.Sentry = Sentry; // Allow GUI access to Sentry via window
|
|
||||||
}
|
|
||||||
|
|
||||||
class Preview extends React.Component {
|
class Preview extends React.Component {
|
||||||
constructor (props) {
|
constructor (props) {
|
||||||
|
@ -258,7 +249,7 @@ class Preview extends React.Component {
|
||||||
// this is a project.json as an object
|
// this is a project.json as an object
|
||||||
// validate expects a string or buffer as input
|
// validate expects a string or buffer as input
|
||||||
// TODO not sure if we need to check that it also isn't a data view
|
// TODO not sure if we need to check that it also isn't a data view
|
||||||
input = JSON.stringify(input);
|
input = JSON.stringify(input); // NOTE: what is the point of doing this??
|
||||||
}
|
}
|
||||||
parser(projectAsset.data, false, (err, projectData) => {
|
parser(projectAsset.data, false, (err, projectData) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
|
@ -1092,16 +1083,13 @@ module.exports.initGuiState = guiInitialState => {
|
||||||
const parts = pathname.split('/').filter(Boolean);
|
const parts = pathname.split('/').filter(Boolean);
|
||||||
// parts[0]: 'projects'
|
// parts[0]: 'projects'
|
||||||
// parts[1]: either :id or 'editor'
|
// parts[1]: either :id or 'editor'
|
||||||
// parts[2]: undefined if no :id, otherwise either 'editor', 'fullscreen' or 'embed'
|
// parts[2]: undefined if no :id, otherwise either 'editor' or 'fullscreen'
|
||||||
if (parts.indexOf('editor') === -1) {
|
if (parts.indexOf('editor') === -1) {
|
||||||
guiInitialState = GUI.initPlayer(guiInitialState);
|
guiInitialState = GUI.initPlayer(guiInitialState);
|
||||||
}
|
}
|
||||||
if (parts.indexOf('fullscreen') !== -1) {
|
if (parts.indexOf('fullscreen') !== -1) {
|
||||||
guiInitialState = GUI.initFullScreen(guiInitialState);
|
guiInitialState = GUI.initFullScreen(guiInitialState);
|
||||||
}
|
}
|
||||||
if (parts.indexOf('embed') !== -1) {
|
|
||||||
guiInitialState = GUI.initEmbedded(guiInitialState);
|
|
||||||
}
|
|
||||||
return guiInitialState;
|
return guiInitialState;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue