Rework profile settings to show a preview and support more fields

This commit is contained in:
Ginger 2025-09-15 10:47:21 -04:00
parent 7f40605bfe
commit 3c1aa0e699
No known key found for this signature in database
9 changed files with 362 additions and 159 deletions

View file

@ -21,6 +21,7 @@ import { UserPresence } from '../../hooks/useUserPresence';
import { AvatarPresence, PresenceBadge } from '../presence';
import { ImageViewer } from '../image-viewer';
import { stopPropagation } from '../../utils/keyboard';
import { extendedProfileFields } from '../../hooks/useExtendedProfile';
type UserHeroProps = {
userId: string;
@ -95,9 +96,11 @@ export function UserHero({ userId, avatarUrl, presence }: UserHeroProps) {
type UserHeroNameProps = {
displayName?: string;
userId: string;
extendedProfile?: extendedProfileFields;
};
export function UserHeroName({ displayName, userId }: UserHeroNameProps) {
export function UserHeroName({ displayName, userId, extendedProfile }: UserHeroNameProps) {
const username = getMxIdLocalPart(userId);
const pronouns = extendedProfile?.["io.fsky.nyx.pronouns"];
return (
<Box grow="Yes" direction="Column" gap="0">
@ -110,9 +113,10 @@ export function UserHeroName({ displayName, userId }: UserHeroNameProps) {
{displayName ?? username ?? userId}
</Text>
</Box>
<Box alignItems="Center" gap="100" wrap="Wrap">
<Box alignItems="Start" gap="100" wrap="Wrap" direction='Column'>
<Text size="T200" className={classNames(BreakWord, LineClamp3)} title={username}>
@{username}
{pronouns && <span> · {pronouns.map(({ summary }) => summary).join(", ")}</span>}
</Text>
</Box>
</Box>

View file

@ -1,5 +1,5 @@
import { Box, Button, config, Icon, Icons, Text } from 'folds';
import React from 'react';
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { UserHero, UserHeroName } from './UserHero';
import { getMxIdServer, mxcUrlToHttp } from '../../utils/matrix';
@ -22,6 +22,8 @@ import { useMemberPowerCompare } from '../../hooks/useMemberPowerCompare';
import { CreatorChip } from './CreatorChip';
import { getDirectCreatePath, withSearchParam } from '../../pages/pathUtils';
import { DirectCreateSearchParams } from '../../pages/paths';
import { useExtendedProfile } from '../../hooks/useExtendedProfile';
import { AsyncStatus } from '../../hooks/useAsyncCallback';
type UserRoomProfileProps = {
userId: string;
@ -56,9 +58,15 @@ export function UserRoomProfile({ userId }: UserRoomProfileProps) {
const displayName = getMemberDisplayName(room, userId);
const avatarMxc = getMemberAvatarMxc(room, userId);
const avatarUrl = (avatarMxc && mxcUrlToHttp(mx, avatarMxc, useAuthentication)) ?? undefined;
const [extendedProfileState, refreshExtendedProfile] = useExtendedProfile(userId);
const extendedProfile = extendedProfileState.status === AsyncStatus.Success ? extendedProfileState.data : undefined;
const presence = useUserPresence(userId);
useEffect(() => {
refreshExtendedProfile();
}, [refreshExtendedProfile]);
const handleMessage = () => {
closeUserRoomProfile();
const directSearchParam: DirectCreateSearchParams = {
@ -77,7 +85,7 @@ export function UserRoomProfile({ userId }: UserRoomProfileProps) {
<Box direction="Column" gap="500" style={{ padding: config.space.S400 }}>
<Box direction="Column" gap="400">
<Box gap="400" alignItems="Start">
<UserHeroName displayName={displayName} userId={userId} />
<UserHeroName displayName={displayName} userId={userId} extendedProfile={extendedProfile} />
{userId !== myUserId && (
<Box shrink="No">
<Button