display presence status message in profile banner

This commit is contained in:
Ajay Bura 2026-07-21 23:16:43 +05:30
commit 33fc3a00a9
4 changed files with 66 additions and 8 deletions

View file

@ -23,10 +23,9 @@ const PresenceToColor: Record<Presence, MainColor> = {
type PresenceBadgeProps = {
presence: Presence;
status?: string;
size?: '200' | '300' | '400' | '500';
};
export function PresenceBadge({ presence, status, size }: PresenceBadgeProps) {
export function PresenceBadge({ presence, size }: PresenceBadgeProps) {
const label = usePresenceLabel();
const badgeLabelId = useId();
@ -40,8 +39,6 @@ export function PresenceBadge({ presence, status, size }: PresenceBadgeProps) {
<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>
}

View file

@ -30,6 +30,8 @@ type UserHeroProps = {
export function UserHero({ userId, avatarUrl, presence }: UserHeroProps) {
const [viewAvatar, setViewAvatar] = useState<string>();
const { status } = presence ?? {};
return (
<Box direction="Column" className={css.UserHero}>
<div
@ -46,9 +48,7 @@ export function UserHero({ userId, avatarUrl, presence }: UserHeroProps) {
<div className={css.UserHeroAvatarContainer}>
<AvatarPresence
className={css.UserAvatarContainer}
badge={
presence && <PresenceBadge presence={presence.presence} status={presence.status} />
}
badge={presence && <PresenceBadge presence={presence.presence} />}
>
<Avatar
as={avatarUrl ? 'button' : 'div'}
@ -65,6 +65,15 @@ export function UserHero({ userId, avatarUrl, presence }: UserHeroProps) {
/>
</Avatar>
</AvatarPresence>
{status && (
<div className={css.UserHeroStatus}>
<div className={css.UserHeroStatusContent}>
<Text className={classNames(BreakWord, LineClamp3)} size="T200">
{status}
</Text>
</div>
</div>
)}
{viewAvatar && (
<Overlay open backdrop={<OverlayBackdrop />}>
<OverlayCenter>

View file

@ -83,6 +83,8 @@ export function UserRoomProfile({ userId }: UserRoomProfileProps) {
navigate(withSearchParam(getDirectCreatePath(), directSearchParam));
};
ct.storage.presence.read.getAll().then((a) => console.log(a.filter((p) => p.content.status_msg)));
return (
<PowerLevelsContextProvider value={powerLevels}>
<PowerLevelTagsContextProvider value={powerLevelTags}>

View file

@ -1,4 +1,4 @@
import { style } from '@vanilla-extract/css';
import { keyframes, style } from '@vanilla-extract/css';
import { color, config, toRem } from 'folds';
export const UserHeader = style({
@ -52,3 +52,53 @@ export const UserHeroAvatarImg = style({
},
},
});
const StatusAnime = keyframes({
'0%': {
transform: 'translateY(2px)',
},
'100%': {
transform: 'translateY(0)',
},
});
export const UserHeroStatus = style({
position: 'absolute',
left: toRem(78),
bottom: toRem(58),
marginRight: config.space.S100,
animation: `${StatusAnime} 100ms`,
selectors: {
'&::before, &::after': {
content: '',
position: 'absolute',
left: toRem(5),
bottom: toRem(-4),
width: toRem(10),
height: toRem(10),
background: color.Surface.Container,
borderRadius: 999,
transform: 'rotate(45deg)',
},
'&::after': {
left: toRem(5),
bottom: toRem(-10),
width: toRem(5),
height: toRem(5),
},
},
});
export const UserHeroStatusContent = style({
position: 'relative',
zIndex: 1,
padding: `${config.space.S100} ${config.space.S200}`,
backgroundColor: color.Surface.Container,
color: color.Surface.OnContainer,
borderRadius: config.radii.R500,
});