Automatically re-open the project edited during last session (#1770)

* If a project is edited and GDevelop is closed, the project will be opened again the next time GDevelop is launched.
  * If the project is closed and GDevelop is then closed, it won't be re-opened automatically.
This commit is contained in:
Harsimran Singh Virk
2020-06-01 23:27:13 +05:30
committed by GitHub
parent f8e0288a44
commit 6ab2cb1384
4 changed files with 110 additions and 7 deletions

View File

@@ -132,6 +132,8 @@ export type PreferencesValues = {|
projectLastUsedPaths: { [string]: { [ResourceKind]: string } },
defaultEditorMosaicNodes: { [EditorMosaicName]: ?EditorMosaicNode },
recentProjectFiles: Array<FileMetadataAndStorageProviderName>,
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<Preferences>(initialPreferences);

View File

@@ -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={<Trans>Auto-save project on Preview</Trans>}
/>
</Line>
<Line>
<Toggle
onToggle={(e, check) => setAutoOpenMostRecentProject(check)}
toggled={values.autoOpenMostRecentProject}
labelPosition="right"
label={
<Trans>
Automatically re-open the project edited during last session
</Trans>
}
/>
</Line>
{Window.isDev() && (
<Line>
<Toggle

View File

@@ -56,6 +56,13 @@ export default class PreferencesProvider extends React.Component<Props, State> {
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<Props, State> {
);
}
_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 (
<PreferencesContext.Provider value={this.state}>

View File

@@ -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<void> => {
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
);
});
});
}
};