Skip to content

Commit

Permalink
Merge pull request #412 from Game-as-a-Service/refactor/website-style
Browse files Browse the repository at this point in the history
refactor: website style
  • Loading branch information
JohnsonMao authored Oct 20, 2024
2 parents ce8f7c9 + acd625b commit 226fbd3
Show file tree
Hide file tree
Showing 10 changed files with 123 additions and 63 deletions.
8 changes: 3 additions & 5 deletions components/rooms/GameWindow.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
type GameWindowProps = {
className?: string;
gameUrl: string;
};

export default function GameWindow({ gameUrl }: GameWindowProps) {
export default function GameWindow({ className, gameUrl }: GameWindowProps) {
return (
<div>
<iframe
className="absolute inset-0 m-auto w-[95%] h-[95vh] border"
src={gameUrl}
>
<iframe className={className} src={gameUrl}>
<p>Your browser does not support iframes.</p>
</iframe>
</div>
Expand Down
4 changes: 3 additions & 1 deletion components/shared/Chat/v2/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export type ChatProps = {
friendList: FriendType[];
roomMessages: MessageType[];
className?: string;
defaultTarget?: ChatTab["id"];
onSubmit: (message: Pick<MessageType, "content" | "target">) => void;
};

Expand All @@ -25,11 +26,12 @@ export default function Chat({
friendList,
roomMessages,
className,
defaultTarget,
onSubmit,
}: Readonly<ChatProps>) {
const [messages, setMessages] = useState(lobbyMessages);
const [target, setTarget] = useState<[ChatTab["id"], string | null]>([
"lobby",
defaultTarget || "lobby",
null,
]);
const [activeTab, friendRoom] = target;
Expand Down
27 changes: 20 additions & 7 deletions containers/layout/AppLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,38 +1,51 @@
import { PropsWithChildren } from "react";
import { PropsWithChildren, useEffect } from "react";
import { useRouter } from "next/router";
import Header from "@/components/shared/Header";
import Sidebar from "@/components/shared/Sidebar";
import Chat from "@/components/shared/Chat/v2/Chat";
import useChat from "@/hooks/useChat";

export default function Layout({ children }: PropsWithChildren) {
const router = useRouter();
const {
roomId,
messageList,
isChatVisible,
openChat,
toggleChatVisibility,
handleSubmitText,
} = useChat();
const roomPathname = "/rooms/[roomId]";

useEffect(() => {
if (router.pathname === roomPathname) {
openChat();
}
}, [router.pathname, openChat]);

return (
<>
<Header
className="sticky top-0 z-40"
className="fixed top-0 inset-x-0 z-40"
onClickChatButton={toggleChatVisibility}
/>
<div className="ml-2 mr-4 my-6 flex grow">
<div className="shrink-0">
<Sidebar className="sticky top-20 z-30 h-main-height" />
<div className="pl-2 pt-20 flex grow">
<div className="shrink-0 w-18">
<Sidebar className="fixed top-20 bottom-6 z-30" />
</div>
<main className="grow overflow-x-hidden">{children}</main>
{isChatVisible && (
<div className="shrink-0">
<div className="shrink-0 w-80 mr-4">
<Chat
className="sticky top-20 z-30 h-main-height"
className="fixed top-20 bottom-6 z-30"
userId=""
roomId={roomId}
friendList={[]}
lobbyMessages={[]}
roomMessages={messageList}
defaultTarget={
router.pathname === roomPathname ? "room" : "lobby"
}
onSubmit={handleSubmitText}
/>
</div>
Expand Down
7 changes: 6 additions & 1 deletion hooks/useChat.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useEffect, useState } from "react";
import { useCallback, useEffect, useState } from "react";
import type { MessageType } from "@/components/shared/Chat/v2/ChatMessages";
import useChatroom from "./context/useChatroom";
import useSocketCore from "./context/useSocketCore";
Expand All @@ -17,6 +17,10 @@ export default function useChat() {
setIsChatVisible((prev) => !prev);
};

const openChat = useCallback(() => {
setIsChatVisible(true);
}, []);

// join chatroom by roomId
useEffect(() => {
if (!roomId) return;
Expand Down Expand Up @@ -48,6 +52,7 @@ export default function useChat() {
roomId,
messageList,
isChatVisible,
openChat,
sendChatMessage,
toggleChatVisibility,
handleSubmitText,
Expand Down
17 changes: 10 additions & 7 deletions hooks/useUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,16 @@ const useUser = () => {
return roomIdOperator.get();
};

const updateRoomId = (roomId?: string) => {
if (roomId) {
roomIdOperator.set(roomId);
} else {
roomIdOperator.remove();
}
};
const updateRoomId = useCallback(
(roomId?: string) => {
if (roomId) {
roomIdOperator.set(roomId);
} else {
roomIdOperator.remove();
}
},
[roomIdOperator]
);

return {
getLoginEndpoint,
Expand Down
2 changes: 1 addition & 1 deletion pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export default function Document() {
<meta name="og:title" content={siteTitle} />
<meta name="twitter:card" content="summary_large_image" />
</Head>
<body className="body-bg text-primary-200">
<body className="body-bg min-h-screen text-primary-200">
<Main />
<NextScript />
</body>
Expand Down
2 changes: 1 addition & 1 deletion pages/auth/token/[token].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const Token: NextPageWithProps = () => {
}
}, [token, login, push]);

return <h1>{token}</h1>;
return <></>;
};

Token.getLayout = (page: ReactElement) => page;
Expand Down
8 changes: 4 additions & 4 deletions pages/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ function CarouselCard({
draggable={false}
priority
fill
objectFit="cover"
className="object-cover"
onError={onImageError}
/>
<div className="m-4 flex gap-4">
Expand Down Expand Up @@ -106,7 +106,7 @@ function CarouselCard({
draggable={false}
priority
fill
objectFit="cover"
className="object-cover"
onError={onImageError}
/>
)}
Expand Down Expand Up @@ -181,12 +181,12 @@ const TabPaneContent = ({
>
<picture className="relative aspect-game-cover overflow-hidden">
<Image
src={game.img}
src={game.img || gameDefaultCoverImg.src}
alt={game.name}
draggable={false}
priority
fill
objectFit="cover"
className="object-cover"
onError={onImageError}
/>
</picture>
Expand Down
107 changes: 71 additions & 36 deletions pages/rooms/[roomId]/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import { useRouter } from "next/router";
import { ReactEventHandler, useEffect, useState } from "react";
import { GetStaticProps, GetStaticPaths } from "next";
import { useRouter } from "next/router";
import Image from "next/image";
import { serverSideTranslations } from "next-i18next/serverSideTranslations";
import RoomUserCardList from "@/components/rooms/RoomUserCardList";
import RoomButtonGroup from "@/components/rooms/RoomButtonGroup";
Expand All @@ -22,10 +23,18 @@ import {
playerCancelReady,
startGame,
} from "@/requests/rooms";
import { GameType, getAllGamesEndpoint } from "@/requests/games";
import useUser from "@/hooks/useUser";
import gameDefaultCoverImg from "@/public/images/game-default-cover.png";

type User = Omit<RoomInfo.User, "isReady">;

const onImageError: ReactEventHandler<HTMLImageElement> = (e) => {
if (e.target instanceof HTMLImageElement) {
e.target.src = gameDefaultCoverImg.src;
}
};

export default function Room() {
const {
roomInfo,
Expand All @@ -44,16 +53,27 @@ export default function Room() {
const { fetch } = useRequest();
const { query, replace } = useRouter();
const [gameUrl, setGameUrl] = useState("");
const [gameList, setGameList] = useState<GameType[]>([]);
const roomId = query.roomId as string;
const player = roomInfo.players.find(
(player) => player.id === currentUser?.id
);
const isHost = roomInfo.host.id === currentUser?.id;
const gameInfo = gameList.find((game) => game.id === roomInfo.game.id);

useEffect(() => {
fetch(getAllGamesEndpoint()).then(setGameList);
}, [fetch]);

useEffect(() => {
async function getRoomInfo() {
const roomInfo = await fetch(getRoomInfoEndpoint(roomId));
initializeRoom(roomInfo);
try {
const roomInfo = await fetch(getRoomInfoEndpoint(roomId));
initializeRoom(roomInfo);
} catch (err) {
updateRoomId();
replace("/rooms");
}
}

getRoomInfo();
Expand Down Expand Up @@ -119,6 +139,7 @@ export default function Room() {
socket,
currentUser?.id,
roomId,
updateRoomId,
addPlayer,
removePlayer,
updateUserReadyStatus,
Expand Down Expand Up @@ -211,40 +232,54 @@ export default function Room() {
};

return (
<section className="px-6">
<div className="relative w-full h-[280px] overflow-hidden">
<img
className="absolute inset-0 w-full h-full object-cover"
src="https://images.unsplash.com/photo-1601987177651-8edfe6c20009?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=2070&q=80"
alt="cover"
<section className="px-4">
{gameUrl ? (
<GameWindow
className="h-[calc(100dvh-104px)] w-full"
gameUrl={gameUrl}
/>
<div className="absolute top-0 left-0 right-0 bottom-0 bg-gradient-to-t from-[#0f0919] to-50% to-[#170D2500]"></div>
<div className="m-2 py-1 px-2 w-fit bg-gray-950/50 backdrop-blur-sm rounded-lg text-sm">
<RoomBreadcrumb roomInfo={roomInfo} />
</div>
<div className="m-2 py-1 px-2 w-fit bg-gray-950/50 backdrop-blur-sm rounded-lg text-sm">
{roomInfo.isLocked ? "非公開" : "公開"}
</div>
<div className="m-2 py-1 px-2 w-fit bg-gray-950/50 backdrop-blur-sm rounded-lg text-sm">
{roomInfo.currentPlayers} / {roomInfo.maxPlayers}
</div>
<div className="absolute bottom-0 right-0 flex items-center">
<RoomButtonGroup
onToggleReady={handleToggleReady}
onClickClose={handleClickClose}
onClickLeave={handleLeave}
onClickStart={handleStart}
isHost={isHost}
isReady={isHost || !!player?.isReady}
) : (
<>
<div className="relative w-full h-[280px] overflow-hidden">
{roomInfo.currentPlayers && (
<Image
src={gameInfo?.img || gameDefaultCoverImg.src}
alt={gameInfo?.name || "default game cover"}
draggable={false}
priority
fill
className="object-cover"
onError={onImageError}
/>
)}
<div className="absolute top-0 left-0 right-0 bottom-0 bg-gradient-to-t from-[#0f0919] to-50% to-[#170D2500]"></div>
<div className="m-2 py-1 px-2 w-fit bg-gray-950/50 backdrop-blur-sm rounded-lg text-sm">
<RoomBreadcrumb roomInfo={roomInfo} />
</div>
<div className="m-2 py-1 px-2 w-fit bg-gray-950/50 backdrop-blur-sm rounded-lg text-sm">
{roomInfo.isLocked ? "非公開" : "公開"}
</div>
<div className="m-2 py-1 px-2 w-fit bg-gray-950/50 backdrop-blur-sm rounded-lg text-sm">
{roomInfo.currentPlayers} / {roomInfo.maxPlayers}
</div>
<div className="absolute bottom-0 right-0 flex items-center">
<RoomButtonGroup
onToggleReady={handleToggleReady}
onClickClose={handleClickClose}
onClickLeave={handleLeave}
onClickStart={handleStart}
isHost={isHost}
isReady={isHost || !!player?.isReady}
/>
</div>
</div>
<RoomUserCardList
roomInfo={roomInfo}
currentUserId={currentUser?.id}
onKickUser={handleClickKick}
/>
</div>
</div>
<RoomUserCardList
roomInfo={roomInfo}
currentUserId={currentUser?.id}
onKickUser={handleClickKick}
/>
{gameUrl && <GameWindow gameUrl={gameUrl} />}
</>
)}
<Popup />
</section>
);
Expand Down
4 changes: 4 additions & 0 deletions styles/global.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

html {
color-scheme: dark;
}

0 comments on commit 226fbd3

Please sign in to comment.