Redesign user profile view (#2396)

* WIP - new profile view

* render common rooms in user profile

* add presence component

* WIP - room user profile

* temp hide profile button

* show mutual rooms in spaces, rooms and direct messages categories

* add message button

* add option to change user powers in profile

* improve ban info and option to unban

* add share user button in user profile

* add option to block user in user profile

* improve blocked user alert body

* add moderation tool in user profile

* open profile view on left side in member drawer

* open new user profile in all places
This commit is contained in:
Ajay Bura
2025-08-09 17:46:10 +05:30
committed by GitHub
parent a41dee4a55
commit 4d1ae4eafd
25 changed files with 1899 additions and 34 deletions

View File

@@ -0,0 +1,80 @@
import {
as,
Badge,
Box,
color,
ContainerColor,
MainColor,
Text,
Tooltip,
TooltipProvider,
toRem,
} from 'folds';
import React, { ReactNode, useId } from 'react';
import * as css from './styles.css';
import { Presence, usePresenceLabel } from '../../hooks/useUserPresence';
const PresenceToColor: Record<Presence, MainColor> = {
[Presence.Online]: 'Success',
[Presence.Unavailable]: 'Warning',
[Presence.Offline]: 'Secondary',
};
type PresenceBadgeProps = {
presence: Presence;
status?: string;
size?: '200' | '300' | '400' | '500';
};
export function PresenceBadge({ presence, status, size }: PresenceBadgeProps) {
const label = usePresenceLabel();
const badgeLabelId = useId();
return (
<TooltipProvider
position="Right"
align="Center"
offset={4}
delay={200}
tooltip={
<Tooltip id={badgeLabelId}>
<Box style={{ maxWidth: toRem(250) }} alignItems="Baseline" gap="100">
<Text size="L400">{label[presence]}</Text>
{status && <Text size="T200"></Text>}
{status && <Text size="T200">{status}</Text>}
</Box>
</Tooltip>
}
>
{(triggerRef) => (
<Badge
aria-labelledby={badgeLabelId}
ref={triggerRef}
size={size}
variant={PresenceToColor[presence]}
fill={presence === Presence.Offline ? 'Soft' : 'Solid'}
radii="Pill"
/>
)}
</TooltipProvider>
);
}
type AvatarPresenceProps = {
badge: ReactNode;
variant?: ContainerColor;
};
export const AvatarPresence = as<'div', AvatarPresenceProps>(
({ as: AsAvatarPresence, badge, variant = 'Surface', children, ...props }, ref) => (
<Box as={AsAvatarPresence} className={css.AvatarPresence} {...props} ref={ref}>
{badge && (
<div
className={css.AvatarPresenceBadge}
style={{ backgroundColor: color[variant].Container }}
>
{badge}
</div>
)}
{children}
</Box>
)
);

View File

@@ -0,0 +1 @@
export * from './Presence';

View File

@@ -0,0 +1,22 @@
import { style } from '@vanilla-extract/css';
import { config } from 'folds';
export const AvatarPresence = style({
display: 'flex',
position: 'relative',
flexShrink: 0,
});
export const AvatarPresenceBadge = style({
position: 'absolute',
bottom: 0,
right: 0,
transform: 'translate(25%, 25%)',
zIndex: 1,
display: 'flex',
padding: config.borderWidth.B600,
backgroundColor: 'inherit',
borderRadius: config.radii.Pill,
overflow: 'hidden',
});