sessions, or something
This commit is contained in:
@@ -7,8 +7,10 @@ import { Source_Sans_3, Nunito } from "next/font/google";
|
||||
import AuthStatus from "muzak/components/AuthStatus";
|
||||
import NavigationBar from "muzak/components/NavigationBar";
|
||||
import Quota from "muzak/components/Quota";
|
||||
import SessionChecker from "muzak/components/SessionChecker";
|
||||
import { AnimationContext } from "muzak/contexts/AnimationContext";
|
||||
import { QuotaContext } from "muzak/contexts/QuotaContext";
|
||||
import { SessionContext } from "muzak/contexts/SessionContext";
|
||||
|
||||
const nunito = Nunito({
|
||||
subsets: ["latin"],
|
||||
@@ -17,6 +19,7 @@ const nunito = Nunito({
|
||||
function LayoutContent({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<>
|
||||
<SessionChecker />
|
||||
<AuthStatus />
|
||||
{children}
|
||||
{/* <NavigationBar /> */}
|
||||
@@ -32,6 +35,7 @@ export default function RootLayout({
|
||||
}) {
|
||||
const [isAnimate, setIsAnimate] = useState(false);
|
||||
const [quota, setQuota] = useState<number | null>(null);
|
||||
const [sessionId, setSessionId] = useState<string | null>(null);
|
||||
|
||||
const toggleAnimation = () => {
|
||||
setIsAnimate(!isAnimate);
|
||||
@@ -43,7 +47,9 @@ export default function RootLayout({
|
||||
<AuthProvider {...oidcConfig}>
|
||||
<AnimationContext.Provider value={{ isAnimate, setIsAnimate }}>
|
||||
<QuotaContext.Provider value={{ quota, setQuota }}>
|
||||
<LayoutContent children={children} />
|
||||
<SessionContext.Provider value={{ sessionId, setSessionId }}>
|
||||
<LayoutContent children={children} />
|
||||
</SessionContext.Provider>
|
||||
</QuotaContext.Provider>
|
||||
</AnimationContext.Provider>
|
||||
</AuthProvider>
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Markazi_Text, Nunito } from "next/font/google";
|
||||
import users from "muzak/data/users.json";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { useSession } from "muzak/contexts/SessionContext";
|
||||
|
||||
const nunito = Nunito({
|
||||
weight: "900",
|
||||
@@ -13,29 +14,44 @@ const nunito = Nunito({
|
||||
const MAX_PARTY_SIZE = 8;
|
||||
|
||||
export default function Lobby() {
|
||||
const [partySize, setPartySize] = useState(0);
|
||||
const [userList, setUserList] = useState([]);
|
||||
const [userList, setUserList] = useState<any[]>([]);
|
||||
const [sessionSocket, setSessionSocket] = useState<WebSocket | null>(null);
|
||||
const { sessionId, setSessionId } = useSession();
|
||||
|
||||
function onMessage(e) {
|
||||
setTimeout(() => {
|
||||
console.log(e);
|
||||
let data = JSON.parse(e.data);
|
||||
for (let key in data) {
|
||||
if (key === "joined") {
|
||||
addUser(data[key]);
|
||||
}
|
||||
}
|
||||
console.log(data);
|
||||
}, 1000);
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
populateUserList();
|
||||
}, [partySize]);
|
||||
if (sessionId) {
|
||||
const socket = new WebSocket(
|
||||
`${process.env.NEXT_PUBLIC_WS_HOST}/voting/session/${sessionId}/`,
|
||||
);
|
||||
socket.onmessage = onMessage;
|
||||
setSessionSocket(socket);
|
||||
}
|
||||
}, [sessionId]);
|
||||
|
||||
function populateUserList() {
|
||||
const mappedUsers = users.slice(0, partySize).map((user) => ({
|
||||
id: user.id,
|
||||
name: user.name,
|
||||
avatar: user.avatar,
|
||||
host: user.host,
|
||||
}));
|
||||
setUserList(mappedUsers);
|
||||
}
|
||||
|
||||
function addUserToParty() {
|
||||
setPartySize((prev) => Math.min(prev + 1, MAX_PARTY_SIZE));
|
||||
}
|
||||
|
||||
function deleteUserFromParty() {
|
||||
setPartySize((prev) => Math.max(prev - 1, 0));
|
||||
function addUser(userName: string) {
|
||||
if (userList.find((user) => user.name === userName)) {
|
||||
return;
|
||||
}
|
||||
const newUser = {
|
||||
id: userList.length + 1,
|
||||
name: userName,
|
||||
avatar: `https://i.pravatar.cc/150?img=${userList.length + 1}`,
|
||||
host: userList.length === 0,
|
||||
};
|
||||
setUserList((prevUserList) => [...prevUserList, newUser]);
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -51,7 +67,7 @@ export default function Lobby() {
|
||||
<div className="flex min-h-[532px] min-w-[500px] flex-col items-center justify-start gap-4 rounded-md bg-blue-950/80 p-8">
|
||||
<div className="flex w-full flex-row items-center justify-between px-1">
|
||||
<div className="text-3xl font-bold text-yellow-500">
|
||||
Players: {partySize}
|
||||
Players: {userList.length}
|
||||
</div>
|
||||
<Link
|
||||
href="/voting"
|
||||
@@ -61,7 +77,7 @@ export default function Lobby() {
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{partySize === 0 ? (
|
||||
{userList.length === 0 ? (
|
||||
<div className="mt-31 min-w-52 text-3xl font-semibold text-white drop-shadow-sm drop-shadow-gray-900">
|
||||
Waiting for players...
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
"use client";
|
||||
import { useSession } from "muzak/contexts/SessionContext";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useAuth } from "react-oidc-context";
|
||||
import { getUser } from "muzak/data/fetcher";
|
||||
import { Nunito } from "next/font/google";
|
||||
|
||||
const nunito = Nunito({
|
||||
weight: "900",
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
export default function Session() {
|
||||
const auth = useAuth();
|
||||
const { sessionId, setSessionId } = useSession();
|
||||
const user = getUser();
|
||||
const [sessionSocket, setSessionSocket] = useState<WebSocket | null>(null);
|
||||
|
||||
function connect() {
|
||||
console.log(`ik ben ${user.profile.nickname}`);
|
||||
console.log(sessionSocket?.readyState);
|
||||
if (sessionSocket?.readyState === WebSocket.OPEN) {
|
||||
console.log("socket is open");
|
||||
sessionSocket.send(
|
||||
JSON.stringify({
|
||||
action: "login",
|
||||
userr: user.profile.nickname,
|
||||
token: user.access_token,
|
||||
}),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (sessionId) {
|
||||
const socket = new WebSocket(
|
||||
`${process.env.NEXT_PUBLIC_WS_HOST}/voting/session/${sessionId}/`,
|
||||
);
|
||||
setSessionSocket(socket);
|
||||
}
|
||||
}, [sessionId]);
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
||||
<div>
|
||||
<h1
|
||||
className={`${nunito.className} text-outline text-[42px] tracking-tighter text-yellow-500`}
|
||||
>
|
||||
LOGIN
|
||||
</h1>
|
||||
</div>
|
||||
<div className="mb-12 flex flex-col items-center justify-between gap-4 rounded-md bg-blue-950/80 p-8">
|
||||
<h1 className="text-xl text-white">{user.profile.nickname}</h1>
|
||||
<button
|
||||
className="rounded-md bg-blue-500 px-4 py-2 text-white hover:bg-blue-600"
|
||||
onClick={connect}
|
||||
>
|
||||
Connect
|
||||
</button>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
"use client";
|
||||
import Link from "next/link";
|
||||
import { useAuth } from "react-oidc-context";
|
||||
import { useState, useEffect, use } from "react";
|
||||
import { useRouter, usePathname } from "next/navigation";
|
||||
import { api, Session } from "muzak/data/fetcher";
|
||||
import { getUser } from "muzak/data/fetcher";
|
||||
import { useSession } from "muzak/contexts/SessionContext";
|
||||
|
||||
export default function SessionChecker() {
|
||||
const auth = useAuth();
|
||||
const router = useRouter();
|
||||
|
||||
const [isSession, setIsSession] = useState(false);
|
||||
const [link, setLink] = useState("/lobby");
|
||||
const { sessionId, setSessionId } = useSession();
|
||||
|
||||
async function getSessions() {
|
||||
if (!auth.isLoading && !auth.error && auth.isAuthenticated) {
|
||||
const { data: sessions } = await api?.sessions?.list({});
|
||||
console.log(sessions);
|
||||
if (sessions?.length > 0) {
|
||||
setIsSession(true);
|
||||
const user = getUser();
|
||||
setSessionId(sessions[0].session_id);
|
||||
if (sessions[0].host === user?.profile?.email) {
|
||||
setLink("/lobby");
|
||||
} else {
|
||||
setLink("/session");
|
||||
}
|
||||
} else {
|
||||
setIsSession(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getSessions();
|
||||
}, [auth]);
|
||||
|
||||
if (isSession) {
|
||||
return (
|
||||
<Link
|
||||
href={link}
|
||||
className="bold text-l absolute top-2 left-2 rounded-[50%] bg-red-500 p-3 font-bold text-white"
|
||||
>
|
||||
Session available!
|
||||
</Link>
|
||||
);
|
||||
}
|
||||
return <> </>;
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
"use client";
|
||||
import { createContext, useContext } from "react";
|
||||
|
||||
interface SessionContextType {
|
||||
sessionId: string;
|
||||
setSessionId: React.Dispatch<React.SetStateAction<string>>;
|
||||
}
|
||||
const SessionContext = createContext<SessionContextType>(
|
||||
{} as SessionContextType,
|
||||
);
|
||||
|
||||
export const useSession = () => useContext(SessionContext);
|
||||
|
||||
export { SessionContext };
|
||||
@@ -83,11 +83,15 @@ export const api = {
|
||||
profiles: {
|
||||
me: fetcher.path("/api/profile/me").method("get").create(),
|
||||
},
|
||||
sessions: {
|
||||
list: fetcher.path("/voting/session/").method("get").create(),
|
||||
},
|
||||
};
|
||||
|
||||
export type User = components["schemas"]["User"];
|
||||
export type Track = components["schemas"]["Track"];
|
||||
export type Album = components["schemas"]["Album"];
|
||||
export type Profile = components["schemas"]["Profile"];
|
||||
export type Session = components["schemas"]["Session"];
|
||||
|
||||
export default api;
|
||||
|
||||
Reference in New Issue
Block a user