From b54032fe63ce95dde3f273ead0c78c5cbb4c7fec Mon Sep 17 00:00:00 2001 From: danis Date: Thu, 30 Nov 2023 10:51:18 +0100 Subject: [PATCH 1/6] feat(leaderboard): wip --- back/src/app.module.ts | 2 + back/src/models/user.ts | 2 + back/src/scores/scores.controller.ts | 3 +- back/src/scores/scores.service.ts | 2 +- front/models/User.ts | 3 + front/views/LeaderboardView.tsx | 126 +++++++++++++++------------ 6 files changed, 80 insertions(+), 58 deletions(-) diff --git a/back/src/app.module.ts b/back/src/app.module.ts index 68493ec..1e633bb 100644 --- a/back/src/app.module.ts +++ b/back/src/app.module.ts @@ -15,6 +15,7 @@ import { AlbumModule } from './album/album.module'; import { SearchModule } from './search/search.module'; import { HistoryModule } from './history/history.module'; import { MailerModule } from '@nestjs-modules/mailer'; +import { ScoresModule } from './scores/scores.module'; @Module({ imports: [ @@ -29,6 +30,7 @@ import { MailerModule } from '@nestjs-modules/mailer'; SearchModule, SettingsModule, HistoryModule, + ScoresModule, MailerModule.forRoot({ transport: process.env.SMTP_TRANSPORT, defaults: { diff --git a/back/src/models/user.ts b/back/src/models/user.ts index e64d3c6..ff7bbe6 100644 --- a/back/src/models/user.ts +++ b/back/src/models/user.ts @@ -11,4 +11,6 @@ export class User { isGuest: boolean; @ApiProperty() partyPlayed: number; + @ApiProperty() + totalScore: number; } diff --git a/back/src/scores/scores.controller.ts b/back/src/scores/scores.controller.ts index 7065958..a833e11 100644 --- a/back/src/scores/scores.controller.ts +++ b/back/src/scores/scores.controller.ts @@ -11,9 +11,8 @@ import { User } from '@prisma/client'; export class ScoresController { constructor(private readonly scoresService: ScoresService) {} - @ApiOkResponse({ description: 'Successfully sent the Top 20 players'}) - @Get('scores/top/20') + @Get('top/20') getTopTwenty(): Promise { return this.scoresService.topTwenty(); } diff --git a/back/src/scores/scores.service.ts b/back/src/scores/scores.service.ts index f2b78f3..c48f229 100644 --- a/back/src/scores/scores.service.ts +++ b/back/src/scores/scores.service.ts @@ -11,7 +11,7 @@ export class ScoresService { async topTwenty(): Promise { return this.prisma.user.findMany({ orderBy: { - partyPlayed: 'desc', + totalScore: 'desc', }, take: 20, }); diff --git a/front/models/User.ts b/front/models/User.ts index 6a66759..6e9db3d 100644 --- a/front/models/User.ts +++ b/front/models/User.ts @@ -18,6 +18,7 @@ export const UserValidator = yup googleID: yup.string().required().nullable(), isGuest: yup.boolean().required(), partyPlayed: yup.number().required(), + totalScore: yup.number().required().nullable(), }) .concat(ModelValidator); @@ -30,6 +31,7 @@ export const UserHandler: ResponseHandler, U premium: false, data: { gamesPlayed: value.partyPlayed as number, + totalScore: value.totalScore as number, xp: 0, createdAt: new Date('2023-04-09T00:00:00.000Z'), avatar: `${API.baseUrl}/users/${value.id}/picture`, @@ -51,6 +53,7 @@ interface User extends Model { interface UserData { gamesPlayed: number; xp: number; + totalScore: number; avatar: string; createdAt: Date; } diff --git a/front/views/LeaderboardView.tsx b/front/views/LeaderboardView.tsx index 0eafcc9..f5167d9 100644 --- a/front/views/LeaderboardView.tsx +++ b/front/views/LeaderboardView.tsx @@ -1,16 +1,21 @@ import { Box, Heading, useBreakpointValue, ScrollView, Text } from 'native-base'; import { View, Image } from 'react-native'; -import { useQuery } from 'react-query'; -import User from '../models/User'; +import { useQuery } from '../Queries'; import API from '../API'; import { Ionicons } from '@expo/vector-icons'; +import { LoadingView } from '../components/Loading'; +import { useNavigation } from '../Navigation'; +import { MedalStar } from 'iconsax-react-native'; type PodiumCardProps = { offset: number; medalColor: string; + userAvatarUrl: string; + userPseudo: string; + userLvl: number; }; -const PodiumCardComponent = ({ offset, medalColor }: PodiumCardProps) => { +const PodiumCardComponent = ({ offset, medalColor, userAvatarUrl, userPseudo, userLvl }: PodiumCardProps) => { return ( { > { borderRadius: 12, }} /> - @@ -55,7 +60,7 @@ const PodiumCardComponent = ({ offset, medalColor }: PodiumCardProps) => { fontWeight: '500', }} > - Momo + {userPseudo} { fontWeight: '500', }} > - 2400 LVL + {userLvl} LVL ); }; -const BoardRowComponent = () => { +type BoardRowProps = { + userAvatarUrl: string; + userPseudo: string; + userLvl: number; + index: number +} + +const BoardRowComponent = ({userAvatarUrl, userPseudo, userLvl, index}: BoardRowProps) => { return ( { > @@ -112,7 +125,7 @@ const BoardRowComponent = () => { fontWeight: '500', }} > - Momo est boutain + {userPseudo} { marginHorizontal: 10, }} > - 200 LVL + { userLvl } LVL { textAlign: 'center', }} > - 8 + { index + 4 } ); }; -const dummyScores = [ - { - id: 1, - }, - { - id: 2, - }, - { - id: 3, - }, - { - id: 4, - }, - { - id: 5, - }, - { - id: 6, - }, - { - id: 7, - }, - { - id: 8, - }, - { - id: 9, - }, -]; - const Leaderboardiew = () => { - // const scoresQuery = useQuery(API.getTopTwentyPlayers()) + const navigation = useNavigation(); + const scoresQuery = useQuery(API.getTopTwentyPlayers()); + + if (scoresQuery.isError) { + navigation.navigate('Error'); + return <>; + } + if (scoresQuery.data === undefined) { + return ; + } + return ( { - - - + + + - {dummyScores.map((comp, index) => ( - + {scoresQuery.data.slice(3).map((comp: any, index: number) => ( + ))} From 7e1f03af5769158ffdb590ae2d7b195b2307337b Mon Sep 17 00:00:00 2001 From: danis Date: Thu, 30 Nov 2023 11:49:39 +0100 Subject: [PATCH 2/6] feat(leaderboard): pretty --- front/views/LeaderboardView.tsx | 162 +++++++++++++++++++++++--------- 1 file changed, 118 insertions(+), 44 deletions(-) diff --git a/front/views/LeaderboardView.tsx b/front/views/LeaderboardView.tsx index f5167d9..b56104e 100644 --- a/front/views/LeaderboardView.tsx +++ b/front/views/LeaderboardView.tsx @@ -15,12 +15,18 @@ type PodiumCardProps = { userLvl: number; }; -const PodiumCardComponent = ({ offset, medalColor, userAvatarUrl, userPseudo, userLvl }: PodiumCardProps) => { +const PodiumCardComponent = ({ + offset, + medalColor, + userAvatarUrl, + userPseudo, + userLvl, +}: PodiumCardProps) => { return ( { +const BoardRowComponent = ({ userAvatarUrl, userPseudo, userLvl, index }: BoardRowProps) => { return ( @@ -135,7 +146,7 @@ const BoardRowComponent = ({userAvatarUrl, userPseudo, userLvl, index}: BoardRow marginHorizontal: 10, }} > - { userLvl } LVL + {userLvl} LVL - { index + 4 } + {index + 4} @@ -167,6 +178,8 @@ const BoardRowComponent = ({userAvatarUrl, userPseudo, userLvl, index}: BoardRow const Leaderboardiew = () => { const navigation = useNavigation(); const scoresQuery = useQuery(API.getTopTwentyPlayers()); + const screenSize = useBreakpointValue({ base: 'small', md: 'big' }); + const isPhone = screenSize === 'small'; if (scoresQuery.isError) { navigation.navigate('Error'); @@ -190,46 +203,107 @@ const Leaderboardiew = () => { alignSelf: 'stretch', }} > - - - - - + {!isPhone ? ( + + + + + + ) : ( + + + + + + + + )} {scoresQuery.data.slice(3).map((comp: any, index: number) => ( + userPseudo={comp?.name ?? '---'} + /> ))} From df682327d6cfb19be062511a245ead47faed4c99 Mon Sep 17 00:00:00 2001 From: danis Date: Thu, 30 Nov 2023 13:34:20 +0100 Subject: [PATCH 3/6] feat(leaderboard): i might be dumb --- front/components/UI/ScaffoldCC.tsx | 2 +- front/views/HomeView.tsx | 2 +- front/views/LeaderboardView.tsx | 218 +++++++++++++++-------------- 3 files changed, 114 insertions(+), 108 deletions(-) diff --git a/front/components/UI/ScaffoldCC.tsx b/front/components/UI/ScaffoldCC.tsx index c761200..c6070a0 100644 --- a/front/components/UI/ScaffoldCC.tsx +++ b/front/components/UI/ScaffoldCC.tsx @@ -13,7 +13,7 @@ const menu = [ { type: 'main', title: 'menuProfile', icon: User, link: 'User' }, { type: 'main', title: 'menuMusic', icon: Music, link: 'Music' }, { type: 'main', title: 'menuSearch', icon: SearchNormal1, link: 'Search' }, - { type: 'main', title: 'menuLeaderBoard', icon: Cup, link: 'Score' }, + { type: 'main', title: 'menuLeaderBoard', icon: Cup, link: 'Leaderboard' }, { type: 'sub', title: 'menuSettings', icon: Setting2, link: 'Settings' }, ] as const; diff --git a/front/views/HomeView.tsx b/front/views/HomeView.tsx index 1023bd1..b057acd 100644 --- a/front/views/HomeView.tsx +++ b/front/views/HomeView.tsx @@ -122,7 +122,7 @@ const HomeView = (props: RouteProps<{}>) => { translate={{ translationKey: 'leaderboardTitle' }} colorScheme="primary" size="sm" - onPress={() => navigation.navigate('Leaderboard')} + onPress={() => navigation.navigate('Leaderboard', {})} /> { +const Leaderboardiew = (props: RouteProps<{}>) => { const navigation = useNavigation(); const scoresQuery = useQuery(API.getTopTwentyPlayers()); const screenSize = useBreakpointValue({ base: 'small', md: 'big' }); @@ -186,107 +186,43 @@ const Leaderboardiew = () => { return <>; } if (scoresQuery.data === undefined) { - return ; + return ( + + + + ); } return ( - - - {!isPhone ? ( - - - - - - ) : ( - - - + + + {!isPhone ? ( + - { userPseudo={scoresQuery.data?.at(2)?.name ?? '---'} userLvl={scoresQuery.data?.at(2)?.data.totalScore ?? 42} /> + + - - )} - {scoresQuery.data.slice(3).map((comp: any, index: number) => ( - - ))} - - + ) : ( + + + + + + + + )} + {scoresQuery.data.slice(3).map((comp: any, index: number) => ( + + ))} + + + ); }; From 347c075ab121b4dc5f13880fff2bea6199fa855e Mon Sep 17 00:00:00 2001 From: danis Date: Fri, 1 Dec 2023 14:05:02 +0100 Subject: [PATCH 4/6] fix(leaderboard): misuse of nullable() for totalScore User validator --- front/models/User.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/front/models/User.ts b/front/models/User.ts index 6e9db3d..929a265 100644 --- a/front/models/User.ts +++ b/front/models/User.ts @@ -18,7 +18,7 @@ export const UserValidator = yup googleID: yup.string().required().nullable(), isGuest: yup.boolean().required(), partyPlayed: yup.number().required(), - totalScore: yup.number().required().nullable(), + totalScore: yup.number().required(), }) .concat(ModelValidator); From 0e26dbfc65c31c3a0d30944617ff96a2d4d4a201 Mon Sep 17 00:00:00 2001 From: danis Date: Fri, 1 Dec 2023 14:14:52 +0100 Subject: [PATCH 5/6] fix(leaderboard): type check + headerShown set to false --- front/Navigation.tsx | 2 +- front/views/LeaderboardView.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/front/Navigation.tsx b/front/Navigation.tsx index 0dd9b72..7649446 100644 --- a/front/Navigation.tsx +++ b/front/Navigation.tsx @@ -90,7 +90,7 @@ const protectedRoutes = () => }, Leaderboard: { component: Leaderboardiew, - options: { title: translate('leaderboardTitle') }, + options: { title: translate('leaderboardTitle'), headerShown: false }, link: '/leaderboard', }, Error: { diff --git a/front/views/LeaderboardView.tsx b/front/views/LeaderboardView.tsx index e5c4d8a..e7a54e7 100644 --- a/front/views/LeaderboardView.tsx +++ b/front/views/LeaderboardView.tsx @@ -131,7 +131,7 @@ const BoardRowComponent = ({ userAvatarUrl, userPseudo, userLvl, index }: BoardR style={{ fontSize: 16, fontStyle: 'normal', - flex: '1 1 0', + flex: 1, marginHorizontal: 10, fontWeight: '500', }} From 8b465731f043e64344b84b423812c25c59f38861 Mon Sep 17 00:00:00 2001 From: danis Date: Fri, 1 Dec 2023 14:28:21 +0100 Subject: [PATCH 6/6] fix(leaderboard): lint removal + rows userAvatar wrong property induced by previous type any --- front/views/LeaderboardView.tsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/front/views/LeaderboardView.tsx b/front/views/LeaderboardView.tsx index e7a54e7..dd64bfa 100644 --- a/front/views/LeaderboardView.tsx +++ b/front/views/LeaderboardView.tsx @@ -6,6 +6,7 @@ import { LoadingView } from '../components/Loading'; import { useNavigation, RouteProps } from '../Navigation'; import { MedalStar } from 'iconsax-react-native'; import ScaffoldCC from '../components/UI/ScaffoldCC'; +import User from '../models/User'; type PodiumCardProps = { offset: number; @@ -175,7 +176,7 @@ const BoardRowComponent = ({ userAvatarUrl, userPseudo, userLvl, index }: BoardR ); }; -const Leaderboardiew = (props: RouteProps<{}>) => { +const Leaderboardiew = (props: RouteProps>) => { const navigation = useNavigation(); const scoresQuery = useQuery(API.getTopTwentyPlayers()); const screenSize = useBreakpointValue({ base: 'small', md: 'big' }); @@ -302,10 +303,11 @@ const Leaderboardiew = (props: RouteProps<{}>) => { )} - {scoresQuery.data.slice(3).map((comp: any, index: number) => ( + {scoresQuery.data.slice(3).map((comp: User, index: number) => (