Presence

Presence is a per-connection state that allows users to track what other users are doing in the same room. Presence can be used to represent movement, selections, and characteristics of a user, and can be really important to building collaborative experiences.

Set presence

To get started with presence for pluv.io, first set a presence config on your createRoomBundle config.

1import { createBundle, createClient } from "@pluv/react";
2import { type AppPluvIO } from "backend/io";
3import { z } from "zod";
4
5const client = createClient<AppPluvIO>({
6 wsEndpoint: (room) => `${process.env.WS_ENDPOINT}/api/room/${room}`,
7});
8
9const { createRoomBundle } = createBundle(client);
10
11export const {
12 PluvRoomProvider,
13 usePluvMyPresence,
14 usePluvMyself,
15 usePluvOther,
16 usePluvOthers,
17 usePluvStorage,
18} = createRoomBundle({
19 // Define the validation schema for presence, using zod
20 presence: z.object({
21 selectionId: z.nullable(z.string()),
22 }),
23});

Set initialPresence on PluvRoomProvider

1import { FC } from "react";
2import { PluvRoomProvider } from "frontend/io";
3
4const Room: FC = () => {
5 return (
6 <PluvRoomProvider
7 // Specify the initial presence for each newly connected user
8 initialPresence={{
9 selectionId: null,
10 }}
11 room="my-example-room"
12 >
13 <ChatRoom />
14 </PluvRoomProvider>
15 );
16};

Observing presence

Current user's presence

1import { usePluvMyPresence, usePluvMyself } from "frontend/io";
2import { useCallback } from "react";
3
4const [myPresence, updateMyPresence] = usePluvMyPresence();
5// ^? const myPresence: { selectionId: string | null } | null
6
7const myself = usePluvMyself();
8// ^? const myself: {
9// connectionId: string;
10// presence: { selectionId: string | null };
11// user: null;
12// } | null;
13
14// Updating the current user's presence
15const selectInput = useCallback((selectionId: string) => {
16 updateMyPresence(selectionId);
17}, [updateMyPresence]);

Others' presence

1import { usePluvOther, usePluvOthers } from "frontend/io";
2
3const others = usePluvOthers();
4// ^? const others: readonly {
5// connectionId: string;
6// presence: { selectionId: string | null };
7// user: null;
8// } | null;
9
10// const connectionId = others[0]?.connectionId!;
11
12const other = usePluvOther(connectionId);
13// ^? const other: {
14// connectionId: string;
15// presence: { selectionId: string | null };
16// user: null;
17// } | null;