mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
1 Commits
v5.4.218
...
feat/updat
Author | SHA1 | Date | |
---|---|---|---|
![]() |
5193b617b3 |
@@ -17,7 +17,9 @@ export type ExampleStoreDialogProps = {|
|
|||||||
onSelectPrivateGameTemplateListingData: (
|
onSelectPrivateGameTemplateListingData: (
|
||||||
privateGameTemplateListingData: ?PrivateGameTemplateListingData
|
privateGameTemplateListingData: ?PrivateGameTemplateListingData
|
||||||
) => void,
|
) => void,
|
||||||
onOpenNewProjectSetupDialog: () => void,
|
onOpenNewProjectSetupDialog: (
|
||||||
|
initialTab: 'from-scratch' | 'ai' | 'example'
|
||||||
|
) => void,
|
||||||
isProjectOpening: boolean,
|
isProjectOpening: boolean,
|
||||||
|};
|
|};
|
||||||
|
|
||||||
@@ -44,7 +46,7 @@ const ExampleStoreDialog = ({
|
|||||||
id="create-blank-project-button"
|
id="create-blank-project-button"
|
||||||
label={<Trans>Create a blank project</Trans>}
|
label={<Trans>Create a blank project</Trans>}
|
||||||
primary
|
primary
|
||||||
onClick={onOpenNewProjectSetupDialog}
|
onClick={() => onOpenNewProjectSetupDialog('from-scratch')}
|
||||||
/>,
|
/>,
|
||||||
],
|
],
|
||||||
[onClose, onOpenNewProjectSetupDialog]
|
[onClose, onOpenNewProjectSetupDialog]
|
||||||
@@ -59,7 +61,7 @@ const ExampleStoreDialog = ({
|
|||||||
title={<Trans>Create a new project</Trans>}
|
title={<Trans>Create a new project</Trans>}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
onRequestClose={onClose}
|
onRequestClose={onClose}
|
||||||
onApply={onOpenNewProjectSetupDialog}
|
onApply={() => onOpenNewProjectSetupDialog('from-scratch')}
|
||||||
open={open}
|
open={open}
|
||||||
fullHeight
|
fullHeight
|
||||||
flexColumnBody
|
flexColumnBody
|
||||||
@@ -67,7 +69,9 @@ const ExampleStoreDialog = ({
|
|||||||
<ExampleStore
|
<ExampleStore
|
||||||
focusOnMount
|
focusOnMount
|
||||||
isOpening={isProjectOpening}
|
isOpening={isProjectOpening}
|
||||||
onOpenNewProjectSetupDialog={onOpenNewProjectSetupDialog}
|
onOpenNewProjectSetupDialog={() =>
|
||||||
|
onOpenNewProjectSetupDialog('example')
|
||||||
|
}
|
||||||
onSelectExampleShortHeader={onSelectExampleShortHeader}
|
onSelectExampleShortHeader={onSelectExampleShortHeader}
|
||||||
onSelectPrivateGameTemplateListingData={
|
onSelectPrivateGameTemplateListingData={
|
||||||
onSelectPrivateGameTemplateListingData
|
onSelectPrivateGameTemplateListingData
|
||||||
|
@@ -98,7 +98,9 @@ export type RenderEditorContainerProps = {|
|
|||||||
canInstallPrivateAsset: () => boolean,
|
canInstallPrivateAsset: () => boolean,
|
||||||
|
|
||||||
// Project creation
|
// Project creation
|
||||||
onOpenNewProjectSetupDialog: () => void,
|
onOpenNewProjectSetupDialog: (
|
||||||
|
initialTab: 'from-scratch' | 'ai' | 'example'
|
||||||
|
) => void,
|
||||||
|
|
||||||
// Project save
|
// Project save
|
||||||
onSave: () => Promise<void>,
|
onSave: () => Promise<void>,
|
||||||
|
@@ -108,7 +108,7 @@ type Props = {|
|
|||||||
canOpen: boolean,
|
canOpen: boolean,
|
||||||
onChooseProject: () => void,
|
onChooseProject: () => void,
|
||||||
onOpenRecentFile: (file: FileMetadataAndStorageProviderName) => Promise<void>,
|
onOpenRecentFile: (file: FileMetadataAndStorageProviderName) => Promise<void>,
|
||||||
onOpenNewProjectSetupDialog: () => void,
|
onOpenNewProjectSetupDialog: (initialTab: 'ai' | 'from-scratch') => void,
|
||||||
onSelectExampleShortHeader: (exampleShortHeader: ExampleShortHeader) => void,
|
onSelectExampleShortHeader: (exampleShortHeader: ExampleShortHeader) => void,
|
||||||
onSelectPrivateGameTemplateListingData: (
|
onSelectPrivateGameTemplateListingData: (
|
||||||
privateGameTemplateListingData: PrivateGameTemplateListingData
|
privateGameTemplateListingData: PrivateGameTemplateListingData
|
||||||
@@ -179,6 +179,8 @@ const BuildSection = ({
|
|||||||
setLastModifiedInfoByProjectId,
|
setLastModifiedInfoByProjectId,
|
||||||
] = React.useState({});
|
] = React.useState({});
|
||||||
|
|
||||||
|
const isMediumOrSmallScreen =
|
||||||
|
windowSize === 'small' || windowSize === 'medium';
|
||||||
const columnsCount = getItemsColumns(windowSize, isLandscape);
|
const columnsCount = getItemsColumns(windowSize, isLandscape);
|
||||||
|
|
||||||
const allGameTemplatesAndExamplesFlaggedAsGameCount = React.useMemo(
|
const allGameTemplatesAndExamplesFlaggedAsGameCount = React.useMemo(
|
||||||
@@ -488,34 +490,41 @@ const BuildSection = ({
|
|||||||
primary
|
primary
|
||||||
fullWidth={!canOpen}
|
fullWidth={!canOpen}
|
||||||
label={
|
label={
|
||||||
isMobile ? (
|
isMediumOrSmallScreen ? (
|
||||||
<Trans>Create</Trans>
|
<Trans>Create</Trans>
|
||||||
) : (
|
) : (
|
||||||
<Trans>Create a project</Trans>
|
<Trans>Create a project</Trans>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
onClick={onOpenNewProjectSetupDialog}
|
onClick={() => onOpenNewProjectSetupDialog('from-scratch')}
|
||||||
icon={<Add fontSize="small" />}
|
icon={<Add fontSize="small" />}
|
||||||
id="home-create-project-button"
|
id="home-create-project-button"
|
||||||
/>
|
/>
|
||||||
|
<RaisedButton
|
||||||
|
primary
|
||||||
|
fullWidth={!canOpen}
|
||||||
|
label={
|
||||||
|
isMediumOrSmallScreen ? (
|
||||||
|
<Trans>✨ AI prototype</Trans>
|
||||||
|
) : (
|
||||||
|
<Trans>✨ Prototype with AI</Trans>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
onClick={() => onOpenNewProjectSetupDialog('ai')}
|
||||||
|
id="home-create-project-button"
|
||||||
|
/>
|
||||||
{canOpen && (
|
{canOpen && (
|
||||||
<>
|
<TextButton
|
||||||
<Text>
|
secondary
|
||||||
<Trans>or</Trans>
|
label={
|
||||||
</Text>
|
isMediumOrSmallScreen ? (
|
||||||
<Spacer />
|
<Trans>Import</Trans>
|
||||||
<TextButton
|
) : (
|
||||||
secondary
|
<Trans>Import a project</Trans>
|
||||||
label={
|
)
|
||||||
isMobile ? (
|
}
|
||||||
<Trans>Open</Trans>
|
onClick={onChooseProject}
|
||||||
) : (
|
/>
|
||||||
<Trans>Open a project</Trans>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
onClick={onChooseProject}
|
|
||||||
/>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
</LineStackLayout>
|
</LineStackLayout>
|
||||||
</Column>
|
</Column>
|
||||||
|
@@ -114,7 +114,9 @@ type Props = {|
|
|||||||
onOpenAbout: () => void,
|
onOpenAbout: () => void,
|
||||||
|
|
||||||
// Project creation
|
// Project creation
|
||||||
onOpenNewProjectSetupDialog: () => void,
|
onOpenNewProjectSetupDialog: (
|
||||||
|
initialTab: 'from-scratch' | 'ai' | 'example'
|
||||||
|
) => void,
|
||||||
|
|
||||||
// Project save
|
// Project save
|
||||||
onSave: () => Promise<void>,
|
onSave: () => Promise<void>,
|
||||||
|
@@ -12,7 +12,9 @@ import AuthenticatedUserContext from '../Profile/AuthenticatedUserContext';
|
|||||||
|
|
||||||
type Props = {|
|
type Props = {|
|
||||||
isProjectOpening: boolean,
|
isProjectOpening: boolean,
|
||||||
onOpenNewProjectSetupDialog: () => void,
|
onOpenNewProjectSetupDialog: (
|
||||||
|
initialTab: 'from-scratch' | 'ai' | 'example'
|
||||||
|
) => void,
|
||||||
|};
|
|};
|
||||||
|
|
||||||
const useExampleOrGameTemplateDialogs = ({
|
const useExampleOrGameTemplateDialogs = ({
|
||||||
@@ -137,7 +139,7 @@ const useExampleOrGameTemplateDialogs = ({
|
|||||||
<ExampleDialog
|
<ExampleDialog
|
||||||
isOpening={isProjectOpening}
|
isOpening={isProjectOpening}
|
||||||
exampleShortHeader={selectedExampleShortHeader}
|
exampleShortHeader={selectedExampleShortHeader}
|
||||||
onOpen={onOpenNewProjectSetupDialog}
|
onOpen={() => onOpenNewProjectSetupDialog('example')}
|
||||||
onClose={() => setSelectedExampleShortHeader(null)}
|
onClose={() => setSelectedExampleShortHeader(null)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
@@ -148,7 +150,9 @@ const useExampleOrGameTemplateDialogs = ({
|
|||||||
selectedPrivateGameTemplate.privateGameTemplateListingData
|
selectedPrivateGameTemplate.privateGameTemplateListingData
|
||||||
}
|
}
|
||||||
isPurchaseDialogOpen={!!purchasingGameTemplateListingData}
|
isPurchaseDialogOpen={!!purchasingGameTemplateListingData}
|
||||||
onCreateWithGameTemplate={onOpenNewProjectSetupDialog}
|
onCreateWithGameTemplate={() =>
|
||||||
|
onOpenNewProjectSetupDialog('example')
|
||||||
|
}
|
||||||
onGameTemplateOpen={privateGameTemplateListingData =>
|
onGameTemplateOpen={privateGameTemplateListingData =>
|
||||||
setSelectedPrivateGameTemplate({
|
setSelectedPrivateGameTemplate({
|
||||||
privateGameTemplateListingData,
|
privateGameTemplateListingData,
|
||||||
|
@@ -359,9 +359,9 @@ const MainFrame = (props: Props) => {
|
|||||||
openPreferencesDialog,
|
openPreferencesDialog,
|
||||||
] = React.useState<boolean>(false);
|
] = React.useState<boolean>(false);
|
||||||
const [
|
const [
|
||||||
newProjectSetupDialogOpen,
|
newProjectSetupDialogInitialTab,
|
||||||
setNewProjectSetupDialogOpen,
|
setNewProjectSetupDialogInitialTab,
|
||||||
] = React.useState<boolean>(false);
|
] = React.useState<null | 'from-scratch' | 'ai' | 'example'>(null);
|
||||||
|
|
||||||
const [isProjectOpening, setIsProjectOpening] = React.useState<boolean>(
|
const [isProjectOpening, setIsProjectOpening] = React.useState<boolean>(
|
||||||
false
|
false
|
||||||
@@ -498,7 +498,7 @@ const MainFrame = (props: Props) => {
|
|||||||
openExampleStoreDialog,
|
openExampleStoreDialog,
|
||||||
} = useExampleOrGameTemplateDialogs({
|
} = useExampleOrGameTemplateDialogs({
|
||||||
isProjectOpening,
|
isProjectOpening,
|
||||||
onOpenNewProjectSetupDialog: () => setNewProjectSetupDialogOpen(true),
|
onOpenNewProjectSetupDialog: setNewProjectSetupDialogInitialTab,
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1144,7 +1144,7 @@ const MainFrame = (props: Props) => {
|
|||||||
},
|
},
|
||||||
getStorageProviderOperations,
|
getStorageProviderOperations,
|
||||||
afterCreatingProject: async ({ project, editorTabs, oldProjectId }) => {
|
afterCreatingProject: async ({ project, editorTabs, oldProjectId }) => {
|
||||||
setNewProjectSetupDialogOpen(false);
|
setNewProjectSetupDialogInitialTab(null);
|
||||||
closeExampleStoreDialog({ deselectExampleAndGameTemplate: true });
|
closeExampleStoreDialog({ deselectExampleAndGameTemplate: true });
|
||||||
findLeaderboardsToReplace(project, oldProjectId);
|
findLeaderboardsToReplace(project, oldProjectId);
|
||||||
openSceneOrProjectManager({
|
openSceneOrProjectManager({
|
||||||
@@ -2960,7 +2960,7 @@ const MainFrame = (props: Props) => {
|
|||||||
onLaunchDebugPreview: launchDebuggerAndPreview,
|
onLaunchDebugPreview: launchDebuggerAndPreview,
|
||||||
onLaunchNetworkPreview: launchNetworkPreview,
|
onLaunchNetworkPreview: launchNetworkPreview,
|
||||||
onOpenHomePage: openHomePage,
|
onOpenHomePage: openHomePage,
|
||||||
onCreateBlank: () => setNewProjectSetupDialogOpen(true),
|
onCreateBlank: () => setNewProjectSetupDialogInitialTab('from-scratch'),
|
||||||
onOpenProject: () => openOpenFromStorageProviderDialog(),
|
onOpenProject: () => openOpenFromStorageProviderDialog(),
|
||||||
onSaveProject: saveProject,
|
onSaveProject: saveProject,
|
||||||
onSaveProjectAs: saveProjectAs,
|
onSaveProjectAs: saveProjectAs,
|
||||||
@@ -3020,7 +3020,7 @@ const MainFrame = (props: Props) => {
|
|||||||
onExportProject: () => openShareDialog('publish'),
|
onExportProject: () => openShareDialog('publish'),
|
||||||
onInviteCollaborators: () => openShareDialog('invite'),
|
onInviteCollaborators: () => openShareDialog('invite'),
|
||||||
onCreateProject: openExampleStoreDialog,
|
onCreateProject: openExampleStoreDialog,
|
||||||
onCreateBlank: () => setNewProjectSetupDialogOpen(true),
|
onCreateBlank: () => setNewProjectSetupDialogInitialTab('from-scratch'),
|
||||||
onOpenProjectManager: () => openProjectManager(true),
|
onOpenProjectManager: () => openProjectManager(true),
|
||||||
onOpenHomePage: openHomePage,
|
onOpenHomePage: openHomePage,
|
||||||
onOpenDebugger: openDebugger,
|
onOpenDebugger: openDebugger,
|
||||||
@@ -3224,9 +3224,7 @@ const MainFrame = (props: Props) => {
|
|||||||
canInstallPrivateAsset,
|
canInstallPrivateAsset,
|
||||||
onChooseProject: () => openOpenFromStorageProviderDialog(),
|
onChooseProject: () => openOpenFromStorageProviderDialog(),
|
||||||
onOpenRecentFile: openFromFileMetadataWithStorageProvider,
|
onOpenRecentFile: openFromFileMetadataWithStorageProvider,
|
||||||
onOpenNewProjectSetupDialog: () => {
|
onOpenNewProjectSetupDialog: setNewProjectSetupDialogInitialTab,
|
||||||
setNewProjectSetupDialogOpen(true);
|
|
||||||
},
|
|
||||||
onOpenProjectManager: () => openProjectManager(true),
|
onOpenProjectManager: () => openProjectManager(true),
|
||||||
onCloseProject: () => askToCloseProject(),
|
onCloseProject: () => askToCloseProject(),
|
||||||
onOpenExampleStore: openExampleStoreDialog,
|
onOpenExampleStore: openExampleStoreDialog,
|
||||||
@@ -3241,7 +3239,7 @@ const MainFrame = (props: Props) => {
|
|||||||
privateGameTemplateListingData,
|
privateGameTemplateListingData,
|
||||||
openDialog: false,
|
openDialog: false,
|
||||||
});
|
});
|
||||||
setNewProjectSetupDialogOpen(true);
|
setNewProjectSetupDialogInitialTab('example');
|
||||||
},
|
},
|
||||||
onOpenProfile: () => openProfileDialog(true),
|
onOpenProfile: () => openProfileDialog(true),
|
||||||
onOpenLanguageDialog: () => openLanguageDialog(true),
|
onOpenLanguageDialog: () => openLanguageDialog(true),
|
||||||
@@ -3366,11 +3364,12 @@ const MainFrame = (props: Props) => {
|
|||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{newProjectSetupDialogOpen && (
|
{newProjectSetupDialogInitialTab && (
|
||||||
<NewProjectSetupDialog
|
<NewProjectSetupDialog
|
||||||
|
initialTab={newProjectSetupDialogInitialTab}
|
||||||
authenticatedUser={authenticatedUser}
|
authenticatedUser={authenticatedUser}
|
||||||
isOpeningProject={isProjectOpening}
|
isOpeningProject={isProjectOpening}
|
||||||
onClose={() => setNewProjectSetupDialogOpen(false)}
|
onClose={() => setNewProjectSetupDialogInitialTab(null)}
|
||||||
onCreateEmptyProject={createEmptyProject}
|
onCreateEmptyProject={createEmptyProject}
|
||||||
onCreateFromExample={createProjectFromExample}
|
onCreateFromExample={createProjectFromExample}
|
||||||
onCreateProjectFromPrivateGameTemplate={
|
onCreateProjectFromPrivateGameTemplate={
|
||||||
|
@@ -17,8 +17,8 @@ import SelectField from '../UI/SelectField';
|
|||||||
import SelectOption from '../UI/SelectOption';
|
import SelectOption from '../UI/SelectOption';
|
||||||
import CreateProfile from '../Profile/CreateProfile';
|
import CreateProfile from '../Profile/CreateProfile';
|
||||||
import Paper from '../UI/Paper';
|
import Paper from '../UI/Paper';
|
||||||
import { Column, Line } from '../UI/Grid';
|
|
||||||
import LeftLoader from '../UI/LeftLoader';
|
import LeftLoader from '../UI/LeftLoader';
|
||||||
|
import { Column, LargeSpacer, Line, Spacer } from '../UI/Grid';
|
||||||
import {
|
import {
|
||||||
checkIfHasTooManyCloudProjects,
|
checkIfHasTooManyCloudProjects,
|
||||||
MaxProjectCountAlertMessage,
|
MaxProjectCountAlertMessage,
|
||||||
@@ -42,7 +42,6 @@ import ResolutionOptions, {
|
|||||||
defaultCustomHeight,
|
defaultCustomHeight,
|
||||||
} from './ResolutionOptions';
|
} from './ResolutionOptions';
|
||||||
import Text from '../UI/Text';
|
import Text from '../UI/Text';
|
||||||
import DismissableAlertMessage from '../UI/DismissableAlertMessage';
|
|
||||||
import generatePrompt from '../Utils/ProjectPromptGenerator';
|
import generatePrompt from '../Utils/ProjectPromptGenerator';
|
||||||
import ProjectGeneratingDialog from './ProjectGeneratingDialog';
|
import ProjectGeneratingDialog from './ProjectGeneratingDialog';
|
||||||
import useAlertDialog from '../UI/Alert/useAlertDialog';
|
import useAlertDialog from '../UI/Alert/useAlertDialog';
|
||||||
@@ -53,6 +52,7 @@ import { I18n } from '@lingui/react';
|
|||||||
import GetSubscriptionCard from '../Profile/Subscription/GetSubscriptionCard';
|
import GetSubscriptionCard from '../Profile/Subscription/GetSubscriptionCard';
|
||||||
import { type PrivateGameTemplateListingData } from '../Utils/GDevelopServices/Shop';
|
import { type PrivateGameTemplateListingData } from '../Utils/GDevelopServices/Shop';
|
||||||
import { extractGDevelopApiErrorStatusAndCode } from '../Utils/GDevelopServices/Errors';
|
import { extractGDevelopApiErrorStatusAndCode } from '../Utils/GDevelopServices/Errors';
|
||||||
|
import { Tabs } from '../UI/Tabs';
|
||||||
|
|
||||||
const electron = optionalRequire('electron');
|
const electron = optionalRequire('electron');
|
||||||
const remote = optionalRequire('@electron/remote');
|
const remote = optionalRequire('@electron/remote');
|
||||||
@@ -71,6 +71,7 @@ export type NewProjectSetup = {|
|
|||||||
|};
|
|};
|
||||||
|
|
||||||
type Props = {|
|
type Props = {|
|
||||||
|
initialTab?: 'ai' | 'from-scratch' | 'example',
|
||||||
isOpeningProject?: boolean,
|
isOpeningProject?: boolean,
|
||||||
onClose: () => void,
|
onClose: () => void,
|
||||||
onCreateEmptyProject: (newProjectSetup: NewProjectSetup) => Promise<void>,
|
onCreateEmptyProject: (newProjectSetup: NewProjectSetup) => Promise<void>,
|
||||||
@@ -96,6 +97,7 @@ type Props = {|
|
|||||||
|};
|
|};
|
||||||
|
|
||||||
const NewProjectSetupDialog = ({
|
const NewProjectSetupDialog = ({
|
||||||
|
initialTab,
|
||||||
isOpeningProject,
|
isOpeningProject,
|
||||||
onClose,
|
onClose,
|
||||||
onCreateEmptyProject,
|
onCreateEmptyProject,
|
||||||
@@ -108,6 +110,10 @@ const NewProjectSetupDialog = ({
|
|||||||
storageProviders,
|
storageProviders,
|
||||||
authenticatedUser,
|
authenticatedUser,
|
||||||
}: Props): React.Node => {
|
}: Props): React.Node => {
|
||||||
|
const [currentTab, setCurrentTab] = React.useState<
|
||||||
|
'ai' | 'from-scratch' | 'example'
|
||||||
|
>(initialTab || 'ai');
|
||||||
|
|
||||||
const generateProjectName = () =>
|
const generateProjectName = () =>
|
||||||
selectedExampleShortHeader
|
selectedExampleShortHeader
|
||||||
? `${generateName()} (${selectedExampleShortHeader.name})`
|
? `${generateName()} (${selectedExampleShortHeader.name})`
|
||||||
@@ -220,7 +226,7 @@ const NewProjectSetupDialog = ({
|
|||||||
? authenticatedUser.limits.quotas['ai-project-generation']
|
? authenticatedUser.limits.quotas['ai-project-generation']
|
||||||
: null;
|
: null;
|
||||||
const canGenerateProjectFromPrompt =
|
const canGenerateProjectFromPrompt =
|
||||||
generationCurrentUsage && !generationCurrentUsage.limitReached;
|
!!generationCurrentUsage && !generationCurrentUsage.limitReached;
|
||||||
|
|
||||||
const needUserAuthenticationForStorage =
|
const needUserAuthenticationForStorage =
|
||||||
storageProvider.needUserAuthentication && !authenticatedUser.authenticated;
|
storageProvider.needUserAuthentication && !authenticatedUser.authenticated;
|
||||||
@@ -243,7 +249,7 @@ const NewProjectSetupDialog = ({
|
|||||||
|
|
||||||
const isLoading = isGeneratingProject || isOpeningProject;
|
const isLoading = isGeneratingProject || isOpeningProject;
|
||||||
|
|
||||||
const isStartingProjectFromScratch =
|
const isCreatingANewProject =
|
||||||
!selectedExampleShortHeader && !selectedPrivateGameTemplateListingData;
|
!selectedExampleShortHeader && !selectedPrivateGameTemplateListingData;
|
||||||
|
|
||||||
// On the local app, prefer to always have something saved so that the user is not blocked.
|
// On the local app, prefer to always have something saved so that the user is not blocked.
|
||||||
@@ -414,6 +420,24 @@ const NewProjectSetupDialog = ({
|
|||||||
title={<Trans>New Project</Trans>}
|
title={<Trans>New Project</Trans>}
|
||||||
id="project-pre-creation-dialog"
|
id="project-pre-creation-dialog"
|
||||||
maxWidth="sm"
|
maxWidth="sm"
|
||||||
|
fixedContent={
|
||||||
|
isCreatingANewProject ? (
|
||||||
|
<Tabs
|
||||||
|
value={currentTab}
|
||||||
|
onChange={setCurrentTab}
|
||||||
|
options={[
|
||||||
|
{
|
||||||
|
value: 'ai',
|
||||||
|
label: <Trans>Create for me</Trans>,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'from-scratch',
|
||||||
|
label: <Trans>Create from scratch</Trans>,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
actions={[
|
actions={[
|
||||||
<FlatButton
|
<FlatButton
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@@ -436,16 +460,20 @@ const NewProjectSetupDialog = ({
|
|||||||
onApply={() => onValidate(i18n)}
|
onApply={() => onValidate(i18n)}
|
||||||
>
|
>
|
||||||
<ColumnStackLayout noMargin>
|
<ColumnStackLayout noMargin>
|
||||||
{isStartingProjectFromScratch && (
|
<LargeSpacer />
|
||||||
<ResolutionOptions
|
{isCreatingANewProject && currentTab === 'from-scratch' && (
|
||||||
onClick={key => setResolutionOption(key)}
|
<>
|
||||||
selectedOption={resolutionOption}
|
<ResolutionOptions
|
||||||
disabled={isLoading}
|
onClick={key => setResolutionOption(key)}
|
||||||
customHeight={customHeight}
|
selectedOption={resolutionOption}
|
||||||
customWidth={customWidth}
|
disabled={isLoading}
|
||||||
onCustomHeightChange={setCustomHeight}
|
customHeight={customHeight}
|
||||||
onCustomWidthChange={setCustomWidth}
|
customWidth={customWidth}
|
||||||
/>
|
onCustomHeightChange={setCustomHeight}
|
||||||
|
onCustomWidthChange={setCustomWidth}
|
||||||
|
/>
|
||||||
|
<Spacer />
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
<TextField
|
<TextField
|
||||||
type="text"
|
type="text"
|
||||||
@@ -467,6 +495,69 @@ const NewProjectSetupDialog = ({
|
|||||||
autoFocus="desktop"
|
autoFocus="desktop"
|
||||||
maxLength={100}
|
maxLength={100}
|
||||||
/>
|
/>
|
||||||
|
{isCreatingANewProject && currentTab === 'ai' && (
|
||||||
|
<ColumnStackLayout noMargin>
|
||||||
|
{authenticatedUser.authenticated &&
|
||||||
|
!canGenerateProjectFromPrompt && (
|
||||||
|
<GetSubscriptionCard subscriptionDialogOpeningReason="Generate project from prompt">
|
||||||
|
<Line>
|
||||||
|
<Column noMargin>
|
||||||
|
<Text noMargin>
|
||||||
|
<Trans>
|
||||||
|
You've used all your daily pre-made AI scenes!
|
||||||
|
Generate as many as you want with a subscription.
|
||||||
|
</Trans>
|
||||||
|
</Text>
|
||||||
|
</Column>
|
||||||
|
</Line>
|
||||||
|
</GetSubscriptionCard>
|
||||||
|
)}
|
||||||
|
<LineStackLayout
|
||||||
|
expand
|
||||||
|
noMargin
|
||||||
|
alignItems="center"
|
||||||
|
justifyContent="center"
|
||||||
|
>
|
||||||
|
<RobotIcon />
|
||||||
|
<TextField
|
||||||
|
type="text"
|
||||||
|
multiline
|
||||||
|
maxLength={200}
|
||||||
|
fullWidth
|
||||||
|
disabled={
|
||||||
|
isLoading ||
|
||||||
|
!authenticatedUser.authenticated ||
|
||||||
|
!isOnline ||
|
||||||
|
!canGenerateProjectFromPrompt
|
||||||
|
}
|
||||||
|
value={generationPrompt}
|
||||||
|
onChange={(e, text) => setGenerationPrompt(text)}
|
||||||
|
floatingLabelText={<Trans>AI prompt</Trans>}
|
||||||
|
floatingLabelFixed
|
||||||
|
translatableHintText={
|
||||||
|
!authenticatedUser.authenticated || !isOnline
|
||||||
|
? t`Log in to generate a project from a prompt`
|
||||||
|
: t`Type a prompt yourself or generate a random one`
|
||||||
|
}
|
||||||
|
endAdornment={
|
||||||
|
<IconButton
|
||||||
|
size="small"
|
||||||
|
onClick={() => setGenerationPrompt(generatePrompt())}
|
||||||
|
tooltip={t`Generate random prompt`}
|
||||||
|
disabled={
|
||||||
|
isLoading ||
|
||||||
|
!authenticatedUser.authenticated ||
|
||||||
|
!isOnline ||
|
||||||
|
!canGenerateProjectFromPrompt
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<Refresh />
|
||||||
|
</IconButton>
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</LineStackLayout>
|
||||||
|
</ColumnStackLayout>
|
||||||
|
)}
|
||||||
<SelectField
|
<SelectField
|
||||||
fullWidth
|
fullWidth
|
||||||
disabled={isLoading}
|
disabled={isLoading}
|
||||||
@@ -533,73 +624,8 @@ const NewProjectSetupDialog = ({
|
|||||||
setSaveAsLocation,
|
setSaveAsLocation,
|
||||||
newProjectsDefaultFolder,
|
newProjectsDefaultFolder,
|
||||||
})}
|
})}
|
||||||
{isStartingProjectFromScratch && (
|
{isCreatingANewProject && currentTab === 'from-scratch' && (
|
||||||
<ColumnStackLayout noMargin expand>
|
<ColumnStackLayout noMargin expand>
|
||||||
<DismissableAlertMessage
|
|
||||||
kind="info"
|
|
||||||
identifier="new-generate-project-from-prompt"
|
|
||||||
>
|
|
||||||
<Trans>NEW! Generate a pre-made AI scene with assets.</Trans>
|
|
||||||
</DismissableAlertMessage>
|
|
||||||
<LineStackLayout
|
|
||||||
expand
|
|
||||||
noMargin
|
|
||||||
alignItems="center"
|
|
||||||
justifyContent="center"
|
|
||||||
>
|
|
||||||
<RobotIcon />
|
|
||||||
<TextField
|
|
||||||
type="text"
|
|
||||||
multiline
|
|
||||||
maxLength={200}
|
|
||||||
fullWidth
|
|
||||||
disabled={
|
|
||||||
isLoading ||
|
|
||||||
!authenticatedUser.authenticated ||
|
|
||||||
!isOnline ||
|
|
||||||
!canGenerateProjectFromPrompt
|
|
||||||
}
|
|
||||||
value={generationPrompt}
|
|
||||||
onChange={(e, text) => setGenerationPrompt(text)}
|
|
||||||
floatingLabelText={<Trans>AI prompt</Trans>}
|
|
||||||
floatingLabelFixed
|
|
||||||
translatableHintText={
|
|
||||||
!authenticatedUser.authenticated || !isOnline
|
|
||||||
? t`Log in to generate a project from a prompt`
|
|
||||||
: t`Type a prompt yourself or generate a random one`
|
|
||||||
}
|
|
||||||
endAdornment={
|
|
||||||
<IconButton
|
|
||||||
size="small"
|
|
||||||
onClick={() => setGenerationPrompt(generatePrompt())}
|
|
||||||
tooltip={t`Generate random prompt`}
|
|
||||||
disabled={
|
|
||||||
isLoading ||
|
|
||||||
!authenticatedUser.authenticated ||
|
|
||||||
!isOnline ||
|
|
||||||
!canGenerateProjectFromPrompt
|
|
||||||
}
|
|
||||||
>
|
|
||||||
<Refresh />
|
|
||||||
</IconButton>
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</LineStackLayout>
|
|
||||||
{authenticatedUser.authenticated &&
|
|
||||||
!canGenerateProjectFromPrompt && (
|
|
||||||
<GetSubscriptionCard subscriptionDialogOpeningReason="Generate project from prompt">
|
|
||||||
<Line>
|
|
||||||
<Column noMargin>
|
|
||||||
<Text noMargin>
|
|
||||||
<Trans>
|
|
||||||
You've used all your daily pre-made AI scenes!
|
|
||||||
Generate as many as you want with a subscription.
|
|
||||||
</Trans>
|
|
||||||
</Text>
|
|
||||||
</Column>
|
|
||||||
</Line>
|
|
||||||
</GetSubscriptionCard>
|
|
||||||
)}
|
|
||||||
<Text size="sub-title">
|
<Text size="sub-title">
|
||||||
<Trans>Advanced File options</Trans>
|
<Trans>Advanced File options</Trans>
|
||||||
</Text>
|
</Text>
|
||||||
|
@@ -23,9 +23,10 @@ export default {
|
|||||||
decorators: [paperDecorator, muiDecorator],
|
decorators: [paperDecorator, muiDecorator],
|
||||||
};
|
};
|
||||||
|
|
||||||
export const OpenAndNotAuthenticated = () => {
|
export const OpenOnAIAndNotAuthenticated = () => {
|
||||||
return (
|
return (
|
||||||
<NewProjectSetupDialog
|
<NewProjectSetupDialog
|
||||||
|
initialTab="ai"
|
||||||
authenticatedUser={fakeNotAuthenticatedUser}
|
authenticatedUser={fakeNotAuthenticatedUser}
|
||||||
storageProviders={[
|
storageProviders={[
|
||||||
UrlStorageProvider,
|
UrlStorageProvider,
|
||||||
@@ -47,9 +48,59 @@ export const OpenAndNotAuthenticated = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const OpenAndAuthenticated = () => {
|
export const OpenOnAIAndAuthenticated = () => {
|
||||||
return (
|
return (
|
||||||
<NewProjectSetupDialog
|
<NewProjectSetupDialog
|
||||||
|
initialTab="ai"
|
||||||
|
authenticatedUser={fakeSilverAuthenticatedUser}
|
||||||
|
storageProviders={[
|
||||||
|
UrlStorageProvider,
|
||||||
|
CloudStorageProvider,
|
||||||
|
GoogleDriveStorageProvider,
|
||||||
|
DownloadFileStorageProvider,
|
||||||
|
]}
|
||||||
|
onClose={() => action('click on close')()}
|
||||||
|
onCreateEmptyProject={() => action('create empty')()}
|
||||||
|
onCreateFromExample={() => action('create from example')()}
|
||||||
|
onCreateWithLogin={() => action('create with login')()}
|
||||||
|
onCreateFromAIGeneration={() => action('create from AI generation')()}
|
||||||
|
onCreateProjectFromPrivateGameTemplate={() =>
|
||||||
|
action('create project from private game template')()
|
||||||
|
}
|
||||||
|
selectedExampleShortHeader={null}
|
||||||
|
selectedPrivateGameTemplateListingData={null}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
export const OpenOnFromScratchAndNotAuthenticated = () => {
|
||||||
|
return (
|
||||||
|
<NewProjectSetupDialog
|
||||||
|
initialTab="from-scratch"
|
||||||
|
authenticatedUser={fakeNotAuthenticatedUser}
|
||||||
|
storageProviders={[
|
||||||
|
UrlStorageProvider,
|
||||||
|
CloudStorageProvider,
|
||||||
|
GoogleDriveStorageProvider,
|
||||||
|
DownloadFileStorageProvider,
|
||||||
|
]}
|
||||||
|
onClose={() => action('click on close')()}
|
||||||
|
onCreateEmptyProject={() => action('create empty')()}
|
||||||
|
onCreateFromExample={() => action('create from example')()}
|
||||||
|
onCreateWithLogin={() => action('create with login')()}
|
||||||
|
onCreateFromAIGeneration={() => action('create from AI generation')()}
|
||||||
|
onCreateProjectFromPrivateGameTemplate={() =>
|
||||||
|
action('create project from private game template')()
|
||||||
|
}
|
||||||
|
selectedExampleShortHeader={null}
|
||||||
|
selectedPrivateGameTemplateListingData={null}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OpenOnFromScratchAndAuthenticated = () => {
|
||||||
|
return (
|
||||||
|
<NewProjectSetupDialog
|
||||||
|
initialTab="from-scratch"
|
||||||
authenticatedUser={fakeSilverAuthenticatedUser}
|
authenticatedUser={fakeSilverAuthenticatedUser}
|
||||||
storageProviders={[
|
storageProviders={[
|
||||||
UrlStorageProvider,
|
UrlStorageProvider,
|
||||||
@@ -96,9 +147,37 @@ export const Opening = () => {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const LimitsReached = () => {
|
export const OpenOnFromScratchAndLimitsReached = () => {
|
||||||
return (
|
return (
|
||||||
<NewProjectSetupDialog
|
<NewProjectSetupDialog
|
||||||
|
initialTab="from-scratch"
|
||||||
|
authenticatedUser={
|
||||||
|
fakeAuthenticatedUserWithNoSubscriptionAndTooManyCloudProjects
|
||||||
|
}
|
||||||
|
storageProviders={[
|
||||||
|
CloudStorageProvider,
|
||||||
|
UrlStorageProvider,
|
||||||
|
GoogleDriveStorageProvider,
|
||||||
|
DownloadFileStorageProvider,
|
||||||
|
]}
|
||||||
|
onClose={() => action('click on close')()}
|
||||||
|
onCreateEmptyProject={() => action('create empty')()}
|
||||||
|
onCreateFromExample={() => action('create from example')()}
|
||||||
|
onCreateWithLogin={() => action('create with login')()}
|
||||||
|
onCreateFromAIGeneration={() => action('create from AI generation')()}
|
||||||
|
onCreateProjectFromPrivateGameTemplate={() =>
|
||||||
|
action('create project from private game template')()
|
||||||
|
}
|
||||||
|
selectedExampleShortHeader={null}
|
||||||
|
selectedPrivateGameTemplateListingData={null}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const OpenOnAIAndLimitsReached = () => {
|
||||||
|
return (
|
||||||
|
<NewProjectSetupDialog
|
||||||
|
initialTab="ai"
|
||||||
authenticatedUser={
|
authenticatedUser={
|
||||||
fakeAuthenticatedUserWithNoSubscriptionAndTooManyCloudProjects
|
fakeAuthenticatedUserWithNoSubscriptionAndTooManyCloudProjects
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user