[Perf] Composer: Prevent invisible animations when opening chat

This commit is contained in:
Alexander Zinchuk 2021-08-03 19:03:11 +03:00
parent 69b9394a18
commit 8dff81f301
4 changed files with 41 additions and 19 deletions

View File

@ -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<OwnProps & StateProps & DispatchProps> = ({
focusingId,
hasFocusHighlight,
isSelectModeActive,
animationLevel,
loadViewportMessages,
setScrollOffset,
lastMessage,
@ -413,11 +413,11 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
// 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<OwnProps>(
focusingId,
hasFocusHighlight,
isSelectModeActive: selectIsInSelectMode(global),
animationLevel: global.settings.byKey.animationLevel,
...(withLastMessageWhenPreloading && { lastMessage }),
botDescription,
threadTopMessageId,

View File

@ -25,7 +25,7 @@ import './AttachmentModal.scss';
export type OwnProps = {
attachments: ApiAttachment[];
caption: string;
canSuggestEmoji?: boolean;
isReady?: boolean;
currentUserId?: number;
groupChatMembers?: ApiChatMember[];
usersById?: Record<number, ApiUser>;
@ -44,14 +44,15 @@ const DROP_LEAVE_TIMEOUT_MS = 150;
const AttachmentModal: FC<OwnProps> = ({
attachments,
caption,
groupChatMembers,
isReady,
currentUserId,
groupChatMembers,
usersById,
recentEmojis,
baseEmojiKeywords,
emojiKeywords,
onCaptionUpdate,
addRecentEmoji,
onCaptionUpdate,
onSend,
onFileAppend,
onClear,
@ -89,6 +90,7 @@ const AttachmentModal: FC<OwnProps> = ({
onCaptionUpdate,
baseEmojiKeywords,
emojiKeywords,
!isReady,
);
useEffect(() => (isOpen ? captureEscKeyListener(onClear) : undefined), [isOpen, onClear]);

View File

@ -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;

View File

@ -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<OwnProps & StateProps & DispatchProps> = ({
dropAreaState,
shouldSchedule,
canScheduleUntilOnline,
onDropHide,
isReady,
onDropHide,
editingMessage,
chatId,
threadId,
@ -520,7 +520,9 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
}
// 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<OwnProps & StateProps & DispatchProps> = ({
openCalendar();
} else {
sendMessage({ sticker });
requestAnimationFrame(() => { resetComposer(shouldPreserveInput); });
requestAnimationFrame(() => {
resetComposer(shouldPreserveInput);
});
}
}, [shouldSchedule, openCalendar, sendMessage, resetComposer]);
@ -547,7 +551,9 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
openCalendar();
} else {
sendMessage({ gif });
requestAnimationFrame(() => { resetComposer(true); });
requestAnimationFrame(() => {
resetComposer(true);
});
}
}, [shouldSchedule, openCalendar, sendMessage, resetComposer]);
@ -567,7 +573,9 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
}
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<OwnProps & StateProps & DispatchProps> = ({
...scheduledMessageArgs,
scheduledAt,
});
requestAnimationFrame(() => { resetComposer(); });
requestAnimationFrame(() => {
resetComposer();
});
}
closeCalendar();
}, [closeCalendar, handleSend, resetComposer, scheduledMessageArgs, sendMessage, serverTimeOffset]);
@ -674,7 +684,9 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
openCalendar();
} else {
handleSend();
requestAnimationFrame(() => { resetComposer(); });
requestAnimationFrame(() => {
resetComposer();
});
}
break;
case MainButtonState.Record:
@ -723,6 +735,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
const symbolMenuButtonClassName = buildClassName(
'mobile-symbol-menu-button',
!isReady && 'not-ready',
isSymbolMenuLoaded
? (isSymbolMenuOpen && 'menu-opened')
: (isSymbolMenuOpen && 'is-loading'),
@ -751,6 +764,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
currentUserId={currentUserId}
usersById={usersById}
recentEmojis={recentEmojis}
isReady={isReady}
onCaptionUpdate={setHtml}
baseEmojiKeywords={baseEmojiKeywords}
emojiKeywords={emojiKeywords}
@ -819,7 +833,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
>
<i className="icon-smile" />
<i className="icon-keyboard" />
{!isSymbolMenuLoaded && <Spinner color="gray" />}
{isSymbolMenuOpen && !isSymbolMenuLoaded && <Spinner color="gray" />}
</Button>
) : (
<ResponsiveHoverButton
@ -945,7 +959,7 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
ref={mainButtonRef}
round
color="secondary"
className={`${mainButtonState} ${activeVoiceRecording ? 'recording' : ''}`}
className={buildClassName(mainButtonState, !isReady && 'not-ready', activeVoiceRecording && 'recording')}
disabled={areVoiceMessagesNotAllowed}
ariaLabel={lang(sendButtonAriaLabel)}
onClick={mainButtonHandler}