mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Add possibility to choose project name before it is created
A random and fun name is generated as a suggestion
This commit is contained in:
@@ -28,8 +28,8 @@ import AuthenticatedUserContext from '../../../Profile/AuthenticatedUserContext'
|
||||
import { useResponsiveWindowWidth } from '../../../UI/Reponsive/ResponsiveWindowMeasurer';
|
||||
import { ExampleDialog } from '../../../AssetStore/ExampleStore/ExampleDialog';
|
||||
import optionalRequire from '../../../Utils/OptionalRequire';
|
||||
import { findEmptyPath } from '../../../ProjectCreation/LocalPathFinder';
|
||||
import LocalProjectPreCreationDialog from '../../../ProjectCreation/LocalProjectPreCreationDialog';
|
||||
import { findEmptyPathInDefaultFolder } from '../../../ProjectCreation/LocalPathFinder';
|
||||
import ProjectPreCreationDialog from '../../../ProjectCreation/ProjectPreCreationDialog';
|
||||
import {
|
||||
type OnCreateFromExampleShortHeaderFunction,
|
||||
type OnCreateBlankFunction,
|
||||
@@ -38,9 +38,9 @@ import {
|
||||
import RaisedButtonWithSplitMenu from '../../../UI/RaisedButtonWithSplitMenu';
|
||||
import PreferencesContext from '../../Preferences/PreferencesContext';
|
||||
import { type FileMetadataAndStorageProviderName } from '../../../ProjectsStorage';
|
||||
import generateName from '../../../Utils/ProjectNameGenerator';
|
||||
|
||||
const electron = optionalRequire('electron');
|
||||
const path = optionalRequire('path');
|
||||
const app = electron ? electron.remote.app : null;
|
||||
|
||||
const styles = {
|
||||
@@ -146,6 +146,7 @@ export const HomePage = React.memo<Props>(
|
||||
}));
|
||||
|
||||
const windowWidth = useResponsiveWindowWidth();
|
||||
const [newProjectName, setNewProjectName] = React.useState<string>('');
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const { getRecentProjectFiles } = React.useContext(PreferencesContext);
|
||||
const {
|
||||
@@ -178,16 +179,7 @@ export const HomePage = React.memo<Props>(
|
||||
]
|
||||
);
|
||||
|
||||
const computeDefaultProjectPath = (): string =>
|
||||
app && path
|
||||
? findEmptyPath(
|
||||
path.join(app.getPath('documents'), 'GDevelop projects')
|
||||
)
|
||||
: '';
|
||||
|
||||
const [outputPath, setOutputPath] = React.useState<string>(
|
||||
computeDefaultProjectPath()
|
||||
);
|
||||
const [outputPath, setOutputPath] = React.useState<string>('');
|
||||
const [
|
||||
preCreationDialogOpen,
|
||||
setPreCreationDialogOpen,
|
||||
@@ -254,44 +246,40 @@ export const HomePage = React.memo<Props>(
|
||||
[]
|
||||
);
|
||||
|
||||
const createBlankProject = async (i18n: I18nType) => {
|
||||
setIsOpening(true);
|
||||
try {
|
||||
const projectMetadata = await onCreateBlank({
|
||||
i18n,
|
||||
outputPath,
|
||||
});
|
||||
if (!projectMetadata) return;
|
||||
const { project, storageProvider, fileMetadata } = projectMetadata;
|
||||
setPreCreationDialogOpen(false);
|
||||
setOutputPath(computeDefaultProjectPath());
|
||||
onOpenProjectAfterCreation({
|
||||
project,
|
||||
storageProvider,
|
||||
fileMetadata,
|
||||
});
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
const openPreCreationDialog = React.useCallback((open: boolean) => {
|
||||
if (open) {
|
||||
setOutputPath(app ? findEmptyPathInDefaultFolder(app) : '');
|
||||
setNewProjectName(generateName());
|
||||
}
|
||||
};
|
||||
|
||||
const createProjectFromExample = async (i18n: I18nType) => {
|
||||
if (!selectedExample) return;
|
||||
setPreCreationDialogOpen(open);
|
||||
}, []);
|
||||
|
||||
const createProject = async (i18n: I18nType) => {
|
||||
setIsOpening(true);
|
||||
|
||||
try {
|
||||
const projectMetadata = await onCreateFromExampleShortHeader({
|
||||
i18n,
|
||||
outputPath,
|
||||
exampleShortHeader: selectedExample,
|
||||
});
|
||||
if (projectMetadata) {
|
||||
const { storageProvider, fileMetadata } = projectMetadata;
|
||||
setPreCreationDialogOpen(false);
|
||||
setSelectedExample(null);
|
||||
setOutputPath(computeDefaultProjectPath());
|
||||
onOpenProjectAfterCreation({ storageProvider, fileMetadata });
|
||||
let projectMetadata;
|
||||
|
||||
if (selectedExample) {
|
||||
projectMetadata = await onCreateFromExampleShortHeader({
|
||||
i18n,
|
||||
outputPath,
|
||||
projectName: newProjectName,
|
||||
exampleShortHeader: selectedExample,
|
||||
});
|
||||
} else {
|
||||
projectMetadata = await onCreateBlank({
|
||||
i18n,
|
||||
outputPath,
|
||||
projectName: newProjectName,
|
||||
});
|
||||
}
|
||||
|
||||
if (!projectMetadata) return;
|
||||
|
||||
openPreCreationDialog(false);
|
||||
setSelectedExample(null);
|
||||
onOpenProjectAfterCreation({ ...projectMetadata });
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
}
|
||||
@@ -322,9 +310,7 @@ export const HomePage = React.memo<Props>(
|
||||
<FlatButton
|
||||
label={<Trans>Create a blank project</Trans>}
|
||||
onClick={() => {
|
||||
electron
|
||||
? setPreCreationDialogOpen(true)
|
||||
: createBlankProject(i18n);
|
||||
openPreCreationDialog(true);
|
||||
}}
|
||||
primary
|
||||
/>
|
||||
@@ -520,24 +506,20 @@ export const HomePage = React.memo<Props>(
|
||||
onClose={() => setSelectedExample(null)}
|
||||
exampleShortHeader={selectedExample}
|
||||
onOpen={() => {
|
||||
electron
|
||||
? setPreCreationDialogOpen(true)
|
||||
: createProjectFromExample(i18n);
|
||||
openPreCreationDialog(true);
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
{preCreationDialogOpen && (
|
||||
<LocalProjectPreCreationDialog
|
||||
<ProjectPreCreationDialog
|
||||
open
|
||||
isOpening={isOpening}
|
||||
onClose={() => setPreCreationDialogOpen(false)}
|
||||
onCreate={() =>
|
||||
selectedExample
|
||||
? createProjectFromExample(i18n)
|
||||
: createBlankProject(i18n)
|
||||
}
|
||||
outputPath={outputPath}
|
||||
onChangeOutputPath={setOutputPath}
|
||||
onClose={() => openPreCreationDialog(false)}
|
||||
onCreate={() => createProject(i18n)}
|
||||
outputPath={electron ? outputPath : undefined}
|
||||
onChangeOutputPath={electron ? setOutputPath : undefined}
|
||||
projectName={newProjectName}
|
||||
onChangeProjectName={setNewProjectName}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
@@ -1971,11 +1971,13 @@ const MainFrame = (props: Props) => {
|
||||
project,
|
||||
storageProvider,
|
||||
fileMetadata,
|
||||
projectName,
|
||||
shouldCloseDialog,
|
||||
}: {|
|
||||
project?: gdProject,
|
||||
storageProvider: ?StorageProvider,
|
||||
fileMetadata: ?FileMetadata,
|
||||
projectName?: string,
|
||||
shouldCloseDialog?: boolean,
|
||||
|}) => {
|
||||
if (shouldCloseDialog)
|
||||
@@ -1987,7 +1989,11 @@ const MainFrame = (props: Props) => {
|
||||
else if (!!fileMetadata) state = await openFromFileMetadata(fileMetadata);
|
||||
|
||||
if (state) {
|
||||
if (state.currentProject) state.currentProject.resetProjectUuid();
|
||||
if (state.currentProject) {
|
||||
const { currentProject } = state;
|
||||
currentProject.resetProjectUuid();
|
||||
if (projectName) currentProject.setName(projectName);
|
||||
}
|
||||
openSceneOrProjectManager({
|
||||
currentProject: state.currentProject,
|
||||
editorTabs: state.editorTabs,
|
||||
|
@@ -8,6 +8,8 @@ import {
|
||||
type OnCreateFromExampleShortHeaderFunction,
|
||||
type OnOpenProjectAfterCreationFunction,
|
||||
} from '../ProjectCreation/CreateProjectDialog';
|
||||
import ProjectPreCreationDialog from './ProjectPreCreationDialog';
|
||||
import generateName from '../Utils/ProjectNameGenerator';
|
||||
|
||||
type Props = {|
|
||||
onOpen: OnOpenProjectAfterCreationFunction,
|
||||
@@ -18,21 +20,27 @@ export default function BrowserExamples({
|
||||
onOpen,
|
||||
onCreateFromExampleShortHeader,
|
||||
}: Props) {
|
||||
const [
|
||||
selectedExampleShortHeader,
|
||||
setSelectedExampleShortShortHeader,
|
||||
] = React.useState<?ExampleShortHeader>(null);
|
||||
const [newProjectName, setNewProjectName] = React.useState<string>(
|
||||
generateName()
|
||||
);
|
||||
const [isOpening, setIsOpening] = React.useState(false);
|
||||
|
||||
const createProjectFromExample = async (
|
||||
i18n: I18nType,
|
||||
exampleShortHeader: ExampleShortHeader
|
||||
) => {
|
||||
const createProjectFromExample = async (i18n: I18nType) => {
|
||||
if (!selectedExampleShortHeader) return;
|
||||
|
||||
setIsOpening(true);
|
||||
try {
|
||||
const projectMetadata = await onCreateFromExampleShortHeader({
|
||||
i18n,
|
||||
exampleShortHeader: exampleShortHeader,
|
||||
projectName: newProjectName,
|
||||
exampleShortHeader: selectedExampleShortHeader,
|
||||
});
|
||||
if (projectMetadata) {
|
||||
const { storageProvider, fileMetadata } = projectMetadata;
|
||||
onOpen({ storageProvider, fileMetadata, shouldCloseDialog: true });
|
||||
onOpen({ ...projectMetadata, shouldCloseDialog: true });
|
||||
}
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
@@ -42,12 +50,24 @@ export default function BrowserExamples({
|
||||
return (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<ExampleStore
|
||||
isOpening={isOpening}
|
||||
onOpen={(exampleShortHeader: ExampleShortHeader) =>
|
||||
createProjectFromExample(i18n, exampleShortHeader)
|
||||
}
|
||||
/>
|
||||
<>
|
||||
<ExampleStore
|
||||
isOpening={isOpening}
|
||||
onOpen={async (example: ?ExampleShortHeader) =>
|
||||
setSelectedExampleShortShortHeader(example)
|
||||
}
|
||||
/>
|
||||
{selectedExampleShortHeader && (
|
||||
<ProjectPreCreationDialog
|
||||
open
|
||||
isOpening={isOpening}
|
||||
onClose={() => setSelectedExampleShortShortHeader(null)}
|
||||
onCreate={() => createProjectFromExample(i18n)}
|
||||
projectName={newProjectName}
|
||||
onChangeProjectName={setNewProjectName}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</I18n>
|
||||
);
|
||||
|
@@ -13,9 +13,8 @@ import { GamesShowcase } from '../GamesShowcase';
|
||||
import { type ExampleShortHeader } from '../Utils/GDevelopServices/Example';
|
||||
import Window from '../Utils/Window';
|
||||
import PublishIcon from '@material-ui/icons/Publish';
|
||||
import { findEmptyPath } from './LocalPathFinder';
|
||||
import { findEmptyPathInDefaultFolder } from './LocalPathFinder';
|
||||
import optionalRequire from '../Utils/OptionalRequire.js';
|
||||
const path = optionalRequire('path');
|
||||
const electron = optionalRequire('electron');
|
||||
const app = electron ? electron.remote.app : null;
|
||||
|
||||
@@ -33,6 +32,7 @@ export type OnOpenProjectAfterCreationFunction = ({|
|
||||
project?: gdProject,
|
||||
storageProvider: ?StorageProvider,
|
||||
fileMetadata: ?FileMetadata,
|
||||
projectName?: string,
|
||||
shouldCloseDialog?: boolean,
|
||||
|}) => Promise<void>;
|
||||
|
||||
@@ -45,19 +45,23 @@ export type CreateProjectDialogWithComponentsProps = {|
|
||||
|
||||
export type OnCreateBlankFunction = ({|
|
||||
i18n: I18nType,
|
||||
projectName: string,
|
||||
outputPath?: string,
|
||||
|}) => Promise<?{|
|
||||
project: gdProject,
|
||||
storageProvider: ?StorageProvider,
|
||||
projectName?: string,
|
||||
fileMetadata: ?FileMetadata,
|
||||
|}>;
|
||||
|
||||
export type OnCreateFromExampleShortHeaderFunction = ({|
|
||||
i18n: I18nType,
|
||||
exampleShortHeader: ExampleShortHeader,
|
||||
projectName: string,
|
||||
outputPath?: string,
|
||||
|}) => Promise<?{|
|
||||
storageProvider: StorageProvider,
|
||||
projectName: string,
|
||||
fileMetadata: FileMetadata,
|
||||
|}>;
|
||||
|
||||
@@ -70,9 +74,7 @@ type Props = {|
|
||||
export default class CreateProjectDialog extends React.Component<Props, State> {
|
||||
state = {
|
||||
currentTab: this.props.initialTab,
|
||||
outputPath: app
|
||||
? findEmptyPath(path.join(app.getPath('documents'), 'GDevelop projects'))
|
||||
: '',
|
||||
outputPath: app ? findEmptyPathInDefaultFolder(app) : '',
|
||||
};
|
||||
|
||||
_onChangeTab = (newTab: CreateProjectDialogTabs) => {
|
||||
|
@@ -8,11 +8,12 @@ import { ExampleStore } from '../AssetStore/ExampleStore';
|
||||
import { type ExampleShortHeader } from '../Utils/GDevelopServices/Example';
|
||||
import { Column } from '../UI/Grid';
|
||||
import { showErrorBox } from '../UI/Messages/MessageBox';
|
||||
import LocalProjectPreCreationDialog from './LocalProjectPreCreationDialog';
|
||||
import ProjectPreCreationDialog from './ProjectPreCreationDialog';
|
||||
import {
|
||||
type OnCreateFromExampleShortHeaderFunction,
|
||||
type OnOpenProjectAfterCreationFunction,
|
||||
} from '../ProjectCreation/CreateProjectDialog';
|
||||
import generateName from '../Utils/ProjectNameGenerator';
|
||||
|
||||
type Props = {|
|
||||
onOpen: OnOpenProjectAfterCreationFunction,
|
||||
@@ -42,6 +43,9 @@ export default function LocalExamples({
|
||||
onCreateFromExampleShortHeader,
|
||||
}: Props) {
|
||||
const [isOpening, setIsOpening] = React.useState<boolean>(false);
|
||||
const [newProjectName, setNewProjectName] = React.useState<string>(
|
||||
generateName()
|
||||
);
|
||||
const [
|
||||
selectedExampleShortHeader,
|
||||
setSelectedExampleShortShortHeader,
|
||||
@@ -55,11 +59,11 @@ export default function LocalExamples({
|
||||
const projectMetadata = await onCreateFromExampleShortHeader({
|
||||
i18n,
|
||||
outputPath,
|
||||
projectName: newProjectName,
|
||||
exampleShortHeader: selectedExampleShortHeader,
|
||||
});
|
||||
if (!!projectMetadata) {
|
||||
const { storageProvider, fileMetadata } = projectMetadata;
|
||||
onOpen({ storageProvider, fileMetadata, shouldCloseDialog: true });
|
||||
onOpen({ ...projectMetadata, shouldCloseDialog: true });
|
||||
}
|
||||
} finally {
|
||||
setIsOpening(false);
|
||||
@@ -80,13 +84,15 @@ export default function LocalExamples({
|
||||
/>
|
||||
</Column>
|
||||
{selectedExampleShortHeader && (
|
||||
<LocalProjectPreCreationDialog
|
||||
<ProjectPreCreationDialog
|
||||
open
|
||||
isOpening={isOpening}
|
||||
onClose={() => setSelectedExampleShortShortHeader(null)}
|
||||
onCreate={() => createProjectFromExample(i18n)}
|
||||
outputPath={outputPath}
|
||||
onChangeOutputPath={onChangeOutputPath}
|
||||
projectName={newProjectName}
|
||||
onChangeProjectName={setNewProjectName}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
|
@@ -1,9 +1,10 @@
|
||||
// @flow
|
||||
import generateName from '../Utils/NewNameGenerator';
|
||||
import optionalRequire from '../Utils/OptionalRequire.js';
|
||||
const path = optionalRequire('path');
|
||||
var fs = optionalRequire('fs-extra');
|
||||
|
||||
export const findEmptyPath = basePath => {
|
||||
const findEmptyPath = (basePath: string) => {
|
||||
if (!path) return basePath;
|
||||
|
||||
const folderName = generateName('My project', name => {
|
||||
@@ -17,3 +18,9 @@ export const findEmptyPath = basePath => {
|
||||
|
||||
return path.join(basePath, folderName);
|
||||
};
|
||||
|
||||
export const findEmptyPathInDefaultFolder = (electronApp: any): string => {
|
||||
return findEmptyPath(
|
||||
path.join(electronApp.getPath('documents'), 'GDevelop projects')
|
||||
);
|
||||
};
|
||||
|
@@ -1,60 +0,0 @@
|
||||
// @flow
|
||||
import { Trans } from '@lingui/macro';
|
||||
import * as React from 'react';
|
||||
import Dialog from '../UI/Dialog';
|
||||
import FlatButton from '../UI/FlatButton';
|
||||
import RaisedButton from '../UI/RaisedButton';
|
||||
import { Column } from '../UI/Grid';
|
||||
import LocalFolderPicker from '../UI/LocalFolderPicker';
|
||||
|
||||
type Props = {|
|
||||
open: boolean,
|
||||
isOpening?: boolean,
|
||||
onClose: () => void,
|
||||
onCreate: () => void | Promise<void>,
|
||||
outputPath: string,
|
||||
onChangeOutputPath: (outputPath: string) => void,
|
||||
|};
|
||||
|
||||
const LocalProjectPreCreationDialog = ({
|
||||
open,
|
||||
isOpening,
|
||||
onClose,
|
||||
onCreate,
|
||||
outputPath,
|
||||
onChangeOutputPath,
|
||||
}: Props): React.Node => {
|
||||
return (
|
||||
<Dialog
|
||||
title={<Trans>Project settings</Trans>}
|
||||
maxWidth="sm"
|
||||
open={open}
|
||||
actions={[
|
||||
<FlatButton
|
||||
disabled={isOpening}
|
||||
key="cancel"
|
||||
label={<Trans>Cancel</Trans>}
|
||||
onClick={onClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
primary
|
||||
disabled={isOpening}
|
||||
key="create"
|
||||
label={<Trans>Create project</Trans>}
|
||||
onClick={onCreate}
|
||||
/>,
|
||||
]}
|
||||
>
|
||||
<Column>
|
||||
<LocalFolderPicker
|
||||
fullWidth
|
||||
value={outputPath}
|
||||
onChange={onChangeOutputPath}
|
||||
type="create-game"
|
||||
/>
|
||||
</Column>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default LocalProjectPreCreationDialog;
|
104
newIDE/app/src/ProjectCreation/ProjectPreCreationDialog.js
Normal file
104
newIDE/app/src/ProjectCreation/ProjectPreCreationDialog.js
Normal file
@@ -0,0 +1,104 @@
|
||||
// @flow
|
||||
import { Trans } from '@lingui/macro';
|
||||
import * as React from 'react';
|
||||
import Dialog from '../UI/Dialog';
|
||||
import FlatButton from '../UI/FlatButton';
|
||||
import RaisedButton from '../UI/RaisedButton';
|
||||
import { Column, Spacer } from '../UI/Grid';
|
||||
import LocalFolderPicker from '../UI/LocalFolderPicker';
|
||||
import TextField from '../UI/TextField';
|
||||
|
||||
type Props = {|
|
||||
open: boolean,
|
||||
isOpening?: boolean,
|
||||
onClose: () => void,
|
||||
onCreate: () => void | Promise<void>,
|
||||
outputPath?: string,
|
||||
onChangeOutputPath?: (outputPath: string) => void,
|
||||
projectName: string,
|
||||
onChangeProjectName: (name: string) => void,
|
||||
|};
|
||||
|
||||
const ProjectPreCreationDialog = ({
|
||||
open,
|
||||
isOpening,
|
||||
onClose,
|
||||
onCreate,
|
||||
outputPath,
|
||||
onChangeOutputPath,
|
||||
projectName,
|
||||
onChangeProjectName,
|
||||
}: Props): React.Node => {
|
||||
const [projectNameError, setProjectNameError] = React.useState<?React.Node>(
|
||||
null
|
||||
);
|
||||
|
||||
const onValidate = React.useCallback(
|
||||
() => {
|
||||
setProjectNameError(null);
|
||||
if (!projectName) {
|
||||
setProjectNameError(
|
||||
<Trans>Please enter a name for your project.</Trans>
|
||||
);
|
||||
return;
|
||||
}
|
||||
onCreate();
|
||||
},
|
||||
[onCreate, projectName]
|
||||
);
|
||||
|
||||
const _onChangeProjectName = React.useCallback(
|
||||
(event, text) => {
|
||||
if (projectNameError) setProjectNameError(null);
|
||||
onChangeProjectName(text);
|
||||
},
|
||||
[onChangeProjectName, projectNameError]
|
||||
);
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
title={<Trans>Project settings</Trans>}
|
||||
maxWidth="sm"
|
||||
open={open}
|
||||
actions={[
|
||||
<FlatButton
|
||||
disabled={isOpening}
|
||||
key="cancel"
|
||||
label={<Trans>Cancel</Trans>}
|
||||
onClick={onClose}
|
||||
/>,
|
||||
<RaisedButton
|
||||
primary
|
||||
disabled={isOpening}
|
||||
key="create"
|
||||
label={<Trans>Create project</Trans>}
|
||||
onClick={onValidate}
|
||||
/>,
|
||||
]}
|
||||
>
|
||||
<Column>
|
||||
<TextField
|
||||
type="text"
|
||||
errorText={projectNameError}
|
||||
disabled={isOpening}
|
||||
value={projectName}
|
||||
onChange={_onChangeProjectName}
|
||||
floatingLabelText={<Trans>Project name</Trans>}
|
||||
/>
|
||||
{onChangeOutputPath && (
|
||||
<>
|
||||
<Spacer />
|
||||
<LocalFolderPicker
|
||||
fullWidth
|
||||
value={outputPath || ''}
|
||||
onChange={onChangeOutputPath}
|
||||
type="create-game"
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
</Column>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProjectPreCreationDialog;
|
@@ -1,52 +1,48 @@
|
||||
// @flow
|
||||
import { t } from '@lingui/macro';
|
||||
import { type I18n as I18nType } from '@lingui/core';
|
||||
|
||||
import UrlStorageProvider from '../../ProjectsStorage/UrlStorageProvider';
|
||||
import { type StorageProvider, type FileMetadata } from '../../ProjectsStorage';
|
||||
import { getExample } from '../../Utils/GDevelopServices/Example';
|
||||
import { sendNewGameCreated } from '../../Utils/Analytics/EventSender';
|
||||
import { showErrorBox } from '../../UI/Messages/MessageBox';
|
||||
import { type ExampleShortHeader } from '../../Utils/GDevelopServices/Example';
|
||||
import {
|
||||
type OnCreateBlankFunction,
|
||||
type OnCreateFromExampleShortHeaderFunction,
|
||||
} from '../CreateProjectDialog';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
// Signatures of this function and its arguments contain useless arguments
|
||||
// because this function has to match the signature of LocalCreation.onCreateBlank
|
||||
// that needs these arguments.
|
||||
export const onCreateBlank = async ({
|
||||
export const onCreateBlank: OnCreateBlankFunction = async ({
|
||||
i18n,
|
||||
outputPath,
|
||||
}: {|
|
||||
i18n: I18nType,
|
||||
outputPath?: string,
|
||||
|}): Promise<?{|
|
||||
project: gdProject,
|
||||
storageProvider: ?StorageProvider,
|
||||
fileMetadata: ?FileMetadata,
|
||||
|}> => {
|
||||
projectName,
|
||||
}) => {
|
||||
sendNewGameCreated('');
|
||||
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
return { project, storageProvider: null, fileMetadata: null };
|
||||
return {
|
||||
project,
|
||||
projectName,
|
||||
storageProvider: null,
|
||||
fileMetadata: null,
|
||||
};
|
||||
};
|
||||
|
||||
export const onCreateFromExampleShortHeader = async ({
|
||||
export const onCreateFromExampleShortHeader: OnCreateFromExampleShortHeaderFunction = async ({
|
||||
i18n,
|
||||
exampleShortHeader,
|
||||
projectName,
|
||||
outputPath,
|
||||
}: {|
|
||||
i18n: I18nType,
|
||||
exampleShortHeader: ExampleShortHeader,
|
||||
outputPath?: string,
|
||||
|}): Promise<?{|
|
||||
storageProvider: StorageProvider,
|
||||
fileMetadata: FileMetadata,
|
||||
|}> => {
|
||||
}) => {
|
||||
try {
|
||||
const example = await getExample(exampleShortHeader);
|
||||
sendNewGameCreated(example.projectFileUrl);
|
||||
return {
|
||||
storageProvider: UrlStorageProvider,
|
||||
projectName,
|
||||
fileMetadata: {
|
||||
fileIdentifier: example.projectFileUrl,
|
||||
},
|
||||
|
@@ -1,33 +1,28 @@
|
||||
// @flow
|
||||
import axios from 'axios';
|
||||
import { t } from '@lingui/macro';
|
||||
import { type I18n as I18nType } from '@lingui/core';
|
||||
|
||||
import LocalFileStorageProvider from '../../ProjectsStorage/LocalFileStorageProvider';
|
||||
import { type StorageProvider, type FileMetadata } from '../../ProjectsStorage';
|
||||
import optionalRequire from '../../Utils/OptionalRequire.js';
|
||||
import { getExample } from '../../Utils/GDevelopServices/Example';
|
||||
import { sendNewGameCreated } from '../../Utils/Analytics/EventSender';
|
||||
import { showErrorBox } from '../../UI/Messages/MessageBox';
|
||||
import { writeAndCheckFile } from '../../ProjectsStorage/LocalFileStorageProvider/LocalProjectWriter';
|
||||
import { type ExampleShortHeader } from '../../Utils/GDevelopServices/Example';
|
||||
import { showGameFileCreationError } from '../LocalExamples';
|
||||
import {
|
||||
type OnCreateBlankFunction,
|
||||
type OnCreateFromExampleShortHeaderFunction,
|
||||
} from '../CreateProjectDialog';
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
const path = optionalRequire('path');
|
||||
var fs = optionalRequire('fs-extra');
|
||||
|
||||
export const onCreateBlank = async ({
|
||||
export const onCreateBlank: OnCreateBlankFunction = async ({
|
||||
i18n,
|
||||
outputPath,
|
||||
}: {|
|
||||
i18n: I18nType,
|
||||
outputPath?: string,
|
||||
|}): Promise<?{|
|
||||
project: gdProject,
|
||||
storageProvider: ?StorageProvider,
|
||||
fileMetadata: ?FileMetadata,
|
||||
|}> => {
|
||||
projectName,
|
||||
}) => {
|
||||
if (!fs || !outputPath) return;
|
||||
|
||||
try {
|
||||
@@ -45,21 +40,16 @@ export const onCreateBlank = async ({
|
||||
project,
|
||||
storageProvider: LocalFileStorageProvider,
|
||||
fileMetadata: { fileIdentifier: filePath },
|
||||
projectName,
|
||||
};
|
||||
};
|
||||
|
||||
export const onCreateFromExampleShortHeader = async ({
|
||||
export const onCreateFromExampleShortHeader: OnCreateFromExampleShortHeaderFunction = async ({
|
||||
i18n,
|
||||
exampleShortHeader,
|
||||
outputPath,
|
||||
}: {|
|
||||
i18n: I18nType,
|
||||
exampleShortHeader: ExampleShortHeader,
|
||||
outputPath?: string,
|
||||
|}): Promise<?{|
|
||||
storageProvider: StorageProvider,
|
||||
fileMetadata: FileMetadata,
|
||||
|}> => {
|
||||
projectName,
|
||||
}) => {
|
||||
if (!fs || !outputPath) return;
|
||||
try {
|
||||
const example = await getExample(exampleShortHeader);
|
||||
@@ -82,6 +72,7 @@ export const onCreateFromExampleShortHeader = async ({
|
||||
return {
|
||||
storageProvider: LocalFileStorageProvider,
|
||||
fileMetadata: { fileIdentifier: localFilePath },
|
||||
projectName,
|
||||
};
|
||||
} catch (error) {
|
||||
showErrorBox({
|
||||
|
2133
newIDE/app/src/Utils/ProjectNameGenerator.js
Normal file
2133
newIDE/app/src/Utils/ProjectNameGenerator.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,35 +0,0 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import muiDecorator from '../ThemeDecorator';
|
||||
import paperDecorator from '../PaperDecorator';
|
||||
import LocalProjectPreCreationDialog from '../../ProjectCreation/LocalProjectPreCreationDialog';
|
||||
|
||||
export default {
|
||||
title: 'Project Creation/LocalProjectPreCreationDialog',
|
||||
component: LocalProjectPreCreationDialog,
|
||||
decorators: [paperDecorator, muiDecorator],
|
||||
};
|
||||
|
||||
export const Open = () => (
|
||||
<LocalProjectPreCreationDialog
|
||||
open
|
||||
outputPath="/path/to/project/file.json"
|
||||
onChangeOutputPath={action('change output path')}
|
||||
onClose={() => action('click on close')()}
|
||||
onCreate={() => action('click on create')()}
|
||||
/>
|
||||
);
|
||||
|
||||
export const Disabled = () => (
|
||||
<LocalProjectPreCreationDialog
|
||||
open
|
||||
isOpening
|
||||
outputPath="/path/to/project/file.json"
|
||||
onChangeOutputPath={action('change output path')}
|
||||
onClose={() => action('click on close')()}
|
||||
onCreate={() => action('click on create')()}
|
||||
/>
|
||||
);
|
@@ -0,0 +1,45 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import muiDecorator from '../ThemeDecorator';
|
||||
import paperDecorator from '../PaperDecorator';
|
||||
import ProjectPreCreationDialog from '../../ProjectCreation/ProjectPreCreationDialog';
|
||||
|
||||
export default {
|
||||
title: 'Project Creation/ProjectPreCreationDialog',
|
||||
component: ProjectPreCreationDialog,
|
||||
decorators: [paperDecorator, muiDecorator],
|
||||
};
|
||||
|
||||
export const Open = () => {
|
||||
const [projectName, setProjectName] = React.useState('Project Name');
|
||||
return (
|
||||
<ProjectPreCreationDialog
|
||||
open
|
||||
outputPath="/path/to/project/file.json"
|
||||
onChangeOutputPath={action('change output path')}
|
||||
onClose={() => action('click on close')()}
|
||||
onCreate={() => action('click on create')()}
|
||||
projectName={projectName}
|
||||
onChangeProjectName={setProjectName}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
export const Disabled = () => {
|
||||
const [projectName, setProjectName] = React.useState('Project Name');
|
||||
return (
|
||||
<ProjectPreCreationDialog
|
||||
open
|
||||
isOpening
|
||||
outputPath="/path/to/project/file.json"
|
||||
onChangeOutputPath={action('change output path')}
|
||||
onClose={() => action('click on close')()}
|
||||
onCreate={() => action('click on create')()}
|
||||
projectName={projectName}
|
||||
onChangeProjectName={setProjectName}
|
||||
/>
|
||||
);
|
||||
};
|
Reference in New Issue
Block a user