Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions apps/backend/src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ interface Message {
time: string;
}
type SocketTypes =
| 'check-room'
| 'create-room'
| 'join-room'
| 'send-message'
Expand Down Expand Up @@ -52,6 +53,10 @@ wss.on('connection', (ws: WebSocket) => {
const data: WebSocketData = JSON.parse(message);

switch (data.type) {
case 'check-room':
const exists = rooms.has(data.roomId!);
ws.send(JSON.stringify({ type: 'room-check-result', exists }));
break;
case 'create-room':
const roomId = generateRoomId();
rooms.set(roomId, {
Expand Down
41 changes: 41 additions & 0 deletions apps/web/src/app/not-found.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
'use client';

import { Button } from '@/components/ui/button';
import { useRouter } from 'next/navigation';
import { Home, Search, XCircle } from 'lucide-react';

export default function RoomNotFound() {
const router = useRouter();

return (
<div className="flex flex-col items-center justify-center min-h-screen p-4">
<div className="text-center space-y-6">
<div>
<XCircle
className="w-24 h-24 text-destructive mx-auto"
strokeWidth={1.5}
/>
</div>

<h1 className="text-4xl font-bold">404: Page Not Found</h1>

<p className="text-lg text-muted-foreground max-w-md">
The page or room doesn&apos;t exist. It might have been closed or
never existed.
</p>

<div>
<Button
onClick={() => router.push('/')}
className="mt-4"
variant="default"
size="lg"
>
<Home className="w-4 h-4 mr-2" />
Back to Home
</Button>
</div>
</div>
</div>
);
}
15 changes: 5 additions & 10 deletions apps/web/src/app/room/[roomId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import RoomHeader from '@/components/room/header';
import RoomChat from '@/components/room/chat';
import { RoomData, VideoMetadata } from '@/types/room';
import { formatDistanceToNow } from 'date-fns';
import { useRouter } from 'next/navigation';
interface YouTubePlayer {
playVideo: () => void;
pauseVideo: () => void;
Expand All @@ -16,11 +17,6 @@ interface YouTubePlayer {
getPlayerState: () => number;
}

type VideoEvent =
| { type: 'video-play'; timestamp: number }
| { type: 'video-pause'; timestamp: number }
| { type: 'video-seek'; timestamp: number };

declare global {
interface Window {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand All @@ -29,7 +25,8 @@ declare global {
}
}

export default function RoomPage() {
export default function ClientPage() {
const router = useRouter();
const params = useParams();
const roomId = params.roomId as string;
const {
Expand All @@ -42,14 +39,12 @@ export default function RoomPage() {
syncVideoState,
addToPlaylist,
subscribeToPlaylistUpdates,
nextVideo,
videoEnded,
} = useSocket();

const [messages, setMessages] = useState<Message[]>([]);
const [participants, setParticipants] = useState(0);
const [videoUrl, setVideoUrl] = useState('');
const [username] = useState(`User-${Math.floor(Math.random() * 1000)}`);
const [videoMetadata, setVideoMetadata] = useState<VideoMetadata>({
title: '',
creator: '',
Expand Down Expand Up @@ -86,7 +81,6 @@ export default function RoomPage() {
});
} else if (playerState === 0) {
videoEnded(roomId);
// nextVideo(roomId);
}
},
[roomId, syncVideoState, videoEnded]
Expand All @@ -107,11 +101,12 @@ export default function RoomPage() {
}
} catch (error) {
console.error('Error joining room:', error);
router.push('/room-not-found');
}
};

fetchRoomData();
}, [isConnected, joinRoom, roomId]);
}, [isConnected, joinRoom, roomId, router]);

useEffect(() => {
if (!isConnected) return;
Expand Down
55 changes: 55 additions & 0 deletions apps/web/src/app/room/[roomId]/server__bla_page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { notFound, redirect } from 'next/navigation';
import ClientPage from './page';

async function checkRoomExists(roomId: string): Promise<boolean> {
return new Promise((resolve) => {
try {
const ws = new WebSocket(process.env.NEXT_PUBLIC_WEBSOCKET_URL!);

ws.onopen = () => {
ws.send(JSON.stringify({ type: 'check-room', roomId }));
};

ws.onmessage = (event) => {
try {
const response = JSON.parse(event.data);
if (response.type === 'room-check-result') {
ws.close();
resolve(response.exists);
}
} catch (error) {
console.error('Error parsing response:', error);
ws.close();
resolve(false);
}
};

ws.onerror = () => {
ws.close();
resolve(false);
};

setTimeout(() => {
ws.close();
resolve(false);
}, 5000);
} catch (error) {
console.error('Error checking room:', error);
resolve(false);
}
});
}

export default async function RoomPage({
params,
}: {
params: { roomId: string };
}) {
const { roomId } = await params;
const roomExists = await checkRoomExists(roomId);

if (!roomExists) {
notFound();
}
return <ClientPage />;
}