import { useEffect, useMemo, useState } from 'react'; import { User, UserEvent, UserEventHandlerMap } from 'matrix-js-sdk'; import { useMatrixClient } from './useMatrixClient'; export enum Presence { Online = 'online', Unavailable = 'unavailable', Offline = 'offline', } export type UserPresence = { presence: Presence; status?: string; active: boolean; lastActiveTs?: number; }; const getUserPresence = (user: User): UserPresence => ({ presence: user.presence as Presence, status: user.presenceStatusMsg, active: user.currentlyActive, lastActiveTs: user.getLastActiveTs(), }); export const useUserPresence = (userId: string): UserPresence | undefined => { const mx = useMatrixClient(); const user = userId ? mx.getUser(userId) : null; const [presence, setPresence] = useState(() => (user ? getUserPresence(user) : undefined)); useEffect(() => { if (!user) { setPresence(undefined); return undefined; } setPresence(getUserPresence(user)); const updatePresence: UserEventHandlerMap[UserEvent.Presence] = (_event, u) => { if (u.userId === user.userId) { setPresence(getUserPresence(user)); } }; user.on(UserEvent.Presence, updatePresence); user.on(UserEvent.CurrentlyActive, updatePresence); user.on(UserEvent.LastPresenceTs, updatePresence); return () => { user.removeListener(UserEvent.Presence, updatePresence); user.removeListener(UserEvent.CurrentlyActive, updatePresence); user.removeListener(UserEvent.LastPresenceTs, updatePresence); }; }, [user]); return presence; }; export const usePresenceLabel = (): Record => useMemo( () => ({ [Presence.Online]: 'Active', [Presence.Unavailable]: 'Busy', [Presence.Offline]: 'Away', }), [] );