diff --git a/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js b/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js index 582c8802e0..f040db090c 100644 --- a/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js +++ b/newIDE/app/src/MainFrame/Preferences/PreferencesContext.js @@ -132,6 +132,8 @@ export type PreferencesValues = {| projectLastUsedPaths: { [string]: { [ResourceKind]: string } }, defaultEditorMosaicNodes: { [EditorMosaicName]: ?EditorMosaicNode }, recentProjectFiles: Array, + autoOpenMostRecentProject: boolean, + hasProjectOpened: boolean, |}; /** @@ -168,6 +170,13 @@ export type Preferences = {| insertRecentProjectFile: ( fileMetadata: FileMetadataAndStorageProviderName ) => void, + removeRecentProjectFile: ( + fileMetadat: FileMetadataAndStorageProviderName + ) => void, + getAutoOpenMostRecentProject: () => boolean, + setAutoOpenMostRecentProject: (enabled: boolean) => void, + hadProjectOpenedDuringLastSession: () => boolean, + setHasProjectOpened: (enabled: boolean) => void, |}; export const initialPreferences = { @@ -188,6 +197,8 @@ export const initialPreferences = { projectLastUsedPaths: {}, defaultEditorMosaicNodes: {}, recentProjectFiles: [], + autoOpenMostRecentProject: true, + hasProjectOpened: false, }, setLanguage: () => {}, setThemeName: () => {}, @@ -214,6 +225,13 @@ export const initialPreferences = { insertRecentProjectFile: ( fileMetadata: FileMetadataAndStorageProviderName ) => {}, + removeRecentProjectFile: ( + fileMetadata: FileMetadataAndStorageProviderName + ) => {}, + getAutoOpenMostRecentProject: () => true, + setAutoOpenMostRecentProject: () => {}, + hadProjectOpenedDuringLastSession: () => false, + setHasProjectOpened: () => {}, }; const PreferencesContext = React.createContext(initialPreferences); diff --git a/newIDE/app/src/MainFrame/Preferences/PreferencesDialog.js b/newIDE/app/src/MainFrame/Preferences/PreferencesDialog.js index 0e31ebc1da..8053a50566 100644 --- a/newIDE/app/src/MainFrame/Preferences/PreferencesDialog.js +++ b/newIDE/app/src/MainFrame/Preferences/PreferencesDialog.js @@ -37,6 +37,7 @@ const PreferencesDialog = ({ onClose }: Props) => { setEventsSheetUseAssignmentOperators, getDefaultEditorMosaicNode, setDefaultEditorMosaicNode, + setAutoOpenMostRecentProject, } = React.useContext(PreferencesContext); return ( @@ -225,6 +226,18 @@ const PreferencesDialog = ({ onClose }: Props) => { label={Auto-save project on Preview} /> + + setAutoOpenMostRecentProject(check)} + toggled={values.autoOpenMostRecentProject} + labelPosition="right" + label={ + + Automatically re-open the project edited during last session + + } + /> + {Window.isDev() && ( { setDefaultEditorMosaicNode: this._setDefaultEditorMosaicNode.bind(this), getRecentProjectFiles: this._getRecentProjectFiles.bind(this), insertRecentProjectFile: this._insertRecentProjectFile.bind(this), + removeRecentProjectFile: this._removeRecentProjectFile.bind(this), + getAutoOpenMostRecentProject: this._getAutoOpenMostRecentProject.bind(this), + setAutoOpenMostRecentProject: this._setAutoOpenMostRecentProject.bind(this), + hadProjectOpenedDuringLastSession: this._hadProjectOpenedDuringLastSession.bind( + this + ), + setHasProjectOpened: this._setHasProjectOpened.bind(this), }; componentDidMount() { @@ -374,6 +381,49 @@ export default class PreferencesProvider extends React.Component { ); } + _removeRecentProjectFile(recentFile: FileMetadataAndStorageProviderName) { + const isNotSadPathRecentFile = recentFileItem => + JSON.stringify(recentFileItem) !== JSON.stringify(recentFile); + this._setRecentProjectFiles( + [...this._getRecentProjectFiles().filter(isNotSadPathRecentFile)].slice( + 0, + 5 + ) + ); + } + + _getAutoOpenMostRecentProject() { + return this.state.values.autoOpenMostRecentProject; + } + + _setAutoOpenMostRecentProject(enabled: boolean) { + this.setState( + state => ({ + values: { + ...state.values, + autoOpenMostRecentProject: enabled, + }, + }), + () => this._persistValuesToLocalStorage(this.state) + ); + } + + _hadProjectOpenedDuringLastSession() { + return this.state.values.hasProjectOpened; + } + + _setHasProjectOpened(enabled: boolean) { + this.setState( + state => ({ + values: { + ...state.values, + hasProjectOpened: enabled, + }, + }), + () => this._persistValuesToLocalStorage(this.state) + ); + } + render() { return ( diff --git a/newIDE/app/src/MainFrame/index.js b/newIDE/app/src/MainFrame/index.js index 545f3449fc..654061a168 100644 --- a/newIDE/app/src/MainFrame/index.js +++ b/newIDE/app/src/MainFrame/index.js @@ -254,6 +254,19 @@ const MainFrame = (props: Props) => { performance.now(), ]); console.info('Startup times:', getStartupTimesSummary()); + + const { + getAutoOpenMostRecentProject, + getRecentProjectFiles, + hadProjectOpenedDuringLastSession, + } = preferences; + + if ( + getAutoOpenMostRecentProject() && + hadProjectOpenedDuringLastSession() && + getRecentProjectFiles()[0] + ) + openFromFileMetadataWithStorageProvider(getRecentProjectFiles()[0]); }) .catch(() => { /* Ignore errors */ @@ -393,6 +406,7 @@ const MainFrame = (props: Props) => { // for another resource with the same name in the new project. ResourcesLoader.burstAllUrlsCache(); // TODO: Pixi cache should also be burst + preferences.setHasProjectOpened(true); return setState(state => ({ ...state, @@ -525,6 +539,7 @@ const MainFrame = (props: Props) => { error ); setIsLoadingProject(false); + return Promise.reject(error); }); }); }; @@ -536,6 +551,7 @@ const MainFrame = (props: Props) => { const closeProject = (): Promise => { const { eventsFunctionsExtensionsState } = props; + preferences.setHasProjectOpened(false); setPreviewState(initialPreviewState); return setState(state => { const { currentProject, editorTabs } = state; @@ -1229,13 +1245,19 @@ const MainFrame = (props: Props) => { if (storageProvider) { getStorageProviderOperations(storageProvider).then(() => { - openFromFileMetadata(fileMetadata).then(state => { - if (state) - openSceneOrProjectManager({ - currentProject: state.currentProject, - editorTabs: state.editorTabs, - }); - }); + openFromFileMetadata(fileMetadata) + .then(state => { + if (state) + openSceneOrProjectManager({ + currentProject: state.currentProject, + editorTabs: state.editorTabs, + }); + }) + .catch(error => { + preferences.removeRecentProjectFile( + fileMetadataAndStorageProviderName + ); + }); }); } };