diff --git a/src/components/gui/gui.jsx b/src/components/gui/gui.jsx index 410fe5edadb..c14060625b7 100644 --- a/src/components/gui/gui.jsx +++ b/src/components/gui/gui.jsx @@ -144,6 +144,8 @@ const GUIComponent = props => { onTelemetryModalOptOut, securityManager, showComingSoon, + showOpenFilePicker, + showSaveFilePicker, soundsTabVisible, stageSizeMode, targetIsStage, @@ -302,6 +304,8 @@ const GUIComponent = props => { logo={logo} renderLogin={renderLogin} showComingSoon={showComingSoon} + showOpenFilePicker={showOpenFilePicker} + showSaveFilePicker={showSaveFilePicker} onClickAbout={onClickAbout} onClickAccountNav={onClickAccountNav} onClickAddonSettings={onClickAddonSettings} @@ -519,6 +523,8 @@ GUIComponent.propTypes = { renderLogin: PropTypes.func, securityManager: PropTypes.shape({}), showComingSoon: PropTypes.bool, + showOpenFilePicker: PropTypes.func, + showSaveFilePicker: PropTypes.func, soundsTabVisible: PropTypes.bool, stageSizeMode: PropTypes.oneOf(Object.keys(STAGE_SIZE_MODES)), targetIsStage: PropTypes.bool, diff --git a/src/components/menu-bar/menu-bar.jsx b/src/components/menu-bar/menu-bar.jsx index 371ffd2c726..4ba677ab9ac 100644 --- a/src/components/menu-bar/menu-bar.jsx +++ b/src/components/menu-bar/menu-bar.jsx @@ -626,55 +626,61 @@ class MenuBar extends React.Component { > {this.props.intl.formatMessage(sharedMessages.loadFromComputerTitle)} - {(_className, downloadProject, extended) => ( - - {extended.available && ( - - {extended.name !== null && ( - // eslint-disable-next-line max-len - + + {(_className, downloadProject, extended) => ( + + {extended.available && ( + + {extended.name !== null && ( + // eslint-disable-next-line max-len + + + + )} + {/* eslint-disable-next-line max-len */} + - )} - {/* eslint-disable-next-line max-len */} - - + + )} + {notScratchDesktop() && ( + + {extended.available ? ( + + ) : ( + + )} - - )} - {notScratchDesktop() && ( - - {extended.available ? ( - - ) : ( - - )} - - )} - - )} + )} + + )} + {this.props.onClickPackager && ( @@ -1125,6 +1131,7 @@ MenuBar.propTypes = { sessionExists: PropTypes.bool, settingsMenuOpen: PropTypes.bool, shouldSaveBeforeTransition: PropTypes.func, + showSaveFilePicker: PropTypes.func, showComingSoon: PropTypes.bool, username: PropTypes.string, userOwnsProject: PropTypes.bool, diff --git a/src/containers/menu-bar-hoc.jsx b/src/containers/menu-bar-hoc.jsx index 1b9407f173c..cc98745b679 100644 --- a/src/containers/menu-bar-hoc.jsx +++ b/src/containers/menu-bar-hoc.jsx @@ -31,14 +31,20 @@ const MenuBarHOC = function (WrappedComponent) { /* eslint-enable no-unused-vars */ ...props } = this.props; - return ({(_className, _downloadProject, extended) => ( - - )}); + return ( + + {(_className, _downloadProject, extended) => ( + + )} + + ); } } @@ -46,7 +52,8 @@ const MenuBarHOC = function (WrappedComponent) { canCreateNew: PropTypes.bool, canSave: PropTypes.bool, confirmWithMessage: PropTypes.func, - projectChanged: PropTypes.bool + projectChanged: PropTypes.bool, + showSaveFilePicker: PropTypes.func }; MenuBarContainer.defaultProps = { // default to using standard js confirm diff --git a/src/containers/sb3-downloader.jsx b/src/containers/sb3-downloader.jsx index e308f2e77f3..5cf782b8cfd 100644 --- a/src/containers/sb3-downloader.jsx +++ b/src/containers/sb3-downloader.jsx @@ -7,7 +7,6 @@ import downloadBlob from '../lib/download-blob'; import {setProjectUnchanged} from '../reducers/project-changed'; import {showStandardAlert, showAlertWithTimeout} from '../reducers/alerts'; import {setFileHandle} from '../reducers/tw'; -import FileSystemAPI from '../lib/tw-filesystem-api'; import {getIsShowingProject} from '../reducers/project-state'; import log from '../lib/log'; @@ -97,7 +96,18 @@ class SB3Downloader extends React.Component { return; } try { - const handle = await FileSystemAPI.showSaveFilePicker(this.props.projectFilename); + const handle = await this.props.showSaveFilePicker({ + suggestedName: this.props.projectFilename, + types: [ + { + description: 'Scratch 3 Project', + accept: { + 'application/x.scratch.sb3': '.sb3' + } + } + ], + excludeAcceptAllOption: true + }); await this.saveToHandle(handle); this.props.onSetFileHandle(handle); const title = getProjectTitleFromFilename(handle.name); @@ -241,7 +251,7 @@ class SB3Downloader extends React.Component { return children( this.props.className, this.downloadProject, - FileSystemAPI.available() ? { + this.props.showSaveFilePicker ? { available: true, name: this.props.fileHandle ? this.props.fileHandle.name : null, saveAsNew: this.saveAsNew, @@ -280,10 +290,12 @@ SB3Downloader.propTypes = { onShowSavingAlert: PropTypes.func, onShowSaveSuccessAlert: PropTypes.func, onShowSaveErrorAlert: PropTypes.func, - onProjectUnchanged: PropTypes.func + onProjectUnchanged: PropTypes.func, + showSaveFilePicker: PropTypes.func }; SB3Downloader.defaultProps = { - className: '' + className: '', + showSaveFilePicker: typeof showSaveFilePicker === 'function' ? window.showSaveFilePicker.bind(window) : null }; const mapStateToProps = state => ({ diff --git a/src/lib/sb-file-uploader-hoc.jsx b/src/lib/sb-file-uploader-hoc.jsx index d740d7a7408..bbc10d29443 100644 --- a/src/lib/sb-file-uploader-hoc.jsx +++ b/src/lib/sb-file-uploader-hoc.jsx @@ -5,7 +5,6 @@ import {intlShape, injectIntl} from 'react-intl'; import {connect} from 'react-redux'; import log from '../lib/log'; import sharedMessages from './shared-messages'; -import FileSystemAPI from './tw-filesystem-api'; import {setFileHandle, setProjectError} from '../reducers/tw'; import { @@ -74,10 +73,20 @@ const SBFileUploaderHOC = function (WrappedComponent) { this.fileReader = new FileReader(); this.fileReader.onload = this.onload; // tw: Use FS API when available - if (FileSystemAPI.available()) { + if (this.props.showOpenFilePicker) { (async () => { try { - const handle = await FileSystemAPI.showOpenFilePicker(); + const [handle] = await this.props.showOpenFilePicker({ + multiple: false, + types: [ + { + description: 'Scratch Project', + accept: { + 'application/x.scratch.sb3': ['.sb', '.sb2', '.sb3'] + } + } + ] + }); const file = await handle.getFile(); this.handleChange({ target: { @@ -261,6 +270,7 @@ const SBFileUploaderHOC = function (WrappedComponent) { onSetProjectTitle: PropTypes.func, projectChanged: PropTypes.bool, requestProjectUpload: PropTypes.func, + showOpenFilePicker: PropTypes.func, userOwnsProject: PropTypes.bool, vm: PropTypes.shape({ loadProject: PropTypes.func, @@ -271,6 +281,9 @@ const SBFileUploaderHOC = function (WrappedComponent) { }), onSetFileHandle: PropTypes.func }; + SBFileUploaderComponent.defaultProps = { + showOpenFilePicker: typeof showOpenFilePicker === 'function' ? window.showOpenFilePicker.bind(window) : null + }; const mapStateToProps = (state, ownProps) => { const loadingState = state.scratchGui.projectState.loadingState; const user = state.session && state.session.session && state.session.session.user; diff --git a/src/lib/tw-filesystem-api.js b/src/lib/tw-filesystem-api.js deleted file mode 100644 index 1c6cf4fcde4..00000000000 --- a/src/lib/tw-filesystem-api.js +++ /dev/null @@ -1,35 +0,0 @@ -const available = () => !!window.showSaveFilePicker; - -const showSaveFilePicker = fileName => window.showSaveFilePicker({ - suggestedName: fileName, - types: [ - { - description: 'Scratch 3 Project', - accept: { - 'application/x.scratch.sb3': '.sb3' - } - } - ], - excludeAcceptAllOption: true -}); - -const showOpenFilePicker = async () => { - const [handle] = await window.showOpenFilePicker({ - multiple: false, - types: [ - { - description: 'Scratch Project', - accept: { - 'application/x.scratch.sb3': ['.sb', '.sb2', '.sb3'] - } - } - ] - }); - return handle; -}; - -export default { - available, - showOpenFilePicker, - showSaveFilePicker -};