stream-chat-react
stream-chat-react copied to clipboard
Stream-chat-react: Redirecting to profile from user avatar in channel
Hello, I have implemented live chat using stream-chat-react. When the user clicks on the avatar he's talking with I need to redirect to that user's profile:
I couldn't find a way to do this in the documentation.
Here's the relevant code:
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { Menu } from "lucide-react";
import {
Channel,
ChannelHeader,
ChannelHeaderProps,
MessageInput,
MessageList,
Window,
} from "stream-chat-react";
interface ChatChannelProps {
open: boolean;
openSidebar: () => void;
}
export default function ChatChannel({ open, openSidebar }: ChatChannelProps) {
return (
<div className={cn("w-full md:block", !open && "hidden")}>
<Channel>
<Window>
<CustomChannelHeader openSidebar={openSidebar} />
<MessageList />
<MessageInput />
</Window>
</Channel>
</div>
);
}
interface CustomChannelHeaderProps extends ChannelHeaderProps {
openSidebar: () => void;
}
function CustomChannelHeader({
openSidebar,
...props
}: CustomChannelHeaderProps) {
return (
<div className="flex items-center gap-3">
<div className="h-full p-2 md:hidden">
<Button size="icon" variant="ghost" onClick={openSidebar}>
<Menu className="size-5" />
</Button>
</div>
<ChannelHeader {...props} />
</div>
);
}
Hello @AGSTRANGER , this sounds like a question how to implement redirect to another URL upon clicking on an HTML element. Is my understanding correct?
Hello not really. I needed a way to:
- Detect on click in user avatar
- Find the other user's id
I managed to do this. Here's the solution in case anyone needs it:
CustomChatAvatar
import { Avatar, AvatarProps, useChatContext } from "stream-chat-react";
import { useRouter } from "next/navigation";
import type { BaseSyntheticEvent } from "react";
import { useSelector } from "react-redux";
import { RootState } from "@/store/store";
export default function CustomAvatar(props: AvatarProps) {
const router = useRouter();
const { channel } = useChatContext();
const {
loading: connectedUserLoading,
error: connectedUserError,
data: connectedUserData,
} = useSelector((state: RootState) => state.users.connectedUser);
let otherUserId: string | undefined = undefined;
if (channel) {
const currentUserId = connectedUserData?._id;
if (currentUserId) {
const otherUser = Object.values(channel.state.members).find(
(member) => member.user_id !== currentUserId,
);
if (otherUser) {
otherUserId = otherUser.user_id;
}
}
}
const handleClick = (event: BaseSyntheticEvent) => {
event.stopPropagation(); // Prevents triggering parent handlers
if (otherUserId) {
router.push(`/users/${otherUserId}`);
}
};
return <Avatar {...props} onClick={handleClick} />;
}
Then I used that here:
ChatChannel
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
import { Menu } from "lucide-react";
import {
Channel,
ChannelHeader,
ChannelHeaderProps,
MessageInput,
MessageList,
Window,
} from "stream-chat-react";
import CustomAvatar from "@/components/CustomChatAvatar";
interface ChatChannelProps {
open: boolean;
openSidebar: () => void;
}
export default function ChatChannel({ open, openSidebar }: ChatChannelProps) {
return (
<div className={cn("w-full md:block", !open && "hidden")}>
<Channel>
<Window>
<CustomChannelHeader openSidebar={openSidebar} />
<MessageList />
<MessageInput />
</Window>
</Channel>
</div>
);
}
interface CustomChannelHeaderProps extends ChannelHeaderProps {
openSidebar: () => void;
}
function CustomChannelHeader({
openSidebar,
...props
}: CustomChannelHeaderProps) {
console.log("🚀 ~ CustomChannelHeader props:", props);
return (
<div className="flex items-center gap-3">
<div className="h-full p-2 md:hidden">
<Button size="icon" variant="ghost" onClick={openSidebar}>
<Menu className="size-5" />
</Button>
</div>
<ChannelHeader {...props} Avatar={CustomAvatar} />
</div>
);
}