WIP: actually load project from command line

Doing it this way works for the initial load but overrides later actions
like File -> New.
This commit is contained in:
Christopher Willis-Ford 2020-09-04 13:26:34 -07:00
parent e2f39580df
commit 05e8b26a34
2 changed files with 46 additions and 12 deletions

View file

@ -2,6 +2,7 @@ import {BrowserWindow, Menu, app, dialog, ipcMain, systemPreferences} from 'elec
import fs from 'fs-extra';
import path from 'path';
import {URL} from 'url';
import {promisify} from 'util';
import argv from './argv';
import {getFilterForExtension} from './FileFilters';
@ -375,4 +376,28 @@ ipcMain.on('open-about-window', () => {
_windows.about.show();
});
ipcMain.handle('get-argv', () => argv);
// start loading initial project data before the GUI needs it so the load seems faster
const initialProjectDataPromise = (async () => {
if (argv._.length === 0) {
// no command line argument means no initial project data
return;
}
if (argv._.length > 1) {
log.warn(`Expected 1 command line argument but received ${argv._.length}.`);
}
const projectPath = argv._[argv._.length - 1];
try {
const projectData = await promisify(fs.readFile)(projectPath, null);
return projectData;
} catch (e) {
dialog.showMessageBox(_windows.main, {
type: 'error',
title: 'Failed to load project',
message: `Could not load project from file:\n${projectPath}`,
detail: e.message
});
}
// load failed: initial project data undefined
})(); // IIFE
ipcMain.handle('get-initial-project-data', () => initialProjectDataPromise);

View file

@ -6,7 +6,6 @@ import {compose} from 'redux';
import GUI, {AppStateHOC} from 'scratch-gui';
import ElectronStorageHelper from '../common/ElectronStorageHelper';
import log from '../common/log';
import styles from './app.css';
@ -40,8 +39,16 @@ const ScratchDesktopHOC = function (WrappedComponent) {
'handleUpdateProjectTitle'
]);
this.state = {
projectTitle: null
projectTitle: null,
projectLoading: true
};
ipcRenderer.invoke('get-initial-project-data').then(projectData => {
this.setState({
projectData,
projectLoading: false
});
});
}
componentDidMount () {
ipcRenderer.on('setTitleFromSave', this.handleSetTitleFromSave);
@ -72,6 +79,11 @@ const ScratchDesktopHOC = function (WrappedComponent) {
}
render () {
const shouldShowTelemetryModal = (typeof ipcRenderer.sendSync('getTelemetryDidOptIn') !== 'boolean');
if (this.state.projectLoading) {
return <p className="splash">Loading File...</p>;
}
return (<WrappedComponent
canEditTitle
isScratchDesktop
@ -84,6 +96,12 @@ const ScratchDesktopHOC = function (WrappedComponent) {
onTelemetryModalOptIn={this.handleTelemetryModalOptIn}
onTelemetryModalOptOut={this.handleTelemetryModalOptOut}
onUpdateProjectTitle={this.handleUpdateProjectTitle}
// completely omit the projectData prop if we have no project data
// passing an empty projectData causes a GUI error
{...(this.state.projectData ? {projectData: this.state.projectData} : {})}
// allow passed-in props to override any of the above
{...this.props}
/>);
}
@ -100,13 +118,4 @@ const WrappedGui = compose(
AppStateHOC
)(GUI);
ipcRenderer.invoke('get-argv').then(
argv => {
log.log(`argv._ = ${argv._}`);
},
err => {
log.warn('Failed to retrieve argv', err);
}
);
ReactDOM.render(<WrappedGui />, appTarget);