Skip to content
This repository was archived by the owner on Feb 21, 2025. It is now read-only.

Commit ea258f1

Browse files
committed
-
1 parent 979e536 commit ea258f1

32 files changed

+408
-335
lines changed

capacitor.config.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import type { CapacitorConfig } from '@capacitor/cli';
1+
import type { CapacitorConfig } from "@capacitor/cli";
22

33
const config: CapacitorConfig = {
4-
appId: 'io.ionic.starter',
5-
appName: 'game-node-mobile',
6-
webDir: 'dist'
4+
appId: "app.gamenode",
5+
appName: "GameNode",
6+
webDir: "dist",
77
};
88

99
export default config;

src/App.test.tsx

Lines changed: 0 additions & 8 deletions
This file was deleted.

src/App.tsx

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,16 @@ import React, { useState } from "react";
22

33
import { Redirect, Route } from "react-router-dom";
44
import * as reactRouterDom from "react-router-dom";
5-
import { IonApp, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs, setupIonicReact } from "@ionic/react";
5+
import {
6+
IonApp,
7+
IonLabel,
8+
IonPage,
9+
IonRouterOutlet,
10+
IonTabBar,
11+
IonTabButton,
12+
IonTabs,
13+
setupIonicReact,
14+
} from "@ionic/react";
615
import { IonReactRouter } from "@ionic/react-router";
716
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
817
import { MantineProvider } from "@mantine/core";
@@ -40,7 +49,7 @@ import "@ionic/react/css/palettes/dark.always.css";
4049

4150
/* Theme variables */
4251
import "./theme/variables.css";
43-
import { getSuperTokensRoutesForReactRouterDom } from "supertokens-auth-react/ui";
52+
import { AuthPage, getSuperTokensRoutesForReactRouterDom } from "supertokens-auth-react/ui";
4453
import { ThirdPartyPreBuiltUI } from "supertokens-auth-react/recipe/thirdparty/prebuiltui";
4554
import { PasswordlessPreBuiltUI } from "supertokens-auth-react/recipe/passwordless/prebuiltui";
4655
import SuperTokensProvider from "./components/auth/SuperTokensProvider";
@@ -49,9 +58,8 @@ import { OpenAPI as ServerOpenAPI } from "@/wrapper/server";
4958
import { OpenAPI as SearchOpenAPI } from "@/wrapper/search";
5059
import ExplorePage from "@/pages/explore";
5160
import SearchResultsPage from "@/pages/search_results";
52-
import GamePage from "@/pages/game";
5361
import HomePage from "./pages/home";
54-
import ProfilePage from "@/pages/profile";
62+
import ProfilePage from "@/pages/profile/profile";
5563
import { getCommonRoutes } from "./pages/routes/getCommonRoutes";
5664
import LibraryPage from "./pages/library";
5765
import NotificationsManager from "./components/general/NotificationsManager";
@@ -72,11 +80,6 @@ const App: React.FC = () => {
7280
defaultOptions: {
7381
queries: {
7482
refetchOnWindowFocus: false,
75-
refetchInterval: false,
76-
refetchOnMount: false,
77-
refetchIntervalInBackground: false,
78-
refetchOnReconnect: false,
79-
staleTime: Infinity,
8083
retry: 2,
8184
},
8285
},
@@ -92,11 +95,6 @@ const App: React.FC = () => {
9295
<IonReactRouter>
9396
<IonTabs>
9497
<IonRouterOutlet>
95-
{/*This renders the login UI on the /auth route*/}
96-
{getSuperTokensRoutesForReactRouterDom(reactRouterDom, [
97-
ThirdPartyPreBuiltUI,
98-
PasswordlessPreBuiltUI,
99-
])}
10098
{/* ---- HOME ROUTES ---- */}
10199
<Route exact path="/">
102100
<Redirect to="/home" />
@@ -135,14 +133,15 @@ const App: React.FC = () => {
135133
<IconRouteAltLeft aria-hidden={"true"} />
136134
<IonLabel>Explore</IonLabel>
137135
</IonTabButton>
138-
<IonTabButton tab="profile" href="/profile">
139-
<IconUser aria-hidden={"true"} />
140-
<IonLabel>Profile</IonLabel>
141-
</IonTabButton>
136+
142137
<IonTabButton tab="library" href="/library">
143138
<IconLibrary aria-hidden={"true"} />
144139
<IonLabel>Library</IonLabel>
145140
</IonTabButton>
141+
<IonTabButton tab="profile" href="/profile">
142+
<IconUser aria-hidden={"true"} />
143+
<IonLabel>Profile</IonLabel>
144+
</IonTabButton>
146145
</IonTabBar>
147146
</IonTabs>
148147
</IonReactRouter>

src/components/achievement/AchievementsScreen.tsx

Lines changed: 41 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,5 @@
11
import React, { useState } from "react";
2-
import {
3-
Box,
4-
Button,
5-
Center,
6-
Divider,
7-
Group,
8-
Pagination,
9-
Paper,
10-
Progress,
11-
SimpleGrid,
12-
Stack,
13-
} from "@mantine/core";
2+
import { Box, Button, Center, Divider, Group, Pagination, Paper, Progress, SimpleGrid, Stack } from "@mantine/core";
143
import { SessionAuth } from "supertokens-auth-react/recipe/session";
154
import useUserId from "@/components/auth/hooks/useUserId";
165
import { useAchievements } from "@/components/achievement/hooks/useAchievements";
@@ -33,62 +22,49 @@ const AchievementsScreen = ({ targetUserId }: Props) => {
3322
const isOwnUserId = userId != undefined && userId === targetUserId;
3423
if (!targetUserId) return null;
3524
return (
36-
<Paper className={"w-full h-full"}>
37-
<Stack w={"100%"} py={"3rem"} px={"2rem"}>
38-
<Group
39-
wrap={"nowrap"}
40-
className={"justify-center lg:justify-between lg:mx-4"}
41-
>
42-
<Box className={"w-5/12 lg:w-8/12"}>
43-
<UserAvatarWithLevelInfo userId={targetUserId} />
44-
</Box>
25+
<Stack w={"100%"} py={"3rem"} px={"2rem"}>
26+
<Group wrap={"wrap"} className={"justify-center"}>
27+
<Box className={"w-full"}>
28+
<UserAvatarWithLevelInfo userId={targetUserId} />
29+
</Box>
4530

46-
{isOwnUserId && (
47-
<Button className={""} disabled>
48-
Redeem a code
49-
</Button>
50-
)}
51-
</Group>
52-
53-
<Divider className={"w-full"} />
54-
{achievements.isError && (
55-
<Center className={"mt-10"}>
56-
Something happened while loading achievements. Please
57-
try again.
58-
</Center>
31+
{isOwnUserId && (
32+
<Button className={"mt-4"} disabled>
33+
Redeem a code
34+
</Button>
5935
)}
60-
{achievements.isLoading && <CenteredLoading />}
61-
<SimpleGrid
62-
cols={{
63-
base: 1,
64-
lg: 2,
36+
</Group>
37+
38+
<Divider className={"w-full"} />
39+
{achievements.isError && (
40+
<Center className={"mt-10"}>Something happened while loading achievements. Please try again.</Center>
41+
)}
42+
{achievements.isLoading && <CenteredLoading />}
43+
<SimpleGrid
44+
cols={{
45+
base: 1,
46+
lg: 2,
47+
}}
48+
>
49+
{achievements.data?.data?.map((achievement) => {
50+
return (
51+
<AchievementItem key={achievement.id} targetUserId={targetUserId} achievement={achievement} />
52+
);
53+
})}
54+
</SimpleGrid>
55+
<Center mt={"1rem"}>
56+
<Pagination
57+
total={achievements.data?.pagination?.totalPages || 1}
58+
onChange={(page) => {
59+
const pageAsOffset = paginationData.limit * (page - 1);
60+
setPaginationData({
61+
offset: pageAsOffset,
62+
limit: paginationData.limit,
63+
});
6564
}}
66-
>
67-
{achievements.data?.data?.map((achievement) => {
68-
return (
69-
<AchievementItem
70-
key={achievement.id}
71-
targetUserId={targetUserId}
72-
achievement={achievement}
73-
/>
74-
);
75-
})}
76-
</SimpleGrid>
77-
<Center mt={"1rem"}>
78-
<Pagination
79-
total={achievements.data?.pagination?.totalPages || 1}
80-
onChange={(page) => {
81-
const pageAsOffset =
82-
paginationData.limit * (page - 1);
83-
setPaginationData({
84-
offset: pageAsOffset,
85-
limit: paginationData.limit,
86-
});
87-
}}
88-
/>
89-
</Center>
90-
</Stack>
91-
</Paper>
65+
/>
66+
</Center>
67+
</Stack>
9268
);
9369
};
9470

src/components/activity/item/CollectionEntryActivityItem.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,11 @@ const CollectionEntryActivityItem = ({ activity }: Props) => {
8585
<Box className={"w-6/12 lg:w-3/12 ms-auto h-full"}>
8686
<Stack className={"w-full h-full items-end justify-between pe-2 lg:pe-3 py-4"}>
8787
<ActivityCreateDate createdAtDate={activity.createdAt} />
88-
<Link to={`/library/${activity.profileUserId}/collection/${activity.collectionId}`}>
88+
<Link
89+
to={getTabAwareHref(
90+
`/library/${activity.profileUserId}?collectionId=${activity.collectionId}`,
91+
)}
92+
>
8993
<Title size={"h3"} lineClamp={onMobile ? 1 : 2}>
9094
{collectionQuery.data?.name}
9195
</Title>

src/components/auth/SuperTokensProvider.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@ import Passwordless from "supertokens-auth-react/recipe/passwordless";
55
import ThirdParty from "supertokens-auth-react/recipe/thirdparty";
66
import { SuperTokensConfig } from "supertokens-auth-react/lib/build/types";
77
import { Capacitor } from "@capacitor/core";
8+
import { getTabAwareHref } from "@/util/getTabAwareHref";
89

910
export const frontendConfig = (): SuperTokensConfig => {
10-
const location = window.location;
11-
const websiteDomain = Capacitor.isNativePlatform()
12-
? `${location.protocol}//${location.host}`
11+
const PARSED_WEBSITE_DOMAIN = Capacitor.isNativePlatform()
12+
? `${window.location.protocol}//${window.location.host}`
1313
: import.meta.env.VITE_PUBLIC_DOMAIN_WEBSITE;
1414

1515
return {
1616
appInfo: {
1717
appName: "GameNode",
1818
apiDomain: import.meta.env.VITE_PUBLIC_DOMAIN_SERVER as string,
19-
websiteDomain: websiteDomain,
19+
websiteDomain: PARSED_WEBSITE_DOMAIN,
2020
apiBasePath: "/v1/auth",
21-
websiteBasePath: "/auth",
21+
websiteBasePath: "/profile/auth",
2222
},
2323
getRedirectionURL: async (context) => {
2424
if (context.action === "SUCCESS" && context.newSessionCreated) {
@@ -33,6 +33,8 @@ export const frontendConfig = (): SuperTokensConfig => {
3333
// user signed in
3434
}
3535
return "/";
36+
} else if (context.action === "TO_AUTH") {
37+
return getTabAwareHref("/auth");
3638
}
3739
return undefined;
3840
},

src/components/collection/collection-entry/form/modal/CollectionEntryAddOrUpdateModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ interface IGameAddModalProps extends BaseModalProps {
1313

1414
const CollectionEntryAddOrUpdateModal = ({ opened, onClose, id }: IGameAddModalProps) => {
1515
const userId = useUserId();
16-
const collectionEntryQuery = useOwnCollectionEntryForGameId(id);
16+
const collectionEntryQuery = useOwnCollectionEntryForGameId(id, opened);
1717
const [isExpanded, setIsExpanded] = useState(false);
1818

1919
const isInLibrary = collectionEntryQuery.data != undefined;

src/components/collection/collection-entry/hooks/useOwnCollectionEntryForGameId.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,29 @@ import { ExtendedUseQueryResult } from "@/util/types/ExtendedUseQueryResult";
77
* Returns a collection entry for the current user based on a game ID.
88
* The collection entry will be undefined if the user doesn't have the game in their library.
99
* @param gameId
10+
* @param enabled
1011
*/
1112
export function useOwnCollectionEntryForGameId(
1213
gameId: number | undefined,
14+
enabled = true,
1315
): ExtendedUseQueryResult<CollectionEntry | undefined> {
1416
const queryClient = useQueryClient();
1517
const queryKey = ["collection-entries", "own", gameId];
16-
const invalidate = () =>
17-
queryClient.invalidateQueries({ queryKey: queryKey.slice(0, 2) });
18+
const invalidate = () => queryClient.invalidateQueries({ queryKey: queryKey.slice(0, 2) });
1819
return {
1920
...useQuery({
2021
queryKey,
2122
queryFn: async () => {
2223
if (!gameId) return null;
2324
try {
24-
const collectionEntry =
25-
await getOwnCollectionEntryByGameId(gameId);
25+
const collectionEntry = await getOwnCollectionEntryByGameId(gameId);
2626
if (!collectionEntry) return null;
2727
return collectionEntry;
2828
} catch (e) {
2929
return null;
3030
}
3131
},
32-
enabled: gameId != undefined,
32+
enabled: enabled && gameId != undefined,
3333
}),
3434
queryKey,
3535
invalidate,
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import React from "react";
22
import { Group, GroupProps } from "@mantine/core";
33
import { UserAvatarGroup } from "@/components/general/avatar/UserAvatarGroup";
4-
import ProfileFollowActions from "@/components/profile/view/ProfileFollowActions";
54
import UserFollowActions from "@/components/follow/input/UserFollowActions";
65

76
interface Props extends GroupProps {
87
userId: string;
98
}
109

11-
const UserFollowGroup = ({ userId, ...groupProps }: Props) => {
10+
const UserAvatarWithFollowActions = ({ userId, ...groupProps }: Props) => {
1211
return (
1312
<Group className={"w-full justify-between flex-nowrap"} {...groupProps}>
1413
<UserAvatarGroup
@@ -17,12 +16,9 @@ const UserFollowGroup = ({ userId, ...groupProps }: Props) => {
1716
wrap: "nowrap",
1817
}}
1918
/>
20-
<UserFollowActions
21-
targetUserId={userId}
22-
withUnfollowButton={false}
23-
/>
19+
<UserFollowActions targetUserId={userId} withUnfollowButton={false} />
2420
</Group>
2521
);
2622
};
2723

28-
export default UserFollowGroup;
24+
export default UserAvatarWithFollowActions;

src/components/follow/input/UserFollowActions.tsx

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,22 @@ import { useInfiniteFollowInfo } from "@/components/follow/hooks/useInfiniteFoll
77
import criteria = FollowInfoRequestDto.criteria;
88
import { ActionIcon, Button, Group, Tooltip } from "@mantine/core";
99
import { IconX } from "@tabler/icons-react";
10+
import { redirectToAuth } from "supertokens-auth-react";
1011

1112
interface Props {
1213
targetUserId: string;
1314
withUnfollowButton?: boolean;
1415
}
1516

16-
const UserFollowActions = ({
17-
targetUserId,
18-
withUnfollowButton = true,
19-
}: Props) => {
17+
const UserFollowActions = ({ targetUserId, withUnfollowButton = true }: Props) => {
2018
const ownUserId = useUserId();
2119
/*
2220
Checks if current logged-in user is following target user
2321
*/
2422
const ownToTargetFollowStatus = useFollowStatus(ownUserId, targetUserId);
2523
const isFollowing = ownToTargetFollowStatus.data?.isFollowing ?? false;
2624

27-
const shouldShowFollowButton =
28-
ownUserId != undefined && ownUserId !== targetUserId;
25+
const shouldEnableFollowButton = ownUserId != undefined && ownUserId !== targetUserId && !isFollowing;
2926

3027
const followMutation = useMutation({
3128
mutationFn: async (action: "register" | "remove") => {
@@ -53,9 +50,13 @@ const UserFollowActions = ({
5350
return (
5451
<Group className={"flex-nowrap w-fit"}>
5552
<Button
56-
disabled={isFollowing}
53+
disabled={!shouldEnableFollowButton}
5754
loading={followMutation.isPending}
5855
onClick={() => {
56+
if (ownUserId == undefined) {
57+
redirectToAuth();
58+
return;
59+
}
5960
followMutation.mutate("register");
6061
}}
6162
>

0 commit comments

Comments
 (0)