Skip to content

Commit

Permalink
[WIP] Add field to enter the GitHub username in user profile
Browse files Browse the repository at this point in the history
  • Loading branch information
4ian committed Apr 23, 2024
1 parent 266f0f2 commit 516cecf
Show file tree
Hide file tree
Showing 12 changed files with 291 additions and 53 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ const GetStartedSection = ({
// Artificial delay to build up expectations.
recommendationsGettingDelayPromise.current = delay(2500);
await Promise.all([
onEditProfile({ survey }, preferences, { throwError: true }),
onEditProfile({ survey }, preferences),
recommendationsGettingDelayPromise.current,
]);
sendUserSurveyCompleted();
Expand Down
36 changes: 4 additions & 32 deletions newIDE/app/src/Profile/Achievement/UserAchievements.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
// @flow

import { Trans } from '@lingui/macro';
import React, { useState, useEffect, useCallback } from 'react';
import React from 'react';
import AlertMessage from '../../UI/AlertMessage';

import { Line } from '../../UI/Grid';
import { ResponsiveLineStackLayout } from '../../UI/Layout';
import Text from '../../UI/Text';
import {
getAchievements,
type Badge,
type Achievement,
} from '../../Utils/GDevelopServices/Badge';
Expand All @@ -19,6 +18,7 @@ import { useResponsiveWindowSize } from '../../UI/Responsive/ResponsiveWindowMea
import PlaceholderLoader from '../../UI/PlaceholderLoader';

type Props = {|
achievements: ?Array<Achievement>,
badges: ?Array<Badge>,
displayUnclaimedAchievements: boolean,
displayNotifications: boolean,
Expand All @@ -41,44 +41,16 @@ const styles = {
};

const UserAchievements = ({
achievements,
badges,
displayUnclaimedAchievements,
displayNotifications,
}: Props) => {
const [achievements, setAchievements] = useState<?Array<Achievement>>(null);
const [displayError, setDisplayError] = useState<boolean>(false);
const { isMobile } = useResponsiveWindowSize();

const fetchAchievements = useCallback(async () => {
try {
setDisplayError(false);
const achievements = await getAchievements();
setAchievements(achievements);
} catch (err) {
console.error(`Error when fetching achievements: ${err}`);
setDisplayError(true);
}
}, []);

useEffect(
() => {
fetchAchievements();
},
[fetchAchievements]
);

return (
<ResponsiveLineStackLayout>
{displayError ? (
<Line>
<AlertMessage kind="error">
<Trans>Unable to display your achievements for now.</Trans>{' '}
<Trans>
Please check your internet connection or try again later.
</Trans>
</AlertMessage>
</Line>
) : !!badges && !!achievements ? (
{!!badges && !!achievements ? (
<>
<div style={styles.leftContainer}>
<div
Expand Down
7 changes: 4 additions & 3 deletions newIDE/app/src/Profile/AuthenticatedUserContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { type PreferencesValues } from '../MainFrame/Preferences/PreferencesContext';
import { type CloudProjectWithUserAccessInfo } from '../Utils/GDevelopServices/Project';
import { User as FirebaseUser } from 'firebase/auth';
import { type Badge } from '../Utils/GDevelopServices/Badge';
import { type Badge, type Achievement } from '../Utils/GDevelopServices/Badge';
import { type Recommendation } from '../Utils/GDevelopServices/User';
import { type Notification } from '../Utils/GDevelopServices/Notification';
import {
Expand Down Expand Up @@ -57,8 +57,7 @@ export type AuthenticatedUser = {|
) => Promise<void>,
onEditProfile: (
payload: PatchUserPayload,
preferences: PreferencesValues,
options: {| throwError: boolean |}
preferences: PreferencesValues
) => Promise<void>,
onResetPassword: ForgotPasswordForm => Promise<void>,
onOpenLoginDialog: () => void,
Expand All @@ -82,6 +81,7 @@ export type AuthenticatedUser = {|
|}) => void,
onAcceptGameStatsEmail: (value: boolean) => Promise<void>,
getAuthorizationHeader: () => Promise<string>,
achievements: ?Array<Achievement>,
|};

export const initialAuthenticatedUser = {
Expand Down Expand Up @@ -129,6 +129,7 @@ export const initialAuthenticatedUser = {
onOpenEmailVerificationDialog: () => {},
onAcceptGameStatsEmail: async () => {},
getAuthorizationHeader: () => Promise.reject(new Error('Unimplemented')),
achievements: null,
};

export const authenticatedUserLoggedOutAttributes = {
Expand Down
54 changes: 45 additions & 9 deletions newIDE/app/src/Profile/AuthenticatedUserProvider.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ import {
listDefaultRecommendations,
listRecommendations,
} from '../Utils/GDevelopServices/User';
import {
type Achievement,
getAchievements,
} from '../Utils/GDevelopServices/Badge';
import Authentication, {
type LoginForm,
type RegisterForm,
Expand Down Expand Up @@ -840,6 +844,17 @@ export default class AuthenticatedUserProvider extends React.Component<
badges,
},
}));

// Load achievements only once, as they are the same across all users.
if (!this.state.authenticatedUser.achievements) {
const achievements = await getAchievements();
this.setState(({ authenticatedUser }) => ({
authenticatedUser: {
...authenticatedUser,
achievements,
},
}));
}
} catch (error) {
console.error('Error while loading user badges:', error);
}
Expand Down Expand Up @@ -991,8 +1006,7 @@ export default class AuthenticatedUserProvider extends React.Component<

_doEdit = async (
payload: PatchUserPayload,
preferences: PreferencesValues,
{ throwError }: {| throwError: boolean |}
preferences: PreferencesValues
) => {
const { authentication } = this.props;
if (!authentication) return;
Expand All @@ -1013,17 +1027,16 @@ export default class AuthenticatedUserProvider extends React.Component<
appLanguage: preferences.language,
donateLink: payload.donateLink,
discordUsername: payload.discordUsername,
githubUsername: payload.githubUsername,
communityLinks: payload.communityLinks,
survey: payload.survey,
}
);
await this._fetchUserProfileWithoutThrowingErrors();
this.openEditProfileDialog(false);
} catch (apiCallError) {
this.setState({ apiCallError });
if (throwError) {
throw apiCallError;
}

throw apiCallError;
} finally {
this.setState({
editInProgress: false,
Expand Down Expand Up @@ -1288,11 +1301,34 @@ export default class AuthenticatedUserProvider extends React.Component<
this.state.editProfileDialogOpen && (
<EditProfileDialog
profile={this.state.authenticatedUser.profile}
achievements={this.state.authenticatedUser.achievements}
badges={this.state.authenticatedUser.badges}
subscription={this.state.authenticatedUser.subscription}
onClose={() => this.openEditProfileDialog(false)}
onEdit={form =>
this._doEdit(form, preferences, { throwError: false })
}
onEdit={async form => {
try {
await this._doEdit(form, preferences);
this.openEditProfileDialog(false);
} catch (error) {
// Ignore errors, we will let the user retry in their profile.
}
}}
onUpdateGitHubStar={async githubUsername => {
const { authentication } = this.props;

await this._doEdit(
{
githubUsername,
},
preferences
);
const response = authentication.updateGitHubStar(
authentication.getAuthorizationHeader
);
this._fetchUserBadges();

return response;
}}
onDelete={this._doDeleteAccount}
actionInProgress={
this.state.editInProgress || this.state.deleteInProgress
Expand Down

0 comments on commit 516cecf

Please sign in to comment.