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:
chrisgarrity 2018-05-24 16:23:07 -04:00 committed by GitHub
parent 15779d833e
commit 80de164d02
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 118 additions and 25 deletions

View file

@ -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",

View file

@ -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

View file

@ -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,

View file

@ -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
);