52 lines
1.4 KiB
TypeScript
52 lines
1.4 KiB
TypeScript
import { createContext, useContext, useMemo } from 'react';
|
|
import { OnlinePresenceContext, useOnlinePresenceNode } from '../hooks/useOnlineUsers';
|
|
import { useAuthStore } from '../stores/auth';
|
|
import { useLastSeenHeartbeat } from '../hooks/useLastSeenHeartbeat';
|
|
import { useFollowing } from '../hooks/useFollowing';
|
|
|
|
export type PresenceContextExtended = {
|
|
onlineUserIds: Set<string>;
|
|
isOnline: (userId: string) => boolean;
|
|
};
|
|
|
|
export const PresenceVisibilityContext = createContext<{
|
|
presenceVisible: boolean;
|
|
setPresenceVisible: (v: boolean) => void;
|
|
}>({
|
|
presenceVisible: true,
|
|
setPresenceVisible: () => {},
|
|
});
|
|
|
|
export function usePresenceVisibility() {
|
|
return useContext(PresenceVisibilityContext);
|
|
}
|
|
|
|
type Props = {
|
|
children: React.ReactNode;
|
|
};
|
|
|
|
export function OnlinePresenceProvider({ children }: Props) {
|
|
const user = useAuthStore((s) => s.user);
|
|
const ids = useOnlinePresenceNode(user?.id ?? null);
|
|
const following = useFollowing();
|
|
|
|
useLastSeenHeartbeat(!!user);
|
|
|
|
const ctx = useMemo(
|
|
() => ({
|
|
onlineUserIds: ids,
|
|
isOnline: (userId: string) => {
|
|
if (!user?.id || userId === user.id) return false;
|
|
return ids.has(userId) && following.has(userId);
|
|
},
|
|
}),
|
|
[ids, following, user?.id],
|
|
);
|
|
|
|
return (
|
|
<OnlinePresenceContext.Provider value={ctx}>
|
|
{children}
|
|
</OnlinePresenceContext.Provider>
|
|
);
|
|
}
|