Files
cinny/src/app/components/room-avatar/RoomAvatar.tsx
T

53 lines
1.4 KiB
TypeScript
Raw Normal View History

import { JoinRule } from 'matrix-js-sdk';
import { AvatarFallback, AvatarImage, Icon, Icons, color } from 'folds';
import React, { ComponentProps, ReactEventHandler, ReactNode, forwardRef, useState } from 'react';
import * as css from './RoomAvatar.css';
2026-03-07 18:03:32 +11:00
import { getRoomIconSrc } from '../../utils/room';
import colorMXID from '../../../util/colorMXID';
type RoomAvatarProps = {
roomId: string;
src?: string;
alt?: string;
renderFallback: () => ReactNode;
};
export function RoomAvatar({ roomId, src, alt, renderFallback }: RoomAvatarProps) {
const [error, setError] = useState(false);
const handleLoad: ReactEventHandler<HTMLImageElement> = (evt) => {
evt.currentTarget.setAttribute('data-image-loaded', 'true');
};
if (!src || error) {
return (
<AvatarFallback
style={{ backgroundColor: colorMXID(roomId ?? ''), color: color.Surface.Container }}
className={css.RoomAvatar}
>
{renderFallback()}
</AvatarFallback>
);
}
return (
<AvatarImage
className={css.RoomAvatar}
src={src}
alt={alt}
onError={() => setError(true)}
onLoad={handleLoad}
draggable={false}
/>
);
}
export const RoomIcon = forwardRef<
SVGSVGElement,
Omit<ComponentProps<typeof Icon>, 'src'> & {
2026-03-07 18:03:32 +11:00
joinRule?: JoinRule;
roomType?: string;
}
2026-03-07 18:03:32 +11:00
>(({ joinRule, roomType, ...props }, ref) => (
<Icon src={getRoomIconSrc(Icons, roomType, joinRule)} {...props} ref={ref} />
));