mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Improve communication around cloud projects
Do not show in changelog
This commit is contained in:
@@ -5,6 +5,7 @@ import {
|
||||
type ResourceSource,
|
||||
type ChooseResourceFunction,
|
||||
} from '../../ResourcesList/ResourceSource';
|
||||
import type { StorageProvider } from '../../ProjectsStorage';
|
||||
import { type PreviewDebuggerServer } from '../../Export/PreviewLauncher.flow';
|
||||
import { type HotReloadPreviewButtonProps } from '../../HotReload/HotReloadPreviewButton';
|
||||
import { type ResourceExternalEditor } from '../../ResourcesList/ResourceExternalEditor.flow';
|
||||
@@ -16,8 +17,12 @@ import {
|
||||
import { type FileMetadataAndStorageProviderName } from '../../ProjectsStorage';
|
||||
|
||||
export type EditorContainerExtraProps = {|
|
||||
// Events function extension editor
|
||||
initiallyFocusedFunctionName?: ?string,
|
||||
initiallyFocusedBehaviorName?: ?string,
|
||||
|
||||
// Homepage
|
||||
storageProviders?: Array<StorageProvider>,
|
||||
|};
|
||||
|
||||
export type RenderEditorContainerProps = {|
|
||||
|
@@ -3,19 +3,25 @@ import * as React from 'react';
|
||||
import { Trans, t } from '@lingui/macro';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { type I18n as I18nType } from '@lingui/core';
|
||||
import { makeStyles } from '@material-ui/core/styles';
|
||||
import List from '@material-ui/core/List';
|
||||
import ListItem from '@material-ui/core/ListItem';
|
||||
import ListItemText from '@material-ui/core/ListItemText';
|
||||
import ListItemAvatar from '@material-ui/core/ListItemAvatar';
|
||||
|
||||
import AddIcon from '@material-ui/icons/Add';
|
||||
import Text from '../../../UI/Text';
|
||||
import TextButton from '../../../UI/TextButton';
|
||||
import RaisedButton from '../../../UI/RaisedButton';
|
||||
import AlertMessage from '../../../UI/AlertMessage';
|
||||
import { Line, Column, Spacer } from '../../../UI/Grid';
|
||||
import { useResponsiveWindowWidth } from '../../../UI/Reponsive/ResponsiveWindowMeasurer';
|
||||
import { LineStackLayout, ResponsiveLineStackLayout } from '../../../UI/Layout';
|
||||
|
||||
import { type FileMetadataAndStorageProviderName } from '../../../ProjectsStorage';
|
||||
import {
|
||||
type FileMetadataAndStorageProviderName,
|
||||
type StorageProvider,
|
||||
} from '../../../ProjectsStorage';
|
||||
import PreferencesContext from '../../Preferences/PreferencesContext';
|
||||
import AuthenticatedUserContext from '../../../Profile/AuthenticatedUserContext';
|
||||
import SectionContainer, { SectionRow } from './SectionContainer';
|
||||
@@ -25,7 +31,10 @@ import ContextMenu, {
|
||||
import CircularProgress from '../../../UI/CircularProgress';
|
||||
import { type MenuItemTemplate } from '../../../UI/Menu/Menu.flow';
|
||||
import useConfirmDialog from '../../../UI/Confirm/useConfirmDialog';
|
||||
import { deleteCloudProject } from '../../../Utils/GDevelopServices/Project';
|
||||
import {
|
||||
CLOUD_PROJECT_MAX_COUNT,
|
||||
deleteCloudProject,
|
||||
} from '../../../Utils/GDevelopServices/Project';
|
||||
import optionalRequire from '../../../Utils/OptionalRequire';
|
||||
import { showErrorBox } from '../../../UI/Messages/MessageBox';
|
||||
import { getRelativeOrAbsoluteDisplayDate } from '../../../Utils/DateDisplay';
|
||||
@@ -51,6 +60,7 @@ type Props = {|
|
||||
onOpen: () => void,
|
||||
onOpenRecentFile: (file: FileMetadataAndStorageProviderName) => void,
|
||||
onCreateProject: () => void,
|
||||
storageProviders: Array<StorageProvider>,
|
||||
|};
|
||||
|
||||
export type BuildSectionInterface = {|
|
||||
@@ -71,8 +81,33 @@ const PrettyBreakablePath = ({ path }: {| path: string |}) => {
|
||||
}, []);
|
||||
};
|
||||
|
||||
const getStorageProviderByInternalName = (
|
||||
storageProviders: Array<StorageProvider>,
|
||||
internalName: string
|
||||
): ?StorageProvider => {
|
||||
return storageProviders.find(
|
||||
storageProvider => storageProvider.internalName === internalName
|
||||
);
|
||||
};
|
||||
|
||||
const useStylesForListItemIcon = makeStyles({
|
||||
root: {
|
||||
minWidth: 0,
|
||||
},
|
||||
});
|
||||
|
||||
const BuildSection = React.forwardRef<Props, BuildSectionInterface>(
|
||||
({ project, canOpen, onOpen, onCreateProject, onOpenRecentFile }, ref) => {
|
||||
(
|
||||
{
|
||||
project,
|
||||
canOpen,
|
||||
onOpen,
|
||||
onCreateProject,
|
||||
onOpenRecentFile,
|
||||
storageProviders,
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const { getRecentProjectFiles, removeRecentProjectFile } = React.useContext(
|
||||
PreferencesContext
|
||||
);
|
||||
@@ -83,6 +118,8 @@ const BuildSection = React.forwardRef<Props, BuildSectionInterface>(
|
||||
const windowWidth = useResponsiveWindowWidth();
|
||||
const forceUpdate = useForceUpdate();
|
||||
|
||||
const iconClasses = useStylesForListItemIcon();
|
||||
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
forceUpdate,
|
||||
}));
|
||||
@@ -91,6 +128,8 @@ const BuildSection = React.forwardRef<Props, BuildSectionInterface>(
|
||||
file => file.fileMetadata
|
||||
);
|
||||
|
||||
let hasTooManyCloudProjects = false;
|
||||
|
||||
// Show cloud projects on the web app only.
|
||||
if (isWebApp) {
|
||||
const { cloudProjects } = authenticatedUser;
|
||||
@@ -112,6 +151,9 @@ const BuildSection = React.forwardRef<Props, BuildSectionInterface>(
|
||||
})
|
||||
.filter(Boolean)
|
||||
);
|
||||
hasTooManyCloudProjects =
|
||||
cloudProjects.filter(cloudProject => !cloudProject.deletedAt)
|
||||
.length >= CLOUD_PROJECT_MAX_COUNT;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -213,7 +255,33 @@ const BuildSection = React.forwardRef<Props, BuildSectionInterface>(
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
<>
|
||||
<SectionContainer title={<Trans>My projects</Trans>}>
|
||||
<SectionContainer
|
||||
title={<Trans>My projects</Trans>}
|
||||
renderFooter={() =>
|
||||
isWebApp &&
|
||||
hasTooManyCloudProjects && (
|
||||
<Line>
|
||||
<Column expand>
|
||||
<AlertMessage kind="warning">
|
||||
<Text size="block-title">
|
||||
<Trans>
|
||||
You've reached your maximum storage of{' '}
|
||||
{CLOUD_PROJECT_MAX_COUNT}
|
||||
cloud-based projects
|
||||
</Trans>
|
||||
</Text>
|
||||
<Text>
|
||||
<Trans>
|
||||
To keep using GDevelop cloud, consider deleting one
|
||||
of your projects.
|
||||
</Trans>
|
||||
</Text>
|
||||
</AlertMessage>
|
||||
</Column>
|
||||
</Line>
|
||||
)
|
||||
}
|
||||
>
|
||||
<SectionRow>
|
||||
<Line noMargin>
|
||||
<ResponsiveLineStackLayout
|
||||
@@ -272,6 +340,11 @@ const BuildSection = React.forwardRef<Props, BuildSectionInterface>(
|
||||
<Trans>File name</Trans>
|
||||
</Text>
|
||||
</Column>
|
||||
<Column expand>
|
||||
<Text color="secondary">
|
||||
<Trans>Location</Trans>
|
||||
</Text>
|
||||
</Column>
|
||||
<Column expand>
|
||||
<Text color="secondary">
|
||||
<Trans>Last edited</Trans>
|
||||
@@ -280,93 +353,136 @@ const BuildSection = React.forwardRef<Props, BuildSectionInterface>(
|
||||
</LineStackLayout>
|
||||
)}
|
||||
<List>
|
||||
{projectFiles.map(file => (
|
||||
<ListItem
|
||||
button
|
||||
key={file.fileMetadata.fileIdentifier}
|
||||
onClick={() => {
|
||||
onOpenRecentFile(file);
|
||||
}}
|
||||
style={styles.listItem}
|
||||
onContextMenu={event =>
|
||||
openContextMenu(event, file)
|
||||
}
|
||||
>
|
||||
{isWindowWidthMediumOrLarger ? (
|
||||
<LineStackLayout
|
||||
justifyContent="flex-start"
|
||||
expand
|
||||
>
|
||||
<Column expand>
|
||||
<Line noMargin alignItems="center">
|
||||
<Text noMargin>
|
||||
{file.fileMetadata.name || (
|
||||
<PrettyBreakablePath
|
||||
path={
|
||||
file.fileMetadata.fileIdentifier
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Text>
|
||||
|
||||
{pendingProject ===
|
||||
file.fileMetadata.fileIdentifier && (
|
||||
<>
|
||||
<Spacer />
|
||||
<CircularProgress size={16} />
|
||||
</>
|
||||
)}
|
||||
</Line>
|
||||
</Column>
|
||||
<Column expand>
|
||||
{file.fileMetadata.lastModifiedDate && (
|
||||
<Text noMargin>
|
||||
{getRelativeOrAbsoluteDisplayDate(
|
||||
i18n,
|
||||
file.fileMetadata.lastModifiedDate
|
||||
)}
|
||||
</Text>
|
||||
{projectFiles.map(file => {
|
||||
const storageProvider = getStorageProviderByInternalName(
|
||||
storageProviders,
|
||||
file.storageProviderName
|
||||
);
|
||||
return (
|
||||
<ListItem
|
||||
button
|
||||
key={file.fileMetadata.fileIdentifier}
|
||||
onClick={() => {
|
||||
onOpenRecentFile(file);
|
||||
}}
|
||||
style={styles.listItem}
|
||||
onContextMenu={event =>
|
||||
openContextMenu(event, file)
|
||||
}
|
||||
>
|
||||
<>
|
||||
{storageProvider &&
|
||||
storageProvider.renderIcon &&
|
||||
!isWindowWidthMediumOrLarger && (
|
||||
<ListItemAvatar
|
||||
classes={iconClasses}
|
||||
style={{
|
||||
marginTop: 8,
|
||||
alignSelf: 'flex-start',
|
||||
}}
|
||||
>
|
||||
{storageProvider.renderIcon({
|
||||
size: 'small',
|
||||
})}
|
||||
</ListItemAvatar>
|
||||
)}
|
||||
</Column>
|
||||
</LineStackLayout>
|
||||
) : (
|
||||
<Column expand>
|
||||
<Line
|
||||
noMargin
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<ListItemText
|
||||
primary={
|
||||
file.fileMetadata.name || (
|
||||
<PrettyBreakablePath
|
||||
path={
|
||||
file.fileMetadata.fileIdentifier
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
secondary={
|
||||
file.fileMetadata.lastModifiedDate
|
||||
? getRelativeOrAbsoluteDisplayDate(
|
||||
{isWindowWidthMediumOrLarger ? (
|
||||
<LineStackLayout
|
||||
justifyContent="flex-start"
|
||||
expand
|
||||
>
|
||||
<Column expand>
|
||||
<Line noMargin alignItems="center">
|
||||
{storageProvider &&
|
||||
storageProvider.renderIcon && (
|
||||
<>
|
||||
{storageProvider.renderIcon({
|
||||
size: 'small',
|
||||
})}
|
||||
<Spacer />
|
||||
</>
|
||||
)}
|
||||
<Text noMargin>
|
||||
{file.fileMetadata.name || (
|
||||
<PrettyBreakablePath
|
||||
path={
|
||||
file.fileMetadata
|
||||
.fileIdentifier
|
||||
}
|
||||
/>
|
||||
)}
|
||||
</Text>
|
||||
|
||||
{pendingProject ===
|
||||
file.fileMetadata
|
||||
.fileIdentifier && (
|
||||
<>
|
||||
<Spacer />
|
||||
<CircularProgress size={16} />
|
||||
</>
|
||||
)}
|
||||
</Line>
|
||||
</Column>
|
||||
<Column expand>
|
||||
<Text noMargin>
|
||||
{storageProvider
|
||||
? i18n._(storageProvider.name)
|
||||
: ''}
|
||||
</Text>
|
||||
</Column>
|
||||
<Column expand>
|
||||
{file.fileMetadata.lastModifiedDate && (
|
||||
<Text noMargin>
|
||||
{getRelativeOrAbsoluteDisplayDate(
|
||||
i18n,
|
||||
file.fileMetadata.lastModifiedDate
|
||||
)}
|
||||
</Text>
|
||||
)}
|
||||
</Column>
|
||||
</LineStackLayout>
|
||||
) : (
|
||||
<Column expand>
|
||||
<Line
|
||||
noMargin
|
||||
alignItems="center"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
<ListItemText
|
||||
primary={
|
||||
file.fileMetadata.name || (
|
||||
<PrettyBreakablePath
|
||||
path={
|
||||
file.fileMetadata
|
||||
.fileIdentifier
|
||||
}
|
||||
/>
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
onContextMenu={event =>
|
||||
openContextMenu(event, file)
|
||||
}
|
||||
/>
|
||||
{pendingProject ===
|
||||
file.fileMetadata.fileIdentifier && (
|
||||
<CircularProgress size={24} />
|
||||
)}
|
||||
</Line>
|
||||
</Column>
|
||||
)}
|
||||
</ListItem>
|
||||
))}
|
||||
}
|
||||
secondary={
|
||||
file.fileMetadata.lastModifiedDate
|
||||
? getRelativeOrAbsoluteDisplayDate(
|
||||
i18n,
|
||||
file.fileMetadata
|
||||
.lastModifiedDate
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
onContextMenu={event =>
|
||||
openContextMenu(event, file)
|
||||
}
|
||||
/>
|
||||
{pendingProject ===
|
||||
file.fileMetadata.fileIdentifier && (
|
||||
<CircularProgress size={24} />
|
||||
)}
|
||||
</Line>
|
||||
</Column>
|
||||
)}
|
||||
</>
|
||||
</ListItem>
|
||||
);
|
||||
})}
|
||||
</List>
|
||||
</Column>
|
||||
</Line>
|
||||
|
@@ -20,6 +20,12 @@ const styles = {
|
||||
paddingLeft: SECTION_PADDING,
|
||||
paddingRight: SECTION_PADDING,
|
||||
},
|
||||
mobileFooter: {
|
||||
padding: 5,
|
||||
},
|
||||
desktopFooter: {
|
||||
paddingLeft: SECTION_PADDING,
|
||||
},
|
||||
rowContainer: {
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
@@ -37,6 +43,7 @@ type Props = {|
|
||||
subtitle?: React.Node,
|
||||
backAction?: () => void,
|
||||
flexBody?: boolean,
|
||||
renderFooter?: () => React.Node,
|
||||
|};
|
||||
|
||||
const SectionContainer = ({
|
||||
@@ -45,12 +52,14 @@ const SectionContainer = ({
|
||||
subtitle,
|
||||
backAction,
|
||||
flexBody,
|
||||
renderFooter,
|
||||
}: Props) => {
|
||||
const windowWidth = useResponsiveWindowWidth();
|
||||
const GDevelopTheme = React.useContext(GDevelopThemeContext);
|
||||
return (
|
||||
<Column useFullHeight noMargin expand>
|
||||
<Paper
|
||||
elevation={0}
|
||||
style={{
|
||||
...styles.scrollContainer,
|
||||
display: flexBody ? 'flex' : 'block',
|
||||
@@ -86,6 +95,20 @@ const SectionContainer = ({
|
||||
{children}
|
||||
</Column>
|
||||
</Paper>
|
||||
{renderFooter && (
|
||||
<Paper
|
||||
elevation={0}
|
||||
style={{
|
||||
borderLeft: `1px solid ${GDevelopTheme.home.separator.color}`,
|
||||
...(windowWidth === 'small'
|
||||
? styles.mobileFooter
|
||||
: styles.desktopFooter),
|
||||
}}
|
||||
square
|
||||
>
|
||||
{renderFooter()}
|
||||
</Paper>
|
||||
)}
|
||||
</Column>
|
||||
);
|
||||
};
|
||||
|
@@ -8,7 +8,10 @@ import {
|
||||
type OnCreateBlankFunction,
|
||||
type OnOpenProjectAfterCreationFunction,
|
||||
} from '../../../ProjectCreation/CreateProjectDialog';
|
||||
import { type FileMetadataAndStorageProviderName } from '../../../ProjectsStorage';
|
||||
import {
|
||||
type FileMetadataAndStorageProviderName,
|
||||
type StorageProvider,
|
||||
} from '../../../ProjectsStorage';
|
||||
import GetStartedSection from './GetStartedSection';
|
||||
import BuildSection, { type BuildSectionInterface } from './BuildSection';
|
||||
import LearnSection from './LearnSection';
|
||||
@@ -29,6 +32,7 @@ type Props = {|
|
||||
projectItemName: ?string,
|
||||
project: ?gdProject,
|
||||
setToolbar: (?React.Node) => void,
|
||||
storageProviders: Array<StorageProvider>,
|
||||
|
||||
// Project opening
|
||||
canOpen: boolean,
|
||||
@@ -74,6 +78,7 @@ export const HomePage = React.memo<Props>(
|
||||
setToolbar,
|
||||
onOpenOnboardingDialog,
|
||||
isActive,
|
||||
storageProviders,
|
||||
}: Props,
|
||||
ref
|
||||
) => {
|
||||
@@ -179,6 +184,7 @@ export const HomePage = React.memo<Props>(
|
||||
onOpen={onOpen}
|
||||
onCreateProject={onCreateProject}
|
||||
onOpenRecentFile={onOpenRecentFile}
|
||||
storageProviders={storageProviders}
|
||||
/>
|
||||
)}
|
||||
{activeTab === 'learn' && (
|
||||
@@ -225,5 +231,8 @@ export const renderHomePageContainer = (
|
||||
onOpenLanguageDialog={props.onOpenLanguageDialog}
|
||||
onOpenProfile={props.onOpenProfile}
|
||||
onOpenOnboardingDialog={props.onOpenOnboardingDialog}
|
||||
storageProviders={
|
||||
(props.extraEditorProps && props.extraEditorProps.storageProviders) || []
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
@@ -1468,11 +1468,14 @@ const MainFrame = (props: Props) => {
|
||||
projectItemName: null,
|
||||
renderEditorContainer: renderHomePageContainer,
|
||||
key: 'start page',
|
||||
extraEditorProps: {
|
||||
storageProviders: props.storageProviders,
|
||||
},
|
||||
closable: false,
|
||||
}),
|
||||
}));
|
||||
},
|
||||
[setState, i18n]
|
||||
[setState, i18n, props.storageProviders]
|
||||
);
|
||||
|
||||
const _openDebugger = React.useCallback(
|
||||
|
@@ -18,8 +18,8 @@ import Cloud from '../../UI/CustomSvgIcons/Cloud';
|
||||
|
||||
export default ({
|
||||
internalName: 'Cloud',
|
||||
name: t`GDevelop cloud storage`,
|
||||
renderIcon: () => <Cloud />,
|
||||
name: t`GDevelop Cloud`,
|
||||
renderIcon: props => <Cloud fontSize={props.size} />,
|
||||
hiddenInOpenDialog: true,
|
||||
needUserAuthentication: true,
|
||||
getFileMetadataFromAppArguments: (appArguments: AppArguments) => {
|
||||
|
@@ -12,7 +12,7 @@ import SaveAlt from '@material-ui/icons/SaveAlt';
|
||||
export default ({
|
||||
internalName: 'DownloadFile',
|
||||
name: t`Download a copy`,
|
||||
renderIcon: () => <SaveAlt />,
|
||||
renderIcon: props => <SaveAlt fontSize={props.size} />,
|
||||
hiddenInOpenDialog: true,
|
||||
createOperations: ({ setDialog, closeDialog }) => ({
|
||||
onSaveProjectAs: (project: gdProject, fileMetadata: ?FileMetadata) => {
|
||||
|
@@ -56,7 +56,7 @@ export default ({
|
||||
internalName: 'Dropbox',
|
||||
name: t`Dropbox (coming soon)`,
|
||||
disabled: true,
|
||||
renderIcon: () => <Dropbox />,
|
||||
renderIcon: props => <Dropbox fontSize={props.size} />,
|
||||
createOperations: ({ setDialog, closeDialog }) => {
|
||||
initializeApis().catch(() => {});
|
||||
|
||||
|
@@ -11,7 +11,7 @@ const FakeCloudStorageProvider = ({
|
||||
internalName: 'FakeCloud',
|
||||
name: t`GDevelop cloud storage (coming soon)`,
|
||||
disabled: true,
|
||||
renderIcon: () => <Cloud />,
|
||||
renderIcon: props => <Cloud fontSize={props.size} />,
|
||||
createOperations: () => {
|
||||
return {
|
||||
doesInitialOpenRequireUserInteraction: true,
|
||||
|
@@ -276,7 +276,7 @@ const showFilePicker = ({
|
||||
export default ({
|
||||
internalName: 'GoogleDrive',
|
||||
name: t`Google Drive`,
|
||||
renderIcon: () => <GoogleDrive />,
|
||||
renderIcon: props => <GoogleDrive fontSize={props.size} />,
|
||||
getFileMetadataFromAppArguments: (appArguments: AppArguments) => {
|
||||
if (appArguments.state) {
|
||||
try {
|
||||
|
@@ -28,7 +28,7 @@ import Computer from '../../UI/CustomSvgIcons/Computer';
|
||||
export default ({
|
||||
internalName: 'LocalFile',
|
||||
name: t`Your computer`,
|
||||
renderIcon: () => <Computer />,
|
||||
renderIcon: props => <Computer fontSize={props.size} />,
|
||||
getFileMetadataFromAppArguments: (appArguments: AppArguments) => {
|
||||
if (!appArguments[POSITIONAL_ARGUMENTS_KEY]) return null;
|
||||
if (!appArguments[POSITIONAL_ARGUMENTS_KEY].length) return null;
|
||||
|
@@ -56,7 +56,7 @@ export default ({
|
||||
internalName: 'OneDrive',
|
||||
name: t`OneDrive (coming soon)`,
|
||||
disabled: true,
|
||||
renderIcon: () => <OneDrive />,
|
||||
renderIcon: props => <OneDrive fontSize={props.size} />,
|
||||
createOperations: ({ setDialog, closeDialog }) => {
|
||||
initializeApis().catch(() => {});
|
||||
|
||||
|
@@ -50,7 +50,7 @@ const OpenFromStorageProviderDialog = ({
|
||||
primaryText={i18n._(storageProvider.name)}
|
||||
leftIcon={
|
||||
storageProvider.renderIcon
|
||||
? storageProvider.renderIcon()
|
||||
? storageProvider.renderIcon({})
|
||||
: undefined
|
||||
}
|
||||
onClick={() => onChooseProvider(storageProvider)}
|
||||
|
@@ -60,12 +60,15 @@ const StorageProviderListItem = ({
|
||||
>
|
||||
<ListItemIcon>
|
||||
{storageProvider.renderIcon
|
||||
? storageProvider.renderIcon()
|
||||
? storageProvider.renderIcon({})
|
||||
: undefined}
|
||||
</ListItemIcon>
|
||||
<ListItemText>
|
||||
<Line justifyContent="space-between" alignItems="center">
|
||||
<Text noMargin>{i18n._(storageProvider.name)}</Text>
|
||||
<Text noMargin>
|
||||
{i18n._(storageProvider.name)}{' '}
|
||||
{storageProvider.internalName === 'Cloud' && i18n._(t`(Beta)`)}
|
||||
</Text>
|
||||
{shouldDisplayAuthenticationButtons && (
|
||||
<Line noMargin>
|
||||
<FlatButton
|
||||
|
@@ -85,7 +85,7 @@ export type StorageProvider = {|
|
||||
hiddenInOpenDialog?: boolean,
|
||||
hiddenInSaveDialog?: boolean,
|
||||
disabled?: boolean,
|
||||
renderIcon?: () => React.Node,
|
||||
renderIcon?: ({| size?: 'small' | 'medium' |}) => React.Node,
|
||||
getFileMetadataFromAppArguments?: AppArguments => ?FileMetadata,
|
||||
createOperations: ({
|
||||
/** Open a dialog (a render function) */
|
||||
|
@@ -7,6 +7,7 @@ import {
|
||||
import { type AuthenticatedUser } from '../../Profile/AuthenticatedUserContext';
|
||||
|
||||
export const CLOUD_PROJECT_NAME_MAX_LENGTH = 50;
|
||||
export const CLOUD_PROJECT_MAX_COUNT = 10;
|
||||
|
||||
const projectResourcesClient = axios.create({
|
||||
baseURL: GDevelopProjectResourcesStorage.baseUrl,
|
||||
|
@@ -18,6 +18,7 @@ import AuthenticatedUserContext, {
|
||||
initialAuthenticatedUser,
|
||||
type AuthenticatedUser,
|
||||
} from '../../Profile/AuthenticatedUserContext';
|
||||
import CloudStorageProvider from '../../ProjectsStorage/CloudStorageProvider';
|
||||
import {
|
||||
fakeIndieAuthenticatedUser,
|
||||
indieUserProfile,
|
||||
@@ -83,6 +84,7 @@ const WrappedHomePage = ({
|
||||
projectItemName={null}
|
||||
setToolbar={() => {}}
|
||||
canOpen={true}
|
||||
storageProviders={[CloudStorageProvider]}
|
||||
onOpen={() => action('onOpen')()}
|
||||
onOpenRecentFile={() => action('onOpenRecentFile')()}
|
||||
onCreateProject={() => action('onCreateProject')()}
|
||||
|
Reference in New Issue
Block a user