[Perf] Reduce amount of global containers (DeleteChatModal, Transition, SafeLink, Audio)
This commit is contained in:
parent
094a235373
commit
3f5c8edceb
@ -1,7 +1,6 @@
|
||||
import React, {
|
||||
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
|
||||
} from '../../lib/teact/teact';
|
||||
import { withGlobal } from '../../lib/teact/teactn';
|
||||
|
||||
import {
|
||||
ApiAudio, ApiMessage, ApiVoice,
|
||||
@ -24,7 +23,6 @@ import { renderWaveformToDataUri } from './helpers/waveform';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
import renderText from './helpers/renderText';
|
||||
import { decodeWaveform, interpolateArray } from '../../util/waveform';
|
||||
import { selectTheme } from '../../modules/selectors';
|
||||
import useMediaWithDownloadProgress from '../../hooks/useMediaWithDownloadProgress';
|
||||
import useShowTransition from '../../hooks/useShowTransition';
|
||||
import useBuffering from '../../hooks/useBuffering';
|
||||
@ -39,10 +37,11 @@ import Link from '../ui/Link';
|
||||
import './Audio.scss';
|
||||
|
||||
type OwnProps = {
|
||||
theme: ISettings['theme'];
|
||||
message: ApiMessage;
|
||||
senderTitle?: string;
|
||||
uploadProgress?: number;
|
||||
renderingFor?: 'searchResult' | 'sharedMedia';
|
||||
target?: 'searchResult' | 'sharedMedia';
|
||||
date?: number;
|
||||
lastSyncTime?: number;
|
||||
className?: string;
|
||||
@ -54,10 +53,6 @@ type OwnProps = {
|
||||
onDateClick?: (messageId: number, chatId: number) => void;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
theme: ISettings['theme'];
|
||||
};
|
||||
|
||||
interface ISeekMethods {
|
||||
handleStartSeek: (e: React.MouseEvent<HTMLElement>) => void;
|
||||
handleSeek: (e: React.MouseEvent<HTMLElement>) => void;
|
||||
@ -70,12 +65,12 @@ const MAX_SPIKES = IS_SINGLE_COLUMN_LAYOUT ? 50 : 75;
|
||||
// This is needed for browsers requiring user interaction before playing.
|
||||
const PRELOAD = true;
|
||||
|
||||
const Audio: FC<OwnProps & StateProps> = ({
|
||||
const Audio: FC<OwnProps> = ({
|
||||
theme,
|
||||
message,
|
||||
senderTitle,
|
||||
uploadProgress,
|
||||
renderingFor,
|
||||
target,
|
||||
date,
|
||||
lastSyncTime,
|
||||
className,
|
||||
@ -229,8 +224,8 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
const fullClassName = buildClassName(
|
||||
'Audio media-inner',
|
||||
className,
|
||||
isOwn && !renderingFor && 'own',
|
||||
renderingFor && 'bigger',
|
||||
isOwn && !target && 'own',
|
||||
target && 'bigger',
|
||||
isSelected && 'audio-is-selected',
|
||||
);
|
||||
|
||||
@ -287,7 +282,7 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
<Button
|
||||
round
|
||||
ripple={!IS_SINGLE_COLUMN_LAYOUT}
|
||||
size={renderingFor ? 'smaller' : 'tiny'}
|
||||
size={target ? 'smaller' : 'tiny'}
|
||||
className={buttonClassNames.join(' ')}
|
||||
ariaLabel={isPlaying ? 'Pause audio' : 'Play audio'}
|
||||
onClick={handleButtonClick}
|
||||
@ -301,7 +296,7 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
<ProgressSpinner
|
||||
progress={transferProgress}
|
||||
transparent
|
||||
size={renderingFor ? 'm' : 's'}
|
||||
size={target ? 'm' : 's'}
|
||||
onClick={isLoadingForPlaying ? handleButtonClick : undefined}
|
||||
noCross={!isLoadingForPlaying}
|
||||
/>
|
||||
@ -318,12 +313,12 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
<i className={isDownloadStarted ? 'icon-close' : 'icon-arrow-down'} />
|
||||
</Button>
|
||||
)}
|
||||
{renderingFor === 'searchResult' && renderSearchResult()}
|
||||
{renderingFor !== 'searchResult' && audio && renderAudio(
|
||||
{target === 'searchResult' && renderSearchResult()}
|
||||
{target !== 'searchResult' && audio && renderAudio(
|
||||
lang, audio, isPlaying, playProgress, bufferedProgress, seekHandlers, date,
|
||||
onDateClick ? handleDateClick : undefined,
|
||||
)}
|
||||
{renderingFor !== 'searchResult' && voice && renderVoice(voice, renderedWaveform, isMediaUnread)}
|
||||
{target !== 'searchResult' && voice && renderVoice(voice, renderedWaveform, isMediaUnread)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -457,6 +452,4 @@ function renderSeekline(
|
||||
);
|
||||
}
|
||||
|
||||
export default memo(withGlobal<OwnProps>((global) => ({
|
||||
theme: selectTheme(global),
|
||||
}))(Audio));
|
||||
export default memo(Audio);
|
||||
|
||||
@ -28,6 +28,7 @@ export type OwnProps = {
|
||||
isOpen: boolean;
|
||||
chat: ApiChat;
|
||||
onClose: () => void;
|
||||
onCloseAnimationEnd?: () => void;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -53,6 +54,7 @@ const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
canDeleteForAll,
|
||||
contactName,
|
||||
onClose,
|
||||
onCloseAnimationEnd,
|
||||
leaveChannel,
|
||||
deleteHistory,
|
||||
deleteChannel,
|
||||
@ -147,9 +149,10 @@ const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return (
|
||||
<Modal
|
||||
isOpen={isOpen}
|
||||
onClose={onClose}
|
||||
className="DeleteChatModal"
|
||||
header={renderHeader()}
|
||||
onClose={onClose}
|
||||
onCloseAnimationEnd={onCloseAnimationEnd}
|
||||
>
|
||||
{renderMessage()}
|
||||
{canDeleteForAll && (
|
||||
|
||||
@ -1,10 +1,8 @@
|
||||
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
|
||||
import { withGlobal } from '../../lib/teact/teactn';
|
||||
import { getDispatch } from '../../lib/teact/teactn';
|
||||
import convertPunycode from '../../lib/punycode';
|
||||
import { GlobalActions } from '../../global/types';
|
||||
|
||||
import { DEBUG, RE_TME_INVITE_LINK, RE_TME_LINK } from '../../config';
|
||||
import { pick } from '../../util/iteratees';
|
||||
import buildClassName from '../../util/buildClassName';
|
||||
|
||||
type OwnProps = {
|
||||
@ -15,17 +13,15 @@ type OwnProps = {
|
||||
isRtl?: boolean;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'toggleSafeLinkModal' | 'openTelegramLink'>;
|
||||
|
||||
const SafeLink: FC<OwnProps & DispatchProps> = ({
|
||||
const SafeLink: FC<OwnProps> = ({
|
||||
url,
|
||||
text,
|
||||
className,
|
||||
children,
|
||||
isRtl,
|
||||
toggleSafeLinkModal,
|
||||
openTelegramLink,
|
||||
}) => {
|
||||
const { toggleSafeLinkModal, openTelegramLink } = getDispatch();
|
||||
|
||||
const content = children || text;
|
||||
const isNotSafe = url !== content;
|
||||
|
||||
@ -113,9 +109,4 @@ function getDomain(url?: string) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export default memo(withGlobal<OwnProps>(
|
||||
undefined,
|
||||
(setGlobal, actions): DispatchProps => pick(actions, [
|
||||
'toggleSafeLinkModal', 'openTelegramLink',
|
||||
]),
|
||||
)(SafeLink));
|
||||
export default memo(SafeLink);
|
||||
|
||||
@ -109,6 +109,7 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
const ref = useRef<HTMLDivElement>(null);
|
||||
|
||||
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();
|
||||
const [shouldRenderDeleteModal, markRenderDeleteModal, unmarkRenderDeleteModal] = useFlag();
|
||||
|
||||
const { lastMessage, typingStatus } = chat || {};
|
||||
const isAction = lastMessage && isActionMessage(lastMessage);
|
||||
@ -171,10 +172,15 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
focusLastMessage,
|
||||
]);
|
||||
|
||||
function handleDelete() {
|
||||
markRenderDeleteModal();
|
||||
openDeleteModal();
|
||||
}
|
||||
|
||||
const contextActions = useChatContextActions({
|
||||
chat,
|
||||
privateChatUser,
|
||||
handleDelete: openDeleteModal,
|
||||
handleDelete,
|
||||
folderId,
|
||||
isPinned,
|
||||
isMuted,
|
||||
@ -277,11 +283,14 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
<Badge chat={chat} isPinned={isPinned} isMuted={isMuted} />
|
||||
</div>
|
||||
</div>
|
||||
<DeleteChatModal
|
||||
isOpen={isDeleteModalOpen}
|
||||
onClose={closeDeleteModal}
|
||||
chat={chat}
|
||||
/>
|
||||
{shouldRenderDeleteModal && (
|
||||
<DeleteChatModal
|
||||
isOpen={isDeleteModalOpen}
|
||||
onClose={closeDeleteModal}
|
||||
onCloseAnimationEnd={unmarkRenderDeleteModal}
|
||||
chat={chat}
|
||||
/>
|
||||
)}
|
||||
</ListItem>
|
||||
);
|
||||
};
|
||||
|
||||
@ -31,6 +31,7 @@ type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'focusMessage
|
||||
const runThrottled = throttle((cb) => cb(), 500, true);
|
||||
|
||||
const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
theme,
|
||||
isVoice,
|
||||
searchQuery,
|
||||
searchChatId,
|
||||
@ -94,8 +95,9 @@ const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
)}
|
||||
<Audio
|
||||
key={message.id}
|
||||
theme={theme}
|
||||
message={message}
|
||||
renderingFor="searchResult"
|
||||
target="searchResult"
|
||||
senderTitle={getSenderName(lang, message, chatsById, usersById)}
|
||||
date={message.date}
|
||||
lastSyncTime={lastSyncTime}
|
||||
|
||||
@ -2,8 +2,12 @@ import { GlobalState } from '../../../../global/types';
|
||||
import {
|
||||
ApiChat, ApiGlobalMessageSearchType, ApiMessage, ApiUser,
|
||||
} from '../../../../api/types';
|
||||
import { ISettings } from '../../../../types';
|
||||
|
||||
import { selectTheme } from '../../../../modules/selectors';
|
||||
|
||||
export type StateProps = {
|
||||
theme: ISettings['theme'];
|
||||
isLoading?: boolean;
|
||||
chatsById: Record<number, ApiChat>;
|
||||
usersById: Record<number, ApiUser>;
|
||||
@ -30,6 +34,7 @@ export function createMapStateToProps(type: ApiGlobalMessageSearchType) {
|
||||
const { foundIds } = (resultsByType && resultsByType[currentType]) || {};
|
||||
|
||||
return {
|
||||
theme: selectTheme(global),
|
||||
isLoading: foundIds === undefined
|
||||
|| (fetchingStatus ? Boolean(fetchingStatus.chats || fetchingStatus.messages) : false),
|
||||
chatsById,
|
||||
|
||||
@ -19,7 +19,9 @@ import {
|
||||
ApiSticker,
|
||||
MAIN_THREAD_ID,
|
||||
} from '../../../api/types';
|
||||
import { FocusDirection, IAlbum, MediaViewerOrigin } from '../../../types';
|
||||
import {
|
||||
FocusDirection, IAlbum, ISettings, MediaViewerOrigin,
|
||||
} from '../../../types';
|
||||
|
||||
import { IS_ANDROID } from '../../../util/environment';
|
||||
import { pick } from '../../../util/iteratees';
|
||||
@ -40,7 +42,9 @@ import {
|
||||
selectForwardedSender,
|
||||
selectThreadTopMessageId,
|
||||
selectShouldAutoLoadMedia,
|
||||
selectShouldAutoPlayMedia, selectShouldLoopStickers,
|
||||
selectShouldAutoPlayMedia,
|
||||
selectShouldLoopStickers,
|
||||
selectTheme,
|
||||
} from '../../../modules/selectors';
|
||||
import {
|
||||
getMessageContent,
|
||||
@ -117,6 +121,7 @@ type OwnProps = {
|
||||
} & MessagePositionProperties;
|
||||
|
||||
type StateProps = {
|
||||
theme: ISettings['theme'];
|
||||
forceSenderName?: boolean;
|
||||
sender?: ApiUser | ApiChat;
|
||||
originSender?: ApiUser | ApiChat;
|
||||
@ -179,6 +184,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
isFirstInDocumentGroup,
|
||||
isLastInDocumentGroup,
|
||||
isLastInList,
|
||||
theme,
|
||||
forceSenderName,
|
||||
sender,
|
||||
originSender,
|
||||
@ -601,6 +607,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
)}
|
||||
{(audio || voice) && (
|
||||
<Audio
|
||||
theme={theme}
|
||||
message={message}
|
||||
uploadProgress={uploadProgress}
|
||||
lastSyncTime={lastSyncTime}
|
||||
@ -907,6 +914,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
}
|
||||
|
||||
return {
|
||||
theme: selectTheme(global),
|
||||
forceSenderName,
|
||||
sender,
|
||||
originSender,
|
||||
|
||||
@ -28,8 +28,8 @@ type StateProps = {
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, ('toggleMessageSelection')>;
|
||||
|
||||
export default function withSelectControl(WrapedComponent: FC) {
|
||||
const Component: FC<OwnProps & StateProps & DispatchProps> = (props) => {
|
||||
export default function withSelectControl(WrappedComponent: FC) {
|
||||
const ComponentWithSelectControl: FC<OwnProps & StateProps & DispatchProps> = (props) => {
|
||||
const {
|
||||
isInSelectMode,
|
||||
isSelected,
|
||||
@ -77,7 +77,7 @@ export default function withSelectControl(WrapedComponent: FC) {
|
||||
</div>
|
||||
)}
|
||||
{/* eslint-disable-next-line react/jsx-props-no-spreading */}
|
||||
<WrapedComponent {...newProps} />
|
||||
<WrappedComponent {...newProps} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -93,5 +93,5 @@ export default function withSelectControl(WrapedComponent: FC) {
|
||||
(setGlobal, actions) => pick(actions, [
|
||||
'toggleMessageSelection',
|
||||
]),
|
||||
)(Component));
|
||||
)(ComponentWithSelectControl));
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@ import {
|
||||
} from '../../api/types';
|
||||
import { GlobalActions } from '../../global/types';
|
||||
import {
|
||||
ISettings,
|
||||
MediaViewerOrigin, ProfileState, ProfileTabType, SharedMediaType,
|
||||
} from '../../types';
|
||||
|
||||
@ -29,6 +30,7 @@ import {
|
||||
selectChat,
|
||||
selectCurrentMediaSearch,
|
||||
selectIsRightColumnShown,
|
||||
selectTheme,
|
||||
} from '../../modules/selectors';
|
||||
import { pick } from '../../util/iteratees';
|
||||
import { captureEvents, SwipeDirection } from '../../util/captureEvents';
|
||||
@ -63,6 +65,7 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
theme: ISettings['theme'];
|
||||
isChannel?: boolean;
|
||||
resolvedUserId?: number;
|
||||
chatMessages?: Record<number, ApiMessage>;
|
||||
@ -96,6 +99,7 @@ const Profile: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
chatId,
|
||||
profileState,
|
||||
onProfileStateChange,
|
||||
theme,
|
||||
isChannel,
|
||||
resolvedUserId,
|
||||
chatMessages,
|
||||
@ -287,8 +291,9 @@ const Profile: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
viewportIds!.map((id) => chatMessages[id] && (
|
||||
<Audio
|
||||
key={id}
|
||||
renderingFor="sharedMedia"
|
||||
theme={theme}
|
||||
message={chatMessages[id]}
|
||||
target="sharedMedia"
|
||||
date={chatMessages[id].date}
|
||||
lastSyncTime={lastSyncTime}
|
||||
className="scroll-item"
|
||||
@ -394,6 +399,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
}
|
||||
|
||||
return {
|
||||
theme: selectTheme(global),
|
||||
isChannel,
|
||||
resolvedUserId,
|
||||
chatMessages,
|
||||
|
||||
@ -2,7 +2,7 @@ import { RefObject } from 'react';
|
||||
import React, {
|
||||
FC, useLayoutEffect, useRef,
|
||||
} from '../../lib/teact/teact';
|
||||
import { withGlobal } from '../../lib/teact/teactn';
|
||||
import { getGlobal } from '../../lib/teact/teactn';
|
||||
|
||||
import { ANIMATION_END_DELAY } from '../../config';
|
||||
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
|
||||
@ -32,10 +32,6 @@ type OwnProps = {
|
||||
children: ChildrenFn;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
animationLevel: number;
|
||||
};
|
||||
|
||||
const ANIMATION_DURATION = {
|
||||
slide: 450,
|
||||
'slide-reversed': 450,
|
||||
@ -51,7 +47,7 @@ const ANIMATION_DURATION = {
|
||||
|
||||
const CLEANED_UP = Symbol('CLEANED_UP');
|
||||
|
||||
const Transition: FC<OwnProps & StateProps> = ({
|
||||
const Transition: FC<OwnProps> = ({
|
||||
ref,
|
||||
activeKey,
|
||||
name,
|
||||
@ -64,8 +60,10 @@ const Transition: FC<OwnProps & StateProps> = ({
|
||||
onStart,
|
||||
onStop,
|
||||
children,
|
||||
animationLevel,
|
||||
}) => {
|
||||
// No need for a container to update on change
|
||||
const { animationLevel } = getGlobal().settings.byKey;
|
||||
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
let containerRef = useRef<HTMLDivElement>(null);
|
||||
if (ref) {
|
||||
@ -255,7 +253,4 @@ const Transition: FC<OwnProps & StateProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default withGlobal<OwnProps>((global) => {
|
||||
const { animationLevel } = global.settings.byKey;
|
||||
return { animationLevel };
|
||||
})(Transition);
|
||||
export default Transition;
|
||||
|
||||
@ -218,6 +218,14 @@ if (DEBUG) {
|
||||
|
||||
document.addEventListener('dblclick', () => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log('GLOBAL CONTAINERS', orderBy(Object.values(containers), 'DEBUG_updates', 'desc'));
|
||||
console.log(
|
||||
'GLOBAL CONTAINERS',
|
||||
orderBy(
|
||||
Array.from(containers.values())
|
||||
.map(({ DEBUG_componentName, DEBUG_updates }) => ({ DEBUG_componentName, DEBUG_updates })),
|
||||
'DEBUG_updates',
|
||||
'desc',
|
||||
),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user