Initial commit of 001code-html Scratch frontend project.
Includes scratch-gui, scratch-vm, scratch-blocks, scratch-render, scratch-l10n, and deployment config. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
123
scratch-gui/src/containers/tips-library.jsx
Normal file
123
scratch-gui/src/containers/tips-library.jsx
Normal file
@@ -0,0 +1,123 @@
|
||||
import bindAll from 'lodash.bindall';
|
||||
import PropTypes from 'prop-types';
|
||||
import React from 'react';
|
||||
import {injectIntl, intlShape, defineMessages} from 'react-intl';
|
||||
|
||||
import decksLibraryContent from '../lib/libraries/decks/index.jsx';
|
||||
import tutorialTags from '../lib/libraries/tutorial-tags';
|
||||
|
||||
import analytics from '../lib/analytics';
|
||||
import {notScratchDesktop} from '../lib/isScratchDesktop';
|
||||
|
||||
import LibraryComponent from '../components/library/library.jsx';
|
||||
|
||||
import {connect} from 'react-redux';
|
||||
|
||||
import {
|
||||
closeTipsLibrary
|
||||
} from '../reducers/modals';
|
||||
|
||||
import {
|
||||
activateDeck
|
||||
} from '../reducers/cards';
|
||||
|
||||
const messages = defineMessages({
|
||||
tipsLibraryTitle: {
|
||||
defaultMessage: 'Choose a Tutorial',
|
||||
description: 'Heading for the help/tutorials library',
|
||||
id: 'gui.tipsLibrary.tutorials'
|
||||
}
|
||||
});
|
||||
|
||||
class TipsLibrary extends React.PureComponent {
|
||||
constructor (props) {
|
||||
super(props);
|
||||
bindAll(this, [
|
||||
'handleItemSelect'
|
||||
]);
|
||||
}
|
||||
handleItemSelect (item) {
|
||||
analytics.event({
|
||||
category: 'library',
|
||||
action: 'Select How-to',
|
||||
label: item.id
|
||||
});
|
||||
|
||||
/*
|
||||
Support tutorials that require specific starter projects.
|
||||
If a tutorial declares "requiredProjectId", check that the URL contains
|
||||
it. If it is not, open a new page with this tutorial and project id.
|
||||
|
||||
TODO remove this at first opportunity. If this is still here after HOC2018,
|
||||
blame Eric R. Andrew is also on record saying "this is temporary".
|
||||
UPDATE well now Paul is wrapped into this as well. Sigh...
|
||||
eventually we will find a solution that doesn't involve loading a whole project
|
||||
*/
|
||||
if (item.requiredProjectId && (item.requiredProjectId !== this.props.projectId)) {
|
||||
const urlParams = `/projects/${item.requiredProjectId}/editor?tutorial=${item.urlId}`;
|
||||
return window.open(window.location.origin + urlParams, '_blank');
|
||||
}
|
||||
|
||||
this.props.onActivateDeck(item.id);
|
||||
}
|
||||
render () {
|
||||
const decksLibraryThumbnailData = Object.keys(decksLibraryContent)
|
||||
.filter(id => {
|
||||
if (notScratchDesktop()) return true; // Do not filter anything in online editor
|
||||
const deck = decksLibraryContent[id];
|
||||
// Scratch Desktop doesn't want tutorials with `requiredProjectId`
|
||||
if (Object.prototype.hasOwnProperty.call(deck, 'requiredProjectId')) return false;
|
||||
// Scratch Desktop should not load tutorials that are _only_ videos
|
||||
if (deck.steps.filter(s => s.title).length === 0) return false;
|
||||
// Allow any other tutorials
|
||||
return true;
|
||||
})
|
||||
.map(id => ({
|
||||
rawURL: decksLibraryContent[id].img,
|
||||
id: id,
|
||||
name: decksLibraryContent[id].name,
|
||||
featured: true,
|
||||
tags: decksLibraryContent[id].tags,
|
||||
urlId: decksLibraryContent[id].urlId,
|
||||
requiredProjectId: decksLibraryContent[id].requiredProjectId,
|
||||
hidden: decksLibraryContent[id].hidden || false
|
||||
}));
|
||||
|
||||
if (!this.props.visible) return null;
|
||||
return (
|
||||
<LibraryComponent
|
||||
filterable
|
||||
data={decksLibraryThumbnailData}
|
||||
id="tipsLibrary"
|
||||
tags={tutorialTags}
|
||||
title={this.props.intl.formatMessage(messages.tipsLibraryTitle)}
|
||||
visible={this.props.visible}
|
||||
onItemSelected={this.handleItemSelect}
|
||||
onRequestClose={this.props.onRequestClose}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TipsLibrary.propTypes = {
|
||||
intl: intlShape.isRequired,
|
||||
onActivateDeck: PropTypes.func.isRequired,
|
||||
onRequestClose: PropTypes.func,
|
||||
projectId: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
|
||||
visible: PropTypes.bool
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
visible: state.scratchGui.modals.tipsLibrary,
|
||||
projectId: state.scratchGui.projectState.projectId
|
||||
});
|
||||
|
||||
const mapDispatchToProps = dispatch => ({
|
||||
onActivateDeck: id => dispatch(activateDeck(id)),
|
||||
onRequestClose: () => dispatch(closeTipsLibrary())
|
||||
});
|
||||
|
||||
export default injectIntl(connect(
|
||||
mapStateToProps,
|
||||
mapDispatchToProps
|
||||
)(TipsLibrary));
|
||||
Reference in New Issue
Block a user