[Perf] Composer: Prevent invisible animations when opening chat
This commit is contained in:
parent
69b9394a18
commit
8dff81f301
@ -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,
|
||||
|
||||
@ -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]);
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user