From 8dff81f301247efff0551d663f9ada0bafc7ec7f Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 3 Aug 2021 19:03:11 +0300 Subject: [PATCH] [Perf] Composer: Prevent invisible animations when opening chat --- src/components/middle/MessageList.tsx | 9 +++-- .../middle/composer/AttachmentModal.tsx | 8 +++-- src/components/middle/composer/Composer.scss | 9 ++++- src/components/middle/composer/Composer.tsx | 34 +++++++++++++------ 4 files changed, 41 insertions(+), 19 deletions(-) diff --git a/src/components/middle/MessageList.tsx b/src/components/middle/MessageList.tsx index d32e97a66..2730e5c1d 100644 --- a/src/components/middle/MessageList.tsx +++ b/src/components/middle/MessageList.tsx @@ -28,6 +28,7 @@ import { isChatChannel, isChatPrivate } from '../../modules/helpers'; import { orderBy, pick } from '../../util/iteratees'; import { fastRaf, debounce, onTickEnd } from '../../util/schedulers'; import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps'; +import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps'; import buildClassName from '../../util/buildClassName'; import { groupMessages } from './helpers/groupMessages'; import { preventMessageInputBlur } from './helpers/preventMessageInputBlur'; @@ -112,7 +113,6 @@ const MessageList: FC = ({ focusingId, hasFocusHighlight, isSelectModeActive, - animationLevel, loadViewportMessages, setScrollOffset, lastMessage, @@ -413,11 +413,11 @@ const MessageList: FC = ({ // This should match deps for `useOnChange` above }, [messageIds, isViewportNewest, containerHeight, hasTools]); - useEffect(() => { - if (!animationLevel || animationLevel > 0) { + useEffectWithPrevDeps(([prevIsSelectModeActive]) => { + if (prevIsSelectModeActive !== undefined) { dispatchHeavyAnimationEvent(SELECT_MODE_ANIMATION_DURATION + ANIMATION_END_DELAY); } - }, [animationLevel, isSelectModeActive]); + }, [isSelectModeActive]); const lang = useLang(); @@ -534,7 +534,6 @@ export default memo(withGlobal( focusingId, hasFocusHighlight, isSelectModeActive: selectIsInSelectMode(global), - animationLevel: global.settings.byKey.animationLevel, ...(withLastMessageWhenPreloading && { lastMessage }), botDescription, threadTopMessageId, diff --git a/src/components/middle/composer/AttachmentModal.tsx b/src/components/middle/composer/AttachmentModal.tsx index 94e33741d..738bd13d5 100644 --- a/src/components/middle/composer/AttachmentModal.tsx +++ b/src/components/middle/composer/AttachmentModal.tsx @@ -25,7 +25,7 @@ import './AttachmentModal.scss'; export type OwnProps = { attachments: ApiAttachment[]; caption: string; - canSuggestEmoji?: boolean; + isReady?: boolean; currentUserId?: number; groupChatMembers?: ApiChatMember[]; usersById?: Record; @@ -44,14 +44,15 @@ const DROP_LEAVE_TIMEOUT_MS = 150; const AttachmentModal: FC = ({ attachments, caption, - groupChatMembers, + isReady, currentUserId, + groupChatMembers, usersById, recentEmojis, baseEmojiKeywords, emojiKeywords, - onCaptionUpdate, addRecentEmoji, + onCaptionUpdate, onSend, onFileAppend, onClear, @@ -89,6 +90,7 @@ const AttachmentModal: FC = ({ onCaptionUpdate, baseEmojiKeywords, emojiKeywords, + !isReady, ); useEffect(() => (isOpen ? captureEscKeyListener(onClear) : undefined), [isOpen, onClear]); diff --git a/src/components/middle/composer/Composer.scss b/src/components/middle/composer/Composer.scss index 11b0f8610..34fc61d02 100644 --- a/src/components/middle/composer/Composer.scss +++ b/src/components/middle/composer/Composer.scss @@ -93,6 +93,10 @@ } } + &.not-ready > i { + animation-duration: 0ms !important; + } + body.animation-level-0 &, body.animation-level-1 & { .icon-send, .icon-microphone-alt, .icon-check { animation-duration: 0ms !important; @@ -123,6 +127,10 @@ animation: hide-icon .4s forwards ease-out; } + &.not-ready > i { + animation-duration: 0ms !important; + } + &.is-loading { .Spinner { animation: grow-icon .4s ease-out; @@ -155,7 +163,6 @@ position: relative; z-index: 1; - .svg-appendix { position: absolute; bottom: -.1875rem; diff --git a/src/components/middle/composer/Composer.tsx b/src/components/middle/composer/Composer.tsx index 0e1d1b3d7..6d135c8d6 100644 --- a/src/components/middle/composer/Composer.tsx +++ b/src/components/middle/composer/Composer.tsx @@ -96,8 +96,8 @@ type OwnProps = { threadId: number; messageListType: MessageListType; dropAreaState: string; - onDropHide: NoneToVoidFunction; isReady: boolean; + onDropHide: NoneToVoidFunction; }; type StateProps = { @@ -160,8 +160,8 @@ const Composer: FC = ({ dropAreaState, shouldSchedule, canScheduleUntilOnline, - onDropHide, isReady, + onDropHide, editingMessage, chatId, threadId, @@ -520,7 +520,9 @@ const Composer: FC = ({ } // Wait until message animation starts - requestAnimationFrame(() => { resetComposer(); }); + requestAnimationFrame(() => { + resetComposer(); + }); }, [ connectionState, attachments, activeVoiceRecording, isForwarding, serverTimeOffset, clearDraft, chatId, resetComposer, stopRecordingVoice, showDialog, slowMode, isAdmin, sendMessage, forwardMessages, lang, @@ -537,7 +539,9 @@ const Composer: FC = ({ openCalendar(); } else { sendMessage({ sticker }); - requestAnimationFrame(() => { resetComposer(shouldPreserveInput); }); + requestAnimationFrame(() => { + resetComposer(shouldPreserveInput); + }); } }, [shouldSchedule, openCalendar, sendMessage, resetComposer]); @@ -547,7 +551,9 @@ const Composer: FC = ({ openCalendar(); } else { sendMessage({ gif }); - requestAnimationFrame(() => { resetComposer(true); }); + requestAnimationFrame(() => { + resetComposer(true); + }); } }, [shouldSchedule, openCalendar, sendMessage, resetComposer]); @@ -567,7 +573,9 @@ const Composer: FC = ({ } clearDraft({ chatId, localOnly: true }); - requestAnimationFrame(() => { resetComposer(); }); + requestAnimationFrame(() => { + resetComposer(); + }); }, [chatId, clearDraft, connectionState, resetComposer, sendInlineBotResult]); const handlePollSend = useCallback((poll: ApiNewPoll) => { @@ -604,7 +612,9 @@ const Composer: FC = ({ ...scheduledMessageArgs, scheduledAt, }); - requestAnimationFrame(() => { resetComposer(); }); + requestAnimationFrame(() => { + resetComposer(); + }); } closeCalendar(); }, [closeCalendar, handleSend, resetComposer, scheduledMessageArgs, sendMessage, serverTimeOffset]); @@ -674,7 +684,9 @@ const Composer: FC = ({ openCalendar(); } else { handleSend(); - requestAnimationFrame(() => { resetComposer(); }); + requestAnimationFrame(() => { + resetComposer(); + }); } break; case MainButtonState.Record: @@ -723,6 +735,7 @@ const Composer: FC = ({ const symbolMenuButtonClassName = buildClassName( 'mobile-symbol-menu-button', + !isReady && 'not-ready', isSymbolMenuLoaded ? (isSymbolMenuOpen && 'menu-opened') : (isSymbolMenuOpen && 'is-loading'), @@ -751,6 +764,7 @@ const Composer: FC = ({ currentUserId={currentUserId} usersById={usersById} recentEmojis={recentEmojis} + isReady={isReady} onCaptionUpdate={setHtml} baseEmojiKeywords={baseEmojiKeywords} emojiKeywords={emojiKeywords} @@ -819,7 +833,7 @@ const Composer: FC = ({ > - {!isSymbolMenuLoaded && } + {isSymbolMenuOpen && !isSymbolMenuLoaded && } ) : ( = ({ ref={mainButtonRef} round color="secondary" - className={`${mainButtonState} ${activeVoiceRecording ? 'recording' : ''}`} + className={buildClassName(mainButtonState, !isReady && 'not-ready', activeVoiceRecording && 'recording')} disabled={areVoiceMessagesNotAllowed} ariaLabel={lang(sendButtonAriaLabel)} onClick={mainButtonHandler}