Skip to content

Commit

Permalink
Discord username can now be added to one's Profile, allowing to claim…
Browse files Browse the repository at this point in the history
… a role on GDevelop's server (#5962)

* If you have a Gold or Startup subscription, head down to your profile, to claim access to a premium channel on Discord, where you can discuss together and ask for support.
  • Loading branch information
ClementPasteau authored Nov 27, 2023
1 parent d34f1a6 commit 38651ed
Show file tree
Hide file tree
Showing 31 changed files with 560 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { formatProductPrice } from '../ProductPriceTag';
import AuthenticatedUserContext from '../../Profile/AuthenticatedUserContext';
import { PrivateAssetPackTile, PromoBundleAssetPackCard } from '../ShopTiles';
import { AssetStoreContext } from '../AssetStoreContext';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

const cellSpacing = 8;

Expand Down Expand Up @@ -290,7 +291,10 @@ const PrivateAssetPackInformationPage = ({
setAssetPack(assetPack);
setSellerPublicProfile(profile);
} catch (error) {
if (error.response && error.response.status === 404) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.status === 404) {
setErrorText(
<Trans>
Asset pack not found - An error occurred, please try again
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
purchaseAppStoreProduct,
} from '../../Utils/AppStorePurchases';
import Form from '../../UI/Form';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

const PasswordPromptDialog = (props: {
passwordValue: string,
Expand Down Expand Up @@ -131,10 +132,13 @@ const PrivateAssetPackPurchaseDialog = ({
});
Window.openExternalURL(checkoutUrl);
} catch (error) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (
error.response &&
error.response.status === 403 &&
error.response.data.code === 'auth/wrong-password'
extractedStatusAndCode &&
extractedStatusAndCode.status === 403 &&
extractedStatusAndCode.code === 'auth/wrong-password'
) {
await showAlert({
title: t`Operation not allowed`,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
getAuthorizationTokenForPrivateAssets,
} from '../../Utils/GDevelopServices/Shop';
import PrivateAssetsAuthorizationContext from './PrivateAssetsAuthorizationContext';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

type Props = {| children: React.Node |};

Expand Down Expand Up @@ -94,7 +95,10 @@ const PrivateAssetsAuthorizationProvider = ({ children }: Props) => {
});
return asset;
} catch (error) {
if (error.response && error.response.status === 404) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.status === 404) {
// If the token is expired, fetch a new one and try again.
token = await fetchAuthorizationToken(userId);
const asset = await getPrivateAsset(assetShortHeader, token, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { formatProductPrice } from '../ProductPriceTag';
import AuthenticatedUserContext from '../../Profile/AuthenticatedUserContext';
import { capitalize } from 'lodash';
import FlatButton from '../../UI/FlatButton';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

const styles = {
disabledText: { opacity: 0.6 },
Expand Down Expand Up @@ -123,7 +124,10 @@ const PrivateGameTemplateInformationPage = ({
setGameTemplate(gameTemplate);
setSellerPublicProfile(profile);
} catch (error) {
if (error.response && error.response.status === 404) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.status === 404) {
setErrorText(
<Trans>
Game template not found - An error occurred, please try again
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import {
purchaseAppStoreProduct,
} from '../../Utils/AppStorePurchases';
import Form from '../../UI/Form';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

const PasswordPromptDialog = (props: {
passwordValue: string,
Expand Down Expand Up @@ -131,10 +132,13 @@ const PrivateGameTemplatePurchaseDialog = ({
});
Window.openExternalURL(checkoutUrl);
} catch (error) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (
error.response &&
error.response.status === 403 &&
error.response.data.code === 'auth/wrong-password'
extractedStatusAndCode &&
extractedStatusAndCode.status === 403 &&
extractedStatusAndCode.code === 'auth/wrong-password'
) {
await showAlert({
title: t`Operation not allowed`,
Expand Down
8 changes: 6 additions & 2 deletions newIDE/app/src/ExportAndShare/ShareDialog/ExportLauncher.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
addCreateBadgePreHookIfNotClaimed,
TRIVIAL_FIRST_WEB_EXPORT,
} from '../../Utils/GDevelopServices/Badge';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

type State = {|
exportStep: BuildStep,
Expand Down Expand Up @@ -169,8 +170,11 @@ export default class ExportLauncher extends Component<Props, State> {
try {
// Try to fetch the game to see if it's registered but do not do anything with it.
await getGame(getAuthorizationHeader, userId, gameId);
} catch (err) {
if (err.response.status === 404) {
} catch (error) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.code === 404) {
// If the game is not registered, register it before launching the export.
const authorName =
this.props.project.getAuthor() || 'Unspecified publisher';
Expand Down
26 changes: 17 additions & 9 deletions newIDE/app/src/ExportAndShare/ShareDialog/InviteHome.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import useAlertDialog from '../../UI/Alert/useAlertDialog';
import SelectField from '../../UI/SelectField';
import SelectOption from '../../UI/SelectOption';
import Form from '../../UI/Form';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

export const emailRegex = /^(.+)@(.+)$/;

Expand Down Expand Up @@ -177,11 +178,14 @@ const InviteHome = ({ cloudProjectId }: Props) => {
setProjectUserAcls(collaboratorProjectUserAcls);
} catch (error) {
console.error('Unable to fetch the project user acls', error);
if (error.response && error.response.status === 404) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.status === 404) {
setFetchError('project-not-found');
return;
}
if (error.response && error.response.status === 403) {
if (extractedStatusAndCode && extractedStatusAndCode.status === 403) {
setFetchError('project-not-owned');
return;
}
Expand Down Expand Up @@ -263,35 +267,39 @@ const InviteHome = ({ cloudProjectId }: Props) => {
await fetchProjectUserAcls();
} catch (error) {
console.error('Unable to add collaborator', error);
if (error.response && error.response.status === 400) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.status === 400) {
if (
error.response.data.code ===
extractedStatusAndCode.code ===
'project-user-acl-creation/user-already-added'
) {
setAddError('user-already-added');
return;
}
if (
error.response.data.code === 'project-user-acl-creation/user-is-owner'
extractedStatusAndCode.code ===
'project-user-acl-creation/user-is-owner'
) {
setAddError('user-owner');
return;
}
}
if (error.response && error.response.status === 404) {
if (extractedStatusAndCode && extractedStatusAndCode.status === 404) {
setAddError('user-not-found');
return;
}
if (error.response && error.response.status === 403) {
if (extractedStatusAndCode && extractedStatusAndCode.status === 403) {
if (
error.response.data.code ===
extractedStatusAndCode.code ===
'project-user-acl-creation/collaborators-not-allowed'
) {
setAddError('not-allowed');
return;
}
if (
error.response.data.code ===
extractedStatusAndCode.code ===
'project-user-acl-creation/too-many-guest-collaborators-on-project'
) {
setAddError('max-guest-collaborators');
Expand Down
12 changes: 8 additions & 4 deletions newIDE/app/src/ExportAndShare/ShareDialog/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import PreferencesContext from '../../MainFrame/Preferences/PreferencesContext';
import { type FileMetadata, type StorageProvider } from '../../ProjectsStorage';
import { useOnlineStatus } from '../../Utils/OnlineStatus';
import ErrorBoundary from '../../UI/ErrorBoundary';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

export type ShareTab = 'invite' | 'publish';
export type ExporterSection = 'browser' | 'desktop' | 'mobile';
Expand Down Expand Up @@ -184,13 +185,16 @@ const ShareDialog = ({
project.getProjectUuid()
);
setGame(game);
} catch (err) {
console.error('Unable to load the game', err);
if (err && err.status === 404) {
} catch (error) {
console.error('Unable to load the game', error);
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.status === 404) {
setGameError('not-found');
return;
}
if (err && err.status === 403) {
if (extractedStatusAndCode && extractedStatusAndCode.status === 403) {
setGameError('not-owned');
return;
}
Expand Down
19 changes: 13 additions & 6 deletions newIDE/app/src/GameDashboard/GameRegistration.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
getGame,
registerGame,
} from '../Utils/GDevelopServices/Game';
import { extractGDevelopApiErrorStatusAndCode } from '../Utils/GDevelopServices/Errors';

export type GameRegistrationProps = {|
project: ?gdProject,
Expand Down Expand Up @@ -65,19 +66,25 @@ export const GameRegistration = ({
);
setUnavailableReason(null);
setGame(game);
} catch (err) {
console.error(err);
if (err.response) {
if (err.response.status === 403) {
} catch (error) {
console.error(
`Unable to get the game ${project.getProjectUuid()}`,
error
);
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode) {
if (extractedStatusAndCode.status === 403) {
setUnavailableReason('unauthorized');
return;
} else if (err.response.status === 404) {
} else if (extractedStatusAndCode.status === 404) {
setUnavailableReason('not-existing');
return;
}
}

setError(err);
setError(error);
}
},
[project, getAuthorizationHeader, profile]
Expand Down
19 changes: 13 additions & 6 deletions newIDE/app/src/GameDashboard/LeaderboardAdmin/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import MaxLeaderboardCountAlertMessage from './MaxLeaderboardCountAlertMessage';
import useAlertDialog from '../../UI/Alert/useAlertDialog';
import Paper from '../../UI/Paper';
import SwitchHorizontal from '../../UI/CustomSvgIcons/SwitchHorizontal';
import { extractGDevelopApiErrorStatusAndCode } from '../../Utils/GDevelopServices/Errors';

type Props = {|
onLoading: boolean => void,
Expand Down Expand Up @@ -312,12 +313,15 @@ export const LeaderboardAdmin = ({
setApiError(null);
try {
await listLeaderboards();
} catch (err) {
if (err.response && err.response.status === 404) {
} catch (error) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
if (extractedStatusAndCode && extractedStatusAndCode.status === 404) {
setDisplayGameRegistration(true);
return;
}
console.error('An error occurred when fetching leaderboards', err);
console.error('An error occurred when fetching leaderboards', error);
setApiError({
action: 'leaderboardsFetching',
message: (
Expand Down Expand Up @@ -406,12 +410,15 @@ export const LeaderboardAdmin = ({
setApiError(null);
try {
await resetLeaderboard();
} catch (err) {
console.error('An error occurred when resetting leaderboard', err);
} catch (error) {
console.error('An error occurred when resetting leaderboard', error);
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
setApiError({
action: 'leaderboardReset',
message:
err.status && err.status === 409 ? (
extractedStatusAndCode && extractedStatusAndCode.status === 409 ? (
<Trans>
This leaderboard is already resetting, please wait a bit, close
the dialog, come back and try again.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { type LastModifiedInfo } from './utils';
import DotBadge from '../../../../UI/DotBadge';
import { type FileMetadata } from '../../../../ProjectsStorage';
import StatusIndicator from './StatusIndicator';
import { extractGDevelopApiErrorStatusAndCode } from '../../../../Utils/GDevelopServices/Errors';
const electron = optionalRequire('electron');
const path = optionalRequire('path');

Expand Down Expand Up @@ -260,8 +261,11 @@ export const ProjectFileListItem = ({
await deleteCloudProject(authenticatedUser, fileMetadata.fileIdentifier);
authenticatedUser.onCloudProjectsChanged();
} catch (error) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
const message =
error.response && error.response.status === 403
extractedStatusAndCode && extractedStatusAndCode.status === 403
? t`You don't have permissions to delete this project.`
: t`An error occurred when saving the project. Please try again later.`;
showAlert({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const getDefaultUser = ({ id }: { id: string }) => ({
description: null,
username: null,
donateLink: null,
discordUsername: null,
email: `${id}@email.net`,
getGameStatsEmail: false,
getNewsletterEmail: false,
Expand Down
6 changes: 5 additions & 1 deletion newIDE/app/src/MainFrame/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,7 @@ import useEditorTabsStateSaving from './EditorTabs/UseEditorTabsStateSaving';
import { type PrivateGameTemplateListingData } from '../Utils/GDevelopServices/Shop';
import PixiResourcesLoader from '../ObjectsRendering/PixiResourcesLoader';
import useResourcesWatcher from './ResourcesWatcher';
import { extractGDevelopApiErrorStatusAndCode } from '../Utils/GDevelopServices/Errors';
const GD_STARTUP_TIMES = global.GD_STARTUP_TIMES || [];

const gd: libGDevelop = global.gd;
Expand Down Expand Up @@ -2489,8 +2490,11 @@ const MainFrame = (props: Props) => {
_replaceSnackMessage(i18n._(t`Project properly saved`));
}
} catch (error) {
const extractedStatusAndCode = extractGDevelopApiErrorStatusAndCode(
error
);
const message =
error.response && error.response.status === 403
extractedStatusAndCode && extractedStatusAndCode.status === 403
? t`You don't have permissions to save this project. Please choose another location.`
: t`An error occurred when saving the project. Please try again later.`;
showAlert({
Expand Down
1 change: 1 addition & 0 deletions newIDE/app/src/Profile/AuthenticatedUserProfileDetails.js
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ const AuthenticatedUserProfileDetails = ({
? { ...authenticatedUser.profile, email: firebaseUser.email }
: null
}
subscription={authenticatedUser.subscription}
isAuthenticatedUserProfile
onOpenChangeEmailDialog={onOpenChangeEmailDialog}
onOpenEditProfileDialog={onOpenEditProfileDialog}
Expand Down
Loading

0 comments on commit 38651ed

Please sign in to comment.