From 4be951e2692f8423a46c3306363edb6a62a071dd Mon Sep 17 00:00:00 2001
From: Dev Kraken
Date: Wed, 15 Jan 2025 02:32:08 +0400
Subject: [PATCH] feat: implement maximum participants limit
- Add MAX_PARTICIPANTS environment variable in wrangler.toml
- Update loader to parse and validate MAX_PARTICIPANTS
- Modify Lobby component to use maxParticipants for determining room capacity
- Implement UI changes to show when a room is full and prevent joining
- Handle cases where MAX_PARTICIPANTS is not set or invalid
---
app/routes/_room.$roomName._index.tsx | 29 ++++++++++++++++++++-------
app/types/Env.ts | 1 +
2 files changed, 23 insertions(+), 7 deletions(-)
diff --git a/app/routes/_room.$roomName._index.tsx b/app/routes/_room.$roomName._index.tsx
index fed8337f..9b626dfb 100644
--- a/app/routes/_room.$roomName._index.tsx
+++ b/app/routes/_room.$roomName._index.tsx
@@ -1,7 +1,12 @@
import { VisuallyHidden } from '@radix-ui/react-visually-hidden'
import type { LoaderFunctionArgs } from '@remix-run/cloudflare'
import { json } from '@remix-run/cloudflare'
-import { useNavigate, useParams, useSearchParams } from '@remix-run/react'
+import {
+ useLoaderData,
+ useNavigate,
+ useParams,
+ useSearchParams,
+} from '@remix-run/react'
import { useObservableAsValue } from 'partytracks/react'
import invariant from 'tiny-invariant'
import { AudioIndicator } from '~/components/AudioIndicator'
@@ -21,9 +26,11 @@ import { useRoomUrl } from '~/hooks/useRoomUrl'
import getUsername from '~/utils/getUsername.server'
export const loader = async ({ request, context }: LoaderFunctionArgs) => {
+ const env = context.env
const username = await getUsername(request)
invariant(username)
- return json({ username, callsAppId: context.env.CALLS_APP_ID })
+ const maxParticipants = env.MAX_PARTICIPANTS ?? null
+ return json({ username, callsAppId: env.CALLS_APP_ID, maxParticipants })
}
let refreshCheckDone = false
@@ -53,11 +60,15 @@ export default function Lobby() {
const session = useObservableAsValue(partyTracks.session$)
const sessionError = useObservableAsValue(partyTracks.sessionError$)
trackRefreshes()
+ const { maxParticipants } = useLoaderData()
const joinedUsers = new Set(
room.otherUsers.filter((u) => u.tracks.audio).map((u) => u.name)
).size
+ const isRoomFull =
+ maxParticipants !== null && joinedUsers >= maxParticipants
+
const roomUrl = useRoomUrl()
const [params] = useSearchParams()
@@ -72,6 +83,7 @@ export default function Lobby() {
{`${joinedUsers} ${
joinedUsers === 1 ? 'user' : 'users'
} in the room.`}{' '}
+ {isRoomFull && Room is full.}
@@ -149,16 +161,13 @@ export default function Lobby() {
@@ -167,6 +176,12 @@ export default function Lobby() {
+ {isRoomFull && (
+
+ This room has reached its maximum capacity of {maxParticipants}{' '}
+ participants.
+
+ )}
diff --git a/app/types/Env.ts b/app/types/Env.ts
index 92210d06..e1133dfc 100644
--- a/app/types/Env.ts
+++ b/app/types/Env.ts
@@ -18,4 +18,5 @@ export type Env = {
OPENAI_API_TOKEN?: string
OPENAI_MODEL_ENDPOINT?: string
OPENAI_MODEL_ID?: string
+ MAX_PARTICIPANTS?: number
}