RocketChat/Rocket.Chat

View on GitHub
apps/meteor/client/components/RoomIcon/OmnichannelRoomIcon/OmnichannelAppSourceRoomIcon.tsx

Summary

Maintainability
A
0 mins
Test Coverage
import { UserStatus, type IOmnichannelRoomFromAppSource } from '@rocket.chat/core-typings';
import { Icon, Box } from '@rocket.chat/fuselage';
import type { ComponentProps, ReactElement } from 'react';
import React from 'react';

import { AsyncStatePhase } from '../../../lib/asyncState/AsyncStatePhase';
import { useOmnichannelRoomIcon } from './context/OmnichannelRoomIconContext';

const colors = {
    busy: 'status-font-on-danger',
    away: 'status-font-on-warning',
    online: 'status-font-on-success',
    offline: 'annotation',
    disabled: 'annotation',
};

const convertBoxSizeToNumber = (boxSize: ComponentProps<typeof Icon>['size']): number => {
    switch (boxSize) {
        case 'x20': {
            return 20;
        }
        case 'x24': {
            return 24;
        }
        case 'x16':
        default: {
            return 16;
        }
    }
};

export const OmnichannelAppSourceRoomIcon = ({
    room,
    size = 16,
    placement = 'default',
}: {
    room: IOmnichannelRoomFromAppSource;
    size: ComponentProps<typeof Icon>['size'];
    placement: 'sidebar' | 'default';
}): ReactElement => {
    const color = colors[room.v.status || UserStatus.OFFLINE];
    const icon = (placement === 'sidebar' && room.source.sidebarIcon) || room.source.defaultIcon;
    const { phase, value } = useOmnichannelRoomIcon(room.source.id, icon || '');
    const fontSize = convertBoxSizeToNumber(size);
    if ([AsyncStatePhase.REJECTED, AsyncStatePhase.LOADING].includes(phase)) {
        return <Icon name='headset' size={size} color={color} />;
    }
    return (
        <Box size={fontSize} color={color}>
            <Box is='svg' size={fontSize} aria-hidden='true'>
                <Box is='use' href={`#${value}`} />
            </Box>
        </Box>
    );
};