Floating Action Button: Fix transition (#6440)

This commit is contained in:
Alexander Zinchuk 2025-11-06 11:36:48 +01:00
parent 5e68196c0c
commit a652cf97ae
33 changed files with 136 additions and 205 deletions

View File

@ -427,9 +427,8 @@ const GroupCall: FC<OwnProps & StateProps> = ({
onClick={handleInviteMember} onClick={handleInviteMember}
className={styles.addParticipantButton} className={styles.addParticipantButton}
ariaLabel={lang('VoipGroupInviteMember')} ariaLabel={lang('VoipGroupInviteMember')}
> iconName="add-user-filled"
<Icon name="add-user-filled" /> />
</FloatingActionButton>
</div> </div>
<div className={styles.mainVideoContainer}> <div className={styles.mainVideoContainer}>

View File

@ -0,0 +1,16 @@
.root {
--icon-size: 1.5rem;
width: var(--icon-size);
height: var(--icon-size);
}
.spinner {
--spinner-size: var(--icon-size);
margin: 0 !important;
}
.icon {
font-size: var(--icon-size);
}

View File

@ -0,0 +1,28 @@
import { memo } from '../../lib/teact/teact';
import type { IconName } from '../../types/icons';
import Spinner from '../ui/Spinner';
import Transition from '../ui/Transition';
import Icon from './icons/Icon';
import styles from './IconWithSpinner.module.scss';
type OwnProps = {
iconName: IconName;
isLoading?: boolean;
};
const IconWithSpinner = ({ iconName, isLoading }: OwnProps) => {
return (
<Transition className={styles.root} activeKey={isLoading ? 0 : 1} name="fade">
{isLoading ? (
<Spinner className={styles.spinner} color="white" />
) : (
<Icon className={styles.icon} name={iconName} />
)}
</Transition>
);
};
export default memo(IconWithSpinner);

View File

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

View File

@ -122,9 +122,8 @@ const NewChatStep1: FC<OwnProps & StateProps> = ({
isShown isShown
onClick={handleNextStep} onClick={handleNextStep}
ariaLabel={isChannel ? 'Continue To Channel Info' : 'Continue To Group Info'} ariaLabel={isChannel ? 'Continue To Channel Info' : 'Continue To Group Info'}
> iconName="arrow-right"
<Icon name="arrow-right" /> />
</FloatingActionButton>
</div> </div>
</div> </div>
); );

View File

@ -21,7 +21,6 @@ import Button from '../../ui/Button';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
export type OwnProps = { export type OwnProps = {
isChannel?: boolean; isChannel?: boolean;
@ -210,13 +209,9 @@ const NewChatStep2: FC<OwnProps & StateProps> = ({
onClick={isChannel ? handleCreateChannel : handleCreateGroup} onClick={isChannel ? handleCreateChannel : handleCreateGroup}
disabled={isLoading} disabled={isLoading}
ariaLabel={isChannel ? lang('ChannelIntro.CreateChannel') : 'Create Group'} ariaLabel={isChannel ? lang('ChannelIntro.CreateChannel') : 'Create Group'}
> iconName="arrow-right"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="arrow-right" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -22,14 +22,12 @@ import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated'; import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import Icon from '../../common/icons/Icon';
import ManageUsernames from '../../common/ManageUsernames'; import ManageUsernames from '../../common/ManageUsernames';
import SafeLink from '../../common/SafeLink'; import SafeLink from '../../common/SafeLink';
import UsernameInput from '../../common/UsernameInput'; import UsernameInput from '../../common/UsernameInput';
import AvatarEditable from '../../ui/AvatarEditable'; import AvatarEditable from '../../ui/AvatarEditable';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import Spinner from '../../ui/Spinner';
import TextArea from '../../ui/TextArea'; import TextArea from '../../ui/TextArea';
type OwnProps = { type OwnProps = {
@ -289,13 +287,9 @@ const SettingsEditProfile: FC<OwnProps & StateProps> = ({
onClick={handleProfileSave} onClick={handleProfileSave}
disabled={isLoading} disabled={isLoading}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -16,7 +16,6 @@ import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar'; import Avatar from '../../common/Avatar';
import FullNameTitle from '../../common/FullNameTitle'; import FullNameTitle from '../../common/FullNameTitle';
import Icon from '../../common/icons/Icon';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Loading from '../../ui/Loading'; import Loading from '../../ui/Loading';
@ -144,9 +143,8 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps> = ({
className="block-user-button" className="block-user-button"
onClick={openBlockUserModal} onClick={openBlockUserModal}
ariaLabel={lang('BlockContact')} ariaLabel={lang('BlockContact')}
> iconName="add"
<Icon name="add" /> />
</FloatingActionButton>
<BlockUserModal <BlockUserModal
isOpen={isBlockUserModalOpen} isOpen={isBlockUserModalOpen}
onClose={closeBlockUserModal} onClose={closeBlockUserModal}

View File

@ -23,7 +23,6 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useLang from '../../../hooks/useLang'; import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PeerPicker from '../../common/pickers/PeerPicker'; import PeerPicker from '../../common/pickers/PeerPicker';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
@ -208,9 +207,8 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
isShown={isSubmitShown} isShown={isSubmitShown}
onClick={handleSubmit} onClick={handleSubmit}
ariaLabel={isAllowList ? oldLang('AlwaysAllow') : oldLang('NeverAllow')} ariaLabel={isAllowList ? oldLang('AlwaysAllow') : oldLang('NeverAllow')}
> iconName="check"
<Icon name="check" /> />
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -18,7 +18,6 @@ import useHistoryBack from '../../../../hooks/useHistoryBack';
import useLastCallback from '../../../../hooks/useLastCallback'; import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang'; import useOldLang from '../../../../hooks/useOldLang';
import Icon from '../../../common/icons/Icon';
import PeerPicker from '../../../common/pickers/PeerPicker'; import PeerPicker from '../../../common/pickers/PeerPicker';
import FloatingActionButton from '../../../ui/FloatingActionButton'; import FloatingActionButton from '../../../ui/FloatingActionButton';
import Loading from '../../../ui/Loading'; import Loading from '../../../ui/Loading';
@ -162,9 +161,8 @@ const SettingsFoldersChatFilters: FC<OwnProps & StateProps> = ({
isShown={isTouched} isShown={isTouched}
onClick={onSaveFilter} onClick={onSaveFilter}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
<Icon name="check" /> />
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -34,7 +34,6 @@ import PrivateChatInfo from '../../../common/PrivateChatInfo';
import FloatingActionButton from '../../../ui/FloatingActionButton'; import FloatingActionButton from '../../../ui/FloatingActionButton';
import InputText from '../../../ui/InputText'; import InputText from '../../../ui/InputText';
import ListItem from '../../../ui/ListItem'; import ListItem from '../../../ui/ListItem';
import Spinner from '../../../ui/Spinner';
type OwnProps = { type OwnProps = {
state: FoldersState; state: FoldersState;
@ -461,13 +460,9 @@ const SettingsFoldersEdit: FC<OwnProps & StateProps> = ({
disabled={state.isLoading} disabled={state.isLoading}
onClick={handleSubmit} onClick={handleSubmit}
ariaLabel={state.mode === 'edit' ? 'Save changes' : 'Create folder'} ariaLabel={state.mode === 'edit' ? 'Save changes' : 'Create folder'}
> iconName="check"
{state.isLoading ? ( isLoading={state.isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -24,11 +24,9 @@ import useLastCallback from '../../../../hooks/useLastCallback';
import useOldLang from '../../../../hooks/useOldLang'; import useOldLang from '../../../../hooks/useOldLang';
import AnimatedIcon from '../../../common/AnimatedIcon'; import AnimatedIcon from '../../../common/AnimatedIcon';
import Icon from '../../../common/icons/Icon';
import LinkField from '../../../common/LinkField'; import LinkField from '../../../common/LinkField';
import PeerPicker from '../../../common/pickers/PeerPicker'; import PeerPicker from '../../../common/pickers/PeerPicker';
import FloatingActionButton from '../../../ui/FloatingActionButton'; import FloatingActionButton from '../../../ui/FloatingActionButton';
import Spinner from '../../../ui/Spinner';
type OwnProps = { type OwnProps = {
isActive?: boolean; isActive?: boolean;
@ -198,13 +196,9 @@ const SettingsShareChatlist: FC<OwnProps & StateProps> = ({
disabled={isDisabled} disabled={isDisabled}
onClick={handleSubmit} onClick={handleSubmit}
ariaLabel="Save changes" ariaLabel="Save changes"
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -21,10 +21,8 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated'; import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import Icon from '../common/icons/Icon';
import PeerPicker from '../common/pickers/PeerPicker'; import PeerPicker from '../common/pickers/PeerPicker';
import FloatingActionButton from '../ui/FloatingActionButton'; import FloatingActionButton from '../ui/FloatingActionButton';
import Spinner from '../ui/Spinner';
import './AddChatMembers.scss'; import './AddChatMembers.scss';
@ -144,13 +142,9 @@ const AddChatMembers: FC<OwnProps & StateProps> = ({
disabled={isLoading} disabled={isLoading}
ariaLabel={lang('lng_channel_add_users')} ariaLabel={lang('lng_channel_add_users')}
onClick={handleNextStep} onClick={handleNextStep}
> iconName="arrow-right"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="arrow-right" />
)}
</FloatingActionButton>
</div> </div>
</div> </div>
); );

View File

@ -19,11 +19,9 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import CustomEmojiPicker from '../common/CustomEmojiPicker'; import CustomEmojiPicker from '../common/CustomEmojiPicker';
import Icon from '../common/icons/Icon';
import TopicIcon from '../common/TopicIcon'; import TopicIcon from '../common/TopicIcon';
import FloatingActionButton from '../ui/FloatingActionButton'; import FloatingActionButton from '../ui/FloatingActionButton';
import InputText from '../ui/InputText'; import InputText from '../ui/InputText';
import Spinner from '../ui/Spinner';
import Transition from '../ui/Transition'; import Transition from '../ui/Transition';
import styles from './ManageTopic.module.scss'; import styles from './ManageTopic.module.scss';
@ -158,13 +156,9 @@ const CreateTopic: FC<OwnProps & StateProps> = ({
disabled={isLoading} disabled={isLoading}
onClick={handleCreateTopic} onClick={handleCreateTopic}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -19,12 +19,10 @@ import useHistoryBack from '../../hooks/useHistoryBack';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import CustomEmojiPicker from '../common/CustomEmojiPicker'; import CustomEmojiPicker from '../common/CustomEmojiPicker';
import Icon from '../common/icons/Icon';
import TopicIcon from '../common/TopicIcon'; import TopicIcon from '../common/TopicIcon';
import FloatingActionButton from '../ui/FloatingActionButton'; import FloatingActionButton from '../ui/FloatingActionButton';
import InputText from '../ui/InputText'; import InputText from '../ui/InputText';
import Loading from '../ui/Loading'; import Loading from '../ui/Loading';
import Spinner from '../ui/Spinner';
import Transition from '../ui/Transition'; import Transition from '../ui/Transition';
import styles from './ManageTopic.module.scss'; import styles from './ManageTopic.module.scss';
@ -174,13 +172,9 @@ const EditTopic: FC<OwnProps & StateProps> = ({
disabled={isLoading} disabled={isLoading}
onClick={handleEditTopic} onClick={handleEditTopic}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -1224,9 +1224,8 @@ const Profile = ({
isShown={canRenderContent} isShown={canRenderContent}
onClick={handleNewMemberDialogOpen} onClick={handleNewMemberDialogOpen}
ariaLabel={oldLang('lng_channel_add_users')} ariaLabel={oldLang('lng_channel_add_users')}
> iconName="add-user-filled"
<Icon name="add-user-filled" /> />
</FloatingActionButton>
)} )}
{canDeleteMembers && ( {canDeleteMembers && (
<DeleteMemberModal <DeleteMemberModal

View File

@ -26,13 +26,11 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia'; import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import AvatarEditable from '../../ui/AvatarEditable'; import AvatarEditable from '../../ui/AvatarEditable';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import SelectAvatar from '../../ui/SelectAvatar'; import SelectAvatar from '../../ui/SelectAvatar';
import Spinner from '../../ui/Spinner';
import TextArea from '../../ui/TextArea'; import TextArea from '../../ui/TextArea';
import './Management.scss'; import './Management.scss';
@ -231,13 +229,9 @@ const ManageBot: FC<OwnProps & StateProps> = ({
onClick={handleProfileSave} onClick={handleProfileSave}
disabled={isLoading} disabled={isLoading}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
<SelectAvatar <SelectAvatar
onChange={handleSelectAvatar} onChange={handleSelectAvatar}
inputRef={inputRef} inputRef={inputRef}

View File

@ -21,13 +21,11 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia'; import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import AvatarEditable from '../../ui/AvatarEditable'; import AvatarEditable from '../../ui/AvatarEditable';
import ConfirmDialog from '../../ui/ConfirmDialog'; import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
import Switcher from '../../ui/Switcher'; import Switcher from '../../ui/Switcher';
import TextArea from '../../ui/TextArea'; import TextArea from '../../ui/TextArea';
@ -358,13 +356,9 @@ const ManageChannel: FC<OwnProps & StateProps> = ({
onClick={handleUpdateChannel} onClick={handleUpdateChannel}
disabled={isLoading} disabled={isLoading}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
<ConfirmDialog <ConfirmDialog
isOpen={isDeleteDialogOpen} isOpen={isDeleteDialogOpen}
onClose={closeDeleteDialog} onClose={closeDeleteDialog}

View File

@ -13,7 +13,6 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import Checkbox from '../../ui/Checkbox'; import Checkbox from '../../ui/Checkbox';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
@ -149,9 +148,8 @@ const ManageChatAdministrators: FC<OwnProps & StateProps> = ({
isShown={canAddNewAdmins} isShown={canAddNewAdmins}
onClick={handleAddAdminClick} onClick={handleAddAdminClick}
ariaLabel={lang('Channel.Management.AddModerator')} ariaLabel={lang('Channel.Management.AddModerator')}
> iconName="add-user-filled"
<Icon name="add-user-filled" /> />
</FloatingActionButton>
</div> </div>
{canToggleSignatures && ( {canToggleSignatures && (

View File

@ -21,7 +21,6 @@ import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated'; import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
import Icon from '../../common/icons/Icon';
import LinkField from '../../common/LinkField'; import LinkField from '../../common/LinkField';
import ManageUsernames from '../../common/ManageUsernames'; import ManageUsernames from '../../common/ManageUsernames';
import SafeLink from '../../common/SafeLink'; import SafeLink from '../../common/SafeLink';
@ -31,7 +30,6 @@ import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Loading from '../../ui/Loading'; import Loading from '../../ui/Loading';
import RadioGroup from '../../ui/RadioGroup'; import RadioGroup from '../../ui/RadioGroup';
import Spinner from '../../ui/Spinner';
type PrivacyType = 'private' | 'public'; type PrivacyType = 'private' | 'public';
@ -281,13 +279,9 @@ const ManageChatPrivacyType: FC<OwnProps & StateProps> = ({
disabled={isLoading} disabled={isLoading}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
onClick={handleSave} onClick={handleSave}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
<ConfirmDialog <ConfirmDialog
isOpen={isUsernameLostDialogOpen} isOpen={isUsernameLostDialogOpen}
onClose={closeUsernameLostDialog} onClose={closeUsernameLostDialog}

View File

@ -12,7 +12,6 @@ import useFlag from '../../../hooks/useFlag';
import useHistoryBack from '../../../hooks/useHistoryBack'; import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem, { type MenuItemContextAction } from '../../ui/ListItem'; import ListItem, { type MenuItemContextAction } from '../../ui/ListItem';
@ -106,9 +105,8 @@ const ManageChatRemovedUsers: FC<OwnProps & StateProps> = ({
isShown isShown
onClick={openRemoveUserModal} onClick={openRemoveUserModal}
ariaLabel={lang('Channel.EditAdmin.Permission.BanUsers')} ariaLabel={lang('Channel.EditAdmin.Permission.BanUsers')}
> iconName="add-user-filled"
<Icon name="add-user-filled" /> />
</FloatingActionButton>
)} )}
{chat && canDeleteMembers && ( {chat && canDeleteMembers && (
<RemoveGroupUserModal <RemoveGroupUserModal

View File

@ -28,14 +28,12 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useMedia from '../../../hooks/useMedia'; import useMedia from '../../../hooks/useMedia';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import AvatarEditable from '../../ui/AvatarEditable'; import AvatarEditable from '../../ui/AvatarEditable';
import Checkbox from '../../ui/Checkbox'; import Checkbox from '../../ui/Checkbox';
import ConfirmDialog from '../../ui/ConfirmDialog'; import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
import Switcher from '../../ui/Switcher'; import Switcher from '../../ui/Switcher';
import TextArea from '../../ui/TextArea'; import TextArea from '../../ui/TextArea';
@ -469,13 +467,9 @@ const ManageGroup: FC<OwnProps & StateProps> = ({
onClick={handleUpdateGroup} onClick={handleUpdateGroup}
disabled={isLoading} disabled={isLoading}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
<ConfirmDialog <ConfirmDialog
isOpen={isDeleteDialogOpen} isOpen={isDeleteDialogOpen}
onClose={closeDeleteDialog} onClose={closeDeleteDialog}

View File

@ -17,14 +17,12 @@ import useFlag from '../../../hooks/useFlag';
import useHistoryBack from '../../../hooks/useHistoryBack'; import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import Checkbox from '../../ui/Checkbox'; import Checkbox from '../../ui/Checkbox';
import ConfirmDialog from '../../ui/ConfirmDialog'; import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
type OwnProps = { type OwnProps = {
chatId: string; chatId: string;
@ -401,13 +399,9 @@ const ManageGroupAdminRights: FC<OwnProps & StateProps> = ({
onClick={handleSavePermissions} onClick={handleSavePermissions}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
disabled={isLoading} disabled={isLoading}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
{!isNewAdmin && ( {!isNewAdmin && (
<ConfirmDialog <ConfirmDialog

View File

@ -24,7 +24,6 @@ import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation'
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import NothingFound from '../../common/NothingFound'; import NothingFound from '../../common/NothingFound';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
@ -258,9 +257,8 @@ const ManageGroupMembers: FC<OwnProps & StateProps> = ({
isShown isShown
onClick={handleNewMemberDialogOpen} onClick={handleNewMemberDialogOpen}
ariaLabel={lang('lng_channel_add_users')} ariaLabel={lang('lng_channel_add_users')}
> iconName="add-user-filled"
<Icon name="add-user-filled" /> />
</FloatingActionButton>
)} )}
{canDeleteMembers && ( {canDeleteMembers && (
<DeleteMemberModal <DeleteMemberModal

View File

@ -25,13 +25,11 @@ import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import useManagePermissions from '../hooks/useManagePermissions'; import useManagePermissions from '../hooks/useManagePermissions';
import Icon from '../../common/icons/Icon';
import PaidMessagePrice from '../../common/paidMessage/PaidMessagePrice'; import PaidMessagePrice from '../../common/paidMessage/PaidMessagePrice';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import PermissionCheckboxList from '../../main/PermissionCheckboxList'; import PermissionCheckboxList from '../../main/PermissionCheckboxList';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
import Switcher from '../../ui/Switcher'; import Switcher from '../../ui/Switcher';
type OwnProps = { type OwnProps = {
@ -340,13 +338,9 @@ const ManageGroupPermissions: FC<OwnProps & StateProps> = ({
onClick={handleUpdatePermissions} onClick={handleUpdatePermissions}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
disabled={arePermissionsLoading} disabled={arePermissionsLoading}
> iconName="check"
{arePermissionsLoading ? ( isLoading={arePermissionsLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -16,13 +16,11 @@ import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import useManagePermissions from '../hooks/useManagePermissions'; import useManagePermissions from '../hooks/useManagePermissions';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import PermissionCheckboxList from '../../main/PermissionCheckboxList'; import PermissionCheckboxList from '../../main/PermissionCheckboxList';
import ConfirmDialog from '../../ui/ConfirmDialog'; import ConfirmDialog from '../../ui/ConfirmDialog';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import Spinner from '../../ui/Spinner';
type OwnProps = { type OwnProps = {
chatId: string; chatId: string;
@ -177,13 +175,9 @@ const ManageGroupUserPermissions: FC<OwnProps & StateProps> = ({
onClick={handleSavePermissions} onClick={handleSavePermissions}
ariaLabel={oldLang('Save')} ariaLabel={oldLang('Save')}
disabled={isLoading} disabled={isLoading}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
<ConfirmDialog <ConfirmDialog
isOpen={isBanConfirmationDialogOpen} isOpen={isBanConfirmationDialogOpen}

View File

@ -16,7 +16,6 @@ import useOldLang from '../../../hooks/useOldLang';
import useSyncEffect from '../../../hooks/useSyncEffect'; import useSyncEffect from '../../../hooks/useSyncEffect';
import CalendarModal from '../../common/CalendarModal'; import CalendarModal from '../../common/CalendarModal';
import Icon from '../../common/icons/Icon';
import Button from '../../ui/Button'; import Button from '../../ui/Button';
import Checkbox from '../../ui/Checkbox'; import Checkbox from '../../ui/Checkbox';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
@ -251,9 +250,8 @@ const ManageInvite: FC<OwnProps & StateProps> = ({
onClick={handleSaveClick} onClick={handleSaveClick}
disabled={isSubmitBlocked} disabled={isSubmitBlocked}
ariaLabel={editingInvite ? lang('SaveLink') : lang('CreateLink')} ariaLabel={editingInvite ? lang('SaveLink') : lang('CreateLink')}
> iconName="check"
<Icon name="check" /> />
</FloatingActionButton>
</div> </div>
<CalendarModal <CalendarModal
isOpen={isCalendarOpened} isOpen={isCalendarOpened}

View File

@ -16,13 +16,11 @@ import { selectChat, selectChatFullInfo } from '../../../global/selectors';
import useHistoryBack from '../../../hooks/useHistoryBack'; import useHistoryBack from '../../../hooks/useHistoryBack';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import ReactionStaticEmoji from '../../common/reactions/ReactionStaticEmoji'; import ReactionStaticEmoji from '../../common/reactions/ReactionStaticEmoji';
import Checkbox from '../../ui/Checkbox'; import Checkbox from '../../ui/Checkbox';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
import RadioGroup from '../../ui/RadioGroup'; import RadioGroup from '../../ui/RadioGroup';
import RangeSlider from '../../ui/RangeSlider'; import RangeSlider from '../../ui/RangeSlider';
import Spinner from '../../ui/Spinner';
type OwnProps = { type OwnProps = {
chatId: string; chatId: string;
@ -254,13 +252,9 @@ const ManageReactions: FC<OwnProps & StateProps> = ({
onClick={handleSaveReactions} onClick={handleSaveReactions}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
disabled={isLoading} disabled={isLoading}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
</div> </div>
); );
}; };

View File

@ -27,7 +27,6 @@ import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Avatar from '../../common/Avatar'; import Avatar from '../../common/Avatar';
import Icon from '../../common/icons/Icon';
import PrivateChatInfo from '../../common/PrivateChatInfo'; import PrivateChatInfo from '../../common/PrivateChatInfo';
import Checkbox from '../../ui/Checkbox'; import Checkbox from '../../ui/Checkbox';
import ConfirmDialog from '../../ui/ConfirmDialog'; import ConfirmDialog from '../../ui/ConfirmDialog';
@ -35,7 +34,6 @@ import FloatingActionButton from '../../ui/FloatingActionButton';
import InputText from '../../ui/InputText'; import InputText from '../../ui/InputText';
import ListItem from '../../ui/ListItem'; import ListItem from '../../ui/ListItem';
import SelectAvatar from '../../ui/SelectAvatar'; import SelectAvatar from '../../ui/SelectAvatar';
import Spinner from '../../ui/Spinner';
import TextArea from '../../ui/TextArea'; import TextArea from '../../ui/TextArea';
import './Management.scss'; import './Management.scss';
@ -315,13 +313,9 @@ const ManageUser: FC<OwnProps & StateProps> = ({
onClick={handleProfileSave} onClick={handleProfileSave}
disabled={isLoading} disabled={isLoading}
ariaLabel={oldLang('Save')} ariaLabel={oldLang('Save')}
> iconName="check"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="check" />
)}
</FloatingActionButton>
<ConfirmDialog <ConfirmDialog
isOpen={isDeleteDialogOpen} isOpen={isDeleteDialogOpen}
onClose={closeDeleteDialog} onClose={closeDeleteDialog}

View File

@ -14,11 +14,9 @@ import useHistoryBack from '../../../hooks/useHistoryBack.ts';
import useLang from '../../../hooks/useLang.ts'; import useLang from '../../../hooks/useLang.ts';
import useLastCallback from '../../../hooks/useLastCallback.ts'; import useLastCallback from '../../../hooks/useLastCallback.ts';
import Icon from '../../common/icons/Icon.tsx';
import AvatarEditable from '../../ui/AvatarEditable.tsx'; import AvatarEditable from '../../ui/AvatarEditable.tsx';
import FloatingActionButton from '../../ui/FloatingActionButton.tsx'; import FloatingActionButton from '../../ui/FloatingActionButton.tsx';
import InputText from '../../ui/InputText.tsx'; import InputText from '../../ui/InputText.tsx';
import Spinner from '../../ui/Spinner.tsx';
type OwnProps = { type OwnProps = {
chatId: string; chatId: string;
@ -113,13 +111,9 @@ const NewDiscussionGroup: FC<OwnProps & StateProps> = ({
onClick={handleCreateGroup} onClick={handleCreateGroup}
disabled={isLoading} disabled={isLoading}
ariaLabel={lang('DiscussionCreateGroup')} ariaLabel={lang('DiscussionCreateGroup')}
> iconName="arrow-right"
{isLoading ? ( isLoading={isLoading}
<Spinner color="white" /> />
) : (
<Icon name="arrow-right" />
)}
</FloatingActionButton>
</div> </div>
</div> </div>
</div> </div>

View File

@ -13,7 +13,6 @@ import useEffectWithPrevDeps from '../../../hooks/useEffectWithPrevDeps';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang'; import useOldLang from '../../../hooks/useOldLang';
import Icon from '../../common/icons/Icon';
import PeerPicker from '../../common/pickers/PeerPicker'; import PeerPicker from '../../common/pickers/PeerPicker';
import FloatingActionButton from '../../ui/FloatingActionButton'; import FloatingActionButton from '../../ui/FloatingActionButton';
@ -85,9 +84,8 @@ function CloseFriends({
isShown={isSubmitShown} isShown={isSubmitShown}
onClick={handleSubmit} onClick={handleSubmit}
ariaLabel={lang('Save')} ariaLabel={lang('Save')}
> iconName="check"
<Icon name="check" /> />
</FloatingActionButton>
</div> </div>
</> </>
); );

View File

@ -1,11 +1,18 @@
.FloatingActionButton { .FloatingActionButton {
--transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1), background-color 0.15s, color 0.15s, opacity 0.15s;
position: absolute; position: absolute;
z-index: 2; z-index: 2;
right: 1rem; right: 1rem;
bottom: 1rem; bottom: 1rem;
transform: translateY(5rem); transform: translateY(5rem);
transition: transform 0.25s cubic-bezier(0.34, 1.56, 0.64, 1); transition: var(--transition);
&:active,
&.clicked {
transition: var(--transition) !important;
}
body.no-page-transitions & { body.no-page-transitions & {
transition: none !important; transition: none !important;

View File

@ -1,35 +1,36 @@
import type { FC } from '../../lib/teact/teact'; import type { IconName } from '../../types/icons';
import type React from '../../lib/teact/teact';
import type { OwnProps as ButtonProps } from './Button'; import type { OwnProps as ButtonProps } from './Button';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import IconWithSpinner from '../common/IconWithSpinner';
import Button from './Button'; import Button from './Button';
import './FloatingActionButton.scss'; import './FloatingActionButton.scss';
type OwnProps = { type OwnProps = {
isShown: boolean; isShown: boolean;
iconName: IconName;
className?: string; className?: string;
color?: ButtonProps['color']; color?: ButtonProps['color'];
ariaLabel?: ButtonProps['ariaLabel']; ariaLabel?: ButtonProps['ariaLabel'];
disabled?: boolean; disabled?: boolean;
isLoading?: boolean;
onClick: () => void; onClick: () => void;
children: React.ReactNode;
}; };
const FloatingActionButton: FC<OwnProps> = ({ const FloatingActionButton = ({
isShown, isShown,
iconName,
className, className,
color = 'primary', color = 'primary',
ariaLabel, ariaLabel,
disabled, disabled,
isLoading,
onClick, onClick,
children, }: OwnProps) => {
}) => {
const lang = useOldLang(); const lang = useOldLang();
const buttonClassName = buildClassName( const buttonClassName = buildClassName(
@ -49,7 +50,7 @@ const FloatingActionButton: FC<OwnProps> = ({
tabIndex={-1} tabIndex={-1}
isRtl={lang.isRtl} isRtl={lang.isRtl}
> >
{children} <IconWithSpinner iconName={iconName} isLoading={isLoading} />
</Button> </Button>
); );
}; };