Skip to content

Commit

Permalink
Feat/ask-name (#152)
Browse files Browse the repository at this point in the history
* chore: added account header

* feat: Ensure username is set during initial user login

* feat: added hook useUserFullProfile

* feat: added info text to inputs

* chore: improved edit page

* feat: ask-name page lifting

* chore: improved headers

* refactor: mooving InputRules (old inputRestriction) to constant

* fix: new way to get participant id

* chore: added InDev page on page not implemented

* fix: handle closing room

* refactor: create component to rooms header
  • Loading branch information
GaspardBBY authored Apr 9, 2024
1 parent eeadb47 commit d607946
Show file tree
Hide file tree
Showing 26 changed files with 432 additions and 166 deletions.
37 changes: 35 additions & 2 deletions expo/app/(tabs)/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import { Redirect, Tabs } from "expo-router";
import { Redirect, Tabs, useRouter } from "expo-router";
import * as WebBrowser from "expo-web-browser";
import HouseLine from "phosphor-react-native/src/icons/HouseLine";
import MusicNote from "phosphor-react-native/src/icons/MusicNote";
import User from "phosphor-react-native/src/icons/User";
import Users from "phosphor-react-native/src/icons/Users";
import { useEffect, useState } from "react";

import { HomeTabHeader } from ".";
import ApplicationLoadingScreen from "../../components/ApplicationLoadingScreen";
import { Text } from "../../components/Tamed";
import { View } from "../../components/Themed";
import FriendHeader from "../../components/headers/FriendHeader";
import Colors from "../../constants/Colors";
import { supabase } from "../../lib/supabase";
import { useSupabaseUserHook } from "../../lib/useSupabaseUser";
import { useUserFullProfile } from "../../lib/userProfile";

WebBrowser.maybeCompleteAuthSession();

Expand All @@ -38,6 +40,37 @@ export default function TabLayout() {
WebBrowser.maybeCompleteAuthSession();

const user = useSupabaseUserHook();
const router = useRouter();

const profile = useUserFullProfile();

const [usernameIsFine, setUsernameIsFine] = useState(true);

useEffect(() => {
if (!profile) return;
setUsernameIsFine(!!profile?.username);
}, [profile]);

/**
* If the user is logged in, we check if the user has a username
* If the user not have a username, we re-fetch the user profile to check if he not comming from the ask-name page
*/
useEffect(() => {
if (!user) return;
if (usernameIsFine) return;

supabase
.from("user_profile")
.select("username")
.eq("account_id", user.id)
.single()
.then(({ data }) => {
if (data?.username) {
return setUsernameIsFine(true);
}
router.push("/ask-name/");
});
}, [usernameIsFine]);

if (user === undefined) return <ApplicationLoadingScreen />;

Expand Down
28 changes: 2 additions & 26 deletions expo/app/(tabs)/friends.tsx
Original file line number Diff line number Diff line change
@@ -1,31 +1,7 @@
import Hammer from "phosphor-react-native/src/icons/Hammer";
import React from "react";
import { View } from "react-native";

import { Text } from "../../components/Themed";
import InDeveloppement from "../../components/InDeveloppement";

export default function TabsFriends() {
return (
<View
style={{
flex: 1,
justifyContent: "center",
alignItems: "center",
flexDirection: "column",
padding: 32,
gap: 16,
}}
>
<Hammer size={32} weight="fill" color="black" />
<Text
style={{
fontSize: 16,
textAlign: "center",
fontFamily: "Outfit-Bold",
}}
>
Cette page est en cours de développement. Merci de revenir plus tard.
</Text>
</View>
);
return <InDeveloppement />;
}
30 changes: 29 additions & 1 deletion expo/app/(tabs)/profile/account/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,19 @@ import { Stack } from "expo-router";

import ErrorBoundary from "../../../../components/ErrorBoundary";
import ProfileErrorBoundary from "../../../../components/ErrorComponent/ProfileError";
import { AccountHeader } from "../../../../components/headers/AccountHeader";

export default function AccountLayout() {
return (
<ErrorBoundary fallback={<ProfileErrorBoundary />}>
<Stack>
<Stack.Screen name="index" options={{ title: "Gérer mon compte" }} />
<Stack.Screen
name="index"
options={{
title: "Gérer mon compte",
header: () => <AccountHeader />,
}}
/>
<Stack.Screen
name="edit"
options={{
Expand All @@ -22,6 +29,27 @@ export default function AccountLayout() {
title: "Lier ses comptes de streaming",
}}
/>
<Stack.Screen
name="security"
options={{
presentation: "modal",
title: "Securité de mon compte",
}}
/>
<Stack.Screen
name="notifications"
options={{
presentation: "modal",
title: "Paramètres de notification",
}}
/>
<Stack.Screen
name="help"
options={{
presentation: "modal",
title: "Assistance",
}}
/>
</Stack>
</ErrorBoundary>
);
Expand Down
91 changes: 82 additions & 9 deletions expo/app/(tabs)/profile/account/edit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,23 @@ import ErrorBoundary from "../../../../components/ErrorBoundary";
import { View } from "../../../../components/Themed";
import Warning from "../../../../components/Warning";
import AvatarForm from "../../../../components/profile/AvatarForm";
import {
displayNameRules,
emailRules,
usernameRules,
} from "../../../../constants/InputRules";
import {
AuthErrorMessage,
SupabaseErrorCode,
} from "../../../../constants/SupabaseErrorCode";
import { emailRules, usernameRules } from "../../../../lib/inputRestriction";
import { supabase } from "../../../../lib/supabase";
import { useSupabaseUserHook } from "../../../../lib/useSupabaseUser";
import { getUserProfile } from "../../../../lib/userProfile";
import { useUserFullProfile } from "../../../../lib/userProfile";

type EditForm = {
email: string;
username: string;
displayName: string;
};

export default function PersonalInfo() {
Expand All @@ -34,12 +39,17 @@ export default function PersonalInfo() {
const scrollViewRef = useRef<ScrollView>(null);

const [initialUsername, setInitialUsername] = useState<string | null>(null);
const [initialDisplayName, setInitialDisplayname] = useState<string | null>(
null
);
const [profilePictureChanged, setProfilePictureChanged] =
useState<boolean>(false);
const [submittable, setSubmittable] = useState<boolean>(false);
const [successMessage, setSuccessMessage] = useState<string | null>(null);
const [emailDisabled, setEmailDisabled] = useState<boolean>(false);

const profile = useUserFullProfile();

const {
control,
handleSubmit,
Expand All @@ -51,28 +61,43 @@ export default function PersonalInfo() {
defaultValues: {
email: "",
username: "",
displayName: "",
},
shouldFocusError: true,
});

const inputsChange = watch();

useEffect(() => {
if (user && user.email) {
if (user.app_metadata.provider !== "email") setEmailDisabled(true);
setValue("email", user.email);
getUserProfile(user.id).then((profile) => {
if (profile && profile.username) {
setValue("username", profile.username);
setInitialUsername(profile.username);
}
});
}
}, [user]);

useEffect(() => {
if (!profile) return;

if (!profile.profile || !profile.username) {
return setError("root", {
message: "Impossible de récupérer vos données",
});
}
const displayName: string = profile.profile.nickname;
setValue("displayName", displayName);
setInitialDisplayname(displayName);

const username: string = profile.username;
setValue("username", username);
setInitialUsername(username);
}, [profile]);

useEffect(() => {
if (inputsChange.email !== user?.email) return setSubmittable(true);
if (inputsChange.username !== initialUsername) return setSubmittable(true);
if (profilePictureChanged) return setSubmittable(true);
if (inputsChange.displayName !== initialDisplayName)
return setSubmittable(true);

setSubmittable(false);
}, [inputsChange]);
Expand Down Expand Up @@ -130,7 +155,40 @@ export default function PersonalInfo() {
return "Pseudo mis à jour";
};

const onSubmit = async ({ email, username }: EditForm) => {
/**
* Update display name
* @param displayName
* @returns string if success, undefined if error
*/
const updateDisplayName = async (
displayName: string
): Promise<string | undefined> => {
if (!profile || !profile.profile?.id) return;
const { error } = await supabase
.from("profile")
.update({
nickname: inputsChange.displayName,
})
.eq("id", profile.profile?.id);

if (error) {
setError("displayName", {
message: "Impossible de mettre à jour le nom d'affichage",
});
return;
}
setInitialDisplayname(displayName);
setValue("displayName", displayName);

return "Nom public";
};

/**
* Possible to upgrade with parallel requests
* @param inputs
* @returns
*/
const onSubmit = async ({ email, username, displayName }: EditForm) => {
const validationResum: string[] = [];

if (inputsChange.email !== user?.email) {
Expand All @@ -143,6 +201,11 @@ export default function PersonalInfo() {
if (res) validationResum.push(res);
}

if (inputsChange.displayName !== initialDisplayName) {
const res = await updateDisplayName(displayName);
if (res) validationResum.push(res);
}

if (profilePictureChanged) {
if (!avatarRef.current) return;
setProfilePictureChanged(false);
Expand Down Expand Up @@ -193,6 +256,15 @@ export default function PersonalInfo() {
placeholder="@nouveau_nom"
rules={usernameRules}
errorMessage={errors.username && errors.username.message}
info="Le nom d'utilisateur doit être unique"
/>
<ControlledInput
control={control}
label="Nom public"
name="displayName"
placeholder="maxouxax"
rules={displayNameRules}
errorMessage={errors.displayName && errors.displayName.message}
/>
<ErrorBoundary
fallback={
Expand Down Expand Up @@ -224,6 +296,7 @@ export default function PersonalInfo() {
size="small"
block
onPress={() => Alert.alert("Not implemented")}
disabled
>
Supprimer mon compte
</Button>
Expand Down
5 changes: 5 additions & 0 deletions expo/app/(tabs)/profile/account/help.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import InDeveloppement from "../../../../components/InDeveloppement";

export default function Help() {
return <InDeveloppement />;
}
7 changes: 4 additions & 3 deletions expo/app/(tabs)/profile/account/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ export default function Account() {
<SettingsOptions
icon={<Lock />}
title="Sécurité"
href="/account/security"
href="/(tabs)/profile/account/security"
/>
<Separator />
<SettingsOptions
icon={<BellRinging />}
title="Notifications"
href="/manage-account/notifications"
href="/(tabs)/profile/account/notifications"
/>
<Separator />
<SettingsOptions
Expand All @@ -40,7 +40,7 @@ export default function Account() {
<SettingsOptions
icon={<Lifebuoy />}
title="Assistance"
href="/manage-account/help"
href="/(tabs)/profile/account/help"
/>
<Separator />
<SettingsOptions
Expand All @@ -49,6 +49,7 @@ export default function Account() {
title="Se déconnecter"
color="red"
/>
<Separator />
</ScrollView>
);
}
5 changes: 5 additions & 0 deletions expo/app/(tabs)/profile/account/notifications.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import InDeveloppement from "../../../../components/InDeveloppement";

export default function Notifications() {
return <InDeveloppement />;
}
5 changes: 5 additions & 0 deletions expo/app/(tabs)/profile/account/security.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import InDeveloppement from "../../../../components/InDeveloppement";

export default function Security() {
return <InDeveloppement />;
}
10 changes: 9 additions & 1 deletion expo/app/(tabs)/rooms/[id]/_layout.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Stack, useLocalSearchParams } from "expo-router";
import { Stack, router, useLocalSearchParams } from "expo-router";
import {
ReactNode,
createContext,
Expand All @@ -8,6 +8,7 @@ import {
} from "react";
import { Socket } from "socket.io-client";

import Alert from "../../../../components/Alert";
import ErrorBoundary from "../../../../components/ErrorBoundary";
import RoomErrorBoundary from "../../../../components/ErrorComponent/RoomError";
import WebsocketError from "../../../../components/ErrorComponent/WebsocketError";
Expand Down Expand Up @@ -54,6 +55,13 @@ const WebSocketProvider = ({
setSocketError(null);
});

socketInstance.on("room:end", () => {
Alert.alert(
"Fermeture de la salle, redirection vers la liste des salles"
);
router.push("/rooms");
});

return () => {
socketInstance.disconnect();
};
Expand Down
Loading

0 comments on commit d607946

Please sign in to comment.