-
Couldn't load subscription status.
- Fork 440
Add README.md with project details and setup instructions #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Signed-off-by: Gaurav <[email protected]>
WalkthroughUpdates branding from YOOM to Ro0m, adds environment variables and ignores, pins Node via .nvmrc, revises README, bumps Next.js, introduces a meeting link utility, refactors meeting link generation and invitation copy, enhances home time display to tick every second, and restructures CallList with unified rendering and error-handled recording fetches. Changes
Sequence Diagram(s)sequenceDiagram
participant C as Component (PersonalRoom/MeetingTypeList)
participant U as getMeetingLink(id)
participant E as process.env.NEXT_PUBLIC_BASE_URL
participant W as window.location.origin
C->>U: getMeetingLink(id)
alt Server-side (no window)
U-->>C: /meeting/{id}
else Client + BASE_URL set and not localhost
U->>E: read BASE_URL
U-->>C: {BASE_URL}/meeting/{id}
else Client fallback
U->>W: read origin
U-->>C: {origin}/meeting/{id}
end
sequenceDiagram
participant V as CallList
participant S as Stream API
participant T as Toast
participant R as Router/Window
V->>V: useEffect(type)
alt type == "recordings"
V->>S: list recordings
alt success
loop per recording
V->>S: fetch recording data
alt item fail
V->>T: destructive toast (error)
end
end
V-->>V: set recordings
else failure
V->>T: destructive toast
V-->>V: clear recordings
end
else ended/upcoming
V-->>V: use provided calls
end
V->>R: onClick item -> open recording URL or navigate to meeting
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
Tip 🔌 Remote MCP (Model Context Protocol) integration is now available!Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats. ✨ Finishing Touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. CodeRabbit Commands (Invoked using PR/Issue comments)Type Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🔭 Outside diff range comments (1)
app/(root)/(home)/personal-room/page.tsx (1)
54-57: Guard against undefined user/meetingId to avoid non-null assertion crashes and poor UI states
meetingId!and string interpolation withuser?.usernamecan render “undefined” or throw if the hook expects a non-empty id. Guard and provide fallbacks in the UI.Apply this diff:
- const meetingId = user?.id; + const meetingId = user?.id ?? ''; @@ - <Table title="Topic" description={`${user?.username}'s Meeting Room`} /> - <Table title="Meeting ID" description={meetingId!} /> - <Table title="Invite Link" description={meetingLink} /> + <Table title="Topic" description={`${user?.username ?? 'Personal'}'s Meeting Room`} /> + <Table title="Meeting ID" description={meetingId || '—'} /> + <Table title="Invite Link" description={meetingLink || '—'} />If
useGetCallByIdcannot accept an empty string, update that hook to short-circuit when the id is falsy, or change the call site to defer usage untilmeetingIdis present. If helpful, I can provide a patch to make the hook tolerant ofundefinedids.Also applies to: 92-95
🧹 Nitpick comments (16)
.nvmrc (1)
1-1: Optional: also enforce Node version via package.json engines.nvmrc helps local devs using nvm, but CI/Vercel/other environments won’t read it. Consider adding an engines field to package.json to enforce Node 18.x (Next 14 typically requires ≥18.17):
Add this to package.json:
{ "engines": { "node": ">=18.17 <19" } }If your team uses asdf, adding a .tool-versions or .node-version file can further reduce drift across environments.
components/MobileNav.tsx (1)
32-32: Nit: capitalize the brand in alt text for consistencyUse "Ro0m logo" to match the visible brand capitalization.
- alt="ro0m logo" + alt="Ro0m logo"components/Navbar.tsx (1)
15-15: Nit: capitalize the brand in alt text for consistencyAlign alt text with the visible brand capitalization.
- alt="ro0m logo" + alt="Ro0m logo"app/layout.tsx (1)
14-15: Brand rename applied — LGTM; minor copy tweak optionalThe title update to Ro0m looks good. Optional: “Video calling App” reads better as “Video calling app.”
- description: "Video calling App", + description: "Video calling app",.gitignore (1)
12-18: Solid env ignores; add a generic pattern and keep an example trackedNice addition. Consider also ignoring any other future stage-specific env files while keeping a sample checked in.
Apply this diff to generalize and preserve an example:
# environment variables .env .env.local .env.development.local .env.test.local .env.production.local +.env.* +!.env.exampleNote: Since a real .env is currently committed in this PR, the ignore rule won’t untrack it. See my comment on .env for steps to remove and rotate secrets.
package.json (1)
2-2: Next.js bump looks intentional; align eslint tooling and engines, and confirm scope
- Align eslint-config-next to the same 14.2 line to avoid rule/plugin mismatches.
- Add an engines field to enforce the Node version your .nvmrc pins (Node 18).
- Given the PR title mentions only README, please confirm these framework/branding bumps are intended here; otherwise consider splitting for cleaner history.
Suggested updates outside the shown lines:
{ "engines": { "node": ">=18.17.0" }, "devDependencies": { "eslint-config-next": "^14.2.31" } }Also applies to: 24-24
lib/meeting-utils.ts (1)
1-12: Harden link building: guard empty id, normalize base URL, and encode the id
Prevents double slashes and handles unexpected characters in IDs. Low-risk polish.Apply this diff:
export const getMeetingLink = (id: string) => { + if (!id) return ''; if (typeof window === 'undefined') { - return `/meeting/${id}`; + return `/meeting/${encodeURIComponent(id)}`; } - const baseUrl = process.env.NEXT_PUBLIC_BASE_URL; + const baseUrl = process.env.NEXT_PUBLIC_BASE_URL?.replace(/\/+$/, ''); if (baseUrl && !baseUrl.includes('localhost')) { - return `${baseUrl}/meeting/${id}`; + return `${baseUrl}/meeting/${encodeURIComponent(id)}`; } - return `${window.location.origin}/meeting/${id}`; + return `${window.location.origin.replace(/\/+$/, '')}/meeting/${encodeURIComponent(id)}`; };components/MeetingTypeList.tsx (1)
70-85: Deduplicate: reuse shared getMeetingLink(...) instead of redefining it locally
This logic now lives in lib/meeting-utils.ts. Importing it avoids divergence and keeps URL rules centralized.Apply this diff:
- const getMeetingLink = () => { - if (!callDetail?.id) return ''; - - const baseUrl = process.env.NEXT_PUBLIC_BASE_URL; - // In production, use the configured URL - if (baseUrl && !baseUrl.includes('localhost')) { - return `${baseUrl}/meeting/${callDetail.id}`; - } - // In development or if BASE_URL is not set, use the current origin - return typeof window !== 'undefined' - ? `${window.location.origin}/meeting/${callDetail.id}` - : `/meeting/${callDetail.id}`; - }; - - const meetingLink = getMeetingLink(); + const meetingLink = callDetail?.id ? getMeetingLink(callDetail.id) : '';Add this import near the top of the file:
import { getMeetingLink } from '../lib/meeting-utils';app/(root)/(home)/page.tsx (1)
7-14: Prevent potential hydration mismatch from server-rendered DateInitializing
nowwithnew Date()can cause hydration warnings because Client Components still render on the server during SSR. The client time will differ from the server-rendered time. Initialize to null and set it on mount, and optionally suppress hydration warnings on the time/date elements.Apply this diff:
- const [now, setNow] = useState<Date>(() => new Date()); + const [now, setNow] = useState<Date | null>(null); useEffect(() => { - // update every second to keep minutes accurate and avoid drift - const tick = () => setNow(new Date()); - const id = setInterval(tick, 1000); - return () => clearInterval(id); + // set once on mount, then update every second + setNow(new Date()); + const id = setInterval(() => setNow(new Date()), 1000); + return () => clearInterval(id); }, []); - const time = now.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' }); - const date = new Intl.DateTimeFormat(undefined, { dateStyle: 'full' }).format(now); + const time = now + ? now.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' }) + : ''; + const date = now + ? new Intl.DateTimeFormat(undefined, { dateStyle: 'full' }).format(now) + : '';Outside the selected range, add the following attributes to suppress hydration warnings until
nowis set:<h1 className="text-4xl font-extrabold lg:text-7xl" suppressHydrationWarning> {time || '—'} </h1> <p className="text-lg font-medium text-sky-1 lg:text-2xl" suppressHydrationWarning> {date || '—'} </p>Also applies to: 16-17, 27-28
app/(root)/(home)/personal-room/page.tsx (3)
74-87: Deduplicate meeting link logic by importing the shared utilityYou’re re-implementing meeting link generation locally. Import and reuse the shared
getMeetingLinkfromlib/meeting-utilsto keep behavior consistent across the app and avoid drift.Apply this diff:
@@ -import Image from "next/image"; +import Image from "next/image"; +import { getMeetingLink as buildMeetingLink } from "@/lib/meeting-utils"; @@ - const getMeetingLink = () => { - const baseUrl = process.env.NEXT_PUBLIC_BASE_URL; - // In production, use the configured URL - if (baseUrl && !baseUrl.includes('localhost')) { - return `${baseUrl}/meeting/${meetingId}?personal=true`; - } - // In development or if BASE_URL is not set, use the current origin - return typeof window !== 'undefined' - ? `${window.location.origin}/meeting/${meetingId}?personal=true` - : `/meeting/${meetingId}?personal=true`; - }; - - const meetingLink = getMeetingLink(); + const meetingLink = meetingId ? `${buildMeetingLink(meetingId)}?personal=true` : "";
58-72: Harden startRoom with missing-id guard and error handlingNetwork calls can fail; also,
meetingIdmay be empty on first render. Add a guard and surface errors via toast.Apply this diff:
const startRoom = async () => { - if (!client || !user) return; + if (!client || !user) return; + if (!meetingId) { + toast({ title: "Error", description: "Meeting ID is not ready yet. Please try again.", variant: "destructive" }); + return; + } const newCall = client.call("default", meetingId!); - if (!call) { - await newCall.getOrCreate({ - data: { - starts_at: new Date().toISOString(), - }, - }); - } + try { + if (!call) { + await newCall.getOrCreate({ + data: { starts_at: new Date().toISOString() }, + }); + } + } catch (err) { + console.error("Failed to start room:", err); + toast({ title: "Error", description: "Failed to start the meeting. Please try again.", variant: "destructive" }); + return; + } router.push(`/meeting/${meetingId}?personal=true`); };
101-105: Avoid “undefined” in invitation topic and improve copy text robustnessIf
user?.usernameis not set, the invitation currently prints “undefined’s Meeting Room”. Provide a sensible fallback.Apply this diff:
- const inviteText = `Join my meeting room!\n\nTopic: ${user?.username}'s Meeting Room\nMeeting ID: ${meetingId}\nJoin Link: ${meetingLink}`; + const displayName = user?.username ?? user?.fullName ?? "Personal"; + const inviteText = `Join my meeting room!\n\nTopic: ${displayName}'s Meeting Room\nMeeting ID: ${meetingId || 'TBD'}\nJoin Link: ${meetingLink || 'TBD'}`;README.md (3)
36-45: Wrap install commands in code fencesWithout fences, markdownlint flags and formatting suffer. Fence these commands.
Apply this diff:
Install dependencies: -npm install -# or -yarn install +```bash +npm install +# or +yarn install +```
46-50: Fence dev commands for consistency and readabilitySame as above for the dev server commands.
Apply this diff:
Run the development server: -npm run dev -# or -yarn dev +```bash +npm run dev +# or +yarn dev +```
51-51: Avoid bare URL (MD034) by formatting the localhost linkThis also reads better.
Apply this diff:
-Open your browser at http://localhost:3000 🎉 +Open your browser at [`http://localhost:3000`](http://localhost:3000) 🎉components/CallList.tsx (1)
20-50: Avoid setState on unmounted component during async recordings fetchAdd a cancellation flag to prevent
setRecordingsafter unmount or type switch.Apply this diff:
useEffect(() => { - const fetchRecordings = async () => { + let cancelled = false; + const fetchRecordings = async () => { if (!callRecordings?.length) { - setRecordings([]); + if (!cancelled) setRecordings([]); return; } try { const callData = await Promise.all( callRecordings.map((meeting) => meeting.queryRecordings().catch((error) => { console.error("Error fetching recording:", error); return { recordings: [] } as any; }), ), ); const newRecordings = callData .filter((c) => c.recordings?.length > 0) .flatMap((c) => c.recordings); - setRecordings(newRecordings); + if (!cancelled) setRecordings(newRecordings); } catch (error) { console.error("Error fetching recordings:", error); toast({ title: "Error", description: "Failed to fetch recordings.", variant: "destructive" }); - setRecordings([]); + if (!cancelled) setRecordings([]); } }; - if (type === "recordings") fetchRecordings(); - }, [type, callRecordings, toast]); + if (type === "recordings") fetchRecordings(); + return () => { + cancelled = true; + }; + }, [type, callRecordings, toast]);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
💡 Knowledge Base configuration:
- MCP integration is disabled by default for public repositories
- Jira integration is disabled by default for public repositories
- Linear integration is disabled by default for public repositories
You can enable these sources in your CodeRabbit configuration.
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (14)
.env(1 hunks).gitignore(1 hunks).nvmrc(1 hunks)README.md(1 hunks)app/(root)/(home)/layout.tsx(1 hunks)app/(root)/(home)/page.tsx(1 hunks)app/(root)/(home)/personal-room/page.tsx(4 hunks)app/layout.tsx(2 hunks)components/CallList.tsx(1 hunks)components/MeetingTypeList.tsx(1 hunks)components/MobileNav.tsx(1 hunks)components/Navbar.tsx(1 hunks)lib/meeting-utils.ts(1 hunks)package.json(2 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (3)
components/MeetingTypeList.tsx (1)
lib/meeting-utils.ts (1)
getMeetingLink(1-12)
app/(root)/(home)/personal-room/page.tsx (2)
components/ui/use-toast.ts (1)
toast(194-194)lib/meeting-utils.ts (1)
getMeetingLink(1-12)
components/CallList.tsx (2)
hooks/useGetCalls.ts (1)
useGetCalls(5-52)components/ui/use-toast.ts (2)
useToast(194-194)toast(194-194)
🪛 dotenv-linter (3.3.0)
.env
[warning] 2-2: [UnorderedKey] The CLERK_SECRET_KEY key should go before the NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY key
(UnorderedKey)
[warning] 10-10: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
🪛 LanguageTool
README.md
[grammar] ~1-~1: There might be a mistake here.
Context: # Ro0m 🎥 An open-source, browser-based alternative...
(QB_NEW_EN)
[grammar] ~6-~6: There might be a mistake here.
Context: ...y. 🔗 Live Demo: ro0m.vercel.app --- ## ✨ Features - 🔊 **Real-time video & audio...
(QB_NEW_EN)
[grammar] ~10-~10: There might be a mistake here.
Context: ...s://ro0m.vercel.app) --- ## ✨ Features - 🔊 Real-time video & audio powered b...
(QB_NEW_EN)
[grammar] ~12-~12: There might be a mistake here.
Context: ...e video & audio** powered by WebRTC - 💬 Chat support during calls - 🖥️ *...
(QB_NEW_EN)
[grammar] ~13-~13: There might be a mistake here.
Context: ... 💬 Chat support during calls - 🖥️ Screen sharing - 📱 **Responsive ...
(QB_NEW_EN)
[grammar] ~14-~14: There might be a mistake here.
Context: ...calls - 🖥️ Screen sharing - 📱 Responsive design (works on desktop &...
(QB_NEW_EN)
[grammar] ~15-~15: There might be a mistake here.
Context: ...gn** (works on desktop & mobile) - 🔗 Instant room creation with unique shar...
(QB_NEW_EN)
[grammar] ~16-~16: There might be a mistake here.
Context: ...** with unique shareable links - 🌐 Self-hostable — deploy on your own serv...
(QB_NEW_EN)
[grammar] ~16-~16: There might be a mistake here.
Context: ...eable links - 🌐 Self-hostable — deploy on your own server or Vercel --- ## 🛠️ T...
(QB_NEW_EN)
[grammar] ~20-~20: There might be a mistake here.
Context: ... your own server or Vercel --- ## 🛠️ Tech Stack - [Next.js](https://nextjs.org/...
(QB_NEW_EN)
[grammar] ~21-~21: There might be a mistake here.
Context: ... or Vercel --- ## 🛠️ Tech Stack - Next.js – React fra...
(QB_NEW_EN)
[grammar] ~22-~22: There might be a mistake here.
Context: ...s://nextjs.org/) – React framework - WebRTC – Real-time ...
(QB_NEW_EN)
[grammar] ~23-~23: There might be a mistake here.
Context: ...tc.org/) – Real-time communication - Tailwind CSS –...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...m/) – Modern utility-first styling - Vercel – Deployment...
(QB_NEW_EN)
[grammar] ~24-~24: There might be a mistake here.
Context: ...ps://vercel.com/) – Deployment & hosting --- ## 🚀 Getting Started ### Prerequisites Mak...
(QB_NEW_EN)
[grammar] ~28-~28: There might be a mistake here.
Context: ... & hosting --- ## 🚀 Getting Started ### Prerequisites Make sure you have the foll...
(QB_NEW_EN)
[grammar] ~30-~30: There might be a mistake here.
Context: ...## 🚀 Getting Started ### Prerequisites Make sure you have the following install...
(QB_NEW_EN)
[grammar] ~31-~31: There might be a mistake here.
Context: ...e sure you have the following installed: - Node.js (v16 or la...
(QB_NEW_EN)
[grammar] ~32-~32: There might be a mistake here.
Context: ...have the following installed: - Node.js (v16 or later) - npm or yarn package ma...
(QB_NEW_EN)
[grammar] ~32-~32: There might be a mistake here.
Context: ....js](https://nodejs.org/) (v16 or later) - npm or yarn package manager ### Install...
(QB_NEW_EN)
[grammar] ~35-~35: There might be a mistake here.
Context: ...r yarn package manager ### Installation 1. Clone the repo: ```bash git clone ...
(QB_NEW_EN)
[grammar] ~41-~41: There might be a mistake here.
Context: ...0m.git cd Ro0m Install dependencies: npm install # or yarn install Run the d...
(QB_NEW_EN)
[grammar] ~42-~42: There might be a mistake here.
Context: ... Ro0m Install dependencies: npm install # or yarn install Run the development ser...
(QB_NEW_EN)
[grammar] ~43-~43: There might be a mistake here.
Context: ... Install dependencies: npm install # or yarn install Run the development server...
(QB_NEW_EN)
[grammar] ~46-~46: There might be a mistake here.
Context: ...arn install Run the development server: npm run dev # or yarn dev Open your bro...
(QB_NEW_EN)
[grammar] ~47-~47: There might be a mistake here.
Context: ... Run the development server: npm run dev # or yarn dev Open your browser at http:/...
(QB_NEW_EN)
[grammar] ~48-~48: There might be a mistake here.
Context: ...the development server: npm run dev # or yarn dev Open your browser at http://lo...
(QB_NEW_EN)
[grammar] ~51-~51: There might be a mistake here.
Context: ...your browser at http://localhost:3000 🎉 ⚙️ Environment Variables NEXT_PUBLIC_PEER...
(QB_NEW_EN)
[grammar] ~53-~53: There might be a mistake here.
Context: ...alhost:3000 🎉 ⚙️ Environment Variables NEXT_PUBLIC_PEER_SERVER=your-peer-server...
(QB_NEW_EN)
[grammar] ~54-~54: There might be a mistake here.
Context: ...NEXT_PUBLIC_PEER_SERVER=your-peer-server NEXT_PUBLIC_TURN_SERVER=your-turn-server...
(QB_NEW_EN)
[grammar] ~55-~55: There might be a mistake here.
Context: ...NEXT_PUBLIC_TURN_SERVER=your-turn-server NEXT_PUBLIC_STUN_SERVER=your-stun-server...
(QB_NEW_EN)
[grammar] ~56-~56: There might be a mistake here.
Context: ...NEXT_PUBLIC_STUN_SERVER=your-stun-server 👉 You can use free Google STUN servers ...
(QB_NEW_EN)
[grammar] ~57-~57: There might be a mistake here.
Context: ...oy your own TURN server for reliability. ☁️ Deployment Deploy instantly with Verce...
(QB_NEW_EN)
[grammar] ~59-~59: There might be a mistake here.
Context: ...N server for reliability. ☁️ Deployment Deploy instantly with Vercel: Fork this ...
(QB_NEW_EN)
[grammar] ~60-~60: There might be a mistake here.
Context: ...Deployment Deploy instantly with Vercel: Fork this repo Push to your GitHub accou...
(QB_NEW_EN)
[grammar] ~65-~65: There might be a mistake here.
Context: ...es (if any) Done 🎉 — your Ro0m is live! 🤝 Contributing Contributions are welcome...
(QB_NEW_EN)
[style] ~71-~71: Consider using a more formal and expressive alternative to ‘awesome’.
Context: ...Commit your changes (git commit -m 'Add awesome feature') Push to the branch (git push ...
(AWESOME)
[grammar] ~75-~75: There might be a mistake here.
Context: ...eature) Open a Pull Request 📜 License This project is licensed under the MIT Li...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ...This project is licensed under the MIT License – see the LICENSE file for details. 🙏 Acknow...
(QB_NEW_EN)
[grammar] ~76-~76: There might be a mistake here.
Context: ...ense – see the LICENSE file for details. 🙏 Acknowledgments adrianhajdin/zoom-clon...
(QB_NEW_EN)
[grammar] ~78-~78: There might be a mistake here.
Context: ...E file for details. 🙏 Acknowledgments adrianhajdin/zoom-clone – Original inspir...
(QB_NEW_EN)
[grammar] ~79-~79: There might be a mistake here.
Context: ... 🙏 Acknowledgments adrianhajdin/zoom-clone – Original inspiration & base project The open-sou...
(QB_NEW_EN)
[grammar] ~79-~79: There might be a mistake here.
Context: ...ne – Original inspiration & base project The open-source community ❤️
(QB_NEW_EN)
🪛 markdownlint-cli2 (0.17.2)
README.md
48-48: Multiple headings with the same content
(MD024, no-duplicate-heading)
51-51: Bare URL used
(MD034, no-bare-urls)
🔇 Additional comments (6)
.nvmrc (1)
1-1: Pinning Node 18 is appropriate for Next.js 14 — LGTMThis aligns with Next 14’s supported Node range and common Vercel defaults.
components/MobileNav.tsx (1)
32-35: Branding update looks goodAlt text and visible brand updated to Ro0m consistently with the rename.
components/Navbar.tsx (1)
15-20: Branding update looks goodAlt text and brand text updated to Ro0m consistently with other components.
app/layout.tsx (1)
30-31: Logo path update looks correctClerkProvider’s logoImageUrl now points to /icons/logo.svg, consistent with the rest of the app and metadata icons.
app/(root)/(home)/layout.tsx (1)
8-9: Brand rename applied — LGTMMetadata title updated to Ro0m; consistent with top-level layout and Navbar/MobileNav.
components/CallList.tsx (1)
54-60: Unified rendering and toast-backed error handling look solidThe consolidation into a single rendering path, selective iconography, and per-item click handling reads cleaner and easier to maintain.
Also applies to: 65-101
| NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_YWNjZXB0ZWQtY2hvdy05NS5jbGVyay5hY2NvdW50cy5kZXYk | ||
| CLERK_SECRET_KEY=sk_test_mpfZe0XiSoV5SZgUn8ZqCNT9pVTu4fYMTAdcpIH8X7 | ||
|
|
||
| NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in | ||
| NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up | ||
|
|
||
| NEXT_PUBLIC_STREAM_API_KEY=wmvqzwwh9s4q | ||
| STREAM_SECRET_KEY=86e88tqe2h82zvah5ge99ct584fn2gwd8mhewyy87vkesk4zmm6z62bgqegwer7j | ||
|
|
||
| NEXT_PUBLIC_BASE_URL=https://ro0m.vercel.app No newline at end of file |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Critical: Secrets are committed to the repo (.env). Remove and rotate immediately.
Committing CLERK_SECRET_KEY and STREAM_SECRET_KEY (even test keys) is a high-severity leak. These credentials should be considered compromised.
Immediate actions:
- Revoke/rotate the exposed secrets in Clerk and Stream dashboards.
- Remove the file from Git and from history:
- In this PR: run
git rm --cached .env, commit, and push (the file will remain in history). - To purge history (recommended for public repos): use BFG Repo-Cleaner or git filter-repo to remove .env from all commits, then force-push.
- In this PR: run
- Add a non-sensitive .env.example with placeholders and keep .env ignored (rules are already in .gitignore).
Optionally, I can provide a .env.example template with the correct keys and comments.
🧰 Tools
🪛 dotenv-linter (3.3.0)
[warning] 2-2: [UnorderedKey] The CLERK_SECRET_KEY key should go before the NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY key
(UnorderedKey)
[warning] 10-10: [EndingBlankLine] No blank line at the end of the file
(EndingBlankLine)
🤖 Prompt for AI Agents
.env lines 1-10: Sensitive secrets (CLERK_SECRET_KEY, STREAM_SECRET_KEY, etc.)
are committed and must be removed and rotated immediately; revoke/rotate the
exposed keys in Clerk and Stream dashboards, delete the file from the repo with
git rm --cached .env then commit and push, and purge the secret from history
using BFG or git filter-repo (force-push after cleaning) for public repos; add a
non-sensitive .env.example with placeholder values, ensure .env is listed in
.gitignore, and avoid re-committing real secrets.
| const date = | ||
| (isRecording ? (meeting as CallRecording).start_time : (meeting as Call).state?.startsAt)?.toLocaleString?.() || | ||
| "No date"; | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix date formatting for strings vs Dates
Calling .toLocaleString?.() on a string does not format the date; you’ll get the unformatted string. Normalize to a Date before formatting.
Apply this diff:
- const date =
- (isRecording ? (meeting as CallRecording).start_time : (meeting as Call).state?.startsAt)?.toLocaleString?.() ||
- "No date";
+ const rawDate = isRecording
+ ? (meeting as CallRecording).start_time
+ : (meeting as Call).state?.startsAt;
+ const date = rawDate ? new Date(rawDate as any).toLocaleString() : "No date";📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const date = | |
| (isRecording ? (meeting as CallRecording).start_time : (meeting as Call).state?.startsAt)?.toLocaleString?.() || | |
| "No date"; | |
| const rawDate = isRecording | |
| ? (meeting as CallRecording).start_time | |
| : (meeting as Call).state?.startsAt; | |
| const date = rawDate ? new Date(rawDate as any).toLocaleString() : "No date"; |
🤖 Prompt for AI Agents
In components/CallList.tsx around lines 72 to 75, the code calls toLocaleString
on values that may be strings, so the string won’t be normalized to a Date;
instead, extract the raw timestamp (use meeting as CallRecording).start_time
when isRecording else (meeting as Call).state?.startsAt, check if that value is
an instance of Date and use it directly, otherwise construct a new
Date(rawValue) and verify it’s valid (date.getTime() is not NaN); then call
toLocaleString on the Date and fall back to "No date" if the value is missing or
invalid. Ensure the branch handles null/undefined safely and does not call
toLocaleString on a string.
| handleClick={() => { | ||
| if (isRecording) { | ||
| const url = (meeting as CallRecording).url; | ||
| if (url) router.push(url); | ||
| else toast({ title: "Error", description: "Recording URL not found", variant: "destructive" }); | ||
| } else { | ||
| openMeeting((meeting as Call).id); | ||
| } | ||
| }} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use window.open for external recording URLs instead of router.push
next/navigation’s router only supports internal navigation. Pushing an absolute URL can fail. Open recordings in a new tab.
Apply this diff:
- handleClick={() => {
+ handleClick={() => {
if (isRecording) {
const url = (meeting as CallRecording).url;
- if (url) router.push(url);
+ if (url) window.open(url, "_blank", "noopener,noreferrer");
else toast({ title: "Error", description: "Recording URL not found", variant: "destructive" });
} else {
openMeeting((meeting as Call).id);
}
}}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| handleClick={() => { | |
| if (isRecording) { | |
| const url = (meeting as CallRecording).url; | |
| if (url) router.push(url); | |
| else toast({ title: "Error", description: "Recording URL not found", variant: "destructive" }); | |
| } else { | |
| openMeeting((meeting as Call).id); | |
| } | |
| }} | |
| handleClick={() => { | |
| if (isRecording) { | |
| const url = (meeting as CallRecording).url; | |
| if (url) window.open(url, "_blank", "noopener,noreferrer"); | |
| else toast({ title: "Error", description: "Recording URL not found", variant: "destructive" }); | |
| } else { | |
| openMeeting((meeting as Call).id); | |
| } | |
| }} |
🤖 Prompt for AI Agents
In components/CallList.tsx around lines 90 to 98, the click handler currently
uses router.push for recording URLs which only supports internal navigation;
change it to open the recording in a new browser tab using window.open(url,
'_blank', 'noopener,noreferrer') when url exists, and keep the toast fallback
for missing URL; leave the non-recording branch calling openMeeting((meeting as
Call).id) unchanged.
| - [Node.js](https://nodejs.org/) (v16 or later) | ||
| - npm or yarn package manager |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incorrect Node.js version requirement for Next.js 14
The project (per package.json in this PR) uses Next.js ^14.2.x, which requires Node.js 18+. Update the prerequisite to avoid setup failures on Node 16.
Apply this diff:
-- [Node.js](https://nodejs.org/) (v16 or later)
+- [Node.js](https://nodejs.org/) (v18 LTS or later)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| - [Node.js](https://nodejs.org/) (v16 or later) | |
| - npm or yarn package manager | |
| - [Node.js](https://nodejs.org/) (v18 LTS or later) | |
| - npm or yarn package manager |
🧰 Tools
🪛 LanguageTool
[grammar] ~32-~32: There might be a mistake here.
Context: ...have the following installed: - Node.js (v16 or later) - npm or yarn package ma...
(QB_NEW_EN)
[grammar] ~32-~32: There might be a mistake here.
Context: ....js](https://nodejs.org/) (v16 or later) - npm or yarn package manager ### Install...
(QB_NEW_EN)
🤖 Prompt for AI Agents
In README.md around lines 32-33, the Node.js prerequisite is incorrect (lists
Node v16) while package.json requires Next.js ^14.2.x which needs Node.js 18+,
so update the prerequisite to state Node.js v18 or later (and optionally mention
an LTS recommendation), leaving the package manager line as-is; ensure the
README reflects Node 18+ to prevent setup failures.
| git clone https://github.com/archduke1337/Ro0m.git | ||
| cd Ro0m | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Repository clone URL likely does not match this project
The README instructs cloning a different repository. Use this repo’s canonical slug or a parameterized placeholder to prevent confusion.
Apply this diff (adjust the URL to the actual canonical repo):
- git clone https://github.com/archduke1337/Ro0m.git
- cd Ro0m
+ git clone https://github.com/adrianhajdin/zoom-clone.git
+ cd zoom-clone📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| git clone https://github.com/archduke1337/Ro0m.git | |
| cd Ro0m | |
| git clone https://github.com/adrianhajdin/zoom-clone.git | |
| cd zoom-clone |
🤖 Prompt for AI Agents
In README.md around lines 38 to 40, the git clone URL points to
"https://github.com/archduke1337/Ro0m.git" which is likely for a different
project; replace it with the repository’s canonical slug or a parameterized
placeholder (e.g. "https://github.com/<org>/<repo>.git" or the actual repo URL)
so cloning instructions match this project and avoid confusion.
| ⚙️ Environment Variables | ||
| NEXT_PUBLIC_PEER_SERVER=your-peer-server | ||
| NEXT_PUBLIC_TURN_SERVER=your-turn-server | ||
| NEXT_PUBLIC_STUN_SERVER=your-stun-server | ||
| 👉 You can use free Google STUN servers or deploy your own TURN server for reliability. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
💡 Verification agent
🧩 Analysis chain
Environment variables are mismatched with the current codebase
The app uses Clerk and Stream Video SDK across multiple files and relies on NEXT_PUBLIC_BASE_URL for meeting links. The listed WebRTC STUN/TURN variables aren’t used, which will mislead new contributors. Document the actual required variables and remove or clearly separate optional ones.
Proposed replacement (verify names used in your codebase before merging):
-⚙️ Environment Variables
-NEXT_PUBLIC_PEER_SERVER=your-peer-server
-NEXT_PUBLIC_TURN_SERVER=your-turn-server
-NEXT_PUBLIC_STUN_SERVER=your-stun-server
-👉 You can use free Google STUN servers or deploy your own TURN server for reliability.
+⚙️ Environment Variables
+Create a `.env.local` file with:
+```env
+# Clerk
+NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
+CLERK_SECRET_KEY=sk_test_...
+
+# Stream
+NEXT_PUBLIC_STREAM_API_KEY=your_stream_api_key
+# STREAM_SECRET=your_stream_secret # if you use server-side tokens
+
+# App base URL (used for invitation links)
+NEXT_PUBLIC_BASE_URL=https://your-domain.com
+```
+If you’re running your own WebRTC infra, list STUN/TURN config separately as optional.If you’d like, I can scan the repository and produce an authoritative list of env vars referenced in code.
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
declare -a vars=(
"NEXT_PUBLIC_PEER_SERVER"
"NEXT_PUBLIC_TURN_SERVER"
"NEXT_PUBLIC_STUN_SERVER"
"NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY"
"CLERK_SECRET_KEY"
"NEXT_PUBLIC_STREAM_API_KEY"
"STREAM_SECRET"
"NEXT_PUBLIC_BASE_URL"
)
echo "Searching for environment variable references in the codebase..."
for var in "${vars[@]}"; do
echo "=== $var ==="
rg -n --color never "$var" || echo "No matches"
echo
doneLength of output: 2344
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
echo "1) Searching for any process.env.*CLERK references..."
rg -n --color never 'process\.env\..*CLERK' -g '*.ts' -g '*.tsx' || echo "No matches for process.env.*CLERK"
echo
echo "2) Locating where ClerkProvider is used:"
rg -n --color never 'ClerkProvider' -g '*.tsx' -g '*.ts' || echo "No matches for ClerkProvider"
echo
echo "3) Broad search for 'clerk' to catch imports or config keys:"
rg -ni --color never 'clerk' -g '*.ts' -g '*.tsx' || echo "No general matches for 'clerk'"Length of output: 1892
Update README.md to reflect actual environment variables
The current snippet lists NEXT_PUBLIC_PEER_SERVER, NEXT_PUBLIC_TURN_SERVER, and NEXT_PUBLIC_STUN_SERVER, but none of these are referenced anywhere in the codebase—they only appear in README.md. Instead, the app and its dependencies read the following from process.env.*:
- Clerk (
@clerk/nextjs+ middleware)
• NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
• CLERK_SECRET_KEY - Stream Video SDK (
providers/StreamClientProvider.tsx,actions/stream.actions.ts)
• NEXT_PUBLIC_STREAM_API_KEY
• STREAM_SECRET_KEY - App invitation links (
lib/meeting-utils.ts,components/MeetingTypeList.tsx, etc.)
• NEXT_PUBLIC_BASE_URL
Please remove the unused STUN/TURN entries and replace with this diff in README.md (around lines 53–57):
--- README.md
@@ 53,57
-⚙️ Environment Variables
-NEXT_PUBLIC_PEER_SERVER=your-peer-server
-NEXT_PUBLIC_TURN_SERVER=your-turn-server
-NEXT_PUBLIC_STUN_SERVER=your-stun-server
-👉 You can use free Google STUN servers or deploy your own TURN server for reliability.
+⚙️ Environment Variables
+Create a `.env.local` file with:
+```env
+# Clerk
+NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_...
+CLERK_SECRET_KEY=sk_test_...
+
+# Stream Video
+NEXT_PUBLIC_STREAM_API_KEY=your_stream_api_key
+STREAM_SECRET_KEY=your_stream_secret_key
+
+# App base URL (used for invitation links)
+NEXT_PUBLIC_BASE_URL=https://your-domain.com
+```
+
+_Optional (only if you run your own WebRTC servers):_
+```env
+STUN_SERVER=your-stun-server
+TURN_SERVER=your-turn-server
+```This aligns the docs with the variables actually consumed by the codebase.
🧰 Tools
🪛 LanguageTool
[grammar] ~53-~53: There might be a mistake here.
Context: ...alhost:3000 🎉 ⚙️ Environment Variables NEXT_PUBLIC_PEER_SERVER=your-peer-server...
(QB_NEW_EN)
[grammar] ~54-~54: There might be a mistake here.
Context: ...NEXT_PUBLIC_PEER_SERVER=your-peer-server NEXT_PUBLIC_TURN_SERVER=your-turn-server...
(QB_NEW_EN)
[grammar] ~55-~55: There might be a mistake here.
Context: ...NEXT_PUBLIC_TURN_SERVER=your-turn-server NEXT_PUBLIC_STUN_SERVER=your-stun-server...
(QB_NEW_EN)
[grammar] ~56-~56: There might be a mistake here.
Context: ...NEXT_PUBLIC_STUN_SERVER=your-stun-server 👉 You can use free Google STUN servers ...
(QB_NEW_EN)
[grammar] ~57-~57: There might be a mistake here.
Context: ...oy your own TURN server for reliability. ☁️ Deployment Deploy instantly with Verce...
(QB_NEW_EN)
🤖 Prompt for AI Agents
In README.md around lines 53 to 57, the listed environment variables
(NEXT_PUBLIC_PEER_SERVER, NEXT_PUBLIC_TURN_SERVER, NEXT_PUBLIC_STUN_SERVER) are
not used by the codebase; update the section to remove those unused entries and
replace them with the actual env vars consumed: add Clerk keys
(NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY and CLERK_SECRET_KEY), Stream Video keys
(NEXT_PUBLIC_STREAM_API_KEY and STREAM_SECRET_KEY), and NEXT_PUBLIC_BASE_URL for
invitation links, and move STUN/TURN into an optional block labeled for
self-hosted WebRTC servers (STUN_SERVER and TURN_SERVER).
This PR adds a complete README.md file for the project.
The README includes:
This will help new developers and users quickly understand, set up, and contribute to the project.
Summary by CodeRabbit
New Features
Style
Documentation
Chores