mirror of
https://github.com/scratchfoundation/scratch-www.git
synced 2024-11-26 17:16:11 -05:00
Handle See inside button (#1890)
* Handle See inside button Import GUI reducers, initial state and middleware (throttle). Update render to handle state and middleware. Remove preview mode state and use scratchGui.mode from redux instead. URL is getting updated, and mode will be updated based on URL. However, the history needs work - it doesn’t work with the modal back. * Update to latest GUI This is the minimum version of GUI that is needed for see-inside * Really remove cruft.
This commit is contained in:
parent
15779d833e
commit
80de164d02
4 changed files with 118 additions and 25 deletions
|
@ -95,7 +95,7 @@
|
|||
"redux-thunk": "2.0.1",
|
||||
"sass-lint": "1.5.1",
|
||||
"sass-loader": "6.0.6",
|
||||
"scratch-gui": "0.1.0-prerelease.20180427201459",
|
||||
"scratch-gui": "0.1.0-prerelease.20180522203439",
|
||||
"scratchr2_translations": "git://github.com/LLK/scratchr2_translations.git#master",
|
||||
"slick-carousel": "1.6.0",
|
||||
"source-map-support": "0.3.2",
|
||||
|
|
|
@ -14,11 +14,13 @@ require('../main.scss');
|
|||
|
||||
/**
|
||||
* Function to render views into a full page
|
||||
* @param {object} jsx jsx component of the view
|
||||
* @param {object} element html element to render to on the template
|
||||
* @param {array} reducers list of view-specific reducers
|
||||
* @param {object} jsx jsx component of the view
|
||||
* @param {object} element html element to render to on the template
|
||||
* @param {array} reducers list of view-specific reducers
|
||||
* @param {object} initialState optional initialState for store
|
||||
* @param {bool} enhancer whether or not to apply redux-throttle middleware
|
||||
*/
|
||||
const render = (jsx, element, reducers) => {
|
||||
const render = (jsx, element, reducers, initialState, enhancer) => {
|
||||
// Get locale and messages from global namespace (see "init.js")
|
||||
let locale = window._locale || 'en';
|
||||
let messages = {};
|
||||
|
@ -35,9 +37,20 @@ const render = (jsx, element, reducers) => {
|
|||
}
|
||||
|
||||
const allReducers = reducer(reducers);
|
||||
|
||||
const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || redux.compose;
|
||||
const enhancers = enhancer ?
|
||||
composeEnhancers(
|
||||
redux.applyMiddleware(thunk),
|
||||
enhancer
|
||||
) :
|
||||
composeEnhancers(
|
||||
redux.applyMiddleware(thunk)
|
||||
);
|
||||
const store = redux.createStore(
|
||||
allReducers,
|
||||
redux.applyMiddleware(thunk)
|
||||
initialState || {},
|
||||
enhancers
|
||||
);
|
||||
|
||||
// Render view component
|
||||
|
|
|
@ -306,7 +306,7 @@ PreviewPresentation.propTypes = {
|
|||
onLoveClicked: PropTypes.func,
|
||||
onSeeInside: PropTypes.func,
|
||||
onUpdate: PropTypes.func,
|
||||
projectId: PropTypes.number,
|
||||
projectId: PropTypes.string,
|
||||
projectInfo: PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
title: PropTypes.string,
|
||||
|
|
|
@ -10,21 +10,26 @@ const PreviewPresentation = require('./presentation.jsx');
|
|||
|
||||
const sessionActions = require('../../redux/session.js');
|
||||
const previewActions = require('../../redux/preview.js');
|
||||
const GUI = require('scratch-gui').default;
|
||||
const IntlGUI = injectIntl(GUI);
|
||||
|
||||
const GUI = require('scratch-gui');
|
||||
const IntlGUI = injectIntl(GUI.default);
|
||||
|
||||
class Preview extends React.Component {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
bindAll(this, [
|
||||
'addEventListeners',
|
||||
'handleFavoriteToggle',
|
||||
'handleLoveToggle',
|
||||
'handlePermissions',
|
||||
'handlePopState',
|
||||
'handleSeeInside',
|
||||
'handleUpdate',
|
||||
'initCounts'
|
||||
'initCounts',
|
||||
'pushHistory'
|
||||
]);
|
||||
this.state = this.initState();
|
||||
this.addEventListeners();
|
||||
}
|
||||
componentDidUpdate (prevProps) {
|
||||
if (this.props.sessionStatus !== prevProps.sessionStatus &&
|
||||
|
@ -52,6 +57,51 @@ class Preview extends React.Component {
|
|||
this.props.getCreditInfo(this.props.projectInfo.remix.root);
|
||||
}
|
||||
}
|
||||
if (this.props.playerMode !== prevProps.playerMode || this.props.fullScreen !== prevProps.fullScreen) {
|
||||
this.pushHistory(history.state === null);
|
||||
}
|
||||
}
|
||||
componentWillUnmount () {
|
||||
this.removeEventListeners();
|
||||
}
|
||||
addEventListeners () {
|
||||
window.addEventListener('popstate', this.handlePopState);
|
||||
}
|
||||
removeEventListeners () {
|
||||
window.removeEventListener('popstate', this.handlePopState);
|
||||
}
|
||||
handlePopState () {
|
||||
const path = window.location.pathname.toLowerCase();
|
||||
const playerMode = path.indexOf('editor') === -1;
|
||||
const fullScreen = path.indexOf('fullscreen') !== -1;
|
||||
if (this.props.playerMode !== playerMode) {
|
||||
this.props.setPlayer(playerMode);
|
||||
}
|
||||
if (this.props.fullScreen !== fullScreen) {
|
||||
this.props.setFullScreen(fullScreen);
|
||||
}
|
||||
}
|
||||
pushHistory (push) {
|
||||
// update URI to match mode
|
||||
const idPath = this.state.projectId ? `${this.state.projectId}/` : '';
|
||||
let modePath = '';
|
||||
if (!this.props.playerMode) modePath = 'editor/';
|
||||
// fullscreen overrides editor
|
||||
if (this.props.fullScreen) modePath = 'fullscreen/';
|
||||
const newPath = `/preview/${idPath}${modePath}`;
|
||||
if (push) {
|
||||
history.pushState(
|
||||
{},
|
||||
document.title,
|
||||
newPath
|
||||
);
|
||||
} else {
|
||||
history.replaceState(
|
||||
{},
|
||||
document.title,
|
||||
newPath
|
||||
);
|
||||
}
|
||||
}
|
||||
initState () {
|
||||
const pathname = window.location.pathname.toLowerCase();
|
||||
|
@ -62,10 +112,8 @@ class Preview extends React.Component {
|
|||
return {
|
||||
editable: false,
|
||||
favoriteCount: 0,
|
||||
inEditor: parts.indexOf('editor') !== -1,
|
||||
isFullScreen: parts.indexOf('fullscreen') !== -1,
|
||||
loveCount: 0,
|
||||
projectId: parts[1] === 'editor' ? null : parts[1]
|
||||
projectId: parts[1] === 'editor' ? 0 : parts[1]
|
||||
};
|
||||
}
|
||||
handleFavoriteToggle () {
|
||||
|
@ -109,8 +157,7 @@ class Preview extends React.Component {
|
|||
}
|
||||
}
|
||||
handleSeeInside () {
|
||||
this.setState({inEditor: true});
|
||||
history.pushState({}, document.title, `/preview/${this.state.projectId}/editor`);
|
||||
this.props.setPlayer(false);
|
||||
}
|
||||
handleUpdate (jsonData) {
|
||||
this.props.updateProject(
|
||||
|
@ -128,13 +175,7 @@ class Preview extends React.Component {
|
|||
}
|
||||
render () {
|
||||
return (
|
||||
this.state.inEditor ?
|
||||
<IntlGUI
|
||||
basePath="/"
|
||||
className="gui"
|
||||
isPlayerOnly={false}
|
||||
projectId={this.state.projectId}
|
||||
/> :
|
||||
this.props.playerMode ?
|
||||
<Page>
|
||||
<PreviewPresentation
|
||||
comments={this.props.comments}
|
||||
|
@ -156,7 +197,13 @@ class Preview extends React.Component {
|
|||
onSeeInside={this.handleSeeInside}
|
||||
onUpdate={this.handleUpdate}
|
||||
/>
|
||||
</Page>
|
||||
</Page> :
|
||||
<IntlGUI
|
||||
enableCommunity
|
||||
basePath="/"
|
||||
className="gui"
|
||||
projectId={this.state.projectId}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -186,6 +233,7 @@ Preview.propTypes = {
|
|||
})
|
||||
}),
|
||||
faved: PropTypes.bool,
|
||||
fullScreen: PropTypes.bool,
|
||||
getCreditInfo: PropTypes.func.isRequired,
|
||||
getFavedStatus: PropTypes.func.isRequired,
|
||||
getLovedStatus: PropTypes.func.isRequired,
|
||||
|
@ -193,6 +241,7 @@ Preview.propTypes = {
|
|||
getRemixes: PropTypes.func.isRequired,
|
||||
getStudios: PropTypes.func.isRequired,
|
||||
loved: PropTypes.bool,
|
||||
playerMode: PropTypes.bool,
|
||||
projectInfo: PropTypes.shape({
|
||||
author: PropTypes.shape({
|
||||
id: PropTypes.number,
|
||||
|
@ -219,7 +268,9 @@ Preview.propTypes = {
|
|||
remixes: PropTypes.arrayOf(PropTypes.object),
|
||||
sessionStatus: PropTypes.string,
|
||||
setFavedStatus: PropTypes.func.isRequired,
|
||||
setFullScreen: PropTypes.func.isRequired,
|
||||
setLovedStatus: PropTypes.func.isRequired,
|
||||
setPlayer: PropTypes.func.isRequired,
|
||||
studios: PropTypes.arrayOf(PropTypes.object),
|
||||
updateProject: PropTypes.func.isRequired,
|
||||
user: PropTypes.shape({
|
||||
|
@ -248,7 +299,9 @@ const mapStateToProps = state => ({
|
|||
remixes: state.preview.remixes,
|
||||
sessionStatus: state.session.status,
|
||||
studios: state.preview.studios,
|
||||
user: state.session.session.user
|
||||
user: state.session.session.user,
|
||||
playerMode: state.scratchGui.mode.isPlayerOnly,
|
||||
fullScreen: state.scratchGui.mode.isFullScreen
|
||||
});
|
||||
|
||||
|
||||
|
@ -285,6 +338,12 @@ const mapDispatchToProps = dispatch => ({
|
|||
},
|
||||
updateProject: (id, formData, username, token) => {
|
||||
dispatch(previewActions.updateProject(id, formData, username, token));
|
||||
},
|
||||
setPlayer: player => {
|
||||
dispatch(GUI.setPlayer(player));
|
||||
},
|
||||
setFullScreen: fullscreen => {
|
||||
dispatch(GUI.setFullScreen(fullscreen));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -293,8 +352,29 @@ const ConnectedPreview = connect(
|
|||
mapDispatchToProps
|
||||
)(Preview);
|
||||
|
||||
GUI.setAppElement(document.getElementById('app'));
|
||||
const initGuiState = guiInitialState => {
|
||||
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'
|
||||
if (parts.indexOf('editor') === -1) {
|
||||
guiInitialState = GUI.initPlayer(guiInitialState);
|
||||
}
|
||||
if (parts.indexOf('fullscreen') !== -1) {
|
||||
guiInitialState = GUI.initFullScreen(guiInitialState);
|
||||
}
|
||||
return guiInitialState;
|
||||
};
|
||||
|
||||
render(
|
||||
<ConnectedPreview />,
|
||||
document.getElementById('app'),
|
||||
{preview: previewActions.previewReducer}
|
||||
{
|
||||
preview: previewActions.previewReducer,
|
||||
...GUI.guiReducers
|
||||
},
|
||||
{scratchGui: initGuiState(GUI.guiInitialState)},
|
||||
GUI.guiMiddleware
|
||||
);
|
||||
|
|
Loading…
Reference in a new issue