Skip to content

Commit

Permalink
feat: Display placeholder users on the user details panel (#14935)
Browse files Browse the repository at this point in the history
  • Loading branch information
atomrc committed Apr 4, 2023
1 parent ae18222 commit eda4600
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/script/components/Avatar/Avatar.tsx
Expand Up @@ -122,7 +122,7 @@ const Avatar: FC<AvatarProps> = ({
}

if (!participant.isAvailable()) {
return <PlaceholderAvatar size={avatarSize} onClick={() => onAvatarClick?.(participant)} />;
return <PlaceholderAvatar avatarSize={avatarSize} onClick={() => onAvatarClick?.(participant)} />;
}

const isMe = participant?.isMe;
Expand Down
Expand Up @@ -17,19 +17,24 @@
*
*/

import React from 'react';

import {AVATAR_SIZE, DIAMETER} from 'Components/Avatar';

import {DefaultAvatarImageSmall, DefaultAvatarImageLarge} from './DefaultAvatarImage';

import {AvatarWrapper} from '../AvatarWrapper';

type PlaceholderAvatarProps = {size: AVATAR_SIZE; onClick: () => void};
interface PlaceholderAvatarProps extends React.HTMLProps<HTMLDivElement> {
avatarSize: AVATAR_SIZE;
onClick?: () => void;
}

export function PlaceholderAvatar({size, onClick}: PlaceholderAvatarProps) {
export function PlaceholderAvatar({avatarSize: size, onClick, ...props}: PlaceholderAvatarProps) {
const diameter = DIAMETER[size];
const ImageComponent = diameter >= DIAMETER[AVATAR_SIZE.LARGE] ? DefaultAvatarImageLarge : DefaultAvatarImageSmall;
return (
<AvatarWrapper avatarSize={size} color={''} onClick={onClick}>
<AvatarWrapper avatarSize={size} color={''} onClick={onClick} {...props}>
<ImageComponent diameter={diameter} />
</AvatarWrapper>
);
Expand Down
Expand Up @@ -106,7 +106,7 @@ export function MessageHeader({
<div className="message-header-label" data-uie-name={uieName}>
<h4
className={`message-header-label-sender ${!noColor && message.accent_color()}`}
css={!isAvailable ? {color: '#676B71'} : {}}
css={!isAvailable ? {color: 'var(--gray-70)'} : {}}
data-uie-name={uieName ? `${uieName}-sender-name` : 'sender-name'}
data-uie-uid={sender.id}
>
Expand Down
18 changes: 18 additions & 0 deletions src/script/components/panel/UserDetails.test.tsx
Expand Up @@ -19,6 +19,7 @@

import {render} from '@testing-library/react';

import {t} from 'Util/LocalizerUtil';
import {createRandomUuid} from 'Util/util';

import {UserDetails} from './UserDetails';
Expand Down Expand Up @@ -88,6 +89,7 @@ describe('UserDetails', () => {
const expirationText = '1h remaining';
const participant = new User(createRandomUuid());
participant.isGuest(true);
participant.name("I'm a guest");
participant.isTemporaryGuest(true);
participant.expirationText(expirationText);

Expand All @@ -103,4 +105,20 @@ describe('UserDetails', () => {
expect(getByTestId('status-guest')).not.toBeNull();
expect(getByText(expirationText)).not.toBeNull();
});

it('renders the placeholder avatar for a user that could not be loaded', () => {
const participant = new User(createRandomUuid());
participant.name('');

const props = {
isGroupAdmin: false,
isSelfVerified: true,
isVerified: false,
participant,
};

const {getByTestId} = render(<UserDetails {...props} />);

expect(getByTestId('status-name').textContent).toBe(t('unavailableUser'));
});
});
20 changes: 12 additions & 8 deletions src/script/components/panel/UserDetails.tsx
Expand Up @@ -44,7 +44,7 @@ export interface UserDetailsProps {
avatarStyles?: React.CSSProperties;
}

const UserDetailsComponent: React.FC<UserDetailsProps> = ({
export const UserDetailsComponent: React.FC<UserDetailsProps> = ({
badge,
participant,
isSelfVerified,
Expand All @@ -60,9 +60,11 @@ const UserDetailsComponent: React.FC<UserDetailsProps> = ({
'name',
'availability',
'is_verified',
'isAvailable',
]);

useEffect(() => {
// This will trigger a user refresh
amplify.publish(WebAppEvents.USER.UPDATE, participant.qualifiedId);
}, [participant]);

Expand All @@ -80,8 +82,12 @@ const UserDetailsComponent: React.FC<UserDetailsProps> = ({
dataUieName="status-name"
/>
) : (
<h2 className="panel-participant__head__name" data-uie-name="status-name">
{user.name}
<h2
className="panel-participant__head__name"
data-uie-name="status-name"
css={user.isAvailable ? undefined : {color: 'var(--gray-70)'}}
>
{user.isAvailable ? user.name : t('unavailableUser')}
</h2>
)}

Expand Down Expand Up @@ -123,14 +129,14 @@ const UserDetailsComponent: React.FC<UserDetailsProps> = ({
</div>
)}

{isGuest && (
{isGuest && user.isAvailable && (
<div className="panel-participant__label" data-uie-name="status-guest">
<Icon.Guest />
<span>{t('conversationGuestIndicator')}</span>
</div>
)}

{user.isTemporaryGuest && (
{user.isTemporaryGuest && user.isAvailable && (
<div className="panel-participant__guest-expiration" data-uie-name="status-expiration-text">
{user.expirationText}
</div>
Expand All @@ -146,12 +152,10 @@ const UserDetailsComponent: React.FC<UserDetailsProps> = ({
);
};

const UserDetails: React.FC<UserDetailsProps> = props => {
export const UserDetails: React.FC<UserDetailsProps> = props => {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<UserDetailsComponent {...props} />
</ErrorBoundary>
);
};

export {UserDetails};

0 comments on commit eda4600

Please sign in to comment.