use-person-photo.ts2.3 KBView on GitHub import { useCallback } from 'react';
import { useActiveConnection } from '@/hooks/use-connections';
import { useOrganisationMembers } from '@/modules/store/useOrganisationMembers';
/**
* One answer to "whose face is this", for every surface that draws a person.
*
* It exists because the old answer was `attendee.self`, and `self` does not mean what it
* looks like. Google sets `attendees[].self` on the attendee matching THE CALENDAR THE
* EVENT WAS READ FROM — so on an event pulled from a colleague's calendar (a shared
* calendar, or one overlaid through "meet with"), `self` marks THEM. Every surface then
* painted the signed-in user's own picture onto their row: open a teammate's invite and
* you are looking at yourself.
*
* The fix is to stop inferring identity from a flag about calendars and compare the
* address instead. Two sources, in order:
*
* 1. the signed-in connection — its `picture` is the Google account photo
* 2. the organisation directory — `member.image`, which is how a TEAMMATE gets a face
* at all. BIMI can only ever return the company's logo for a colleague's address,
* which is why a name like `<email>` reliably came back as the Cedar
* mark (or a letter) and never as Isabel.
*
* Anyone else — a buyer, a stranger — returns `undefined`, which is the signal for the
* caller to fall back to `BimiAvatar` (BIMI, then the domain logo, then the initial).
*/
export function usePersonPhoto(): (email: string | null | undefined) => string | undefined {
const { data: activeConnection } = useActiveConnection();
// Cached and deduped by react-query, and served from the persisted store on first
// paint, so calling this from several surfaces at once costs one request.
const members = useOrganisationMembers();
const selfEmail = activeConnection?.email?.toLowerCase();
const selfPicture = activeConnection?.picture ?? undefined;
return useCallback(
(email: string | null | undefined) => {
const key=[redacted];
if (!key) return undefined;
if (selfEmail && key === selfEmail) return selfPicture;
const member = members.find((m) => m.email?.toLowerCase() === key);
return member?.image ?? undefined;
},
[members, selfEmail, selfPicture],
);
}