Skip to content

Commit

Permalink
Allow overriding showOpenFilePicker/showSaveFilePicker
Browse files Browse the repository at this point in the history
  • Loading branch information
GarboMuffin committed Aug 1, 2024
1 parent f2f5a8f commit 457b36f
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 96 deletions.
6 changes: 6 additions & 0 deletions src/components/gui/gui.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ const GUIComponent = props => {
onTelemetryModalOptOut,
securityManager,
showComingSoon,
showOpenFilePicker,
showSaveFilePicker,
soundsTabVisible,
stageSizeMode,
targetIsStage,
Expand Down Expand Up @@ -302,6 +304,8 @@ const GUIComponent = props => {
logo={logo}
renderLogin={renderLogin}
showComingSoon={showComingSoon}
showOpenFilePicker={showOpenFilePicker}
showSaveFilePicker={showSaveFilePicker}
onClickAbout={onClickAbout}
onClickAccountNav={onClickAccountNav}
onClickAddonSettings={onClickAddonSettings}
Expand Down Expand Up @@ -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,
Expand Down
95 changes: 51 additions & 44 deletions src/components/menu-bar/menu-bar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -626,55 +626,61 @@ class MenuBar extends React.Component {
>
{this.props.intl.formatMessage(sharedMessages.loadFromComputerTitle)}
</MenuItem>
<SB3Downloader>{(_className, downloadProject, extended) => (
<React.Fragment>
{extended.available && (
<React.Fragment>
{extended.name !== null && (
// eslint-disable-next-line max-len
<MenuItem onClick={this.getSaveToComputerHandler(extended.saveToLastFile)}>
<SB3Downloader
showSaveFilePicker={this.props.showSaveFilePicker}
>
{(_className, downloadProject, extended) => (
<React.Fragment>
{extended.available && (
<React.Fragment>
{extended.name !== null && (
// eslint-disable-next-line max-len
<MenuItem onClick={this.getSaveToComputerHandler(extended.saveToLastFile)}>
<FormattedMessage
defaultMessage="Save to {file}"
// eslint-disable-next-line max-len
description="Menu bar item to save project to an existing file on the user's computer"
id="tw.saveTo"
values={{
file: extended.name
}}
/>
</MenuItem>
)}
{/* eslint-disable-next-line max-len */}
<MenuItem onClick={this.getSaveToComputerHandler(extended.saveAsNew)}>
<FormattedMessage
defaultMessage="Save to {file}"
defaultMessage="Save as..."
// eslint-disable-next-line max-len
description="Menu bar item to save project to an existing file on the user's computer"
id="tw.saveTo"
values={{
file: extended.name
}}
description="Menu bar item to select a new file to save the project as"
id="tw.saveAs"
/>
</MenuItem>
)}
{/* eslint-disable-next-line max-len */}
<MenuItem onClick={this.getSaveToComputerHandler(extended.saveAsNew)}>
<FormattedMessage
defaultMessage="Save as..."
// eslint-disable-next-line max-len
description="Menu bar item to select a new file to save the project as"
id="tw.saveAs"
/>
</React.Fragment>
)}
{notScratchDesktop() && (
<MenuItem
onClick={this.getSaveToComputerHandler(downloadProject)}
>
{extended.available ? (
<FormattedMessage
defaultMessage="Save to separate file..."
// eslint-disable-next-line max-len
description="Download the project once, without being able to easily save to the same spot"
id="tw.oldDownload"
/>
) : (
<FormattedMessage
defaultMessage="Save to your computer"
description="Menu bar item for downloading a project to your computer" // eslint-disable-line max-len
id="gui.menuBar.downloadToComputer"
/>
)}
</MenuItem>
</React.Fragment>
)}
{notScratchDesktop() && (
<MenuItem onClick={this.getSaveToComputerHandler(downloadProject)}>
{extended.available ? (
<FormattedMessage
defaultMessage="Save to separate file..."
// eslint-disable-next-line max-len
description="Download the project once, without being able to easily save to the same spot"
id="tw.oldDownload"
/>
) : (
<FormattedMessage
defaultMessage="Save to your computer"
description="Menu bar item for downloading a project to your computer" // eslint-disable-line max-len
id="gui.menuBar.downloadToComputer"
/>
)}
</MenuItem>
)}
</React.Fragment>
)}</SB3Downloader>
)}
</React.Fragment>
)}
</SB3Downloader>
</MenuSection>
{this.props.onClickPackager && (
<MenuSection>
Expand Down Expand Up @@ -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,
Expand Down
25 changes: 16 additions & 9 deletions src/containers/menu-bar-hoc.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,29 @@ const MenuBarHOC = function (WrappedComponent) {
/* eslint-enable no-unused-vars */
...props
} = this.props;
return (<SB3Downloader>{(_className, _downloadProject, extended) => (
<WrappedComponent
confirmReadyToReplaceProject={this.confirmReadyToReplaceProject}
shouldSaveBeforeTransition={this.shouldSaveBeforeTransition}
handleSaveProject={extended.smartSave}
{...props}
/>
)}</SB3Downloader>);
return (
<SB3Downloader
showSaveFilePicker={this.props.showSaveFilePicker}
>
{(_className, _downloadProject, extended) => (
<WrappedComponent
confirmReadyToReplaceProject={this.confirmReadyToReplaceProject}
shouldSaveBeforeTransition={this.shouldSaveBeforeTransition}
handleSaveProject={extended.smartSave}
{...props}
/>
)}
</SB3Downloader>
);
}
}

MenuBarContainer.propTypes = {
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
Expand Down
22 changes: 17 additions & 5 deletions src/containers/sb3-downloader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';

Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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 => ({
Expand Down
19 changes: 16 additions & 3 deletions src/lib/sb-file-uploader-hoc.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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: {
Expand Down Expand Up @@ -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,
Expand All @@ -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;
Expand Down
35 changes: 0 additions & 35 deletions src/lib/tw-filesystem-api.js

This file was deleted.

0 comments on commit 457b36f

Please sign in to comment.