Skip to content

Commit

Permalink
-
Browse files Browse the repository at this point in the history
  • Loading branch information
Lamarcke committed Aug 12, 2024
1 parent 979e536 commit ea258f1
Show file tree
Hide file tree
Showing 32 changed files with 408 additions and 335 deletions.
8 changes: 4 additions & 4 deletions capacitor.config.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import type { CapacitorConfig } from '@capacitor/cli';
import type { CapacitorConfig } from "@capacitor/cli";

const config: CapacitorConfig = {
appId: 'io.ionic.starter',
appName: 'game-node-mobile',
webDir: 'dist'
appId: "app.gamenode",
appName: "GameNode",
webDir: "dist",
};

export default config;
8 changes: 0 additions & 8 deletions src/App.test.tsx

This file was deleted.

35 changes: 17 additions & 18 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ import React, { useState } from "react";

import { Redirect, Route } from "react-router-dom";
import * as reactRouterDom from "react-router-dom";
import { IonApp, IonLabel, IonRouterOutlet, IonTabBar, IonTabButton, IonTabs, setupIonicReact } from "@ionic/react";
import {
IonApp,
IonLabel,
IonPage,
IonRouterOutlet,
IonTabBar,
IonTabButton,
IonTabs,
setupIonicReact,
} from "@ionic/react";
import { IonReactRouter } from "@ionic/react-router";
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
import { MantineProvider } from "@mantine/core";
Expand Down Expand Up @@ -40,7 +49,7 @@ import "@ionic/react/css/palettes/dark.always.css";

/* Theme variables */
import "./theme/variables.css";
import { getSuperTokensRoutesForReactRouterDom } from "supertokens-auth-react/ui";
import { AuthPage, getSuperTokensRoutesForReactRouterDom } from "supertokens-auth-react/ui";
import { ThirdPartyPreBuiltUI } from "supertokens-auth-react/recipe/thirdparty/prebuiltui";
import { PasswordlessPreBuiltUI } from "supertokens-auth-react/recipe/passwordless/prebuiltui";
import SuperTokensProvider from "./components/auth/SuperTokensProvider";
Expand All @@ -49,9 +58,8 @@ import { OpenAPI as ServerOpenAPI } from "@/wrapper/server";
import { OpenAPI as SearchOpenAPI } from "@/wrapper/search";
import ExplorePage from "@/pages/explore";
import SearchResultsPage from "@/pages/search_results";
import GamePage from "@/pages/game";
import HomePage from "./pages/home";
import ProfilePage from "@/pages/profile";
import ProfilePage from "@/pages/profile/profile";
import { getCommonRoutes } from "./pages/routes/getCommonRoutes";
import LibraryPage from "./pages/library";
import NotificationsManager from "./components/general/NotificationsManager";
Expand All @@ -72,11 +80,6 @@ const App: React.FC = () => {
defaultOptions: {
queries: {
refetchOnWindowFocus: false,
refetchInterval: false,
refetchOnMount: false,
refetchIntervalInBackground: false,
refetchOnReconnect: false,
staleTime: Infinity,
retry: 2,
},
},
Expand All @@ -92,11 +95,6 @@ const App: React.FC = () => {
<IonReactRouter>
<IonTabs>
<IonRouterOutlet>
{/*This renders the login UI on the /auth route*/}
{getSuperTokensRoutesForReactRouterDom(reactRouterDom, [
ThirdPartyPreBuiltUI,
PasswordlessPreBuiltUI,
])}
{/* ---- HOME ROUTES ---- */}
<Route exact path="/">
<Redirect to="/home" />
Expand Down Expand Up @@ -135,14 +133,15 @@ const App: React.FC = () => {
<IconRouteAltLeft aria-hidden={"true"} />
<IonLabel>Explore</IonLabel>
</IonTabButton>
<IonTabButton tab="profile" href="/profile">
<IconUser aria-hidden={"true"} />
<IonLabel>Profile</IonLabel>
</IonTabButton>

<IonTabButton tab="library" href="/library">
<IconLibrary aria-hidden={"true"} />
<IonLabel>Library</IonLabel>
</IonTabButton>
<IonTabButton tab="profile" href="/profile">
<IconUser aria-hidden={"true"} />
<IonLabel>Profile</IonLabel>
</IonTabButton>
</IonTabBar>
</IonTabs>
</IonReactRouter>
Expand Down
106 changes: 41 additions & 65 deletions src/components/achievement/AchievementsScreen.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,5 @@
import React, { useState } from "react";
import {
Box,
Button,
Center,
Divider,
Group,
Pagination,
Paper,
Progress,
SimpleGrid,
Stack,
} from "@mantine/core";
import { Box, Button, Center, Divider, Group, Pagination, Paper, Progress, SimpleGrid, Stack } from "@mantine/core";
import { SessionAuth } from "supertokens-auth-react/recipe/session";
import useUserId from "@/components/auth/hooks/useUserId";
import { useAchievements } from "@/components/achievement/hooks/useAchievements";
Expand All @@ -33,62 +22,49 @@ const AchievementsScreen = ({ targetUserId }: Props) => {
const isOwnUserId = userId != undefined && userId === targetUserId;
if (!targetUserId) return null;
return (
<Paper className={"w-full h-full"}>
<Stack w={"100%"} py={"3rem"} px={"2rem"}>
<Group
wrap={"nowrap"}
className={"justify-center lg:justify-between lg:mx-4"}
>
<Box className={"w-5/12 lg:w-8/12"}>
<UserAvatarWithLevelInfo userId={targetUserId} />
</Box>
<Stack w={"100%"} py={"3rem"} px={"2rem"}>
<Group wrap={"wrap"} className={"justify-center"}>
<Box className={"w-full"}>
<UserAvatarWithLevelInfo userId={targetUserId} />
</Box>

{isOwnUserId && (
<Button className={""} disabled>
Redeem a code
</Button>
)}
</Group>

<Divider className={"w-full"} />
{achievements.isError && (
<Center className={"mt-10"}>
Something happened while loading achievements. Please
try again.
</Center>
{isOwnUserId && (
<Button className={"mt-4"} disabled>
Redeem a code
</Button>
)}
{achievements.isLoading && <CenteredLoading />}
<SimpleGrid
cols={{
base: 1,
lg: 2,
</Group>

<Divider className={"w-full"} />
{achievements.isError && (
<Center className={"mt-10"}>Something happened while loading achievements. Please try again.</Center>
)}
{achievements.isLoading && <CenteredLoading />}
<SimpleGrid
cols={{
base: 1,
lg: 2,
}}
>
{achievements.data?.data?.map((achievement) => {
return (
<AchievementItem key={achievement.id} targetUserId={targetUserId} achievement={achievement} />
);
})}
</SimpleGrid>
<Center mt={"1rem"}>
<Pagination
total={achievements.data?.pagination?.totalPages || 1}
onChange={(page) => {
const pageAsOffset = paginationData.limit * (page - 1);
setPaginationData({
offset: pageAsOffset,
limit: paginationData.limit,
});
}}
>
{achievements.data?.data?.map((achievement) => {
return (
<AchievementItem
key={achievement.id}
targetUserId={targetUserId}
achievement={achievement}
/>
);
})}
</SimpleGrid>
<Center mt={"1rem"}>
<Pagination
total={achievements.data?.pagination?.totalPages || 1}
onChange={(page) => {
const pageAsOffset =
paginationData.limit * (page - 1);
setPaginationData({
offset: pageAsOffset,
limit: paginationData.limit,
});
}}
/>
</Center>
</Stack>
</Paper>
/>
</Center>
</Stack>
);
};

Expand Down
6 changes: 5 additions & 1 deletion src/components/activity/item/CollectionEntryActivityItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,11 @@ const CollectionEntryActivityItem = ({ activity }: Props) => {
<Box className={"w-6/12 lg:w-3/12 ms-auto h-full"}>
<Stack className={"w-full h-full items-end justify-between pe-2 lg:pe-3 py-4"}>
<ActivityCreateDate createdAtDate={activity.createdAt} />
<Link to={`/library/${activity.profileUserId}/collection/${activity.collectionId}`}>
<Link
to={getTabAwareHref(
`/library/${activity.profileUserId}?collectionId=${activity.collectionId}`,
)}
>
<Title size={"h3"} lineClamp={onMobile ? 1 : 2}>
{collectionQuery.data?.name}
</Title>
Expand Down
12 changes: 7 additions & 5 deletions src/components/auth/SuperTokensProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import Passwordless from "supertokens-auth-react/recipe/passwordless";
import ThirdParty from "supertokens-auth-react/recipe/thirdparty";
import { SuperTokensConfig } from "supertokens-auth-react/lib/build/types";
import { Capacitor } from "@capacitor/core";
import { getTabAwareHref } from "@/util/getTabAwareHref";

export const frontendConfig = (): SuperTokensConfig => {
const location = window.location;
const websiteDomain = Capacitor.isNativePlatform()
? `${location.protocol}//${location.host}`
const PARSED_WEBSITE_DOMAIN = Capacitor.isNativePlatform()
? `${window.location.protocol}//${window.location.host}`
: import.meta.env.VITE_PUBLIC_DOMAIN_WEBSITE;

return {
appInfo: {
appName: "GameNode",
apiDomain: import.meta.env.VITE_PUBLIC_DOMAIN_SERVER as string,
websiteDomain: websiteDomain,
websiteDomain: PARSED_WEBSITE_DOMAIN,
apiBasePath: "/v1/auth",
websiteBasePath: "/auth",
websiteBasePath: "/profile/auth",
},
getRedirectionURL: async (context) => {
if (context.action === "SUCCESS" && context.newSessionCreated) {
Expand All @@ -33,6 +33,8 @@ export const frontendConfig = (): SuperTokensConfig => {
// user signed in
}
return "/";
} else if (context.action === "TO_AUTH") {
return getTabAwareHref("/auth");
}
return undefined;
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ interface IGameAddModalProps extends BaseModalProps {

const CollectionEntryAddOrUpdateModal = ({ opened, onClose, id }: IGameAddModalProps) => {
const userId = useUserId();
const collectionEntryQuery = useOwnCollectionEntryForGameId(id);
const collectionEntryQuery = useOwnCollectionEntryForGameId(id, opened);
const [isExpanded, setIsExpanded] = useState(false);

const isInLibrary = collectionEntryQuery.data != undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,29 +7,29 @@ import { ExtendedUseQueryResult } from "@/util/types/ExtendedUseQueryResult";
* Returns a collection entry for the current user based on a game ID.
* The collection entry will be undefined if the user doesn't have the game in their library.
* @param gameId
* @param enabled
*/
export function useOwnCollectionEntryForGameId(
gameId: number | undefined,
enabled = true,
): ExtendedUseQueryResult<CollectionEntry | undefined> {
const queryClient = useQueryClient();
const queryKey = ["collection-entries", "own", gameId];
const invalidate = () =>
queryClient.invalidateQueries({ queryKey: queryKey.slice(0, 2) });
const invalidate = () => queryClient.invalidateQueries({ queryKey: queryKey.slice(0, 2) });
return {
...useQuery({
queryKey,
queryFn: async () => {
if (!gameId) return null;
try {
const collectionEntry =
await getOwnCollectionEntryByGameId(gameId);
const collectionEntry = await getOwnCollectionEntryByGameId(gameId);
if (!collectionEntry) return null;
return collectionEntry;
} catch (e) {
return null;
}
},
enabled: gameId != undefined,
enabled: enabled && gameId != undefined,
}),
queryKey,
invalidate,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import React from "react";
import { Group, GroupProps } from "@mantine/core";
import { UserAvatarGroup } from "@/components/general/avatar/UserAvatarGroup";
import ProfileFollowActions from "@/components/profile/view/ProfileFollowActions";
import UserFollowActions from "@/components/follow/input/UserFollowActions";

interface Props extends GroupProps {
userId: string;
}

const UserFollowGroup = ({ userId, ...groupProps }: Props) => {
const UserAvatarWithFollowActions = ({ userId, ...groupProps }: Props) => {
return (
<Group className={"w-full justify-between flex-nowrap"} {...groupProps}>
<UserAvatarGroup
Expand All @@ -17,12 +16,9 @@ const UserFollowGroup = ({ userId, ...groupProps }: Props) => {
wrap: "nowrap",
}}
/>
<UserFollowActions
targetUserId={userId}
withUnfollowButton={false}
/>
<UserFollowActions targetUserId={userId} withUnfollowButton={false} />
</Group>
);
};

export default UserFollowGroup;
export default UserAvatarWithFollowActions;
15 changes: 8 additions & 7 deletions src/components/follow/input/UserFollowActions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,25 +7,22 @@ import { useInfiniteFollowInfo } from "@/components/follow/hooks/useInfiniteFoll
import criteria = FollowInfoRequestDto.criteria;
import { ActionIcon, Button, Group, Tooltip } from "@mantine/core";
import { IconX } from "@tabler/icons-react";
import { redirectToAuth } from "supertokens-auth-react";

interface Props {
targetUserId: string;
withUnfollowButton?: boolean;
}

const UserFollowActions = ({
targetUserId,
withUnfollowButton = true,
}: Props) => {
const UserFollowActions = ({ targetUserId, withUnfollowButton = true }: Props) => {
const ownUserId = useUserId();
/*
Checks if current logged-in user is following target user
*/
const ownToTargetFollowStatus = useFollowStatus(ownUserId, targetUserId);
const isFollowing = ownToTargetFollowStatus.data?.isFollowing ?? false;

const shouldShowFollowButton =
ownUserId != undefined && ownUserId !== targetUserId;
const shouldEnableFollowButton = ownUserId != undefined && ownUserId !== targetUserId && !isFollowing;

const followMutation = useMutation({
mutationFn: async (action: "register" | "remove") => {
Expand Down Expand Up @@ -53,9 +50,13 @@ const UserFollowActions = ({
return (
<Group className={"flex-nowrap w-fit"}>
<Button
disabled={isFollowing}
disabled={!shouldEnableFollowButton}
loading={followMutation.isPending}
onClick={() => {
if (ownUserId == undefined) {
redirectToAuth();
return;
}
followMutation.mutate("register");
}}
>
Expand Down
Loading

0 comments on commit ea258f1

Please sign in to comment.