import { useEffect, useState } from 'react'; import { Method } from 'matrix-js-sdk'; import { useMatrixClient } from './useMatrixClient'; export type ExtendedProfile = { pronouns?: string; timezone?: string; }; export const useExtendedProfile = (userId: string): ExtendedProfile => { const mx = useMatrixClient(); const [extProfile, setExtProfile] = useState({}); useEffect(() => { let cancelled = false; const myUserId = mx.getUserId(); const fetchField = async >( field: string, ): Promise => { try { const res = await mx.http.authedRequest( Method.Get, `/profile/${encodeURIComponent(userId)}/${field}`, ); return res[field as keyof T] as string | undefined; } catch { return undefined; } }; const run = async () => { const [pronouns, tzFromProfile] = await Promise.all([ fetchField<{ 'm.pronouns': string }>('m.pronouns'), fetchField<{ 'm.tz': string }>('m.tz'), ]); let timezone = tzFromProfile; // Standard Synapse doesn't support m.tz — fall back to account data for own profile if (!timezone && userId === myUserId) { try { const res = await mx.http.authedRequest<{ timezone: string }>( Method.Get, `/user/${encodeURIComponent(userId)}/account_data/im.lotus.timezone`, ); timezone = res.timezone || undefined; } catch { // not set yet } } if (!cancelled) { setExtProfile({ pronouns: pronouns || undefined, timezone: timezone || undefined }); } }; run(); return () => { cancelled = true; }; }, [mx, userId]); return extProfile; };