[Refactoring] Migrate to Icon component (#5485)

This commit is contained in:
zubiden 2025-01-21 18:22:01 +01:00 committed by Alexander Zinchuk
parent aecd1d216f
commit 88f14ab310
126 changed files with 429 additions and 328 deletions

View File

@ -3,11 +3,17 @@
.icon-char::before {
font-family: Roboto, "Helvetica Neue", sans-serif;
content: attr(data-char);
width: 1.5rem;
width: 1em;
text-align: center;
display: block;
}
.icon-placeholder::before {
content: '';
display: block;
width: 1em;
}
@mixin icon {
/* use !important to prevent issues with browser extensions that change fonts */
/* stylelint-disable-next-line font-family-no-missing-generic-family-keyword */

View File

@ -30,6 +30,7 @@ import useOldLang from '../../../hooks/useOldLang';
import { useFullscreenStatus } from '../../../hooks/window/useFullscreen';
import useGroupCallVideoLayout from './hooks/useGroupCallVideoLayout';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Checkbox from '../../ui/Checkbox';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -278,10 +279,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
className={buildClassName(styles.headerButton, styles.firstButton)}
ariaLabel={lang(isFullscreen ? 'AccExitFullscreen' : 'AccSwitchToFullscreen')}
>
<i
className={buildClassName('icon', isFullscreen ? 'icon-smallscreen' : 'icon-fullscreen')}
aria-hidden
/>
<Icon name={isFullscreen ? 'smallscreen' : 'fullscreen'} />
</Button>
)}
@ -298,7 +296,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
onClick={handleToggleSidebar}
ariaLabel={lang('AccDescrExpandPanel')}
>
<i className="icon icon-sidebar" aria-hidden />
<Icon name="sidebar" />
</Button>
)}
</div>
@ -328,7 +326,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
onClick={handleToggleFullscreen}
ariaLabel={lang('AccSwitchToFullscreen')}
>
<i className="icon icon-fullscreen" aria-hidden />
<Icon name="fullscreen" />
</Button>
)}
@ -341,10 +339,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
className={buildClassName(styles.headerButton, styles.firstButton)}
ariaLabel={lang('Close')}
>
<i
className={buildClassName('icon', 'icon-close')}
aria-hidden
/>
<Icon name="close" />
</Button>
)}
@ -361,7 +356,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
onClick={handleToggleSidebar}
ariaLabel={lang('AccDescrCollapsePanel')}
>
<i className="icon icon-sidebar" aria-hidden />
<Icon name="sidebar" />
</Button>
)}
@ -389,7 +384,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
onClick={handleInviteMember}
ariaLabel={lang('VoipGroupInviteMember')}
>
<i className="icon icon-add-user" aria-hidden />
<Icon name="add-user" />
</Button>
)}
</div>
@ -438,7 +433,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
className={styles.addParticipantButton}
ariaLabel={lang('VoipGroupInviteMember')}
>
<i className="icon icon-add-user-filled" aria-hidden />
<Icon name="add-user-filled" />
</FloatingActionButton>
</div>
@ -482,7 +477,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
ariaLabel={lang(hasVideo ? 'VoipStopVideo' : 'VoipStartVideo')}
disabled={isConnecting}
>
<i className={buildClassName('icon', !hasVideo ? 'icon-video-stop' : 'icon-video')} aria-hidden />
<Icon name={!hasVideo ? 'video-stop' : 'video'} />
</Button>
<Button
@ -498,10 +493,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
ariaLabel={lang(hasPresentation ? 'lng_group_call_screen_share_stop' : 'lng_group_call_tooltip_screen')}
disabled={isConnecting || !IS_SCREENSHARE_SUPPORTED}
>
<i
className={buildClassName('icon', !hasPresentation ? 'icon-share-screen-stop' : 'icon-share-screen')}
aria-hidden
/>
<Icon name={!hasPresentation ? 'share-screen-stop' : 'share-screen'} />
</Button>
<MicrophoneButton className={styles.actionButton} />
@ -518,7 +510,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
ariaLabel={lang('lng_group_call_settings')}
disabled
>
<i className="icon icon-settings-filled" aria-hidden />
<Icon name="settings-filled" />
</Button>
<Button
@ -532,7 +524,7 @@ const GroupCall: FC<OwnProps & StateProps> = ({
onClick={handleLeaveGroupCall}
ariaLabel={lang('lng_group_call_leave')}
>
<i className="icon icon-close" aria-hidden />
<Icon name="close" />
</Button>
</div>

View File

@ -19,6 +19,7 @@ import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import ListItem from '../../ui/ListItem';
import GroupCallParticipantMenu from './GroupCallParticipantMenu';
import OutlinedMicrophoneIcon from './OutlinedMicrophoneIcon';
@ -128,9 +129,9 @@ const GroupCallParticipant: FC<OwnProps & StateProps> = ({
>
<FullNameTitle peer={peer} withEmojiStatus className={styles.title} />
<span className={buildClassName(styles.subtitle, 'subtitle', aboutColor)}>
{hasPresentationStream && <i className="icon icon-share-screen" aria-hidden />}
{hasVideoStream && <i className="icon icon-video" aria-hidden />}
{hasCustomVolume && <i className="icon icon-speaker" aria-hidden />}
{hasPresentationStream && <Icon name="share-screen" />}
{hasVideoStream && <Icon name="video" />}
{hasCustomVolume && <Icon name="speaker" />}
<span className={styles.subtitleText}>{renderText(aboutText)}</span>
</span>
<GroupCallParticipantMenu

View File

@ -25,6 +25,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Skeleton from '../../ui/placeholder/Skeleton';
import GroupCallParticipantMenu from './GroupCallParticipantMenu';
@ -292,7 +293,7 @@ const GroupCallParticipantVideo: FC<OwnProps & StateProps> = ({
ariaLabel={lang(isPinned ? 'lng_group_call_context_unpin_camera' : 'lng_group_call_context_pin_camera')}
onClick={handleClickPin}
>
<i className={buildClassName('icon', isPinned ? 'icon-unpin' : 'icon-pin')} />
<Icon name={isPinned ? 'unpin' : 'pin'} />
</Button>
)}
<div className={styles.bottomPanel}>

View File

@ -31,6 +31,7 @@ import useOldLang from '../../../hooks/useOldLang';
import AnimatedIcon from '../../common/AnimatedIcon';
import Avatar from '../../common/Avatar';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Modal from '../../ui/Modal';
import PhoneCallButton from './PhoneCallButton';
@ -273,7 +274,7 @@ const PhoneCall: FC<StateProps> = ({
onClick={handleToggleFullscreen}
ariaLabel={lang(isFullscreen ? 'AccExitFullscreen' : 'AccSwitchToFullscreen')}
>
<i className={buildClassName('icon', isFullscreen ? 'icon-smallscreen' : 'icon-fullscreen')} />
<Icon name={isFullscreen ? 'smallscreen' : 'fullscreen'} />
</Button>
)}
@ -284,7 +285,7 @@ const PhoneCall: FC<StateProps> = ({
onClick={handleClose}
className={styles.closeButton}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
</div>
<div

View File

@ -5,6 +5,7 @@ import type { IconName } from '../../../types/icons';
import buildClassName from '../../../util/buildClassName';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import styles from './PhoneCallButton.module.scss';
@ -38,7 +39,7 @@ const PhoneCallButton: FC<OwnProps> = ({
onClick={onClick}
disabled={isDisabled}
>
{customIcon || <i className={buildClassName(iconClassName, 'icon', `icon-${icon}`)} />}
{customIcon || <Icon name={icon!} className={iconClassName} />}
</Button>
<div className={styles.buttonText}>{label}</div>
</div>

View File

@ -8,6 +8,7 @@ import buildClassName from '../../../util/buildClassName';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import InputText from '../../ui/InputText';
import Modal from '../../ui/Modal';
@ -54,10 +55,9 @@ const RatePhoneCallModal: FC<OwnProps> = ({
{new Array(5).fill(undefined).map((_, i) => {
const isFilled = rating !== undefined && rating >= i;
return (
<i
<Icon
name={isFilled ? 'favorite-filled' : 'favorite'}
className={buildClassName(
'icon',
isFilled ? 'icon-favorite-filled' : 'icon-favorite',
isFilled && styles.isFilled,
styles.star,
)}

View File

@ -413,7 +413,7 @@ const Audio: FC<OwnProps> = ({
<div className={fullClassName} dir={lang.isRtl ? 'rtl' : 'ltr'}>
{isSelectable && (
<div className="message-select-control">
{isSelected && <i className="icon icon-select" />}
{isSelected && <Icon name="select" />}
</div>
)}
{renderTooglePlayWrapper()}
@ -448,7 +448,7 @@ const Audio: FC<OwnProps> = ({
ariaLabel={isDownloading ? 'Cancel download' : 'Download'}
onClick={handleDownloadClick}
>
<i className={buildClassName('icon', isDownloading ? 'icon-close' : 'icon-arrow-down')} />
<Icon name={isDownloading ? 'close' : 'arrow-down'} />
</Button>
)}
{origin === AudioOrigin.Search && renderWithTitle()}
@ -589,12 +589,12 @@ function renderVoice(
}
}}
>
<i className={buildClassName(
'transcribe-icon',
'icon',
(isTranscribed || isTranscriptionError) ? 'icon-down' : 'icon-transcribe',
(isTranscribed || isTranscriptionError) && !isTranscriptionHidden && 'transcribe-shown',
)}
<Icon
name={(isTranscribed || isTranscriptionError) ? 'down' : 'transcribe'}
className={buildClassName(
'transcribe-icon',
(isTranscribed || isTranscriptionError) && !isTranscriptionHidden && 'transcribe-shown',
)}
/>
{isTranscribing && (
<svg viewBox="0 0 32 24" className="loading-svg">

View File

@ -15,6 +15,7 @@ import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
import Icon from './icons/Icon';
import './CalendarModal.scss';
@ -258,7 +259,7 @@ const CalendarModal: FC<OwnProps> = ({
color="translucent"
onClick={onClose}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<h4>
@ -274,7 +275,7 @@ const CalendarModal: FC<OwnProps> = ({
disabled={shouldDisablePrevMonth}
onClick={!shouldDisablePrevMonth ? handlePrevMonth : undefined}
>
<i className="icon icon-previous" />
<Icon name="previous" />
</Button>
<Button
@ -284,7 +285,7 @@ const CalendarModal: FC<OwnProps> = ({
disabled={shouldDisableNextMonth}
onClick={!shouldDisableNextMonth ? handleNextMonth : undefined}
>
<i className="icon icon-next" />
<Icon name="next" />
</Button>
</div>
</div>

View File

@ -20,6 +20,7 @@ import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated
import Link from '../ui/Link';
import ProgressSpinner from '../ui/ProgressSpinner';
import Icon from './icons/Icon';
import './File.scss';
@ -103,7 +104,7 @@ const File: FC<OwnProps> = ({
<div ref={elementRef} className={fullClassName} dir={lang.isRtl ? 'rtl' : undefined}>
{isSelectable && (
<div className="message-select-control">
{isSelected && <i className="icon icon-select" />}
{isSelected && <Icon name="select" />}
</div>
)}
<div className="file-icon-container" onClick={isUploading ? undefined : onClick}>
@ -141,13 +142,9 @@ const File: FC<OwnProps> = ({
</div>
)}
{onClick && (
<i
className={buildClassName(
'action-icon',
'icon',
actionIcon ? `icon-${actionIcon}` : 'icon-download',
shouldSpinnerRender && 'hidden',
)}
<Icon
name={actionIcon || 'download'}
className={buildClassName('action-icon', shouldSpinnerRender && 'hidden')}
/>
)}
</div>

View File

@ -24,6 +24,7 @@ import Menu from '../ui/Menu';
import MenuItem from '../ui/MenuItem';
import OptimizedVideo from '../ui/OptimizedVideo';
import Spinner from '../ui/Spinner';
import Icon from './icons/Icon';
import './GifButton.scss';
@ -141,7 +142,7 @@ const GifButton: FC<OwnProps> = ({
noFastClick
onClick={handleUnsaveClick}
>
<i className="icon icon-close gif-unsave-button-icon" />
<Icon name="close" className="gif-unsave-button-icon" />
</Button>
)}
{withThumb && (

View File

@ -69,7 +69,7 @@ const InviteLink: FC<OwnProps> = ({
onClick={onTrigger}
ariaLabel={lang('AccDescrOpenMenu2')}
>
<i className="icon icon-more" />
<Icon name="more" />
</Button>
);
}, [isMobile, lang]);

View File

@ -15,6 +15,7 @@ import useAppLayout from '../../hooks/useAppLayout';
import useOldLang from '../../hooks/useOldLang';
import Button from '../ui/Button';
import Icon from './icons/Icon';
type OwnProps = {
submitLabel?: string;
@ -149,7 +150,7 @@ const PasswordForm: FC<OwnProps> = ({
title="Toggle password visibility"
aria-label="Toggle password visibility"
>
<i className={buildClassName('icon', isPasswordVisible ? 'icon-eye' : 'icon-eye-closed')} />
<Icon name={isPasswordVisible ? 'eye' : 'eye-closed'} />
</div>
</div>
{description && <p className="description">{description}</p>}

View File

@ -5,6 +5,7 @@ import buildClassName from '../../util/buildClassName';
import { IS_TOUCH_ENV } from '../../util/windowEnvironment';
import Button from '../ui/Button';
import Icon from './icons/Icon';
import styles from './SliderDots.module.scss';
@ -46,7 +47,7 @@ const SliderDots: FC<OwnProps> = ({
round
onClick={handleGoBack}
>
<i className="icon icon-previous" />
<Icon name="previous" />
</Button>
)}
<div className={styles.root} style={`--start-from: ${startFrom}; --length: ${length}; --count: ${count};`}>
@ -81,7 +82,7 @@ const SliderDots: FC<OwnProps> = ({
disabled={active === length - 1}
onClick={handleGoForward}
>
<i className="icon icon-next" />
<Icon name="next" />
</Button>
)}
</div>

View File

@ -37,6 +37,7 @@ import DropdownMenu from '../ui/DropdownMenu';
import Loading from '../ui/Loading';
import MenuItem from '../ui/MenuItem';
import Modal from '../ui/Modal';
import Icon from './icons/Icon';
import StickerButton from './StickerButton';
import './StickerSetModal.scss';
@ -183,7 +184,7 @@ const StickerSetModal: FC<OwnProps & StateProps> = ({
onClick={onTrigger}
ariaLabel="More actions"
>
<i className="icon icon-more" />
<Icon name="more" />
</Button>
);
}, [isMobile]);
@ -194,7 +195,7 @@ const StickerSetModal: FC<OwnProps & StateProps> = ({
return (
<div className={fullClassName} dir={lang.isRtl ? 'rtl' : undefined}>
<Button round color="translucent" size="smaller" ariaLabel={lang('Close')} onClick={onClose}>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<div className="modal-title">
{renderingStickerSet ? renderText(renderingStickerSet.title, ['emoji', 'links']) : lang('AccDescrStickerSet')}

View File

@ -10,6 +10,7 @@ import renderText from './helpers/renderText';
import useOldLang from '../../hooks/useOldLang';
import Icon from './icons/Icon';
import TopicIcon from './TopicIcon';
import styles from './TopicChip.module.scss';
@ -40,8 +41,8 @@ const TopicChip: FC<OwnProps> = ({
? <TopicIcon topic={topic} size={TOPIC_ICON_SIZE} />
: <img src={blankSrc} alt="" draggable={false} />}
{topic?.title ? renderText(topic.title) : lang('Loading')}
{topic?.isClosed && <i className="icon icon-lock" />}
<i className="icon icon-next" />
{topic?.isClosed && <Icon name="lock" />}
<Icon name="next" />
</div>
);
};

View File

@ -7,6 +7,8 @@ import { getTopicDefaultIcon } from '../../util/forumColors';
import { getFirstLetters } from '../../util/textFormat';
import renderText from './helpers/renderText';
import Icon from './icons/Icon';
import styles from './TopicDefaultIcon.module.scss';
type OwnProps = {
@ -30,8 +32,9 @@ const TopicDefaultIcon: FC<OwnProps> = ({
if (topicId === GENERAL_TOPIC_ID) {
return (
<i
className={buildClassName(styles.root, className, 'icon', 'icon-hashtag', 'general-forum-icon')}
<Icon
name="hashtag"
className={buildClassName(styles.root, className, 'general-forum-icon')}
onClick={onClick}
/>
);

View File

@ -11,6 +11,8 @@ import { areLinesWrapping } from '../helpers/renderText';
import useOldLang from '../../../hooks/useOldLang';
import useWindowSize from '../../../hooks/window/useWindowSize';
import Icon from '../icons/Icon';
import styles from './CodeOverlay.module.scss';
export type OwnProps = {
@ -63,12 +65,12 @@ const CodeOverlay: FC<OwnProps> = ({
<div className={contentClass}>
{withWordWrapButton && (
<div className={wrapClass} onClick={handleWordWrapClick} title="Word Wrap">
<i className="icon icon-word-wrap" />
<Icon name="word-wrap" />
</div>
)}
{!noCopy && (
<div className={styles.copy} onClick={handleCopy} title={lang('Copy')}>
<i className="icon icon-copy" />
<Icon name="copy" />
</div>
)}
</div>

View File

@ -11,23 +11,29 @@ type OwnProps = {
style?: string;
role?: AriaRole;
ariaLabel?: string;
character?: string;
ref?: React.RefObject<HTMLElement>;
onClick?: (e: React.MouseEvent<HTMLDivElement>) => void;
};
const Icon = ({
name,
ref,
className,
style,
role,
ariaLabel,
character,
onClick,
}: OwnProps) => {
return (
<i
ref={ref}
className={buildClassName(`icon icon-${name}`, className)}
style={style}
aria-hidden={!ariaLabel}
aria-label={ariaLabel}
data-char={character}
role={role}
onClick={onClick}
/>

View File

@ -33,6 +33,7 @@ import Modal from '../../ui/Modal';
import Transition from '../../ui/Transition';
import Avatar from '../Avatar';
import FullNameTitle from '../FullNameTitle';
import Icon from '../icons/Icon';
import TopicIcon from '../TopicIcon';
import PickerItem from './PickerItem';
@ -231,7 +232,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
<>
<div className="modal-header" dir={lang.isRtl ? 'rtl' : undefined}>
<Button round color="translucent" size="smaller" ariaLabel={lang('Back')} onClick={handleHeaderBackClick}>
<i className="icon icon-arrow-left" />
<Icon name="arrow-left" />
</Button>
<InputText
ref={topicSearchRef}
@ -284,7 +285,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
ariaLabel={lang('Close')}
onClick={onClose}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<InputText
ref={searchRef}

View File

@ -11,6 +11,7 @@ import useMedia from '../../../hooks/useMedia';
import useMediaTransitionDeprecated from '../../../hooks/useMediaTransitionDeprecated';
import CustomEmoji from '../CustomEmoji';
import Icon from '../icons/Icon';
import './ReactionStaticEmoji.scss';
@ -58,7 +59,7 @@ const ReactionStaticEmoji: FC<OwnProps> = ({
if (shouldReplaceWithHeartIcon) {
return (
<i className="ReactionStaticEmoji icon icon-heart" style={`font-size: ${size}px; width: ${size}px`} />
<Icon name="heart" className="ReactionStaticEmoji" style={`font-size: ${size}px; width: ${size}px`} />
);
}

View File

@ -17,6 +17,7 @@ import useOldLang from '../../hooks/useOldLang';
import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated';
import useLeftHeaderButtonRtlForumTransition from './main/hooks/useLeftHeaderButtonRtlForumTransition';
import Icon from '../common/icons/Icon';
import StoryRibbon from '../story/StoryRibbon';
import StoryToggler from '../story/StoryToggler';
import Button from '../ui/Button';
@ -103,7 +104,7 @@ const ArchivedChats: FC<OwnProps> = ({
)}
onTransitionEnd={handleDropdownMenuTransitionEnd}
>
<i className="icon icon-arrow-left" />
<Icon name="arrow-left" />
</Button>
{shouldRenderTitle && <h3 className={titleClassNames}>{lang('ArchivedChats')}</h3>}
<div className="story-toggler-wrapper">

View File

@ -5,6 +5,7 @@ import type { ConnectionStatus } from '../../hooks/useConnectionStatus';
import useOldLang from '../../hooks/useOldLang';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import Spinner from '../ui/Spinner';
import Transition from '../ui/Transition';
@ -37,7 +38,7 @@ const ConnectionStatusOverlay: FC<OwnProps> = ({
size="tiny"
color="translucent-black"
>
<span className="icon icon-close" />
<Icon name="close" />
</Button>
</div>
);

View File

@ -7,6 +7,7 @@ import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import Menu from '../ui/Menu';
import MenuItem from '../ui/MenuItem';
@ -68,8 +69,8 @@ const NewChatButton: FC<OwnProps> = ({
ariaLabel={lang(isMenuOpen ? 'Close' : 'NewMessageTitle')}
tabIndex={-1}
>
<i className="icon icon-new-chat-filled" />
<i className="icon icon-close" />
<Icon name="new-chat-filled" />
<Icon name="close" />
</Button>
<Menu
isOpen={isMenuOpen}

View File

@ -67,6 +67,7 @@ import useChatListEntry from './hooks/useChatListEntry';
import Avatar from '../../common/Avatar';
import DeleteChatModal from '../../common/DeleteChatModal';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import StarIcon from '../../common/icons/StarIcon';
import LastMessageMeta from '../../common/LastMessageMeta';
import ListItem from '../../ui/ListItem';
@ -383,7 +384,7 @@ const Chat: FC<OwnProps & StateProps> = ({
isSavedDialog={isSavedDialog}
observeIntersection={observeIntersection}
/>
{isMuted && !isSavedDialog && <i className="icon icon-muted" />}
{isMuted && !isSavedDialog && <Icon name="muted" />}
<div className="separator" />
{lastMessage && (
<LastMessageMeta

View File

@ -15,6 +15,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import AnimatedCounter from '../../common/AnimatedCounter';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import ShowTransition from '../../ui/ShowTransition';
@ -110,13 +111,13 @@ const ChatBadge: FC<OwnProps> = ({
function renderContent() {
const unreadReactionsElement = unreadReactionsCount && (
<div className={buildClassName('ChatBadge reaction', shouldBeMuted && 'muted')}>
<i className="icon icon-heart" />
<Icon name="heart" />
</div>
);
const unreadMentionsElement = unreadMentionsCount && (
<div className="ChatBadge mention">
<i className="icon icon-mention" />
<Icon name="mention" />
</div>
);
@ -132,7 +133,7 @@ const ChatBadge: FC<OwnProps> = ({
const pinnedElement = isPinned && (
<div className={className}>
<i className="icon icon-pinned-chat" />
<Icon name="pinned-chat" />
</div>
);

View File

@ -12,6 +12,7 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton';
import InfiniteScroll from '../../ui/InfiniteScroll';
@ -100,7 +101,7 @@ const ContactList: FC<OwnProps & StateProps> = ({
onClick={openNewContactDialog}
ariaLabel={lang('CreateNewContact')}
>
<i className="icon icon-add-user-filled" />
<Icon name="add-user-filled" />
</FloatingActionButton>
</InfiniteScroll>
);

View File

@ -12,6 +12,7 @@ import useAppLayout from '../../../hooks/useAppLayout';
import useOldLang from '../../../hooks/useOldLang';
import AnimatedIconFromSticker from '../../common/AnimatedIconFromSticker';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import styles from './EmptyFolder.module.scss';
@ -59,7 +60,7 @@ const EmptyFolder: FC<OwnProps & StateProps> = ({
size="smaller"
isRtl={lang.isRtl}
>
<i className="icon icon-settings" />
<Icon name="settings" />
<div className={styles.buttonText}>
{lang('ChatList.EmptyChatListEditFilter')}
</div>

View File

@ -39,6 +39,7 @@ import useOrderDiff from './hooks/useOrderDiff';
import GroupCallTopPane from '../../calls/group/GroupCallTopPane';
import GroupChatInfo from '../../common/GroupChatInfo';
import Icon from '../../common/icons/Icon';
import HeaderActions from '../../middle/HeaderActions';
import Button from '../../ui/Button';
import InfiniteScroll from '../../ui/InfiniteScroll';
@ -234,7 +235,7 @@ const ForumPanel: FC<OwnProps & StateProps> = ({
onClick={handleClose}
ariaLabel={lang('Close')}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
{chat && (

View File

@ -36,6 +36,7 @@ import useOldLang from '../../../hooks/useOldLang';
import { useFullscreenStatus } from '../../../hooks/window/useFullscreen';
import useLeftHeaderButtonRtlForumTransition from './hooks/useLeftHeaderButtonRtlForumTransition';
import Icon from '../../common/icons/Icon';
import PeerChip from '../../common/PeerChip';
import StoryToggler from '../../story/StoryToggler';
import Button from '../../ui/Button';
@ -310,7 +311,7 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
onClick={handleLockScreen}
className={buildClassName(!isCurrentUserPremium && 'extra-spacing')}
>
<i className="icon icon-lock" />
<Icon name="lock" />
</Button>
)}
<ShowTransition

View File

@ -36,6 +36,7 @@ import useOldLang from '../../../hooks/useOldLang';
import useChatListEntry from './hooks/useChatListEntry';
import useTopicContextActions from './hooks/useTopicContextActions';
import Icon from '../../common/icons/Icon';
import LastMessageMeta from '../../common/LastMessageMeta';
import TopicIcon from '../../common/TopicIcon';
import ConfirmDialog from '../../ui/ConfirmDialog';
@ -190,15 +191,10 @@ const Topic: FC<OwnProps & StateProps> = ({
<TopicIcon topic={topic} className={styles.topicIcon} observeIntersection={observeIntersection} />
<h3 dir="auto" className="fullName">{renderText(topic.title)}</h3>
</div>
{topic.isMuted && <i className="icon icon-muted" />}
{topic.isMuted && <Icon name="muted" />}
<div className="separator" />
{isClosed && (
<i className={buildClassName(
'icon',
'icon-lock-badge',
styles.closedIcon,
)}
/>
<Icon name="lock-badge" className={styles.closedIcon} />
)}
{lastMessage && (
<LastMessageMeta

View File

@ -37,6 +37,7 @@ import useMedia from '../../../../hooks/useMedia';
import useOldLang from '../../../../hooks/useOldLang';
import ChatForumLastMessage from '../../../common/ChatForumLastMessage';
import Icon from '../../../common/icons/Icon';
import MessageSummary from '../../../common/MessageSummary';
import TypingStatus from '../../../common/TypingStatus';
@ -183,8 +184,8 @@ export default function useChatListEntry({
<span className="colon">:</span>
</>
)}
{!isSavedDialog && lastMessage.forwardInfo && (<i className="icon icon-share-filled chat-prefix-icon" />)}
{lastMessage.replyInfo?.type === 'story' && (<i className="icon icon-story-reply chat-prefix-icon" />)}
{!isSavedDialog && lastMessage.forwardInfo && (<Icon name="share-filled" className="chat-prefix-icon" />)}
{lastMessage.replyInfo?.type === 'story' && (<Icon name="story-reply" className="chat-prefix-icon" />)}
{renderSummary(lastMessage, observeIntersection, mediaBlobUrl || mediaThumbnail, isRoundVideo)}
</p>
);
@ -279,7 +280,7 @@ function renderSummary(
}
draggable={false}
/>
{getMessageVideo(message) && <i className="icon icon-play" />}
{getMessageVideo(message) && <Icon name="play" />}
{messageSummary}
</span>
);

View File

@ -10,6 +10,7 @@ import sortChatIds from '../../common/helpers/sortChatIds';
import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PeerPicker from '../../common/pickers/PeerPicker';
import Button from '../../ui/Button';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -94,7 +95,7 @@ const NewChatStep1: FC<OwnProps & StateProps> = ({
onClick={onReset}
ariaLabel="Return to Chat List"
>
<i className="icon icon-arrow-left" />
<Icon name="arrow-left" />
</Button>
<h3>{lang('GroupAddMembers')}</h3>
</div>
@ -120,7 +121,7 @@ const NewChatStep1: FC<OwnProps & StateProps> = ({
onClick={handleNextStep}
ariaLabel={isChannel ? 'Continue To Channel Info' : 'Continue To Group Info'}
>
<i className="icon icon-arrow-right" />
<Icon name="arrow-right" />
</FloatingActionButton>
</div>
</div>

View File

@ -13,6 +13,7 @@ import { selectTabState } from '../../../global/selectors';
import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo';
import AvatarEditable from '../../ui/AvatarEditable';
import Button from '../../ui/Button';
@ -157,7 +158,7 @@ const NewChatStep2: FC<OwnProps & StateProps > = ({
onClick={() => onReset()}
ariaLabel="Return to member selection"
>
<i className="icon icon-arrow-left" />
<Icon name="arrow-left" />
</Button>
<h3>{lang(isChannel ? 'NewChannel' : 'NewGroup')}</h3>
</div>
@ -211,7 +212,7 @@ const NewChatStep2: FC<OwnProps & StateProps > = ({
{isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-arrow-right" />
<Icon name="arrow-right" />
)}
</FloatingActionButton>
</div>

View File

@ -30,6 +30,7 @@ import useSelectWithEnter from '../../../hooks/useSelectWithEnter';
import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import Link from '../../ui/Link';
import ListItem from '../../ui/ListItem';
@ -129,7 +130,7 @@ function renderSummary(
}
draggable={false}
/>
{getMessageVideo(message) && <i className="icon icon-play" />}
{getMessageVideo(message) && <Icon name="play" />}
{renderMessageSummary(lang, message, true, searchQuery)}
</span>
);

View File

@ -3,6 +3,8 @@ import React, { memo, useMemo } from '../../../lib/teact/teact';
import { formatDateToString } from '../../../util/dates/dateFormat';
import Icon from '../../common/icons/Icon';
import './DateSuggest.scss';
const SUGGESTION_COUNT = 8;
@ -25,7 +27,7 @@ const DateSuggest: FC<OwnProps> = ({
className="date-item"
key={text}
>
<i className="icon icon-calendar" />
<Icon name="calendar" />
<span>{text}</span>
</div>
);

View File

@ -16,6 +16,7 @@ import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import LeftSearchResultChat from './LeftSearchResultChat';
@ -113,7 +114,7 @@ const RecentContacts: FC<OwnProps & StateProps> = ({
onClick={handleClearRecentlyFoundChats}
isRtl={lang.isRtl}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
</h3>
{recentlyFoundChatIds.map((id) => (

View File

@ -11,6 +11,7 @@ import getSessionIcon from './helpers/getSessionIcon';
import useCurrentOrPrev from '../../../hooks/useCurrentOrPrev';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import ListItem from '../../ui/ListItem';
import Modal from '../../ui/Modal';
@ -63,7 +64,7 @@ const SettingsActiveSession: FC<OwnProps & StateProps> = ({
return (
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
<Button round color="translucent" size="smaller" ariaLabel={lang('Close')} onClick={onClose}>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<div className="modal-title">{lang('SessionPreview.Title')}</div>
<Button

View File

@ -11,6 +11,7 @@ import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Modal from '../../ui/Modal';
@ -52,7 +53,7 @@ const SettingsActiveWebsite: FC<OwnProps & StateProps> = ({
return (
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
<Button round color="translucent" size="smaller" ariaLabel={lang('Close')} onClick={onClose}>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<div className="modal-title">{lang('WebSessionsTitle')}</div>
<Button

View File

@ -22,6 +22,7 @@ import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import Icon from '../../common/icons/Icon';
import ManageUsernames from '../../common/ManageUsernames';
import SafeLink from '../../common/SafeLink';
import UsernameInput from '../../common/UsernameInput';
@ -286,7 +287,7 @@ const SettingsEditProfile: FC<OwnProps & StateProps> = ({
{isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-check" />
<Icon name="check" />
)}
</FloatingActionButton>
</div>

View File

@ -11,6 +11,7 @@ import useLang from '../../../hooks/useLang';
import useMultiClick from '../../../hooks/useMultiClick';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import ConfirmDialog from '../../ui/ConfirmDialog';
import DropdownMenu from '../../ui/DropdownMenu';
@ -71,7 +72,7 @@ const SettingsHeader: FC<OwnProps> = ({
onClick={onTrigger}
ariaLabel="More actions"
>
<i className="icon icon-more" />
<Icon name="more" />
</Button>
);
}, [isMobile]);
@ -269,7 +270,7 @@ const SettingsHeader: FC<OwnProps> = ({
onClick={() => onScreenSelect(SettingsScreens.EditProfile)}
ariaLabel={oldLang('lng_settings_information')}
>
<i className="icon icon-edit" />
<Icon name="edit" />
</Button>
<DropdownMenu
className="settings-more-menu"
@ -292,7 +293,7 @@ const SettingsHeader: FC<OwnProps> = ({
onClick={onReset}
ariaLabel={oldLang('AccDescrGoBack')}
>
<i className="icon icon-arrow-left" />
<Icon name="arrow-left" />
</Button>
{renderHeaderContent()}
<ConfirmDialog

View File

@ -15,6 +15,7 @@ import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem';
import Loading from '../../ui/Loading';
@ -138,7 +139,7 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps> = ({
onClick={openBlockUserModal}
ariaLabel={lang('BlockContact')}
>
<i className="icon icon-add" />
<Icon name="add" />
</FloatingActionButton>
<BlockUserModal
isOpen={isBlockUserModalOpen}

View File

@ -22,6 +22,7 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PeerPicker from '../../common/pickers/PeerPicker';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -200,7 +201,7 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
onClick={handleSubmit}
ariaLabel={isAllowList ? oldLang('AlwaysAllow') : oldLang('NeverAllow')}
>
<i className="icon icon-check" />
<Icon name="check" />
</FloatingActionButton>
</div>
);

View File

@ -25,6 +25,7 @@ import useOldLang from '../../../../hooks/useOldLang';
import AnimatedIcon from '../../../common/AnimatedIcon';
import GroupChatInfo from '../../../common/GroupChatInfo';
import Icon from '../../../common/icons/Icon';
import PrivateChatInfo from '../../../common/PrivateChatInfo';
import FloatingActionButton from '../../../ui/FloatingActionButton';
import InputText from '../../../ui/InputText';
@ -386,7 +387,7 @@ const SettingsFoldersEdit: FC<OwnProps & StateProps> = ({
{state.isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-check" />
<Icon name="check" />
)}
</FloatingActionButton>
</div>

View File

@ -310,10 +310,10 @@ const SettingsFoldersMain: FC<OwnProps & StateProps> = ({
entities: folder.title.entities,
noCustomEmojiPlayback: folder.noTitleAnimations,
})}
{isBlocked && <i className="icon icon-lock-badge settings-folders-blocked-icon" />}
{isBlocked && <Icon name="lock-badge" className="settings-folders-blocked-icon" />}
</span>
<span className="subtitle">
{folder.isChatList && <i className="icon icon-link mr-1" />}
{folder.isChatList && <Icon name="link" className="mr-1" />}
{folder.subtitle}
</span>
</ListItem>

View File

@ -24,6 +24,7 @@ import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';
import AnimatedIcon from '../../../common/AnimatedIcon';
import Icon from '../../../common/icons/Icon';
import LinkField from '../../../common/LinkField';
import PeerPicker from '../../../common/pickers/PeerPicker';
import FloatingActionButton from '../../../ui/FloatingActionButton';
@ -201,7 +202,7 @@ const SettingsShareChatlist: FC<OwnProps & StateProps> = ({
{isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-check" />
<Icon name="check" />
)}
</FloatingActionButton>
</div>

View File

@ -1,25 +1,31 @@
import React, { memo } from '../../../lib/teact/teact';
import buildClassName from '../../../util/buildClassName';
import type { IconName } from '../../../types/icons';
import { hexToRgb, lerpRgb } from '../../../util/switchTheme';
import renderText from '../../common/helpers/renderText';
import useLastCallback from '../../../hooks/useLastCallback';
import Icon from '../../common/icons/Icon';
import ListItem from '../../ui/ListItem';
import styles from './PremiumFeatureItem.module.scss';
type OwnProps<T> = {
icon: string;
isFontIcon?: boolean;
title: string;
text: string;
index: number;
count: number;
section: T;
onClick?: (section: T) => void;
};
} & ({
icon: IconName;
isFontIcon: true;
} | {
icon: string;
isFontIcon?: false;
});
const COLORS = [
'#F2862D', '#EB7B4D', '#E46D72', '#DD6091', '#CC5FBA', '#B464E7',
@ -49,11 +55,7 @@ const PremiumFeatureItem = <T,>({
return (
<ListItem buttonClassName={styles.root} onClick={handleClick} inactive={!onClick}>
{isFontIcon ? (
<i
className={buildClassName(styles.fontIcon, `icon icon-${icon}`)}
aria-hidden
style={`--item-color: rgb(${r},${g},${b})`}
/>
<Icon name={icon} className={styles.fontIcon} style={`--item-color: rgb(${r},${g},${b})`} />
) : (
<img src={icon} className={styles.icon} alt="" style={`--item-color: rgb(${r},${g},${b})`} draggable={false} />
)}

View File

@ -24,6 +24,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import Icon from '../../common/icons/Icon';
import SliderDots from '../../common/SliderDots';
import Button from '../../ui/Button';
import PremiumLimitPreview from './common/PremiumLimitPreview';
@ -221,7 +222,7 @@ const PremiumFeatureModal: FC<OwnProps> = ({
onClick={onBack}
ariaLabel={lang('Back')}
>
<i className="icon icon-arrow-left" />
<Icon name="arrow-left" />
</Button>
<div className={styles.preview} />

View File

@ -7,6 +7,8 @@ import buildClassName from '../../../../util/buildClassName';
import useOldLang from '../../../../hooks/useOldLang';
import Icon from '../../../common/icons/Icon';
import styles from './PremiumLimitsCompare.module.scss';
type OwnProps = {
@ -30,7 +32,7 @@ const PremiumLimitsCompare: FC<OwnProps> = ({
<div className={buildClassName(styles.root, className)}>
{floatingBadgeIcon && (
<div className={styles.floatingBadge}>
<i className={buildClassName(styles.floatingBadgeIcon, `icon-${floatingBadgeIcon}`, 'icon')} />
<Icon name={floatingBadgeIcon} className={styles.floatingBadgeIcon} />
<div className={styles.floatingBadgeValue} dir={lang.isRtl ? 'rtl' : undefined}>{leftValue}</div>
<div className={styles.floatingBadgeTriangle}>
<svg width="26" height="9" viewBox="0 0 26 9" fill="none">

View File

@ -2,6 +2,7 @@ import React, { memo, useLayoutEffect, useRef } from '../../../../lib/teact/teac
import { withGlobal } from '../../../../global';
import type { ApiUser } from '../../../../api/types';
import type { IconName } from '../../../../types/icons';
import { selectUser } from '../../../../global/selectors';
import buildClassName from '../../../../util/buildClassName';
@ -41,7 +42,7 @@ const STORY_FEATURE_DESCRIPTIONS = {
stories_link: 'PremiumStoriesFormattingDescription',
};
const STORY_FEATURE_ICONS = {
const STORY_FEATURE_ICONS: Record<string, IconName> = {
stories_order: 'story-priority',
stories_stealth: 'eye-closed-outline',
stories_views: 'eye-outline',

View File

@ -53,6 +53,7 @@ import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import { dispatchPriorityPlaybackEvent } from '../../hooks/usePriorityPlaybackCheck';
import { useMediaProps } from './hooks/useMediaProps';
import Icon from '../common/icons/Icon';
import ReportAvatarModal from '../common/ReportAvatarModal';
import Button from '../ui/Button';
import ShowTransition from '../ui/ShowTransition';
@ -426,7 +427,7 @@ const MediaViewer = ({
ariaLabel={lang('Close')}
onClick={handleClose}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
)}
<Transition activeKey={animationKey.current!} name={headerAnimation}>

View File

@ -3,6 +3,7 @@ import React, { memo, useMemo } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global';
import type { ActiveDownloads, MediaViewerOrigin, MessageListType } from '../../types';
import type { IconName } from '../../types/icons';
import type { MenuItemProps } from '../ui/MenuItem';
import type { MediaViewerItem } from './helpers/getViewableMedia';
@ -31,6 +32,7 @@ import useOldLang from '../../hooks/useOldLang';
import useZoomChange from './hooks/useZoomChangeSignal';
import DeleteProfilePhotoModal from '../common/DeleteProfilePhotoModal';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import DropdownMenu from '../ui/DropdownMenu';
import MenuItem from '../ui/MenuItem';
@ -158,7 +160,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
onClick={onTrigger}
ariaLabel="More actions"
>
<i className="icon icon-more" />
<Icon name="more" />
</Button>
);
}, []);
@ -191,7 +193,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
{isDownloading ? (
<ProgressSpinner progress={downloadProgress} size="s" onClick={handleDownloadClick} />
) : (
<i className="icon icon-download" />
<Icon name="download" />
)}
</Button>
) : (
@ -203,7 +205,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
color="translucent-white"
ariaLabel={lang('AccActionDownload')}
>
<i className="icon icon-download" />
<Icon name="download" />
</Button>
));
}
@ -286,7 +288,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
}) => (
<MenuItem
key={icon}
icon={icon}
icon={icon as IconName}
href={href}
download={download}
onClick={onClick}
@ -312,7 +314,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Forward')}
onClick={onForward}
>
<i className="icon icon-forward" />
<Icon name="forward" />
</Button>
)}
{renderDownloadButton()}
@ -323,7 +325,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
ariaLabel={lang('MediaZoomOut')}
onClick={handleZoomOut}
>
<i className="icon icon-zoom-out" />
<Icon name="zoom-out" />
</Button>
<Button
round
@ -332,7 +334,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
ariaLabel={lang('MediaZoomIn')}
onClick={handleZoomIn}
>
<i className="icon icon-zoom-in" />
<Icon name="zoom-in" />
</Button>
{canReportAvatar && (
<Button
@ -342,7 +344,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
ariaLabel={lang(isVideo ? 'PeerInfo.ReportProfileVideo' : 'PeerInfo.ReportProfilePhoto')}
onClick={onReport}
>
<i className="icon icon-flag" />
<Icon name="flag" />
</Button>
)}
{canUpdate && (
@ -353,7 +355,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
ariaLabel={lang('ProfilePhoto.SetMainPhoto')}
onClick={handleUpdate}
>
<i className="icon icon-copy-media" />
<Icon name="copy-media" />
</Button>
)}
{canDelete && (
@ -364,7 +366,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Delete')}
onClick={openDeleteModalHandler}
>
<i className="icon icon-delete" />
<Icon name="delete" />
</Button>
)}
<Button
@ -374,7 +376,7 @@ const MediaViewerActions: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Close')}
onClick={onCloseMediaViewer}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
{canDelete && renderDeleteModal()}
</div>

View File

@ -23,6 +23,7 @@ import useFullscreen from '../../hooks/window/useFullscreen';
import useControlsSignal from './hooks/useControlsSignal';
import useVideoWaitingSignal from './hooks/useVideoWaitingSignal';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import ProgressSpinner from '../ui/ProgressSpinner';
import VideoPlayerControls from './VideoPlayerControls';
@ -327,7 +328,7 @@ const VideoPlayer: FC<OwnProps> = ({
</div>
{shouldRenderPlayButton && (
<Button round className={`play-button ${playButtonClassNames}`} onClick={togglePlayState}>
<i className="icon icon-play" />
<Icon name="play" />
</Button>
)}
{shouldRenderSpinner && (

View File

@ -7,6 +7,7 @@ import React, {
import type { ApiDimensions } from '../../api/types';
import type { BufferedRange } from '../../hooks/useBuffering';
import type { IconName } from '../../types/icons';
import buildClassName from '../../util/buildClassName';
import { formatMediaDuration } from '../../util/dates/dateFormat';
@ -21,6 +22,7 @@ import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import useControlsSignal from './hooks/useControlsSignal';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import Menu from '../ui/Menu';
import MenuItem from '../ui/MenuItem';
@ -147,11 +149,11 @@ const VideoPlayerControls: FC<OwnProps> = ({
setIsSeeking(true);
});
const volumeIcon = useMemo(() => {
if (volume === 0 || isMuted) return 'icon-muted';
if (volume < 0.3) return 'icon-volume-1';
if (volume < 0.6) return 'icon-volume-2';
return 'icon-volume-3';
const volumeIcon: IconName = useMemo(() => {
if (volume === 0 || isMuted) return 'muted';
if (volume < 0.3) return 'volume-1';
if (volume < 0.6) return 'volume-2';
return 'volume-3';
}, [volume, isMuted]);
return (
@ -182,7 +184,7 @@ const VideoPlayerControls: FC<OwnProps> = ({
round
onClick={onPlayPause}
>
<i className={buildClassName('icon', isPlaying ? 'icon-pause' : 'icon-play')} />
<Icon name={isPlaying ? 'pause' : 'play'} />
</Button>
<Button
ariaLabel="Volume"
@ -192,7 +194,7 @@ const VideoPlayerControls: FC<OwnProps> = ({
round
onClick={onVolumeClick}
>
<i className={buildClassName('icon', volumeIcon)} />
<Icon name={volumeIcon} />
</Button>
{!IS_IOS && (
<RangeSlider bold className="volume-slider" value={isMuted ? 0 : volume * 100} onChange={onVolumeChange} />
@ -223,7 +225,7 @@ const VideoPlayerControls: FC<OwnProps> = ({
round
onClick={onPictureInPictureChange}
>
<i className="icon icon-pip" />
<Icon name="pip" />
</Button>
)}
{isFullscreenSupported && (
@ -235,7 +237,7 @@ const VideoPlayerControls: FC<OwnProps> = ({
round
onClick={onChangeFullscreen}
>
<i className={buildClassName('icon ', isFullscreen ? 'icon-smallscreen' : 'icon-fullscreen')} />
<Icon name={isFullscreen ? 'smallscreen' : 'fullscreen'} />
</Button>
)}
</div>

View File

@ -37,6 +37,7 @@ import { useHotkeys } from '../../hooks/useHotkeys';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import DropdownMenu from '../ui/DropdownMenu';
import MenuItem from '../ui/MenuItem';
@ -290,7 +291,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
onClick={onTrigger}
ariaLabel={lang('TranslateMessage')}
>
<i className="icon icon-language" aria-hidden />
<Icon name="language" />
</Button>
);
}, [isRightColumnShown, lang]);
@ -376,7 +377,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
onClick={handleSearchClick}
ariaLabel={lang('Conversation.SearchPlaceholder')}
>
<i className="icon icon-search" aria-hidden />
<Icon name="search" />
</Button>
)}
{canCall && (
@ -387,7 +388,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
onClick={handleRequestCall}
ariaLabel="Call"
>
<i className="icon icon-phone" aria-hidden />
<Icon name="phone" />
</Button>
)}
</>
@ -402,7 +403,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
onClick={handleJoinRequestsClick}
ariaLabel={isChannel ? lang('SubscribeRequests') : lang('MemberRequests')}
>
<i className="icon icon-user" aria-hidden />
<Icon name="user" />
<div className="badge">{pendingJoinRequests}</div>
</Button>
)}
@ -417,7 +418,7 @@ const HeaderActions: FC<OwnProps & StateProps> = ({
ariaLabel="More actions"
onClick={handleHeaderMenuOpen}
>
<i className="icon icon-more" aria-hidden />
<Icon name="more" />
</Button>
{menuAnchor && (
<HeaderMenuContainer

View File

@ -24,6 +24,7 @@ import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import useCopySelectedMessages from './hooks/useCopySelectedMessages';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import DeleteSelectedMessageModal from './DeleteSelectedMessageModal';
@ -143,7 +144,7 @@ const MessageSelectToolbar: FC<OwnProps & StateProps> = ({
title={label}
aria-label={label}
>
<i className={buildClassName('icon', `icon-${icon}`)} />
<Icon name={icon} />
</div>
);
};
@ -157,7 +158,7 @@ const MessageSelectToolbar: FC<OwnProps & StateProps> = ({
onClick={handleExitMessageSelectMode}
ariaLabel="Exit select mode"
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<span className="MessageSelectToolbar-count" title={formattedMessagesCount}>
{formattedMessagesCount}

View File

@ -80,6 +80,7 @@ import useWindowSize from '../../hooks/window/useWindowSize';
import usePinnedMessage from './hooks/usePinnedMessage';
import Composer from '../common/Composer';
import Icon from '../common/icons/Icon';
import PrivacySettingsNoticeModal from '../common/PrivacySettingsNoticeModal.async';
import SeenByModal from '../common/SeenByModal.async';
import UnpinAllMessagesModal from '../common/UnpinAllMessagesModal.async';
@ -573,7 +574,7 @@ function MiddleColumn({
className="composer-button unpin-all-button"
onClick={handleOpenUnpinModal}
>
<i className="icon icon-unpin" />
<Icon name="unpin" />
<span>{lang('Chat.Pinned.UnpinAll', pinnedMessagesCount, 'i')}</span>
</Button>
</div>

View File

@ -10,6 +10,7 @@ import renderText from '../common/helpers/renderText';
import useOldLang from '../../hooks/useOldLang';
import Icon from '../common/icons/Icon';
import TopicIcon from '../common/TopicIcon';
import './NoMessages.scss';
@ -79,7 +80,7 @@ function renderSavedMessages(lang: OldLangFn) {
return (
<div className="NoMessages">
<div className="wrapper">
<i className="icon no-messages-icon icon-cloud-download" />
<Icon name="cloud-download" className="no-messages-icon" />
<h3 className="title">{lang('Conversation.CloudStorageInfo.Title')}</h3>
<ul className="description">
<li>{lang('Conversation.ClousStorageInfo.Description1')}</li>

View File

@ -25,6 +25,7 @@ import useOldLang from '../../hooks/useOldLang';
import Avatar from '../common/Avatar';
import FullNameTitle from '../common/FullNameTitle';
import Icon from '../common/icons/Icon';
import PrivateChatInfo from '../common/PrivateChatInfo';
import ReactionStaticEmoji from '../common/reactions/ReactionStaticEmoji';
import Button from '../ui/Button';
@ -154,7 +155,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
// eslint-disable-next-line react/jsx-no-bind
onClick={() => setChosenTab(undefined)}
>
<i className="icon icon-heart" />
<Icon name="heart" />
{Boolean(reactors?.count) && formatIntegerCompact(reactors.count)}
</Button>
{allReactions.map((reaction) => {
@ -210,7 +211,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
<div className="info">
<FullNameTitle peer={peer} withEmojiStatus />
<span className="status" dir="auto">
<i className="icon icon-heart-outline status-icon" />
<Icon name="heart-outline" className="status-icon" />
{formatDateAtTime(lang, r.addedDate * 1000)}
</span>
</div>

View File

@ -9,6 +9,7 @@ import { formatIntegerCompact } from '../../util/textFormat';
import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
import useOldLang from '../../hooks/useOldLang';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import Menu from '../ui/Menu';
import MenuItem from '../ui/MenuItem';
@ -53,7 +54,7 @@ const ScrollDownButton: FC<OwnProps> = ({
onContextMenu={handleContextMenu}
ariaLabel={lang(ariaLabelLang)}
>
<i className={buildClassName(styles.icon, 'icon', `icon-${icon}`)} />
<Icon name={icon} className={styles.icon} />
</Button>
{Boolean(unreadCount) && <div className={styles.unreadCount}>{formatIntegerCompact(unreadCount)}</div>}
{onReadAll && (

View File

@ -45,6 +45,7 @@ import useCustomEmojiTooltip from './hooks/useCustomEmojiTooltip';
import useEmojiTooltip from './hooks/useEmojiTooltip';
import useMentionTooltip from './hooks/useMentionTooltip';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import DropdownMenu from '../../ui/DropdownMenu';
import MenuItem from '../../ui/MenuItem';
@ -438,7 +439,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
onClick={onTrigger}
ariaLabel="More actions"
>
<i className="icon icon-more" />
<Icon name="more" />
</Button>
);
}, [isMobile]);
@ -498,7 +499,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
return (
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
<Button round color="translucent" size="smaller" ariaLabel="Cancel attachments" onClick={onClear}>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<div className="modal-title">{title}</div>
{notEditingFile && !isInAlbum

View File

@ -12,6 +12,7 @@ import { REM } from '../../common/helpers/mediaDimensions';
import useLastCallback from '../../../hooks/useLastCallback';
import File from '../../common/File';
import Icon from '../../common/icons/Icon';
import MediaSpoiler from '../../common/MediaSpoiler';
import styles from './AttachmentModalItem.module.scss';
@ -84,8 +85,10 @@ const AttachmentModalItem: FC<OwnProps> = ({
smaller
/>
{onDelete && (
<i
className={buildClassName('icon', 'icon-delete', styles.actionItem, styles.deleteFile)}
<Icon
name="delete"
className={buildClassName(styles.actionItem, styles.deleteFile)}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => onDelete(index)}
/>
)}
@ -113,19 +116,14 @@ const AttachmentModalItem: FC<OwnProps> = ({
/>
{shouldRenderOverlay && (
<div className={styles.overlay}>
<i
className={buildClassName(
'icon',
attachment.shouldSendAsSpoiler ? 'icon-spoiler-disable' : 'icon-spoiler',
styles.actionItem,
)}
<Icon
name={attachment.shouldSendAsSpoiler ? 'spoiler-disable' : 'spoiler'}
className={styles.actionItem}
onClick={handleSpoilerClick}
/>
{onDelete && (
<i
className={buildClassName('icon', 'icon-delete', styles.actionItem)}
onClick={() => onDelete(index)}
/>
// eslint-disable-next-line react/jsx-no-bind
<Icon name="delete" className={styles.actionItem} onClick={() => onDelete(index)} />
)}
</div>
)}

View File

@ -4,6 +4,7 @@ import React, { memo, useEffect, useRef } from '../../../lib/teact/teact';
import buildClassName from '../../../util/buildClassName';
import renderText from '../../common/helpers/renderText';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
type OwnProps = {
@ -52,7 +53,7 @@ const BotMenuButton: FC<OwnProps> = ({
onClick={onClick}
ariaLabel="Open bot command keyboard"
>
<i className={buildClassName('bot-menu-icon', 'icon', 'icon-webapp', isOpen && 'open')} />
<Icon name="webapp" className={buildClassName('bot-menu-icon', isOpen && 'open')} />
<span ref={textRef} className="bot-menu-text">{renderText(text)}</span>
</Button>
);

View File

@ -59,10 +59,6 @@
.bubble {
width: auto;
}
.icon-placeholder {
width: 1.5rem;
}
}
.quote-reply {

View File

@ -280,7 +280,7 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
ariaLabel={oldLang('Cancel')}
onClick={handleClearClick}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
{(isShowingReply || isForwarding) && !isContextMenuDisabled && (
<Menu
@ -297,7 +297,7 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
<>
<MenuItem
icon={!noAuthors ? 'message-succeeded' : undefined}
customIcon={noAuthors ? <i className="icon icon-placeholder" /> : undefined}
customIcon={noAuthors ? <Icon name="placeholder" /> : undefined}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => setForwardNoAuthors({
noAuthors: false,
@ -307,7 +307,7 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
</MenuItem>
<MenuItem
icon={noAuthors ? 'message-succeeded' : undefined}
customIcon={!noAuthors ? <i className="icon icon-placeholder" /> : undefined}
customIcon={!noAuthors ? <Icon name="placeholder" /> : undefined}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => setForwardNoAuthors({
noAuthors: true,
@ -320,7 +320,7 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
<MenuSeparator />
<MenuItem
icon={!noCaptions ? 'message-succeeded' : undefined}
customIcon={noCaptions ? <i className="icon icon-placeholder" /> : undefined}
customIcon={noCaptions ? <Icon name="placeholder" /> : undefined}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => setForwardNoCaptions({
noCaptions: false,
@ -330,7 +330,7 @@ const ComposerEmbeddedMessage: FC<OwnProps & StateProps> = ({
</MenuItem>
<MenuItem
icon={noCaptions ? 'message-succeeded' : undefined}
customIcon={!noCaptions ? <i className="icon icon-placeholder" /> : undefined}
customIcon={!noCaptions ? <Icon name="placeholder" /> : undefined}
// eslint-disable-next-line react/jsx-no-bind
onClick={() => setForwardNoCaptions({
noCaptions: true,

View File

@ -8,6 +8,8 @@ import useFlag from '../../../hooks/useFlag';
import useLastCallback from '../../../hooks/useLastCallback';
import useResizeObserver from '../../../hooks/useResizeObserver';
import Icon from '../../common/icons/Icon';
import './DropTarget.scss';
export type OwnProps = {
@ -68,7 +70,7 @@ const DropTarget: FC<OwnProps> = ({ isQuick, isGeneric, onFileSelect }) => {
<rect className="target-outline" x="0" y="0" width="100%" height="100%" rx="8" />
</svg>
<div className="target-content">
<div className={`icon icon-${isQuick ? 'photo' : 'document'}`} />
<Icon name={isQuick ? 'photo' : 'document'} />
<div className="title">Drop files here to send them</div>
{!isGeneric && <div className="description">{isQuick ? 'in a quick way' : 'without compression'}</div>}
</div>

View File

@ -6,6 +6,7 @@ import React, {
import { withGlobal } from '../../../global';
import type { GlobalState } from '../../../global/types';
import type { IconName } from '../../../types/icons';
import type {
EmojiData,
EmojiModule,
@ -30,6 +31,7 @@ import useOldLang from '../../../hooks/useOldLang';
import useScrolledState from '../../../hooks/useScrolledState';
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Loading from '../../ui/Loading';
import EmojiCategory from './EmojiCategory';
@ -45,16 +47,16 @@ type StateProps = Pick<GlobalState, 'recentEmojis'>;
type EmojiCategoryData = { id: string; name: string; emojis: string[] };
const ICONS_BY_CATEGORY: Record<string, string> = {
recent: 'icon-recent',
people: 'icon-smile',
nature: 'icon-animals',
foods: 'icon-eats',
activity: 'icon-sport',
places: 'icon-car',
objects: 'icon-lamp',
symbols: 'icon-language',
flags: 'icon-flag',
const ICONS_BY_CATEGORY: Record<string, IconName> = {
recent: 'recent',
people: 'smile',
nature: 'animals',
foods: 'eats',
activity: 'sport',
places: 'car',
objects: 'lamp',
symbols: 'language',
flags: 'flag',
};
const OPEN_ANIMATION_DELAY = 200;
@ -200,7 +202,7 @@ const EmojiPicker: FC<OwnProps & StateProps> = ({
onClick={() => selectCategory(index)}
ariaLabel={category.name}
>
<i className={buildClassName('icon', icon)} />
<Icon name={icon} />
</Button>
);
}

View File

@ -33,6 +33,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import useInputCustomEmojis from './hooks/useInputCustomEmojis';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import TextTimer from '../../ui/TextTimer';
import TextFormatter from './TextFormatter.async';
@ -597,7 +598,7 @@ const MessageInput: FC<OwnProps & StateProps> = ({
dir="auto"
>
{!isAttachmentModalInput && !canSendPlainText
&& <i className="icon icon-lock-badge placeholder-icon" />}
&& <Icon name="lock-badge" className="placeholder-icon" />}
{shouldDisplayTimer ? (
<TextTimer langKey={timedPlaceholderLangKey!} endsAt={timedPlaceholderDate!} onEnd={handleTimerEnd} />
) : placeholder}

View File

@ -13,6 +13,7 @@ import parseHtmlAsFormattedText from '../../../util/parseHtmlAsFormattedText';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Checkbox from '../../ui/Checkbox';
import InputText from '../../ui/InputText';
@ -245,7 +246,7 @@ const PollModal: FC<OwnProps> = ({
return (
<div className="modal-header-condensed">
<Button round color="translucent" size="smaller" ariaLabel="Cancel poll creation" onClick={onClear}>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<div className="modal-title">{lang('NewPoll')}</div>
<Button
@ -283,7 +284,7 @@ const PollModal: FC<OwnProps> = ({
// eslint-disable-next-line react/jsx-no-bind
onClick={() => removeOption(index)}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
)}
</div>

View File

@ -15,6 +15,7 @@ import { useKeyboardNavigation } from './hooks/useKeyboardNavigation';
import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import ListItem from '../../ui/ListItem';
import Menu from '../../ui/Menu';
@ -123,7 +124,7 @@ const SendAsMenu: FC<OwnProps> = ({
onClick={handleClick}
focus={selectedSendAsIndex === index}
rightElement={!isCurrentUserPremium && isPremium
&& <i className="icon icon-lock-badge send-as-icon-locked" />}
&& <Icon name="lock-badge" className="send-as-icon-locked" />}
>
<Avatar
size="small"

View File

@ -38,6 +38,7 @@ import { useStickerPickerObservers } from '../../common/hooks/useStickerPickerOb
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
import Avatar from '../../common/Avatar';
import Icon from '../../common/icons/Icon';
import StickerButton from '../../common/StickerButton';
import StickerSet from '../../common/StickerSet';
import Button from '../../ui/Button';
@ -292,9 +293,9 @@ const StickerPicker: FC<OwnProps & StateProps> = ({
onClick={() => selectStickerSet(index)}
>
{stickerSet.id === RECENT_SYMBOL_SET_ID ? (
<i className="icon icon-recent" />
<Icon name="recent" />
) : stickerSet.id === FAVORITE_SYMBOL_SET_ID ? (
<i className="icon icon-favorite" />
<Icon name="favorite" />
) : stickerSet.id === CHAT_STICKER_SET_ID ? (
<Avatar peer={chat} size="small" />
) : (

View File

@ -21,6 +21,7 @@ import useOldLang from '../../../hooks/useOldLang';
import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated';
import CustomEmojiPicker from '../../common/CustomEmojiPicker';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Menu from '../../ui/Menu';
import Portal from '../../ui/Portal';
@ -270,7 +271,7 @@ const SymbolMenu: FC<OwnProps & StateProps> = ({
size="tiny"
onClick={onClose}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
)}
<SymbolMenuFooter

View File

@ -11,6 +11,7 @@ import buildClassName from '../../../util/buildClassName';
import useFlag from '../../../hooks/useFlag';
import useLastCallback from '../../../hooks/useLastCallback';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import ResponsiveHoverButton from '../../ui/ResponsiveHoverButton';
import Spinner from '../../ui/Spinner';
@ -150,8 +151,8 @@ const SymbolMenuButton: FC<OwnProps> = ({
onClick={isSymbolMenuOpen ? closeSymbolMenu : handleSymbolMenuOpen}
ariaLabel="Choose emoji, sticker or GIF"
>
<i className="icon icon-smile" />
<i className="icon icon-keyboard" />
<Icon name="smile" />
<Icon name="keyboard" />
{isSymbolMenuOpen && !isSymbolMenuLoaded && <Spinner color="gray" />}
</Button>
) : (
@ -163,7 +164,7 @@ const SymbolMenuButton: FC<OwnProps> = ({
ariaLabel="Choose emoji, sticker or GIF"
>
<div ref={triggerRef} className="symbol-menu-trigger" />
<i className="icon icon-smile" />
<Icon name="smile" />
</ResponsiveHoverButton>
)}

View File

@ -6,6 +6,7 @@ import buildClassName from '../../../util/buildClassName';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
type OwnProps = {
@ -80,7 +81,7 @@ const SymbolMenuFooter: FC<OwnProps> = ({
color="translucent"
onClick={handleSearchOpen}
>
<i className="icon icon-search" />
<Icon name="search" />
</Button>
)}
@ -98,7 +99,7 @@ const SymbolMenuFooter: FC<OwnProps> = ({
faded
color="translucent"
>
<i className="icon icon-delete-left" />
<Icon name="delete-left" />
</Button>
)}
</div>

View File

@ -20,6 +20,7 @@ import useOldLang from '../../../hooks/useOldLang';
import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated';
import useVirtualBackdrop from '../../../hooks/useVirtualBackdrop';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import './TextFormatter.scss';
@ -421,7 +422,7 @@ const TextFormatter: FC<OwnProps> = ({
className={getFormatButtonClassName('spoiler')}
onClick={handleSpoilerText}
>
<i className="icon icon-eye-closed" />
<Icon name="eye-closed" />
</Button>
<div className="TextFormatter-divider" />
<Button
@ -430,7 +431,7 @@ const TextFormatter: FC<OwnProps> = ({
className={getFormatButtonClassName('bold')}
onClick={handleBoldText}
>
<i className="icon icon-bold" />
<Icon name="bold" />
</Button>
<Button
color="translucent"
@ -438,7 +439,7 @@ const TextFormatter: FC<OwnProps> = ({
className={getFormatButtonClassName('italic')}
onClick={handleItalicText}
>
<i className="icon icon-italic" />
<Icon name="italic" />
</Button>
<Button
color="translucent"
@ -446,7 +447,7 @@ const TextFormatter: FC<OwnProps> = ({
className={getFormatButtonClassName('underline')}
onClick={handleUnderlineText}
>
<i className="icon icon-underlined" />
<Icon name="underlined" />
</Button>
<Button
color="translucent"
@ -454,7 +455,7 @@ const TextFormatter: FC<OwnProps> = ({
className={getFormatButtonClassName('strikethrough')}
onClick={handleStrikethroughText}
>
<i className="icon icon-strikethrough" />
<Icon name="strikethrough" />
</Button>
<Button
color="translucent"
@ -462,18 +463,18 @@ const TextFormatter: FC<OwnProps> = ({
className={getFormatButtonClassName('monospace')}
onClick={handleMonospaceText}
>
<i className="icon icon-monospace" />
<Icon name="monospace" />
</Button>
<div className="TextFormatter-divider" />
<Button color="translucent" ariaLabel={lang('TextFormat.AddLinkTitle')} onClick={openLinkControl}>
<i className="icon icon-link" />
<Icon name="link" />
</Button>
</div>
<div className="TextFormatter-link-control">
<div className="TextFormatter-buttons">
<Button color="translucent" ariaLabel={lang('Cancel')} onClick={closeLinkControl}>
<i className="icon icon-arrow-left" />
<Icon name="arrow-left" />
</Button>
<div className="TextFormatter-divider" />
@ -502,7 +503,7 @@ const TextFormatter: FC<OwnProps> = ({
className="color-primary"
onClick={handleLinkUrlConfirm}
>
<i className="icon icon-check" />
<Icon name="check" />
</Button>
</div>
</div>

View File

@ -37,10 +37,6 @@
.bubble {
width: auto;
}
.icon-placeholder {
width: 1.5rem;
}
}
& &-left-icon {

View File

@ -25,6 +25,7 @@ import useOldLang from '../../../hooks/useOldLang';
import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated';
import useSyncEffect from '../../../hooks/useSyncEffect';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import Menu from '../../ui/Menu';
import MenuItem from '../../ui/MenuItem';
@ -219,7 +220,7 @@ const WebPagePreview: FC<OwnProps & StateProps> = ({
<div className={buildClassName('WebPagePreview', transitionClassNames)} ref={ref}>
<div className="WebPagePreview_inner">
<div className="WebPagePreview-left-icon" onClick={handlePreviewClick}>
<i className="icon icon-link" />
<Icon name="link" />
</div>
<WebPage
message={messageStub}
@ -236,7 +237,7 @@ const WebPagePreview: FC<OwnProps & StateProps> = ({
ariaLabel="Clear Webpage Preview"
onClick={handleClearWebpagePreview}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
{!isEditing && renderContextMenu()}
</div>

View File

@ -16,6 +16,7 @@ import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import useShowTransitionDeprecated from '../../../hooks/useShowTransitionDeprecated';
import Icon from '../../common/icons/Icon';
import MediaAreaOverlay from '../../story/mediaArea/MediaAreaOverlay';
import styles from './BaseStory.module.scss';
@ -99,7 +100,7 @@ function BaseStory({
)}
{isExpired && (
<span>
<i className={buildClassName(styles.expiredIcon, 'icon icon-story-expired')} aria-hidden />
<Icon name="story-expired" className={styles.expiredIcon} />
{lang('StoryExpiredSubtitle')}
</span>
)}

View File

@ -14,6 +14,7 @@ import useAsyncRendering from '../../right/hooks/useAsyncRendering';
import AnimatedCounter from '../../common/AnimatedCounter';
import Avatar from '../../common/Avatar';
import Icon from '../../common/icons/Icon';
import Spinner from '../../ui/Spinner';
import './CommentButton.scss';
@ -105,14 +106,14 @@ const CommentButton: FC<OwnProps> = ({
role="button"
tabIndex={0}
>
<i
<Icon
name="comments-sticker"
className={buildClassName(
'CommentButton_icon-comments icon icon-comments-sticker',
'CommentButton_icon-comments',
isLoading && shouldRenderLoading && 'CommentButton_hidden',
)}
aria-hidden
/>
{!recentRepliers?.length && <i className="icon icon-comments" aria-hidden />}
{!recentRepliers?.length && <Icon name="comments" />}
{renderRecentRepliers()}
<div className="label" dir="auto">
{messagesCount ? commentsText : lang('LeaveAComment')}
@ -127,12 +128,12 @@ const CommentButton: FC<OwnProps> = ({
color={isCustomShape ? 'white' : 'blue'}
/>
) }
<i
<Icon
name="next"
className={buildClassName(
'CommentButton_icon-open icon icon-next',
'CommentButton_icon-open',
isLoading && shouldRenderLoading && 'CommentButton_hidden',
)}
aria-hidden
/>
</div>
</div>

View File

@ -13,6 +13,7 @@ import useInterval from '../../../hooks/schedulers/useInterval';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import MediaSpoiler from '../../common/MediaSpoiler';
import styles from './InvoiceMediaPreview.module.scss';
@ -73,7 +74,7 @@ const InvoiceMediaPreview: FC<OwnProps> = ({
/>
{Boolean(duration) && <div className={styles.duration}>{formatMediaDuration(duration)}</div>}
<div className={styles.buy}>
<i className={buildClassName('icon', 'icon-lock', styles.lock)} />
<Icon name="lock" className={styles.lock} />
{lang('Checkout.PayPrice', formatCurrencyAsString(amount, currency))}
</div>
</div>

View File

@ -11,6 +11,7 @@ import { ARE_CALLS_SUPPORTED } from '../../../util/windowEnvironment';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import styles from './MessagePhoneCall.module.scss';
@ -70,15 +71,14 @@ const MessagePhoneCall: FC<OwnProps> = ({
disabled={!ARE_CALLS_SUPPORTED}
ariaLabel={lang(isOutgoing ? 'CallAgain' : 'CallBack')}
>
<i className={buildClassName('icon', isVideo ? 'icon-video-outlined' : 'icon-phone')} />
<Icon name={isVideo ? 'video-outlined' : 'phone'} />
</Button>
<div className={styles.info}>
<div className={styles.reason}>{lang(reasonText)}</div>
<div className={styles.meta}>
<i
<Icon
name="arrow-right"
className={buildClassName(
'icon',
'icon-arrow-right',
styles.arrow,
isMissed && styles.missed,
isCancelled && styles.canceled,

View File

@ -25,6 +25,7 @@ import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import useShowTransition from '../../../hooks/useShowTransition';
import useBlurredMediaThumbRef from './hooks/useBlurredMediaThumbRef';
import Icon from '../../common/icons/Icon';
import MediaSpoiler from '../../common/MediaSpoiler';
import ProgressSpinner from '../../ui/ProgressSpinner';
@ -242,7 +243,7 @@ const Photo = <T,>({
<ProgressSpinner progress={transferProgress} onClick={isUploading ? handleClick : undefined} />
</div>
)}
{shouldRenderDownloadButton && <i ref={downloadButtonRef} className="icon icon-download" />}
{shouldRenderDownloadButton && <Icon ref={downloadButtonRef} name="download" />}
<MediaSpoiler
isVisible={isSpoilerShown}
withAnimation

View File

@ -25,6 +25,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import AvatarList from '../../common/AvatarList';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import CheckboxGroup from '../../ui/CheckboxGroup';
import RadioGroup from '../../ui/RadioGroup';
@ -264,7 +265,7 @@ const Poll: FC<OwnProps> = ({
onClick={showSolution}
ariaLabel="Show Solution"
>
<i className="icon icon-lamp" />
<Icon name="lamp" />
</Button>
)}
</div>

View File

@ -319,7 +319,7 @@ const RoundVideo: FC<OwnProps> = ({
)}
{shouldRenderSpoiler && !shouldRenderSpinner && renderPlayWrapper()}
{!mediaData && !isLoadAllowed && (
<i className="icon icon-download" />
<Icon name="download" />
)}
{!isInOneTimeModal && (
<div className="message-media-duration">

View File

@ -183,7 +183,7 @@ function SimilarChannel({ channel }: { channel: ApiChat }) {
<div className={styles.item} onClick={() => openChat({ id: channel.id })}>
<Avatar className={styles.avatar} key={channel.id} size="large" peer={channel} />
<div style={`background: ${color}`} className={styles.badge}>
<i className={buildClassName(styles.icon, 'icon icon-user-filled')} />
<Icon name="user-filled" className={styles.icon} />
<span className={styles.membersCount}>{formatIntegerCompact(channel?.membersCount || 0)}
</span>
</div>

View File

@ -26,6 +26,7 @@ import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import useShowTransition from '../../../hooks/useShowTransition';
import useBlurredMediaThumbRef from './hooks/useBlurredMediaThumbRef';
import Icon from '../../common/icons/Icon';
import MediaSpoiler from '../../common/MediaSpoiler';
import OptimizedVideo from '../../ui/OptimizedVideo';
import ProgressSpinner from '../../ui/ProgressSpinner';
@ -271,7 +272,7 @@ const Video = <T,>({
<canvas ref={thumbRef} className="thumbnail" />
)}
{isProtected && <span className="protector" />}
<i ref={playButtonRef} className="icon icon-large-play" />
<Icon ref={playButtonRef} name="large-play" />
<MediaSpoiler
isVisible={isSpoilerShown}
withAnimation
@ -289,7 +290,7 @@ const Video = <T,>({
</div>
)}
{!isLoadAllowed && !fullMediaData && (
<i className="icon icon-download" />
<Icon name="download" />
)}
{isTransferring && (!isUnsupported || isDownloading) ? (
<span className="message-transfer-progress">
@ -298,7 +299,7 @@ const Video = <T,>({
) : (
<div className="message-media-duration">
{!isPaidPreview && video.isGif ? 'GIF' : formatMediaDuration(Math.max(duration - playProgress, 0))}
{isUnsupported && <i className="icon icon-message-failed playback-failed" />}
{isUnsupported && <Icon name="message-failed" className="playback-failed" />}
</div>
)}
</div>

View File

@ -14,6 +14,8 @@ import buildClassName from '../../../../util/buildClassName';
import useLastCallback from '../../../../hooks/useLastCallback';
import Icon from '../../../common/icons/Icon';
type OwnProps<T> =
(PhotoProps<T> | VideoProps<T>) & {
clickArg: number;
@ -65,7 +67,7 @@ export default function withSelectControl(WrappedComponent: FC) {
{isInSelectMode && (
<div className="message-select-control">
{isSelected && (
<i className="icon icon-select" />
<Icon name="select" />
)}
</div>
)}

View File

@ -20,6 +20,7 @@ import buildClassName, { createClassNameBuilder } from '../../../../util/buildCl
import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';
import Icon from '../../../common/icons/Icon';
import Button from '../../../ui/Button';
import Link from '../../../ui/Link';
import ReactionSelectorCustomReaction from './ReactionSelectorCustomReaction';
@ -228,7 +229,7 @@ const ReactionSelector: FC<OwnProps> = ({
className={cn('show-more')}
onClick={handleShowMoreClick}
>
<i className="icon icon-down" />
<Icon name="down" />
</Button>
)}
</div>

View File

@ -225,7 +225,6 @@
.icon-check, .icon-placeholder {
margin-left: 0.25rem;
margin-right: 0.25rem;
width: 1.5rem;
}
}
}

View File

@ -6,6 +6,7 @@ import type {
ApiAudio, ApiChat, ApiMessage, ApiPeer,
MediaContent,
} from '../../../api/types';
import type { IconName } from '../../../types/icons';
import { PLAYBACK_RATE_FOR_AUDIO_MIN_DURATION } from '../../../config';
import {
@ -31,6 +32,7 @@ import useOldLang from '../../../hooks/useOldLang';
import useShowTransition from '../../../hooks/useShowTransition';
import useHeaderPane, { type PaneState } from '../hooks/useHeaderPane';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button';
import DropdownMenu from '../../ui/DropdownMenu';
import MenuItem from '../../ui/MenuItem';
@ -242,11 +244,11 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
);
});
const volumeIcon = useMemo(() => {
if (volume === 0 || isMuted) return 'icon-muted';
if (volume < 0.3) return 'icon-volume-1';
if (volume < 0.6) return 'icon-volume-2';
return 'icon-volume-3';
const volumeIcon: IconName = useMemo(() => {
if (volume === 0 || isMuted) return 'muted';
if (volume < 0.3) return 'volume-1';
if (volume < 0.6) return 'volume-2';
return 'volume-3';
}, [volume, isMuted]);
if (noUi || !shouldRender) {
@ -274,7 +276,7 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
onClick={requestPreviousTrack}
ariaLabel="Previous track"
>
<i className="icon icon-skip-previous" />
<Icon name="skip-previous" />
</Button>
<Button
round
@ -285,8 +287,8 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
onClick={playPause}
ariaLabel={isPlaying ? 'Pause audio' : 'Play audio'}
>
<i className="icon icon-play" />
<i className="icon icon-pause" />
<Icon name="play" />
<Icon name="pause" />
</Button>
<Button
round
@ -298,7 +300,7 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
onClick={requestNextTrack}
ariaLabel="Next track"
>
<i className="icon icon-skip-next" />
<Icon name="skip-next" />
</Button>
<div className="volume-button-wrapper">
@ -311,7 +313,7 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
onClick={handleVolumeClick}
ripple={!isMobile}
>
<i className={buildClassName('icon', volumeIcon)} />
<Icon name={volumeIcon} />
</Button>
{!IS_IOS && (
@ -349,7 +351,7 @@ const AudioPlayer: FC<OwnProps & StateProps> = ({
onClick={handleClose}
ariaLabel="Close player"
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
</div>
);
@ -389,7 +391,7 @@ function renderPlaybackRateMenuItem(
// eslint-disable-next-line react/jsx-no-bind
onClick={() => onClick(rate)}
icon={isSelected ? 'check' : undefined}
customIcon={!isSelected ? <i className="icon icon-placeholder" /> : undefined}
customIcon={!isSelected ? <Icon name="placeholder" /> : undefined}
>
{rate}X
</MenuItem>

View File

@ -19,6 +19,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import AvatarList from '../../common/AvatarList';
import Icon from '../../common/icons/Icon';
import PeerPicker from '../../common/pickers/PeerPicker';
import Button from '../../ui/Button';
import Modal from '../../ui/Modal';
@ -133,7 +134,7 @@ const InviteViaLinkModal: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Close')}
onClick={handleClose}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
{premiumSectionText && (
<>

View File

@ -23,6 +23,7 @@ import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang';
import Avatar from '../../../common/Avatar';
import Icon from '../../../common/icons/Icon';
import SafeLink from '../../../common/SafeLink';
import Button from '../../../ui/Button';
import Modal from '../../../ui/Modal';
@ -165,7 +166,7 @@ const StarsGiftModal: FC<OwnProps & StateProps> = ({
onClick={() => closeStarsGiftModal()}
ariaLabel={oldLang('Close')}
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<div className={buildClassName(styles.header, isHeaderHidden && styles.hiddenHeader)}>
<h2 className={styles.starHeaderText}>

View File

@ -27,6 +27,7 @@ import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
import Spinner from '../ui/Spinner';
@ -573,10 +574,7 @@ const PaymentModal: FC<OwnProps & StateProps> = ({
onClick={step === PaymentStep.Checkout ? closeModal : handleBackClick}
ariaLabel="Close"
>
<i className={buildClassName(
'icon', step === PaymentStep.Checkout ? 'icon-close' : 'icon-arrow-left',
)}
/>
<Icon name={step === PaymentStep.Checkout ? 'close' : 'arrow-left'} />
</Button>
<h3>{modalHeader}</h3>
</div>

View File

@ -10,6 +10,7 @@ import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import usePrevious from '../../hooks/usePrevious';
import Icon from '../common/icons/Icon';
import Button from '../ui/Button';
import Modal from '../ui/Modal';
import Checkout from './Checkout';
@ -66,7 +67,7 @@ const ReceiptModal: FC<OwnProps & StateProps> = ({
onClick={closeModal}
ariaLabel="Close"
>
<i className="icon icon-close" />
<Icon name="close" />
</Button>
<h3> {lang('PaymentReceipt')} </h3>
</div>

View File

@ -20,6 +20,7 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import Icon from '../common/icons/Icon';
import PeerPicker from '../common/pickers/PeerPicker';
import FloatingActionButton from '../ui/FloatingActionButton';
import Spinner from '../ui/Spinner';
@ -142,7 +143,7 @@ const AddChatMembers: FC<OwnProps & StateProps> = ({
{isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-arrow-right" />
<Icon name="arrow-right" />
)}
</FloatingActionButton>
</div>

View File

@ -18,6 +18,7 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang';
import CustomEmojiPicker from '../common/CustomEmojiPicker';
import Icon from '../common/icons/Icon';
import TopicIcon from '../common/TopicIcon';
import FloatingActionButton from '../ui/FloatingActionButton';
import InputText from '../ui/InputText';
@ -160,7 +161,7 @@ const CreateTopic: FC<OwnProps & StateProps> = ({
{isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-check" />
<Icon name="check" />
)}
</FloatingActionButton>
</div>

View File

@ -18,6 +18,7 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang';
import CustomEmojiPicker from '../common/CustomEmojiPicker';
import Icon from '../common/icons/Icon';
import TopicIcon from '../common/TopicIcon';
import FloatingActionButton from '../ui/FloatingActionButton';
import InputText from '../ui/InputText';
@ -176,7 +177,7 @@ const EditTopic: FC<OwnProps & StateProps> = ({
{isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-check" />
<Icon name="check" />
)}
</FloatingActionButton>
</div>

View File

@ -83,6 +83,7 @@ import Audio from '../common/Audio';
import Document from '../common/Document';
import UserGift from '../common/gift/UserGift';
import GroupChatInfo from '../common/GroupChatInfo';
import Icon from '../common/icons/Icon';
import Media from '../common/Media';
import NothingFound from '../common/NothingFound';
import PreviewMedia from '../common/PreviewMedia';
@ -721,7 +722,7 @@ const Profile: FC<OwnProps & StateProps> = ({
{/* eslint-disable-next-line react/jsx-no-bind */}
<Button className="show-more-channels" size="smaller" onClick={() => openPremiumModal()}>
{oldLang('UnlockSimilar')}
<i className="icon icon-unlock-badge" />
<Icon name="unlock-badge" />
</Button>
<div className="more-similar">
{renderText(oldLang('MoreSimilarText', limitSimilarPeers), ['simple_markdown'])}
@ -760,7 +761,7 @@ const Profile: FC<OwnProps & StateProps> = ({
{/* eslint-disable-next-line react/jsx-no-bind */}
<Button className="show-more-bots" size="smaller" onClick={() => openPremiumModal()}>
{lang('UnlockMoreSimilarBots')}
<i className="icon icon-unlock-badge" />
<Icon name="unlock-badge" />
</Button>
<div className="more-similar">
{renderText(lang('MoreSimilarBotsText', { count: limitSimilarPeers }, {
@ -829,7 +830,7 @@ const Profile: FC<OwnProps & StateProps> = ({
onClick={handleNewMemberDialogOpen}
ariaLabel={oldLang('lng_channel_add_users')}
>
<i className="icon icon-add-user-filled" />
<Icon name="add-user-filled" />
</FloatingActionButton>
)}
{canDeleteMembers && (

View File

@ -378,7 +378,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Edit')}
onClick={handleEditInviteClick}
>
<i className="icon icon-edit" />
<Icon name="edit" />
</Button>
)}
{currentInviteInfo && currentInviteInfo.isRevoked && (
@ -390,7 +390,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Delete')}
onClick={openDeleteDialog}
>
<i className="icon icon-delete" />
<Icon name="delete" />
</Button>
<ConfirmDialog
isOpen={isDeleteDialogOpen}
@ -475,7 +475,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
ariaLabel={lang('AddContact')}
onClick={handleAddContact}
>
<i className="icon icon-add-user" aria-hidden />
<Icon name="add-user" />
</Button>
)}
{canManage && !isInsideTopic && (
@ -486,7 +486,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Edit')}
onClick={handleToggleManagement}
>
<i className="icon icon-edit" />
<Icon name="edit" />
</Button>
)}
{canEditBot && (
@ -508,7 +508,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
ariaLabel={lang('EditTopic')}
onClick={toggleEditTopic}
>
<i className="icon icon-edit" />
<Icon name="edit" />
</Button>
)}
{canViewStatistics && (
@ -519,7 +519,7 @@ const RightHeader: FC<OwnProps & StateProps> = ({
ariaLabel={lang('Statistics')}
onClick={handleToggleStatistics}
>
<i className="icon icon-stats" />
<Icon name="stats" />
</Button>
)}
</section>

View File

@ -20,6 +20,7 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import AvatarEditable from '../../ui/AvatarEditable';
import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton';
@ -331,7 +332,7 @@ const ManageChannel: FC<OwnProps & StateProps> = ({
{isLoading ? (
<Spinner color="white" />
) : (
<i className="icon icon-check" />
<Icon name="check" />
)}
</FloatingActionButton>
<ConfirmDialog

Some files were not shown because too many files have changed in this diff Show More