Skip to content

Commit

Permalink
Video call
Browse files Browse the repository at this point in the history
  • Loading branch information
HarshitBamotra committed Feb 14, 2024
1 parent 8adc6f0 commit 9397a7d
Show file tree
Hide file tree
Showing 8 changed files with 546 additions and 100 deletions.
120 changes: 70 additions & 50 deletions app/(main)/(routes)/servers/[serverId]/channels/[channelId]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,80 +1,100 @@
import { ChatHeader } from "@/components/chat/chat-header";
import { ChatInput } from "@/components/chat/chat-input";
import { ChatMessages } from "@/components/chat/chat-messages";
import { currentProfile } from "@/lib/current-profile"
import { MediaRoom } from "@/components/media-room";
import { currentProfile } from "@/lib/current-profile";
import { db } from "@/lib/db";
import { redirectToSignIn } from "@clerk/nextjs";
import { ChannelType } from "@prisma/client";
import { redirect } from "next/navigation";

interface ChannelIdPageProps{
params:{
serverId: string,
channelId: string
}
interface ChannelIdPageProps {
params: {
serverId: string;
channelId: string;
};
}


const ChannelIdPage = async (
{params}: ChannelIdPageProps
)=>{

const ChannelIdPage = async ({ params }: ChannelIdPageProps) => {
const profile = await currentProfile();
if(!profile){
if (!profile) {
return redirectToSignIn();
}

const channel = await db.channel.findUnique({
where:{
id: params.channelId
}
where: {
id: params.channelId,
},
});

const member = await db.member.findFirst({
where:{
where: {
serverId: params.serverId,
profileId: profile.id
}
profileId: profile.id,
},
});
if(!channel || !member){

if (!channel || !member) {
redirect("/");
}



return(
return (
<div className="bg-white dark:bg-[#313338] flex flex-col h-full">
<ChatHeader
name={channel.name}
serverId={channel.serverId}
type="channel"
/>
<ChatMessages
member={member}
name={channel.name}
chatId={channel.id}
type="channel"
apiUrl = "/api/messages"
socketUrl = "/api/socket/messages"
socketQuery={{
channelId: channel.id,
serverId: channel.serverId
}}
paramKey= "channelId"
paramValue={channel.id}
/>
<ChatInput
name={channel.name}
type="channel"
apiUrl="/api/socket/messages"
query={{
channelId: channel.id,
serverId: channel.serverId
}}
/>
</div>
)
}
{channel.type === ChannelType.TEXT && (
<>
<ChatMessages
member={member}
name={channel.name}
chatId={channel.id}
type="channel"
apiUrl="/api/messages"
socketUrl="/api/socket/messages"
socketQuery={{
channelId: channel.id,
serverId: channel.serverId,
}}
paramKey="channelId"
paramValue={channel.id}
/>
<ChatInput
name={channel.name}
type="channel"
apiUrl="/api/socket/messages"
query={{
channelId: channel.id,
serverId: channel.serverId,
}}
/>
</>
)}
{
channel.type===ChannelType.AUDIO && (
<MediaRoom
chatId={channel.id}
video={false}
audio={true}
/>
)
}
{
channel.type===ChannelType.VIDEO && (
<MediaRoom
chatId={channel.id}
video={true}
audio={true}
/>
)
}



export default ChannelIdPage;
</div>
);
};

export default ChannelIdPage;
Original file line number Diff line number Diff line change
@@ -1,84 +1,97 @@
import { ChatHeader } from "@/components/chat/chat-header";
import { ChatInput } from "@/components/chat/chat-input";
import { ChatMessages } from "@/components/chat/chat-messages";
import { MediaRoom } from "@/components/media-room";
import { getOrCreateConversation } from "@/lib/conversation";
import { currentProfile } from "@/lib/current-profile"
import { currentProfile } from "@/lib/current-profile";
import { db } from "@/lib/db";
import { redirectToSignIn } from "@clerk/nextjs";
import { redirect } from "next/navigation";

interface MemberIdPageProps{
params:{
memberId: string,
serverId: string
}
interface MemberIdPageProps {
params: {
memberId: string;
serverId: string;
};
searchParams: {
video?: boolean;
};
}

const MemberIdPage = async (
{params}: MemberIdPageProps
)=>{

const MemberIdPage = async ({ params, searchParams }: MemberIdPageProps) => {
const profile = await currentProfile();
if(!profile){
if (!profile) {
return redirectToSignIn();
}

const currentMember = await db.member.findFirst({
where:{
where: {
serverId: params.serverId,
profileId: profile.id
profileId: profile.id,
},
include: {
profile: true,
},
include:{
profile: true
}
})
});

if(!currentMember){
if (!currentMember) {
return redirect("/");
}

const conversation = await getOrCreateConversation(currentMember.id, params.memberId);
if(!conversation){
const conversation = await getOrCreateConversation(
currentMember.id,
params.memberId
);
if (!conversation) {
return redirect(`/servers/${params.serverId}`);
}

const {memberOne, memberTwo} = conversation;
const otherMember = memberOne.profileId === profile.id ? memberTwo : memberOne;



const { memberOne, memberTwo } = conversation;
const otherMember =
memberOne.profileId === profile.id ? memberTwo : memberOne;

return(
return (
<div className="bg-white dark:bg-[#313338] flex flex-col h-full">
<ChatHeader
name={otherMember.profile.name}
imageUrl={otherMember.profile.imageUrl}
serverId={params.serverId}
type="conversation"
/>
<ChatMessages
member={currentMember}
name={currentMember.profile.name}
chatId={conversation.id}
type="conversation"
apiUrl="/api/direct-messages"
paramKey="conversationId"
paramValue={conversation.id}
socketUrl="/api/socket/direct-messages"
socketQuery={{
conversationId: conversation.id
}}
/>
<ChatInput
name={otherMember.profile.name}
type="conversation"
apiUrl="/api/socket/direct-messages"
query={{
conversationId: conversation.id
}}
/>
{!searchParams.video && (
<>
<ChatMessages
member={currentMember}
name={currentMember.profile.name}
chatId={conversation.id}
type="conversation"
apiUrl="/api/direct-messages"
paramKey="conversationId"
paramValue={conversation.id}
socketUrl="/api/socket/direct-messages"
socketQuery={{
conversationId: conversation.id,
}}
/>
<ChatInput
name={otherMember.profile.name}
type="conversation"
apiUrl="/api/socket/direct-messages"
query={{
conversationId: conversation.id,
}}
/>
</>
)}
{searchParams.video && (
<MediaRoom
chatId={conversation.id}
video={false}
audio={true}
/>
)}
</div>
)
}
);
};

export default MemberIdPage;
export default MemberIdPage;
35 changes: 35 additions & 0 deletions app/api/livekit/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { AccessToken } from "livekit-server-sdk";
import { NextRequest, NextResponse } from "next/server";

export async function GET(req: NextRequest) {
const room = req.nextUrl.searchParams.get("room");
const username = req.nextUrl.searchParams.get("username");
if (!room) {
return NextResponse.json(
{ error: 'Missing "room" query parameter' },
{ status: 400 }
);
} else if (!username) {
return NextResponse.json(
{ error: 'Missing "username" query parameter' },
{ status: 400 }
);
}

const apiKey = process.env.LIVEKIT_API_KEY;
const apiSecret = process.env.LIVEKIT_SECRET_KEY;
const wsUrl = process.env.NEXT_PUBLIC_LIVEKIT_URL;

if (!apiKey || !apiSecret || !wsUrl) {
return NextResponse.json(
{ error: "Server misconfigured" },
{ status: 500 }
);
}

const at = new AccessToken(apiKey, apiSecret, { identity: username });

at.addGrant({ room, roomJoin: true, canPublish: true, canSubscribe: true });

return NextResponse.json({ token: await at.toJwt() });
}
4 changes: 4 additions & 0 deletions components/chat/chat-header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { Hash} from "lucide-react"
import { MobileToggle } from "../mobile-toggle"
import { UserAvatar } from "../userAvatar"
import { SocketIndicator } from "../socket-indicator"
import { ChatVideoButton } from "./chat-video-button"

interface ChatHeaderProps{
serverId: string,
Expand All @@ -28,6 +29,9 @@ export const ChatHeader = (
{name}
</p>
<div className="ml-auto flex items-center">
{type==="conversation" && (
<ChatVideoButton/>
)}
<SocketIndicator></SocketIndicator>
</div>
</div>
Expand Down
Loading

0 comments on commit 9397a7d

Please sign in to comment.