mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Use premium colors in most places where a subscription can be purchased (#7284)
This commit is contained in:
@@ -3,66 +3,87 @@ import * as React from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
|
||||
import Text from '../../UI/Text';
|
||||
import RaisedButton from '../../UI/RaisedButton';
|
||||
import AlertMessage from '../../UI/AlertMessage';
|
||||
import { Line, Column } from '../../UI/Grid';
|
||||
import { type Limits } from '../../Utils/GDevelopServices/Usage';
|
||||
import GetSubscriptionCard from '../../Profile/Subscription/GetSubscriptionCard';
|
||||
import AuthenticatedUserContext, {
|
||||
type AuthenticatedUser,
|
||||
} from '../../Profile/AuthenticatedUserContext';
|
||||
import { type Leaderboard } from '../../Utils/GDevelopServices/Play';
|
||||
import { hasValidSubscriptionPlan } from '../../Utils/GDevelopServices/Usage';
|
||||
|
||||
type Props = {|
|
||||
onUpgrade: () => void,
|
||||
onClose: () => void,
|
||||
limits: Limits,
|
||||
|};
|
||||
export const checkIfHasTooManyLeaderboards = (
|
||||
authenticatedUser: AuthenticatedUser,
|
||||
leaderboards: ?Array<Leaderboard>
|
||||
) => {
|
||||
if (!authenticatedUser.authenticated) return false;
|
||||
|
||||
const { limits } = authenticatedUser;
|
||||
|
||||
if (!limits) return false;
|
||||
|
||||
const leaderboardLimits = limits.capabilities.leaderboards;
|
||||
|
||||
return (
|
||||
leaderboards &&
|
||||
leaderboardLimits &&
|
||||
leaderboardLimits.maximumCountPerGame > 0 &&
|
||||
leaderboards.filter(leaderboard => !leaderboard.deletedAt).length >=
|
||||
leaderboardLimits.maximumCountPerGame
|
||||
);
|
||||
};
|
||||
|
||||
const MaxLeaderboardCountAlertMessage = () => {
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const { limits, subscription } = authenticatedUser;
|
||||
if (!limits) return null;
|
||||
|
||||
const hasValidSubscription = hasValidSubscriptionPlan(subscription);
|
||||
|
||||
const MaxLeaderboardCountAlertMessage = ({
|
||||
onUpgrade,
|
||||
onClose,
|
||||
limits,
|
||||
}: Props) => {
|
||||
const leaderboardLimits = limits.capabilities.leaderboards;
|
||||
if (!leaderboardLimits) return null;
|
||||
|
||||
return (
|
||||
<Line>
|
||||
<Column expand>
|
||||
<AlertMessage
|
||||
kind="warning"
|
||||
onHide={onClose}
|
||||
renderRightButton={
|
||||
leaderboardLimits.canMaximumCountPerGameBeIncreased
|
||||
? () => (
|
||||
<RaisedButton
|
||||
primary
|
||||
label={<Trans>Check our premiums plans</Trans>}
|
||||
onClick={onUpgrade}
|
||||
/>
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<Text size="block-title">
|
||||
<Trans>
|
||||
You've reached your maximum of{' '}
|
||||
{leaderboardLimits.maximumCountPerGame} leaderboards for your game
|
||||
</Trans>
|
||||
</Text>
|
||||
<Text>
|
||||
{leaderboardLimits.canMaximumCountPerGameBeIncreased ? (
|
||||
<Trans>
|
||||
Upgrade to GDevelop Premium to get more leaderboards, storage,
|
||||
and one-click packagings!
|
||||
</Trans>
|
||||
<GetSubscriptionCard
|
||||
subscriptionDialogOpeningReason="Leaderboard count per game limit reached"
|
||||
label={
|
||||
!hasValidSubscription ? (
|
||||
<Trans>Upgrade to GDevelop Premium</Trans>
|
||||
) : (
|
||||
// This should not happen at the moment since leaderboards are unlimited
|
||||
// in any paid plans but it could happen in the future with a plan that
|
||||
// cannot be increased and that has a max number of leaderboards.
|
||||
<Trans>
|
||||
To keep using GDevelop leaderboards, consider deleting old,
|
||||
unused leaderboards.
|
||||
</Trans>
|
||||
)}
|
||||
</Text>
|
||||
</AlertMessage>
|
||||
<Trans>Upgrade your Premium Plan</Trans>
|
||||
)
|
||||
}
|
||||
hideButton={!leaderboardLimits.canMaximumCountPerGameBeIncreased}
|
||||
>
|
||||
<Line>
|
||||
<Column noMargin expand>
|
||||
<Text size="block-title">
|
||||
<Trans>
|
||||
You've reached your maximum of{' '}
|
||||
{leaderboardLimits.maximumCountPerGame} leaderboards for your
|
||||
game
|
||||
</Trans>
|
||||
</Text>
|
||||
<Text>
|
||||
{leaderboardLimits.canMaximumCountPerGameBeIncreased ? (
|
||||
<Trans>
|
||||
Upgrade to GDevelop Premium to get more leaderboards,
|
||||
storage, and one-click packagings!
|
||||
</Trans>
|
||||
) : (
|
||||
// This should not happen at the moment since leaderboards are unlimited
|
||||
// in any paid plans but it could happen in the future with a plan that
|
||||
// cannot be increased and that has a max number of leaderboards.
|
||||
<Trans>
|
||||
To keep using GDevelop leaderboards, consider deleting old,
|
||||
unused leaderboards.
|
||||
</Trans>
|
||||
)}
|
||||
</Text>
|
||||
</Column>
|
||||
</Line>
|
||||
</GetSubscriptionCard>
|
||||
</Column>
|
||||
</Line>
|
||||
);
|
||||
|
@@ -66,8 +66,9 @@ import LeaderboardOptionsDialog, {
|
||||
import { formatScore } from '../../Leaderboard/LeaderboardScoreFormatter';
|
||||
import Toggle from '../../UI/Toggle';
|
||||
import AuthenticatedUserContext from '../../Profile/AuthenticatedUserContext';
|
||||
import { SubscriptionSuggestionContext } from '../../Profile/Subscription/SubscriptionSuggestionContext';
|
||||
import MaxLeaderboardCountAlertMessage from './MaxLeaderboardCountAlertMessage';
|
||||
import MaxLeaderboardCountAlertMessage, {
|
||||
checkIfHasTooManyLeaderboards,
|
||||
} from './MaxLeaderboardCountAlertMessage';
|
||||
import useAlertDialog from '../../UI/Alert/useAlertDialog';
|
||||
import Paper from '../../UI/Paper';
|
||||
import SwitchHorizontal from '../../UI/CustomSvgIcons/SwitchHorizontal';
|
||||
@@ -234,9 +235,6 @@ export const LeaderboardAdmin = ({
|
||||
fetchLeaderboardEntries,
|
||||
browsing: { entries, goToNextPage, goToPreviousPage, goToFirstPage },
|
||||
} = React.useContext(LeaderboardContext);
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
|
||||
const setIsLoading = React.useCallback(
|
||||
(yesOrNo: boolean) => {
|
||||
@@ -332,13 +330,7 @@ export const LeaderboardAdmin = ({
|
||||
setApiError(null);
|
||||
try {
|
||||
if (limits && leaderboards) {
|
||||
const leaderboardLimits = limits.capabilities.leaderboards;
|
||||
if (
|
||||
leaderboardLimits &&
|
||||
leaderboardLimits.maximumCountPerGame > 0 &&
|
||||
leaderboards.filter(leaderboard => !leaderboard.deletedAt).length >=
|
||||
leaderboardLimits.maximumCountPerGame
|
||||
) {
|
||||
if (checkIfHasTooManyLeaderboards(authenticatedUser, leaderboards)) {
|
||||
setDisplayMaxLeaderboardCountReachedWarning(true);
|
||||
return;
|
||||
}
|
||||
@@ -907,20 +899,8 @@ export const LeaderboardAdmin = ({
|
||||
{({ i18n }) => (
|
||||
<>
|
||||
<Column noMargin expand>
|
||||
{displayMaxLeaderboardCountReachedWarning && limits && (
|
||||
<MaxLeaderboardCountAlertMessage
|
||||
onUpgrade={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: 'Leaderboard count per game limit reached',
|
||||
},
|
||||
})
|
||||
}
|
||||
onClose={() =>
|
||||
setDisplayMaxLeaderboardCountReachedWarning(false)
|
||||
}
|
||||
limits={limits}
|
||||
/>
|
||||
{displayMaxLeaderboardCountReachedWarning && (
|
||||
<MaxLeaderboardCountAlertMessage />
|
||||
)}
|
||||
<ResponsiveLineStackLayout
|
||||
noMargin
|
||||
|
@@ -3,16 +3,14 @@ import * as React from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
|
||||
import Text from '../../../../UI/Text';
|
||||
import RaisedButton from '../../../../UI/RaisedButton';
|
||||
import AlertMessage from '../../../../UI/AlertMessage';
|
||||
import { Line, Column } from '../../../../UI/Grid';
|
||||
import { type Limits } from '../../../../Utils/GDevelopServices/Usage';
|
||||
import { type AuthenticatedUser } from '../../../../Profile/AuthenticatedUserContext';
|
||||
import Gold from '../../../../Profile/Subscription/Icons/Gold';
|
||||
import AuthenticatedUserContext, {
|
||||
type AuthenticatedUser,
|
||||
} from '../../../../Profile/AuthenticatedUserContext';
|
||||
import GetSubscriptionCard from '../../../../Profile/Subscription/GetSubscriptionCard';
|
||||
import { hasValidSubscriptionPlan } from '../../../../Utils/GDevelopServices/Usage';
|
||||
|
||||
type Props = {|
|
||||
onUpgrade: () => void,
|
||||
limits: Limits,
|
||||
margin?: 'dense',
|
||||
|};
|
||||
|
||||
@@ -31,49 +29,34 @@ export const checkIfHasTooManyCloudProjects = (
|
||||
: false;
|
||||
};
|
||||
|
||||
export const MaxProjectCountAlertMessage = ({
|
||||
onUpgrade,
|
||||
limits,
|
||||
margin,
|
||||
}: Props) => {
|
||||
export const MaxProjectCountAlertMessage = ({ margin }: Props) => {
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const { limits, subscription } = authenticatedUser;
|
||||
if (!limits) return null;
|
||||
|
||||
const hasValidSubscription = hasValidSubscriptionPlan(subscription);
|
||||
|
||||
const {
|
||||
maximumCount,
|
||||
canMaximumCountBeIncreased,
|
||||
} = limits.capabilities.cloudProjects;
|
||||
|
||||
return (
|
||||
<Line noMargin>
|
||||
<Column noMargin expand>
|
||||
<AlertMessage
|
||||
kind="warning"
|
||||
renderLeftIcon={() => (
|
||||
<Gold
|
||||
style={{
|
||||
width: 48,
|
||||
height: 48,
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
renderRightButton={
|
||||
canMaximumCountBeIncreased
|
||||
? () => (
|
||||
<Column noMargin>
|
||||
<RaisedButton
|
||||
primary
|
||||
label={
|
||||
margin === 'dense' ? (
|
||||
<Trans>Upgrade</Trans>
|
||||
) : (
|
||||
<Trans>Upgrade to GDevelop Premium</Trans>
|
||||
)
|
||||
}
|
||||
onClick={onUpgrade}
|
||||
/>
|
||||
</Column>
|
||||
)
|
||||
: undefined
|
||||
}
|
||||
>
|
||||
<GetSubscriptionCard
|
||||
subscriptionDialogOpeningReason="Cloud Project limit reached"
|
||||
label={
|
||||
margin === 'dense' ? (
|
||||
<Trans>Upgrade</Trans>
|
||||
) : !hasValidSubscription ? (
|
||||
<Trans>Upgrade to GDevelop Premium</Trans>
|
||||
) : (
|
||||
<Trans>Upgrade your Premium Plan</Trans>
|
||||
)
|
||||
}
|
||||
hideButton={!canMaximumCountBeIncreased}
|
||||
>
|
||||
<Line noMargin={margin === 'dense'}>
|
||||
<Column noMargin expand>
|
||||
<Text
|
||||
size={margin === 'dense' ? 'sub-title' : 'block-title'}
|
||||
noMargin={margin === 'dense'}
|
||||
@@ -89,7 +72,7 @@ export const MaxProjectCountAlertMessage = ({
|
||||
</Text>
|
||||
<Text noMargin={margin === 'dense'}>
|
||||
{canMaximumCountBeIncreased ? (
|
||||
maximumCount === 1 ? (
|
||||
!hasValidSubscription ? (
|
||||
<Trans>
|
||||
Thanks for trying GDevelop! Unlock more projects, publishing,
|
||||
multiplayer, courses and much more by upgrading.
|
||||
@@ -107,8 +90,8 @@ export const MaxProjectCountAlertMessage = ({
|
||||
</Trans>
|
||||
)}
|
||||
</Text>
|
||||
</AlertMessage>
|
||||
</Column>
|
||||
</Line>
|
||||
</Column>
|
||||
</Line>
|
||||
</GetSubscriptionCard>
|
||||
);
|
||||
};
|
||||
|
@@ -47,7 +47,6 @@ import {
|
||||
checkIfHasTooManyCloudProjects,
|
||||
MaxProjectCountAlertMessage,
|
||||
} from './MaxProjectCountAlertMessage';
|
||||
import { SubscriptionSuggestionContext } from '../../../../Profile/Subscription/SubscriptionSuggestionContext';
|
||||
import { useProjectsListFor } from './utils';
|
||||
import { deleteCloudProject } from '../../../../Utils/GDevelopServices/Project';
|
||||
import { getDefaultRegisterGameProperties } from '../../../../Utils/UseGameAndBuildsManager';
|
||||
@@ -149,9 +148,6 @@ const CreateSection = ({
|
||||
const { routeArguments, removeRouteArguments } = React.useContext(
|
||||
RouterContext
|
||||
);
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
// $FlowIgnore
|
||||
const quickCustomizationRecommendation: ?QuickCustomizationRecommendation = React.useMemo(
|
||||
() => {
|
||||
@@ -450,20 +446,11 @@ const CreateSection = ({
|
||||
<SectionContainer
|
||||
flexBody
|
||||
renderFooter={
|
||||
!isMobile && limits && hasTooManyCloudProjects
|
||||
!isMobile && hasTooManyCloudProjects
|
||||
? () => (
|
||||
<Line>
|
||||
<Column expand>
|
||||
<MaxProjectCountAlertMessage
|
||||
limits={limits}
|
||||
onUpgrade={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: 'Cloud Project limit reached',
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
<MaxProjectCountAlertMessage />
|
||||
</Column>
|
||||
</Line>
|
||||
)
|
||||
@@ -538,18 +525,8 @@ const CreateSection = ({
|
||||
searchText={searchText}
|
||||
setSearchText={setSearchText}
|
||||
/>
|
||||
{isMobile && limits && hasTooManyCloudProjects && (
|
||||
<MaxProjectCountAlertMessage
|
||||
margin="dense"
|
||||
limits={limits}
|
||||
onUpgrade={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: 'Cloud Project limit reached',
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
{isMobile && hasTooManyCloudProjects && (
|
||||
<MaxProjectCountAlertMessage margin="dense" />
|
||||
)}
|
||||
{quickCustomizationRecommendation && (
|
||||
<ColumnStackLayout noMargin>
|
||||
|
@@ -39,6 +39,9 @@ type Props = {|
|
||||
label: React.Node,
|
||||
onPayWithCredits: () => void,
|
||||
|},
|
||||
onUpgrade?: () => void,
|
||||
forceColumnLayout?: boolean,
|
||||
filter?: 'individual' | 'team' | 'education',
|
||||
|};
|
||||
|
||||
const GetSubscriptionCard = ({
|
||||
@@ -47,21 +50,26 @@ const GetSubscriptionCard = ({
|
||||
label,
|
||||
hideButton,
|
||||
payWithCreditsOptions,
|
||||
onUpgrade,
|
||||
forceColumnLayout,
|
||||
filter,
|
||||
}: Props) => {
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
const { isMobile } = useResponsiveWindowSize();
|
||||
const columnLayout = forceColumnLayout || isMobile;
|
||||
return (
|
||||
<div className={classes.premiumContainer}>
|
||||
<Paper style={styles.paper} background="medium">
|
||||
<Line expand alignItems="center" noMargin={!isMobile}>
|
||||
<Line expand alignItems="center" noMargin={!columnLayout}>
|
||||
<img src="res/diamond.svg" style={styles.diamondIcon} alt="diamond" />
|
||||
<Column expand justifyContent="center">
|
||||
<ResponsiveLineStackLayout
|
||||
alignItems="center"
|
||||
noColumnMargin
|
||||
noMargin
|
||||
forceMobileLayout={columnLayout}
|
||||
>
|
||||
<Column noMargin expand>
|
||||
{children}
|
||||
@@ -79,10 +87,14 @@ const GetSubscriptionCard = ({
|
||||
label={label || <Trans>Upgrade</Trans>}
|
||||
primary
|
||||
onClick={() => {
|
||||
if (onUpgrade) {
|
||||
onUpgrade();
|
||||
}
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: subscriptionDialogOpeningReason,
|
||||
},
|
||||
filter,
|
||||
});
|
||||
}}
|
||||
icon={<CrownShining fontSize="small" />}
|
||||
|
@@ -3,20 +3,19 @@
|
||||
import * as React from 'react';
|
||||
import { Trans } from '@lingui/macro';
|
||||
import FlatButton from '../../UI/FlatButton';
|
||||
import Dialog, { DialogPrimaryButton } from '../../UI/Dialog';
|
||||
import Star from '@material-ui/icons/Star';
|
||||
import Favorite from '@material-ui/icons/Favorite';
|
||||
import Dialog from '../../UI/Dialog';
|
||||
import AuthenticatedUserContext from '../AuthenticatedUserContext';
|
||||
import { Column, LargeSpacer, Line } from '../../UI/Grid';
|
||||
import { Column } from '../../UI/Grid';
|
||||
import {
|
||||
sendSubscriptionCheckDialogShown,
|
||||
sendSubscriptionCheckDismiss,
|
||||
} from '../../Utils/Analytics/EventSender';
|
||||
import { SubscriptionSuggestionContext } from './SubscriptionSuggestionContext';
|
||||
import Text from '../../UI/Text';
|
||||
import { hasValidSubscriptionPlan } from '../../Utils/GDevelopServices/Usage';
|
||||
import { isNativeMobileApp } from '../../Utils/Platform';
|
||||
import InAppTutorialContext from '../../InAppTutorial/InAppTutorialContext';
|
||||
import GetSubscriptionCard from './GetSubscriptionCard';
|
||||
import { ColumnStackLayout } from '../../UI/Layout';
|
||||
|
||||
export type SubscriptionCheckerInterface = {|
|
||||
checkUserHasSubscription: () => boolean,
|
||||
@@ -35,11 +34,6 @@ type Props = {|
|
||||
isNotShownDuringInAppTutorial?: boolean,
|
||||
|};
|
||||
|
||||
const styles = {
|
||||
icon: { width: 40, height: 40, marginRight: 20 },
|
||||
iconText: { flex: 1 },
|
||||
};
|
||||
|
||||
const SubscriptionChecker = React.forwardRef<
|
||||
Props,
|
||||
SubscriptionCheckerInterface
|
||||
@@ -50,9 +44,6 @@ const SubscriptionChecker = React.forwardRef<
|
||||
) => {
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const [dialogOpen, setDialogOpen] = React.useState<boolean>(false);
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
|
||||
const closeDialog = () => {
|
||||
sendSubscriptionCheckDismiss();
|
||||
@@ -94,7 +85,7 @@ const SubscriptionChecker = React.forwardRef<
|
||||
return (
|
||||
<Dialog
|
||||
open={dialogOpen}
|
||||
title={mode === 'try' ? <Trans>We need your support!</Trans> : title}
|
||||
title={title}
|
||||
actions={[
|
||||
<FlatButton
|
||||
label={
|
||||
@@ -108,67 +99,39 @@ const SubscriptionChecker = React.forwardRef<
|
||||
primary={false}
|
||||
onClick={closeDialog}
|
||||
/>,
|
||||
<DialogPrimaryButton
|
||||
label={<Trans>Get a subscription or login</Trans>}
|
||||
key="subscribe"
|
||||
primary
|
||||
onClick={() => {
|
||||
if (onChangeSubscription) onChangeSubscription();
|
||||
setDialogOpen(false);
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: id,
|
||||
preStep: 'subscriptionChecker',
|
||||
},
|
||||
});
|
||||
}}
|
||||
/>,
|
||||
]}
|
||||
onRequestClose={closeDialog}
|
||||
maxWidth="sm"
|
||||
>
|
||||
<Column noMargin>
|
||||
<Line noMargin alignItems="center">
|
||||
{mode === 'try' ? (
|
||||
<Text>
|
||||
<Trans>
|
||||
Please get a subscription to keep GDevelop running.
|
||||
</Trans>
|
||||
</Text>
|
||||
) : (
|
||||
<Text>
|
||||
<Trans>
|
||||
To use this feature, you need a GDevelop subscription.
|
||||
</Trans>
|
||||
</Text>
|
||||
)}
|
||||
</Line>
|
||||
<Line noMargin alignItems="center">
|
||||
<Star style={styles.icon} />
|
||||
<Text style={styles.iconText}>
|
||||
<Trans>
|
||||
Get a subscription to gain more one-click exports, cloud
|
||||
projects, leaderboards and remove the GDevelop splashscreen.
|
||||
</Trans>
|
||||
</Text>
|
||||
</Line>
|
||||
<Line noMargin alignItems="center">
|
||||
<Favorite style={styles.icon} />
|
||||
<Text style={styles.iconText}>
|
||||
<Trans>
|
||||
You're also supporting the development of GDevelop, an
|
||||
open-source software! In the future, more online services will
|
||||
be available for users with a subscription.
|
||||
</Trans>
|
||||
</Text>
|
||||
</Line>
|
||||
<LargeSpacer />
|
||||
<Text align="right">
|
||||
<b>
|
||||
<Trans>Thanks!</Trans>
|
||||
</b>
|
||||
<ColumnStackLayout noMargin>
|
||||
<Text size="sub-title">
|
||||
❤️ <Trans>Support What You Love</Trans>
|
||||
</Text>
|
||||
</Column>
|
||||
<Text color="secondary">
|
||||
<Trans>
|
||||
Your membership helps the GDevelop company maintain servers, build
|
||||
new features and keep the open-source project thriving. Our goal:
|
||||
make game development fast, fun and accessible to all.
|
||||
</Trans>
|
||||
</Text>
|
||||
<GetSubscriptionCard
|
||||
subscriptionDialogOpeningReason={id}
|
||||
label={<Trans>Get Premium</Trans>}
|
||||
onUpgrade={() => {
|
||||
if (onChangeSubscription) onChangeSubscription();
|
||||
setDialogOpen(false);
|
||||
}}
|
||||
>
|
||||
<Column noMargin expand>
|
||||
<Text>
|
||||
<Trans>
|
||||
Upgrade to get more cloud projects, publishing, multiplayer,
|
||||
courses and credits every month with GDevelop Premium.
|
||||
</Trans>
|
||||
</Text>
|
||||
</Column>
|
||||
</GetSubscriptionCard>
|
||||
</ColumnStackLayout>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
@@ -38,6 +38,7 @@ import GDevelopThemeContext from '../../UI/Theme/GDevelopThemeContext';
|
||||
import PlaceholderError from '../../UI/PlaceholderError';
|
||||
import Link from '../../UI/Link';
|
||||
import Window from '../../Utils/Window';
|
||||
import GetSubscriptionCard from './GetSubscriptionCard';
|
||||
|
||||
const styles = {
|
||||
diamondIcon: {
|
||||
@@ -82,7 +83,7 @@ const subscriptionOptions: {
|
||||
title: <Trans>For Education</Trans>,
|
||||
description: <Trans>Teachers, courses and universities</Trans>,
|
||||
icon: <EducationPlans style={{ width: 110, height: 100 }} />,
|
||||
buttonColor: 'primary',
|
||||
buttonColor: 'premium',
|
||||
},
|
||||
};
|
||||
|
||||
@@ -386,40 +387,16 @@ const SubscriptionDetails = ({
|
||||
)
|
||||
) : !isSubscriptionExpired ? (
|
||||
isOnOrSimulateMobileApp ? (
|
||||
<Paper background="medium" variant="outlined" style={styles.paper}>
|
||||
<ResponsiveLineStackLayout
|
||||
alignItems="center"
|
||||
expand
|
||||
noMargin
|
||||
noResponsiveLandscape
|
||||
>
|
||||
<Column expand noMargin>
|
||||
<LineStackLayout alignItems="center">
|
||||
<img
|
||||
src="res/diamond.svg"
|
||||
style={styles.diamondIcon}
|
||||
alt="diamond"
|
||||
/>
|
||||
<Text noMargin>
|
||||
<Trans>
|
||||
Unlock full access to GDevelop to create without limits!
|
||||
</Trans>
|
||||
</Text>
|
||||
</LineStackLayout>
|
||||
</Column>
|
||||
<Column noMargin>
|
||||
<RaisedButton
|
||||
label={<Trans>Choose a subscription</Trans>}
|
||||
primary
|
||||
onClick={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: { reason: 'Consult profile' },
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Column>
|
||||
</ResponsiveLineStackLayout>
|
||||
</Paper>
|
||||
<GetSubscriptionCard
|
||||
label={<Trans>Choose a subscription</Trans>}
|
||||
subscriptionDialogOpeningReason="Consult profile"
|
||||
>
|
||||
<Text noMargin>
|
||||
<Trans>
|
||||
Unlock full access to GDevelop to create without limits!
|
||||
</Trans>
|
||||
</Text>
|
||||
</GetSubscriptionCard>
|
||||
) : (
|
||||
<ResponsiveLineStackLayout noColumnMargin noResponsiveLandscape>
|
||||
{Object.keys(subscriptionOptions).map(key => {
|
||||
@@ -477,42 +454,18 @@ const SubscriptionDetails = ({
|
||||
</ResponsiveLineStackLayout>
|
||||
)
|
||||
) : (
|
||||
<Paper background="medium" variant="outlined" style={styles.paper}>
|
||||
<ResponsiveLineStackLayout
|
||||
alignItems="center"
|
||||
expand
|
||||
noMargin
|
||||
noResponsiveLandscape
|
||||
>
|
||||
<Column expand noMargin>
|
||||
<LineStackLayout alignItems="center">
|
||||
<img
|
||||
src="res/diamond.svg"
|
||||
style={styles.diamondIcon}
|
||||
alt="diamond"
|
||||
/>
|
||||
<Text noMargin>
|
||||
<Trans>
|
||||
Oh no! Your subscription from the redemption code has
|
||||
expired. You can renew it by redeeming a new code or getting
|
||||
a new subscription.
|
||||
</Trans>
|
||||
</Text>
|
||||
</LineStackLayout>
|
||||
</Column>
|
||||
<Column noMargin>
|
||||
<RaisedButton
|
||||
label={<Trans>Choose a subscription</Trans>}
|
||||
primary
|
||||
onClick={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: { reason: 'Consult profile' },
|
||||
})
|
||||
}
|
||||
/>
|
||||
</Column>
|
||||
</ResponsiveLineStackLayout>
|
||||
</Paper>
|
||||
<GetSubscriptionCard
|
||||
label={<Trans>Choose a subscription</Trans>}
|
||||
subscriptionDialogOpeningReason="Consult profile"
|
||||
>
|
||||
<Text noMargin>
|
||||
<Trans>
|
||||
Oh no! Your subscription from the redemption code has expired. You
|
||||
can renew it by redeeming a new code or getting a new
|
||||
subscription.
|
||||
</Trans>
|
||||
</Text>
|
||||
</GetSubscriptionCard>
|
||||
)}
|
||||
</Column>
|
||||
);
|
||||
|
@@ -791,11 +791,13 @@ export default function SubscriptionDialog({
|
||||
❤️ <Trans>Support What You Love</Trans>
|
||||
</Text>
|
||||
<Text size="body" color="secondary">
|
||||
The GDevelop project is open-source, powered by passion and
|
||||
community. Your membership helps the GDevelop company maintain
|
||||
servers, build new features, develop commercial offerings and
|
||||
keep the open-source project thriving. Our goal: make game
|
||||
development fast, fun and accessible to all.
|
||||
<Trans>
|
||||
The GDevelop project is open-source, powered by passion and
|
||||
community. Your membership helps the GDevelop company
|
||||
maintain servers, build new features, develop commercial
|
||||
offerings and keep the open-source project thriving. Our
|
||||
goal: make game development fast, fun and accessible to all.
|
||||
</Trans>
|
||||
</Text>
|
||||
</Column>
|
||||
{getPlanSpecificRequirements(
|
||||
|
@@ -20,7 +20,6 @@ import {
|
||||
checkIfHasTooManyCloudProjects,
|
||||
MaxProjectCountAlertMessage,
|
||||
} from '../MainFrame/EditorContainers/HomePage/CreateSection/MaxProjectCountAlertMessage';
|
||||
import { SubscriptionSuggestionContext } from '../Profile/Subscription/SubscriptionSuggestionContext';
|
||||
import optionalRequire from '../Utils/OptionalRequire';
|
||||
import PreferencesContext from '../MainFrame/Preferences/PreferencesContext';
|
||||
import Checkbox from '../UI/Checkbox';
|
||||
@@ -132,7 +131,6 @@ const NewProjectSetupDialog = ({
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const { windowSize, isLandscape } = useResponsiveWindowSize();
|
||||
const {
|
||||
limits,
|
||||
authenticated,
|
||||
onOpenLoginDialog,
|
||||
onOpenCreateAccountDialog,
|
||||
@@ -157,9 +155,6 @@ const NewProjectSetupDialog = ({
|
||||
const { currentlyRunningInAppTutorial } = React.useContext(
|
||||
InAppTutorialContext
|
||||
);
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
const [projectNameError, setProjectNameError] = React.useState<?React.Node>(
|
||||
null
|
||||
);
|
||||
@@ -674,17 +669,8 @@ const NewProjectSetupDialog = ({
|
||||
</Paper>
|
||||
</Line>
|
||||
)}
|
||||
{limits && hasTooManyCloudProjects ? (
|
||||
<MaxProjectCountAlertMessage
|
||||
limits={limits}
|
||||
onUpgrade={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: 'Cloud Project limit reached',
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
{hasTooManyCloudProjects ? (
|
||||
<MaxProjectCountAlertMessage />
|
||||
) : null}
|
||||
</ColumnStackLayout>
|
||||
)}
|
||||
|
@@ -13,7 +13,6 @@ import {
|
||||
checkIfHasTooManyCloudProjects,
|
||||
MaxProjectCountAlertMessage,
|
||||
} from '../MainFrame/EditorContainers/HomePage/CreateSection/MaxProjectCountAlertMessage';
|
||||
import { SubscriptionSuggestionContext } from '../Profile/Subscription/SubscriptionSuggestionContext';
|
||||
|
||||
type Props = {|
|
||||
storageProviders: Array<StorageProvider>,
|
||||
@@ -27,11 +26,8 @@ const SaveToStorageProviderDialog = ({
|
||||
onChooseProvider,
|
||||
}: Props) => {
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
|
||||
const { profile, limits, cloudProjects } = authenticatedUser;
|
||||
const { profile, cloudProjects } = authenticatedUser;
|
||||
|
||||
const isLoadingCloudProjects = !!profile && !cloudProjects;
|
||||
const isCloudProjectsMaximumReached = checkIfHasTooManyCloudProjects(
|
||||
@@ -67,19 +63,8 @@ const SaveToStorageProviderDialog = ({
|
||||
}
|
||||
/>
|
||||
{storageProvider.internalName === 'Cloud' &&
|
||||
isCloudProjectsMaximumReached &&
|
||||
limits && (
|
||||
<MaxProjectCountAlertMessage
|
||||
margin="dense"
|
||||
limits={limits}
|
||||
onUpgrade={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: 'Cloud Project limit reached',
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
isCloudProjectsMaximumReached && (
|
||||
<MaxProjectCountAlertMessage margin="dense" />
|
||||
)}
|
||||
</React.Fragment>
|
||||
))}
|
||||
|
@@ -9,7 +9,6 @@ import RaisedButton from '../UI/RaisedButton';
|
||||
import { I18n } from '@lingui/react';
|
||||
import { type Exporter } from '../ExportAndShare/ShareDialog';
|
||||
import Text from '../UI/Text';
|
||||
import { type Limits } from '../Utils/GDevelopServices/Usage';
|
||||
import {
|
||||
getBuildArtifactUrl,
|
||||
type Build,
|
||||
@@ -33,7 +32,6 @@ import {
|
||||
checkIfHasTooManyCloudProjects,
|
||||
MaxProjectCountAlertMessage,
|
||||
} from '../MainFrame/EditorContainers/HomePage/CreateSection/MaxProjectCountAlertMessage';
|
||||
import { SubscriptionSuggestionContext } from '../Profile/Subscription/SubscriptionSuggestionContext';
|
||||
import ArrowLeft from '../UI/CustomSvgIcons/ArrowLeft';
|
||||
|
||||
type Props = {|
|
||||
@@ -66,13 +64,9 @@ export const QuickPublish = ({
|
||||
onLaunchPreview,
|
||||
}: Props) => {
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
const {
|
||||
profile,
|
||||
onOpenCreateAccountDialog,
|
||||
limits,
|
||||
cloudProjects,
|
||||
getAuthorizationHeader,
|
||||
} = authenticatedUser;
|
||||
@@ -94,19 +88,6 @@ export const QuickPublish = ({
|
||||
});
|
||||
}, []);
|
||||
|
||||
const renderCallout = (limits: Limits) => (
|
||||
<MaxProjectCountAlertMessage
|
||||
limits={limits}
|
||||
onUpgrade={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: {
|
||||
reason: 'Cloud Project limit reached',
|
||||
},
|
||||
})
|
||||
}
|
||||
/>
|
||||
);
|
||||
|
||||
const isLoadingCloudProjects = !!profile && !cloudProjects;
|
||||
const isCloudProjectsMaximumReached = checkIfHasTooManyCloudProjects(
|
||||
authenticatedUser
|
||||
@@ -203,8 +184,8 @@ export const QuickPublish = ({
|
||||
{profile ? (
|
||||
isLoadingCloudProjects ? (
|
||||
<PlaceholderLoader />
|
||||
) : cantContinueBecauseCloudProjectsMaximumReached && limits ? (
|
||||
renderCallout(limits)
|
||||
) : cantContinueBecauseCloudProjectsMaximumReached ? (
|
||||
<MaxProjectCountAlertMessage />
|
||||
) : (
|
||||
<I18n>
|
||||
{({ i18n }) => (
|
||||
|
@@ -367,7 +367,6 @@ export type SubscriptionDialogDisplayReason =
|
||||
| 'Consult profile'
|
||||
| 'Build limit reached'
|
||||
| 'Leaderboard customization'
|
||||
| 'Extend redeemed subscription'
|
||||
| 'Generate project from prompt'
|
||||
| 'Version history'
|
||||
| 'Add collaborators on project'
|
||||
|
@@ -16,14 +16,13 @@ import { Column, Line } from '../UI/Grid';
|
||||
import VersionHistory, { type OpenedVersionStatus } from '.';
|
||||
import UnsavedChangesContext from '../MainFrame/UnsavedChangesContext';
|
||||
import AlertMessage from '../UI/AlertMessage';
|
||||
import { ColumnStackLayout } from '../UI/Layout';
|
||||
import RaisedButton from '../UI/RaisedButton';
|
||||
import { SubscriptionSuggestionContext } from '../Profile/Subscription/SubscriptionSuggestionContext';
|
||||
import useAlertDialog from '../UI/Alert/useAlertDialog';
|
||||
import PlaceholderLoader from '../UI/PlaceholderLoader';
|
||||
import type { MessageDescriptor } from '../Utils/i18n/MessageDescriptor.flow';
|
||||
import PlaceholderError from '../UI/PlaceholderError';
|
||||
import CloudStorageProvider from '../ProjectsStorage/CloudStorageProvider';
|
||||
import GetSubscriptionCard from '../Profile/Subscription/GetSubscriptionCard';
|
||||
import Text from '../UI/Text';
|
||||
|
||||
const getCloudProjectFileMetadataIdentifier = (
|
||||
storageProviderInternalName: string,
|
||||
@@ -96,9 +95,6 @@ const useVersionHistory = ({
|
||||
}: Props) => {
|
||||
const { hasUnsavedChanges } = React.useContext(UnsavedChangesContext);
|
||||
const { showAlert } = useAlertDialog();
|
||||
const { openSubscriptionDialog } = React.useContext(
|
||||
SubscriptionSuggestionContext
|
||||
);
|
||||
const [
|
||||
versionsFetchingError,
|
||||
setVersionsFetchingError,
|
||||
@@ -447,27 +443,19 @@ const useVersionHistory = ({
|
||||
</Column>
|
||||
</Line>
|
||||
) : !isUserAllowedToSeeVersionHistory ? (
|
||||
<Line expand>
|
||||
<ColumnStackLayout>
|
||||
<AlertMessage kind="info">
|
||||
<Trans>
|
||||
Access project history, name saves, restore older versions.
|
||||
<br />
|
||||
Upgrade to a Pro plan to get started!
|
||||
</Trans>
|
||||
</AlertMessage>
|
||||
<RaisedButton
|
||||
primary
|
||||
label={<Trans>Upgrade my subscription</Trans>}
|
||||
onClick={() =>
|
||||
openSubscriptionDialog({
|
||||
analyticsMetadata: { reason: 'Version history' },
|
||||
filter: 'team',
|
||||
})
|
||||
}
|
||||
/>
|
||||
</ColumnStackLayout>
|
||||
</Line>
|
||||
<GetSubscriptionCard
|
||||
subscriptionDialogOpeningReason="Version history"
|
||||
forceColumnLayout
|
||||
filter="team"
|
||||
>
|
||||
<Text>
|
||||
<Trans>
|
||||
Access project history, name saves, restore older versions.
|
||||
<br />
|
||||
Upgrade to a Pro plan to get started!
|
||||
</Trans>
|
||||
</Text>
|
||||
</GetSubscriptionCard>
|
||||
) : !state.versions && versionsFetchingError ? (
|
||||
<Line expand>
|
||||
<Column expand>
|
||||
|
@@ -2380,7 +2380,7 @@ export const limitsForNoSubscriptionUser: Limits = {
|
||||
platforms: false,
|
||||
},
|
||||
cloudProjects: {
|
||||
maximumCount: 10,
|
||||
maximumCount: 3,
|
||||
canMaximumCountBeIncreased: true,
|
||||
maximumGuestCollaboratorsPerProject: 0,
|
||||
},
|
||||
@@ -2491,7 +2491,7 @@ export const limitsForGoldUser: Limits = {
|
||||
},
|
||||
cloudProjects: {
|
||||
maximumCount: 100,
|
||||
canMaximumCountBeIncreased: false,
|
||||
canMaximumCountBeIncreased: true,
|
||||
maximumGuestCollaboratorsPerProject: 0,
|
||||
},
|
||||
leaderboards: {
|
||||
|
@@ -1,12 +1,14 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import { MaxProjectCountAlertMessage } from '../../../../MainFrame/EditorContainers/HomePage/CreateSection/MaxProjectCountAlertMessage';
|
||||
import paperDecorator from '../../../PaperDecorator';
|
||||
import {
|
||||
limitsForSilverUser,
|
||||
limitsForGoldUser,
|
||||
defaultAuthenticatedUserWithNoSubscription,
|
||||
fakeGoldAuthenticatedUser,
|
||||
fakeSilverAuthenticatedUser,
|
||||
fakeStartupAuthenticatedUser,
|
||||
} from '../../../../fixtures/GDevelopServicesTestData';
|
||||
import AuthenticatedUserContext from '../../../../Profile/AuthenticatedUserContext';
|
||||
|
||||
export default {
|
||||
title: 'HomePage/CreateSection/MaxProjectCountAlertMessage',
|
||||
@@ -14,16 +16,34 @@ export default {
|
||||
decorators: [paperDecorator],
|
||||
};
|
||||
|
||||
export const ForFreeUser = () => (
|
||||
<AuthenticatedUserContext.Provider
|
||||
value={defaultAuthenticatedUserWithNoSubscription}
|
||||
>
|
||||
<MaxProjectCountAlertMessage />
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
||||
export const ForIndieUser = () => (
|
||||
<MaxProjectCountAlertMessage
|
||||
limits={limitsForSilverUser}
|
||||
onUpgrade={() => action('onUpgrade')()}
|
||||
/>
|
||||
<AuthenticatedUserContext.Provider value={fakeSilverAuthenticatedUser}>
|
||||
<MaxProjectCountAlertMessage />
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
||||
export const ForGoldUser = () => (
|
||||
<AuthenticatedUserContext.Provider value={fakeGoldAuthenticatedUser}>
|
||||
<MaxProjectCountAlertMessage />
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
||||
export const ForProUser = () => (
|
||||
<MaxProjectCountAlertMessage
|
||||
limits={limitsForGoldUser}
|
||||
onUpgrade={() => action('onUpgrade')()}
|
||||
/>
|
||||
<AuthenticatedUserContext.Provider value={fakeStartupAuthenticatedUser}>
|
||||
<MaxProjectCountAlertMessage />
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
||||
export const DenseMargins = () => (
|
||||
<AuthenticatedUserContext.Provider value={fakeSilverAuthenticatedUser}>
|
||||
<MaxProjectCountAlertMessage margin="dense" />
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
@@ -1,9 +1,9 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
import paperDecorator from '../../PaperDecorator';
|
||||
import { limitsReached } from '../../../fixtures/GDevelopServicesTestData';
|
||||
import { defaultAuthenticatedUserWithNoSubscription } from '../../../fixtures/GDevelopServicesTestData';
|
||||
import MaxLeaderboardCountAlertMessage from '../../../GameDashboard/LeaderboardAdmin/MaxLeaderboardCountAlertMessage';
|
||||
import AuthenticatedUserContext from '../../../Profile/AuthenticatedUserContext';
|
||||
|
||||
export default {
|
||||
title: 'Leaderboard/MaxLeaderboardCountAlertMessage',
|
||||
@@ -12,9 +12,9 @@ export default {
|
||||
};
|
||||
|
||||
export const Default = () => (
|
||||
<MaxLeaderboardCountAlertMessage
|
||||
limits={limitsReached}
|
||||
onUpgrade={() => action('onUpgrade')()}
|
||||
onClose={() => action('onClose')()}
|
||||
/>
|
||||
<AuthenticatedUserContext.Provider
|
||||
value={defaultAuthenticatedUserWithNoSubscription}
|
||||
>
|
||||
<MaxLeaderboardCountAlertMessage />
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
@@ -82,3 +82,20 @@ export const PayWithCreditsOptions = () => (
|
||||
</GetSubscriptionCard>
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
||||
export const ForceColumnLayout = () => (
|
||||
<AuthenticatedUserContext.Provider value={fakeNotAuthenticatedUser}>
|
||||
<GetSubscriptionCard
|
||||
subscriptionDialogOpeningReason="Build limit reached"
|
||||
forceColumnLayout
|
||||
>
|
||||
<Line>
|
||||
<Column noMargin>
|
||||
<Text noMargin>
|
||||
Upgrade your GDevelop subscription to unlock this packaging.
|
||||
</Text>
|
||||
</Column>
|
||||
</Line>
|
||||
</GetSubscriptionCard>
|
||||
</AuthenticatedUserContext.Provider>
|
||||
);
|
||||
|
Reference in New Issue
Block a user