Location hooks
This hook keeps the current user's live locations updated. It's exported from stream-chat-react.
Location sharing, and why live locations need this hook, is explained on Location sharing. The location being shared from the composer is in locationComposer.state: see Composer hooks.
The entry gives the signature, then:
- Returns: what the hook gives back.
- Reads: the store or the context it reads.
- Re-renders: what makes the component render again.
- Needs: where the component must sit, and what the hook does outside that place.
useLiveLocationSharingManager
Creates the manager that sends the user's position to every live location they're sharing.
useLiveLocationSharingManager(params: {
client?: StreamChat | null;
getDeviceId?: () => string;
watchLocation: WatchLocation;
}): LiveLocationManager | nullThe params:
-
client: the client whose user shares the locations. -
watchLocation:(handler) => unsubscribe. It starts watching the device's position and callshandlerwith each{ latitude, longitude }. The manager calls it while at least one live share is active, and calls the returned function when none is left. -
getDeviceId: the id of the device the shares come from. By default it's built from the device type, the browser and the user id, such asweb-desktop-chrome-ann. -
Returns: a
LiveLocationManager, ornullwhileclientisnullorundefined. The hook starts it withLiveLocationManager.init()and stops it when the component unmounts or the hook creates another one. -
Reads: no store and no context. The manager keeps its own state in
manager.state. -
Re-renders: never by itself. A new
client,getDeviceIdorwatchLocationcreates a new manager, so declare the functions at module scope or withuseCallback. -
Needs: nothing: it takes the client as a param and works outside
Chat. The client must have a connected user, or creating the manager throws.useCreateChatClientreturnsnulluntil the user is connected, so its result can be passed as it is.
Call it once, in a component that stays mounted while the user is signed in. Two managers would both send each position. This one also shows how many live locations are active:
import type { LiveLocationManagerState, WatchLocation } from "stream-chat";
import {
useChatContext,
useLiveLocationSharingManager,
useStateStore,
} from "stream-chat-react";
const watchLocation: WatchLocation = (handler) => {
const watchId = navigator.geolocation.watchPosition((position) => {
handler({
latitude: position.coords.latitude,
longitude: position.coords.longitude,
});
});
return () => navigator.geolocation.clearWatch(watchId);
};
const sharesSelector = ({ messages }: LiveLocationManagerState) => ({
messages,
});
export const LiveLocationStatus = () => {
const { client } = useChatContext();
const manager = useLiveLocationSharingManager({ client, watchLocation });
const { messages } = useStateStore(manager?.state, sharesSelector) ?? {};
if (!messages?.size) return null;
return <span>Sharing your live location in {messages.size} messages</span>;
};Live location state without a hook
stream-chat-react has no hook for the manager's state. Read manager.state with useStateStore, as LiveLocationStatus does:
ready: whether the manager has loaded the user's active live locations.messages: aMapfrom message id to each live location the user is sharing, with itsend_at.
A location shown in a message is message.shared_location, and changes with the message's message.updated event.