-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
create or get conversation get member, get messages, endpoint hooks c…
…reated and integrated , get member id hook, and 1:1 convo dm started, threads properly working now with validation
- Loading branch information
Showing
16 changed files
with
634 additions
and
9 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { v } from "convex/values"; | ||
import { mutation } from "./_generated/server"; | ||
import { getAuthUserId } from "@convex-dev/auth/server"; | ||
|
||
export const createOrGet = mutation({ | ||
args: { | ||
workspaceId: v.id("workspaces"), | ||
memberId: v.id("members"), | ||
}, | ||
handler: async (ctx, args) => { | ||
const userId = await getAuthUserId(ctx); | ||
if (!userId) throw new Error("Unauthorized"); | ||
|
||
const currentMember = await ctx.db | ||
.query("members") | ||
.withIndex("by_workspace_id_user_id", (q) => | ||
q.eq("workspaceId", args.workspaceId).eq("userId", userId) | ||
) | ||
.unique(); | ||
|
||
const otherMember = await ctx.db.get(args.memberId); | ||
if (!currentMember || !otherMember) throw new Error("Member not found"); | ||
|
||
const existingConversation = await ctx.db | ||
.query("conversations") | ||
.filter((q) => q.eq(q.field("workspaceId"), args.workspaceId)) | ||
.filter((q) => | ||
q.or( | ||
q.and( | ||
q.eq(q.field("memberOneId"), currentMember._id), | ||
q.eq(q.field("memberTwoId"), otherMember._id) | ||
), | ||
q.and( | ||
q.eq(q.field("memberOneId"), otherMember._id), | ||
q.eq(q.field("memberTwoId"), currentMember._id) | ||
) | ||
) | ||
) | ||
.unique(); | ||
|
||
if (existingConversation) return existingConversation._id; | ||
|
||
const conversationId = await ctx.db.insert("conversations", { | ||
workspaceId: args.workspaceId, | ||
memberOneId: currentMember._id, | ||
memberTwoId: otherMember._id, | ||
}); | ||
|
||
const conversation = await ctx.db.get(conversationId); | ||
if (!conversation) throw new Error("Conversation not found"); | ||
|
||
return conversationId; | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 39 additions & 0 deletions
39
src/app/workspace/[workspaceId]/member/[memberId]/conversation.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
import { useMemberId } from "@/hooks/use-member-id"; | ||
import { Id } from "../../../../../../convex/_generated/dataModel"; | ||
import { useGetMember } from "@/features/members/api/use-get-member"; | ||
import { useGetMessages } from "@/features/messages/api/use-get-messages"; | ||
import { Loader } from "lucide-react"; | ||
import { Header } from "./header"; | ||
|
||
interface ConversationProps { | ||
id: Id<"conversations">; | ||
} | ||
|
||
export const Conversations = ({ id }: ConversationProps) => { | ||
const memberId = useMemberId(); | ||
|
||
const { data: member, isLoading: memberLoading } = useGetMember({ | ||
id: memberId, | ||
}); | ||
console.log(member); | ||
const { results, status, loadMore } = useGetMessages({ | ||
conversationId: id, | ||
}); | ||
|
||
if (memberLoading || status === "LoadingFirstPage") | ||
return ( | ||
<div className="h-full flex justify-center items-center"> | ||
<Loader className="size-6 animate-spin text-muted-foreground" /> | ||
</div> | ||
); | ||
|
||
return ( | ||
<div className="flex flex-col h-full"> | ||
<Header | ||
memberName={member?.user.name} | ||
memberImage={member?.user.image} | ||
onClick={() => {}} | ||
/> | ||
</div> | ||
); | ||
}; |
30 changes: 30 additions & 0 deletions
30
src/app/workspace/[workspaceId]/member/[memberId]/header.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; | ||
import { Button } from "@/components/ui/button"; | ||
import { FaChevronDown } from "react-icons/fa"; | ||
|
||
interface HeaderProps { | ||
memberName?: string; | ||
memberImage?: string; | ||
onClick?: () => void; | ||
} | ||
|
||
export const Header = ({ memberName, memberImage, onClick }: HeaderProps) => { | ||
const avatarFallback = memberName?.charAt(0).toUpperCase(); | ||
return ( | ||
<div className="bg-white border-b h-[49px] flex items-center px-4 overflow-hidden"> | ||
<Button | ||
variant="ghost" | ||
className="text-lg font-semibold px-2 overflow-hidden w-auto" | ||
size="sm" | ||
onClick={onClick} | ||
> | ||
<Avatar className="size-6 mr-2"> | ||
<AvatarImage src={memberImage} /> | ||
<AvatarFallback>{avatarFallback}</AvatarFallback> | ||
</Avatar> | ||
<span className="truncate">{memberName}</span> | ||
<FaChevronDown className="size-2.5 ml-2" /> | ||
</Button> | ||
</div> | ||
); | ||
}; |
56 changes: 56 additions & 0 deletions
56
src/app/workspace/[workspaceId]/member/[memberId]/page.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
"use client"; | ||
|
||
import { useCreateOrGetConversation } from "@/features/conversations/api/use-create-or-get-conversation"; | ||
import { useMemberId } from "@/hooks/use-member-id"; | ||
import { useWorkspaceId } from "@/hooks/use-workspace-id"; | ||
import { AlertTriangle, Loader } from "lucide-react"; | ||
import { useEffect, useState } from "react"; | ||
import { Id } from "../../../../../../convex/_generated/dataModel"; | ||
import { toast } from "sonner"; | ||
import { Conversations } from "./conversation"; | ||
|
||
const MemberIdPage = () => { | ||
const workspaceId = useWorkspaceId(); | ||
const memberId = useMemberId(); | ||
|
||
const [conversationId, setConversationId] = | ||
useState<Id<"conversations"> | null>(null); | ||
|
||
const { mutate, isPending } = useCreateOrGetConversation(); | ||
|
||
useEffect(() => { | ||
mutate( | ||
{ | ||
workspaceId, | ||
memberId, | ||
}, | ||
{ | ||
onSuccess(data) { | ||
setConversationId(data); | ||
}, | ||
onError(error) { | ||
toast.error("Failed to create or get conversation."); | ||
}, | ||
} | ||
); | ||
}, [memberId, workspaceId, mutate]); | ||
if (isPending) | ||
return ( | ||
<div className="h-full flex items-center justify-center"> | ||
<Loader className="size-6 animate-spin text-muted-foreground" /> | ||
</div> | ||
); | ||
|
||
if (!conversationId) | ||
return ( | ||
<div className="h-full flex flex-col gap-y-2 items-center justify-center"> | ||
<AlertTriangle className="size-6 text-muted-foreground" /> | ||
<span className="text-sm text-muted-foreground"> | ||
Conversation not found | ||
</span> | ||
</div> | ||
); | ||
return <Conversations id = {conversationId}/>; | ||
}; | ||
|
||
export default MemberIdPage; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.