[Perf] TeactN: Get rid of redundant iterations for global actions

This commit is contained in:
Alexander Zinchuk 2021-12-31 18:17:27 +01:00
parent d12c9d384d
commit 3ef7136621
133 changed files with 1116 additions and 1797 deletions

View File

@ -1,7 +1,7 @@
import { FC, useEffect } from './lib/teact/teact';
import React, { withGlobal } from './lib/teact/teactn';
import React, { getDispatch, withGlobal } from './lib/teact/teactn';
import { GlobalActions, GlobalState } from './global/types';
import { GlobalState } from './global/types';
import { INACTIVE_MARKER, PAGE_TITLE } from './config';
import { pick } from './util/iteratees';
@ -17,9 +17,10 @@ import { hasStoredSession } from './util/sessions';
// import Test from './components/test/TestNoRedundancy';
type StateProps = Pick<GlobalState, 'authState'>;
type DispatchProps = Pick<GlobalActions, 'disconnect'>;
const App: FC<StateProps & DispatchProps> = ({ authState, disconnect }) => {
const App: FC<StateProps> = ({ authState }) => {
const { disconnect } = getDispatch();
const [isInactive, markInactive] = useFlag(false);
useEffect(() => {
@ -67,5 +68,4 @@ function renderMain() {
export default withGlobal(
(global): StateProps => pick(global, ['authState']),
(setGlobal, actions): DispatchProps => pick(actions, ['disconnect']),
)(App);

View File

@ -1,7 +1,7 @@
import React, { FC, useEffect, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../global/types';
import { GlobalState } from '../../global/types';
import '../../modules/actions/initial';
import { pick } from '../../util/iteratees';
@ -19,11 +19,14 @@ import AuthQrCode from './AuthQrCode';
import './Auth.scss';
type StateProps = Pick<GlobalState, 'authState'>;
type DispatchProps = Pick<GlobalActions, 'reset' | 'initApi' | 'returnToAuthPhoneNumber' | 'goToAuthQrCode'>;
const Auth: FC<StateProps & DispatchProps> = ({
authState, reset, initApi, returnToAuthPhoneNumber, goToAuthQrCode,
const Auth: FC<StateProps> = ({
authState,
}) => {
const {
reset, initApi, returnToAuthPhoneNumber, goToAuthQrCode,
} = getDispatch();
useEffect(() => {
reset();
initApi();
@ -73,5 +76,4 @@ const Auth: FC<StateProps & DispatchProps> = ({
export default memo(withGlobal(
(global): StateProps => pick(global, ['authState']),
(global, actions): DispatchProps => pick(actions, ['reset', 'initApi', 'returnToAuthPhoneNumber', 'goToAuthQrCode']),
)(Auth));

View File

@ -2,8 +2,8 @@ import { FormEvent } from 'react';
import React, {
FC, useState, useEffect, useCallback, memo, useRef,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { GlobalState, GlobalActions } from '../../global/types';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalState } from '../../global/types';
import { IS_TOUCH_ENV } from '../../util/environment';
import { pick } from '../../util/iteratees';
@ -16,21 +16,21 @@ import Loading from '../ui/Loading';
import TrackingMonkey from '../common/TrackingMonkey';
type StateProps = Pick<GlobalState, 'authPhoneNumber' | 'authIsCodeViaApp' | 'authIsLoading' | 'authError'>;
type DispatchProps = Pick<GlobalActions, (
'setAuthCode' | 'returnToAuthPhoneNumber' | 'clearAuthError'
)>;
const CODE_LENGTH = 5;
const AuthCode: FC<StateProps & DispatchProps> = ({
const AuthCode: FC<StateProps> = ({
authPhoneNumber,
authIsCodeViaApp,
authIsLoading,
authError,
setAuthCode,
returnToAuthPhoneNumber,
clearAuthError,
}) => {
const {
setAuthCode,
returnToAuthPhoneNumber,
clearAuthError,
} = getDispatch();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);
@ -120,9 +120,4 @@ const AuthCode: FC<StateProps & DispatchProps> = ({
export default memo(withGlobal(
(global): StateProps => pick(global, ['authPhoneNumber', 'authIsCodeViaApp', 'authIsLoading', 'authError']),
(setGlobal, actions): DispatchProps => pick(actions, [
'setAuthCode',
'returnToAuthPhoneNumber',
'clearAuthError',
]),
)(AuthCode));

View File

@ -1,9 +1,9 @@
import React, {
FC, memo, useCallback, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalState, GlobalActions } from '../../global/types';
import { GlobalState } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
@ -12,11 +12,12 @@ import MonkeyPassword from '../common/PasswordMonkey';
import PasswordForm from '../common/PasswordForm';
type StateProps = Pick<GlobalState, 'authIsLoading' | 'authError' | 'authHint'>;
type DispatchProps = Pick<GlobalActions, 'setAuthPassword' | 'clearAuthError'>;
const AuthPassword: FC<StateProps & DispatchProps> = ({
authIsLoading, authError, authHint, setAuthPassword, clearAuthError,
const AuthPassword: FC<StateProps> = ({
authIsLoading, authError, authHint,
}) => {
const { setAuthPassword, clearAuthError } = getDispatch();
const lang = useLang();
const [showPassword, setShowPassword] = useState(false);
@ -50,5 +51,4 @@ const AuthPassword: FC<StateProps & DispatchProps> = ({
export default memo(withGlobal(
(global): StateProps => pick(global, ['authIsLoading', 'authError', 'authHint']),
(setGlobal, actions): DispatchProps => pick(actions, ['setAuthPassword', 'clearAuthError']),
)(AuthPassword));

View File

@ -6,9 +6,9 @@ import monkeyPath from '../../assets/monkey.svg';
import React, {
FC, memo, useCallback, useEffect, useLayoutEffect, useRef, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../global/types';
import { GlobalState } from '../../global/types';
import { LangCode } from '../../types';
import { ApiCountryCode } from '../../api/types';
@ -38,16 +38,12 @@ type StateProps = Pick<GlobalState, (
language?: LangCode;
phoneCodeList: ApiCountryCode[];
};
type DispatchProps = Pick<GlobalActions, (
'setAuthPhoneNumber' | 'setAuthRememberMe' | 'loadNearestCountry' | 'loadCountryList' | 'clearAuthError' |
'goToAuthQrCode' | 'setSettingOption'
)>;
const MIN_NUMBER_LENGTH = 7;
let isPreloadInitiated = false;
const AuthPhoneNumber: FC<StateProps & DispatchProps> = ({
const AuthPhoneNumber: FC<StateProps> = ({
connectionState,
authState,
authPhoneNumber,
@ -58,14 +54,17 @@ const AuthPhoneNumber: FC<StateProps & DispatchProps> = ({
authNearestCountry,
phoneCodeList,
language,
setAuthPhoneNumber,
setAuthRememberMe,
loadNearestCountry,
loadCountryList,
clearAuthError,
goToAuthQrCode,
setSettingOption,
}) => {
const {
setAuthPhoneNumber,
setAuthRememberMe,
loadNearestCountry,
loadCountryList,
clearAuthError,
goToAuthQrCode,
setSettingOption,
} = getDispatch();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);
@ -278,13 +277,4 @@ export default memo(withGlobal(
phoneCodeList,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setAuthPhoneNumber',
'setAuthRememberMe',
'clearAuthError',
'loadNearestCountry',
'loadCountryList',
'goToAuthQrCode',
'setSettingOption',
]),
)(AuthPhoneNumber));

View File

@ -2,13 +2,12 @@ import QrCreator from 'qr-creator';
import React, {
FC, useEffect, useRef, memo, useCallback,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalState, GlobalActions } from '../../global/types';
import { GlobalState } from '../../global/types';
import { LangCode } from '../../types';
import { DEFAULT_LANG_CODE } from '../../config';
import { pick } from '../../util/iteratees';
import { setLanguage } from '../../util/langProvider';
import renderText from '../common/helpers/renderText';
import useLangString from '../../hooks/useLangString';
@ -19,23 +18,25 @@ import { getSuggestedLanguage } from './helpers/getSuggestedLanguage';
import Loading from '../ui/Loading';
import Button from '../ui/Button';
type StateProps = Pick<GlobalState, 'connectionState' | 'authState' | 'authQrCode'> & {
language?: LangCode;
};
type DispatchProps = Pick<GlobalActions, (
'returnToAuthPhoneNumber' | 'setSettingOption'
)>;
type StateProps =
Pick<GlobalState, 'connectionState' | 'authState' | 'authQrCode'>
& {
language?: LangCode;
};
const DATA_PREFIX = 'tg://login?token=';
const AuthCode: FC<StateProps & DispatchProps> = ({
const AuthCode: FC<StateProps> = ({
connectionState,
authState,
authQrCode,
language,
returnToAuthPhoneNumber,
setSettingOption,
}) => {
const {
returnToAuthPhoneNumber,
setSettingOption,
} = getDispatch();
const suggestedLanguage = getSuggestedLanguage();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
@ -118,7 +119,4 @@ export default memo(withGlobal(
language,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'returnToAuthPhoneNumber', 'setSettingOption',
]),
)(AuthCode));

View File

@ -1,8 +1,8 @@
import { ChangeEvent } from 'react';
import React, { FC, useState, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalState, GlobalActions } from '../../global/types';
import { GlobalState } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
@ -12,11 +12,12 @@ import InputText from '../ui/InputText';
import AvatarEditable from '../ui/AvatarEditable';
type StateProps = Pick<GlobalState, 'authIsLoading' | 'authError'>;
type DispatchProps = Pick<GlobalActions, 'signUp' | 'clearAuthError' | 'uploadProfilePhoto'>;
const AuthRegister: FC<StateProps & DispatchProps> = ({
authIsLoading, authError, signUp, clearAuthError, uploadProfilePhoto,
const AuthRegister: FC<StateProps> = ({
authIsLoading, authError,
}) => {
const { signUp, clearAuthError, uploadProfilePhoto } = getDispatch();
const lang = useLang();
const [isButtonShown, setIsButtonShown] = useState(false);
const [croppedFile, setCroppedFile] = useState<File | undefined>();
@ -83,5 +84,4 @@ const AuthRegister: FC<StateProps & DispatchProps> = ({
export default memo(withGlobal(
(global): StateProps => pick(global, ['authIsLoading', 'authError']),
(setGlobal, actions): DispatchProps => pick(actions, ['signUp', 'clearAuthError', 'uploadProfilePhoto']),
)(AuthRegister));

View File

@ -2,13 +2,11 @@ import { GroupCallParticipant } from '../../lib/secret-sauce';
import React, {
FC, memo, useEffect,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiGroupCall } from '../../api/types';
import { selectActiveGroupCall, selectGroupCallParticipant } from '../../modules/selectors/calls';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
@ -20,14 +18,13 @@ type StateProps = {
groupCall?: ApiGroupCall;
};
type DispatchProps = Pick<GlobalActions, 'toggleGroupCallPanel'>;
const ActiveCallHeader: FC<StateProps & DispatchProps> = ({
const ActiveCallHeader: FC<StateProps> = ({
groupCall,
meParticipant,
isGroupCallPanelHidden,
toggleGroupCallPanel,
}) => {
const { toggleGroupCallPanel } = getDispatch();
const lang = useLang();
useEffect(() => {
@ -61,7 +58,4 @@ export default memo(withGlobal(
meParticipant: selectGroupCallParticipant(global, global.groupCalls.activeGroupCallId!, global.currentUserId!),
};
},
(setGlobal, actions) => pick(actions, [
'toggleGroupCallPanel',
]),
)(ActiveCallHeader));

View File

@ -1,9 +1,5 @@
import React, { FC, memo, useState } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { pick } from '../../util/iteratees';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import ConfirmDialog from '../ui/ConfirmDialog';
import Checkbox from '../ui/Checkbox';
@ -21,15 +17,16 @@ interface StateProps {
channelTitle: string;
}
type DispatchProps = Pick<GlobalActions, 'closeCallFallbackConfirm' | 'inviteToCallFallback'>;
const CallFallbackConfirm: FC<OwnProps & StateProps & DispatchProps> = ({
const CallFallbackConfirm: FC<OwnProps & StateProps> = ({
isOpen,
channelTitle,
userFullName,
closeCallFallbackConfirm,
inviteToCallFallback,
}) => {
const {
closeCallFallbackConfirm,
inviteToCallFallback,
} = getDispatch();
const [shouldRemove, setShouldRemove] = useState(true);
const renderingUserFullName = useCurrentOrPrev(userFullName, true);
@ -62,7 +59,4 @@ export default memo(withGlobal<OwnProps>(
channelTitle: selectCallFallbackChannelTitle(global),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'closeCallFallbackConfirm', 'inviteToCallFallback',
]),
)(CallFallbackConfirm));

View File

@ -5,10 +5,9 @@ import {
import React, {
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import '../../../modules/actions/calls';
import { GlobalActions } from '../../../global/types';
import { IAnchorPosition } from '../../../types';
import {
@ -17,7 +16,6 @@ import {
IS_REQUEST_FULLSCREEN_SUPPORTED,
IS_SINGLE_COLUMN_LAYOUT,
} from '../../../util/environment';
import { pick } from '../../../util/iteratees';
import buildClassName from '../../../util/buildClassName';
import {
selectGroupCall,
@ -59,12 +57,7 @@ type StateProps = {
participants: Record<string, TypeGroupCallParticipant>;
};
type DispatchProps = Pick<GlobalActions, (
'toggleGroupCallVideo' | 'leaveGroupCall' | 'toggleGroupCallPresentation' | 'toggleGroupCallPanel' |
'connectToActiveGroupCall' | 'playGroupCallSound'
)>;
const GroupCall: FC<OwnProps & StateProps & DispatchProps> = ({
const GroupCall: FC<OwnProps & StateProps> = ({
groupCallId,
isGroupCallPanelHidden,
connectionState,
@ -74,13 +67,16 @@ const GroupCall: FC<OwnProps & StateProps & DispatchProps> = ({
isAdmin,
participants,
toggleGroupCallVideo,
toggleGroupCallPresentation,
leaveGroupCall,
toggleGroupCallPanel,
connectToActiveGroupCall,
playGroupCallSound,
}) => {
const {
toggleGroupCallVideo,
toggleGroupCallPresentation,
leaveGroupCall,
toggleGroupCallPanel,
connectToActiveGroupCall,
playGroupCallSound,
} = getDispatch();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
@ -411,12 +407,4 @@ export default memo(withGlobal<OwnProps>(
participants,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'toggleGroupCallVideo',
'leaveGroupCall',
'toggleGroupCallPresentation',
'toggleGroupCallPanel',
'connectToActiveGroupCall',
'playGroupCallSound',
]),
)(GroupCall));

View File

@ -1,10 +1,7 @@
import { GroupCallParticipant as TypeGroupCallParticipant } from '../../../lib/secret-sauce';
import React, { FC, memo, useMemo } from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { pick } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import { selectActiveGroupCall } from '../../../modules/selectors/calls';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
@ -22,15 +19,16 @@ type StateProps = {
canInvite?: boolean;
};
type DispatchProps = Pick<GlobalActions, 'createGroupCallInviteLink' | 'loadMoreGroupCallParticipants'>;
const GroupCallParticipantList: FC<OwnProps & StateProps & DispatchProps> = ({
createGroupCallInviteLink,
loadMoreGroupCallParticipants,
const GroupCallParticipantList: FC<OwnProps & StateProps> = ({
participants,
participantsCount,
openParticipantMenu,
}) => {
const {
createGroupCallInviteLink,
loadMoreGroupCallParticipants,
} = getDispatch();
const lang = useLang();
const participantsIds = useMemo(() => {
@ -82,8 +80,4 @@ export default memo(withGlobal<OwnProps>(
participantsCount: participantsCount || 0,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'createGroupCallInviteLink',
'loadMoreGroupCallParticipants',
]),
)(GroupCallParticipantList));

View File

@ -2,17 +2,15 @@ import { GroupCallParticipant } from '../../../lib/secret-sauce';
import React, {
FC, memo, useCallback, useEffect, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { IAnchorPosition } from '../../../types';
import { GlobalActions } from '../../../global/types';
import buildClassName from '../../../util/buildClassName';
import useThrottle from '../../../hooks/useThrottle';
import useFlag from '../../../hooks/useFlag';
import useLang from '../../../hooks/useLang';
import { selectIsAdminInActiveGroupCall } from '../../../modules/selectors/calls';
import { pick } from '../../../util/iteratees';
import { GROUP_CALL_DEFAULT_VOLUME, GROUP_CALL_VOLUME_MULTIPLIER } from '../../../config';
import Menu from '../../ui/Menu';
@ -36,10 +34,6 @@ type StateProps = {
isAdmin: boolean;
};
type DispatchProps = Pick<GlobalActions, (
'toggleGroupCallMute' | 'setGroupCallParticipantVolume' | 'toggleGroupCallPanel' | 'openChat' | 'requestToSpeak'
)>;
const VOLUME_ZERO = 0;
const VOLUME_LOW = 50;
const VOLUME_MEDIUM = 100;
@ -49,19 +43,21 @@ const VOLUME_CHANGE_THROTTLE = 500;
const SPEAKER_ICON_SIZE = 24;
const GroupCallParticipantMenu: FC<OwnProps & StateProps & DispatchProps> = ({
const GroupCallParticipantMenu: FC<OwnProps & StateProps> = ({
participant,
closeDropdown,
isDropdownOpen,
anchor,
isAdmin,
toggleGroupCallMute,
setGroupCallParticipantVolume,
toggleGroupCallPanel,
openChat,
requestToSpeak,
}) => {
const {
toggleGroupCallMute,
setGroupCallParticipantVolume,
toggleGroupCallPanel,
openChat,
requestToSpeak,
} = getDispatch();
const lang = useLang();
const [isDeleteUserModalOpen, openDeleteUserModal, closeDeleteUserModal] = useFlag();
@ -229,11 +225,4 @@ export default memo(withGlobal<OwnProps>(
isAdmin: selectIsAdminInActiveGroupCall(global),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setGroupCallParticipantVolume',
'toggleGroupCallMute',
'openChat',
'toggleGroupCallPanel',
'requestToSpeak',
]),
)(GroupCallParticipantMenu));

View File

@ -1,12 +1,10 @@
import React, {
FC, memo, useCallback, useEffect, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiChat, ApiGroupCall, ApiUser } from '../../../api/types';
import { pick } from '../../../util/iteratees';
import { selectChatGroupCall } from '../../../modules/selectors/calls';
import buildClassName from '../../../util/buildClassName';
import { selectChat } from '../../../modules/selectors';
@ -29,18 +27,19 @@ type StateProps = {
chatsById: Record<string, ApiChat>;
};
type DispatchProps = Pick<GlobalActions, 'joinGroupCall' | 'subscribeToGroupCallUpdates'>;
const GroupCallTopPane: FC<OwnProps & StateProps & DispatchProps> = ({
const GroupCallTopPane: FC<OwnProps & StateProps> = ({
chatId,
isActive,
groupCall,
hasPinnedOffset,
joinGroupCall,
subscribeToGroupCallUpdates,
usersById,
chatsById,
}) => {
const {
joinGroupCall,
subscribeToGroupCallUpdates,
} = getDispatch();
const lang = useLang();
const handleJoinGroupCall = useCallback(() => {
@ -132,8 +131,4 @@ export default memo(withGlobal<OwnProps>(
&& (global.groupCalls.activeGroupCallId !== groupCall?.id),
};
},
(setGlobal, actions) => pick(actions, [
'joinGroupCall',
'subscribeToGroupCallUpdates',
]),
)(GroupCallTopPane));

View File

@ -2,13 +2,10 @@ import { GroupCallConnectionState } from '../../../lib/secret-sauce';
import React, {
FC, memo, useEffect, useMemo, useRef, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import buildClassName from '../../../util/buildClassName';
import { vibrateShort } from '../../../util/vibrate';
import { pick } from '../../../util/iteratees';
import usePrevious from '../../../hooks/usePrevious';
import { selectActiveGroupCall, selectGroupCallParticipant } from '../../../modules/selectors/calls';
import useLang from '../../../hooks/useLang';
@ -27,22 +24,23 @@ type StateProps = {
noAudioStream: boolean;
};
type DispatchProps = Pick<GlobalActions, 'toggleGroupCallMute' | 'requestToSpeak' | 'playGroupCallSound'>;
const REQUEST_TO_SPEAK_THROTTLE = 3000;
const HOLD_TO_SPEAK_TIME = 200;
const ICON_SIZE = 48;
const MicrophoneButton: FC<StateProps & DispatchProps> = ({
const MicrophoneButton: FC<StateProps> = ({
noAudioStream,
canSelfUnmute,
isMuted,
hasRequestedToSpeak,
connectionState,
toggleGroupCallMute,
requestToSpeak,
playGroupCallSound,
}) => {
const {
toggleGroupCallMute,
requestToSpeak,
playGroupCallSound,
} = getDispatch();
const lang = useLang();
const muteMouseDownState = useRef('up');
@ -179,9 +177,4 @@ export default memo(withGlobal(
isMuted,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'toggleGroupCallMute',
'requestToSpeak',
'playGroupCallSound',
]),
)(MicrophoneButton));

View File

@ -1,9 +1,9 @@
import React, {
FC, memo, useCallback, useEffect,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../global/types';
import { GlobalState } from '../../global/types';
import { ApiChat, ApiCountryCode, ApiUser } from '../../api/types';
import {
@ -13,7 +13,6 @@ import {
getChatDescription, getChatLink, getHasAdminRight, isChatChannel, isUserId, isUserRightBanned, selectIsChatMuted,
} from '../../modules/helpers';
import renderText from './helpers/renderText';
import { pick } from '../../util/iteratees';
import { copyTextToClipboard } from '../../util/clipboard';
import { formatPhoneNumberWithCode } from '../../util/phoneNumber';
import useLang from '../../hooks/useLang';
@ -26,17 +25,17 @@ type OwnProps = {
forceShowSelf?: boolean;
};
type StateProps = {
user?: ApiUser;
chat?: ApiChat;
canInviteUsers?: boolean;
isMuted?: boolean;
phoneCodeList: ApiCountryCode[];
} & Pick<GlobalState, 'lastSyncTime'>;
type StateProps =
{
user?: ApiUser;
chat?: ApiChat;
canInviteUsers?: boolean;
isMuted?: boolean;
phoneCodeList: ApiCountryCode[];
}
& Pick<GlobalState, 'lastSyncTime'>;
type DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'updateChatMutedState' | 'showNotification'>;
const ChatExtra: FC<OwnProps & StateProps & DispatchProps> = ({
const ChatExtra: FC<OwnProps & StateProps> = ({
lastSyncTime,
user,
chat,
@ -44,10 +43,13 @@ const ChatExtra: FC<OwnProps & StateProps & DispatchProps> = ({
canInviteUsers,
isMuted,
phoneCodeList,
loadFullUser,
showNotification,
updateChatMutedState,
}) => {
const {
loadFullUser,
showNotification,
updateChatMutedState,
} = getDispatch();
const {
id: userId,
fullInfo,
@ -152,7 +154,4 @@ export default memo(withGlobal<OwnProps>(
lastSyncTime, phoneCodeList, chat, user, canInviteUsers, isMuted,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadFullUser', 'updateChatMutedState', 'showNotification',
]),
)(ChatExtra));

View File

@ -1,9 +1,6 @@
import React, { FC, useCallback } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import Link from '../ui/Link';
@ -14,11 +11,11 @@ type OwnProps = {
children: any;
};
type DispatchProps = Pick<GlobalActions, 'openChat'>;
const ChatLink: FC<OwnProps & DispatchProps> = ({
className, chatId, openChat, children,
const ChatLink: FC<OwnProps> = ({
className, chatId, children,
}) => {
const { openChat } = getDispatch();
const handleClick = useCallback(() => {
if (chatId) {
openChat({ id: chatId });
@ -34,7 +31,4 @@ const ChatLink: FC<OwnProps & DispatchProps> = ({
);
};
export default withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, ['openChat']),
)(ChatLink);
export default ChatLink;

View File

@ -1,8 +1,7 @@
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiChat } from '../../api/types';
import { GlobalActions } from '../../global/types';
import { selectIsChatWithSelf, selectUser } from '../../modules/selectors';
import {
@ -15,7 +14,6 @@ import {
isChatChannel,
getChatTitle,
} from '../../modules/helpers';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import renderText from './helpers/renderText';
@ -44,11 +42,7 @@ type StateProps = {
contactName?: string;
};
type DispatchProps = Pick<GlobalActions, (
'leaveChannel' | 'deleteHistory' | 'deleteChannel' | 'deleteChatUser' | 'blockContact'
)>;
const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
const DeleteChatModal: FC<OwnProps & StateProps> = ({
isOpen,
chat,
isChannel,
@ -62,12 +56,15 @@ const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
contactName,
onClose,
onCloseAnimationEnd,
leaveChannel,
deleteHistory,
deleteChannel,
deleteChatUser,
blockContact,
}) => {
const {
leaveChannel,
deleteHistory,
deleteChannel,
deleteChatUser,
blockContact,
} = getDispatch();
const lang = useLang();
const chatTitle = getChatTitle(lang, chat);
@ -217,6 +214,4 @@ export default memo(withGlobal<OwnProps>(
contactName,
};
},
(setGlobal, actions): DispatchProps => pick(actions,
['leaveChannel', 'deleteHistory', 'deleteChannel', 'deleteChatUser', 'blockContact']),
)(DeleteChatModal));

View File

@ -1,11 +1,9 @@
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiMessage } from '../../api/types';
import { IAlbum } from '../../types';
import { GlobalActions } from '../../global/types';
import {
selectAllowedMessageActions,
selectChat,
@ -20,7 +18,6 @@ import {
isChatSuperGroup,
} from '../../modules/helpers';
import renderText from './helpers/renderText';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import Modal from '../ui/Modal';
@ -41,9 +38,7 @@ type StateProps = {
willDeleteForAll?: boolean;
};
type DispatchProps = Pick<GlobalActions, 'deleteMessages' | 'deleteScheduledMessages'>;
const DeleteMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
const DeleteMessageModal: FC<OwnProps & StateProps> = ({
isOpen,
isSchedule,
message,
@ -53,9 +48,12 @@ const DeleteMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
willDeleteForCurrentUserOnly,
willDeleteForAll,
onClose,
deleteMessages,
deleteScheduledMessages,
}) => {
const {
deleteMessages,
deleteScheduledMessages,
} = getDispatch();
const handleDeleteMessageForAll = useCallback(() => {
const messageIds = album?.messages
? album.messages.map(({ id }) => id)
@ -129,7 +127,4 @@ export default memo(withGlobal<OwnProps>(
willDeleteForAll,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'deleteMessages', 'deleteScheduledMessages',
]),
)(DeleteMessageModal));

View File

@ -1,13 +1,11 @@
import React, { FC, useCallback } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiGroupCall } from '../../api/types';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import Link from '../ui/Link';
import { getDispatch } from '../../lib/teact/teactn';
type OwnProps = {
className?: string;
@ -15,11 +13,11 @@ type OwnProps = {
children: any;
};
type DispatchProps = Pick<GlobalActions, 'joinGroupCall'>;
const GroupCallLink: FC<OwnProps & DispatchProps> = ({
className, groupCall, joinGroupCall, children,
const GroupCallLink: FC<OwnProps> = ({
className, groupCall, children,
}) => {
const { joinGroupCall } = getDispatch();
const handleClick = useCallback(() => {
if (groupCall) {
joinGroupCall({ id: groupCall.id, accessHash: groupCall.accessHash });
@ -35,7 +33,4 @@ const GroupCallLink: FC<OwnProps & DispatchProps> = ({
);
};
export default withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, ['joinGroupCall']),
)(GroupCallLink);
export default GroupCallLink;

View File

@ -2,10 +2,10 @@ import { MouseEvent as ReactMouseEvent } from 'react';
import React, {
FC, useEffect, useCallback, memo,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiChat, ApiTypingStatus } from '../../api/types';
import { GlobalActions, GlobalState } from '../../global/types';
import { GlobalState } from '../../global/types';
import { MediaViewerOrigin } from '../../types';
import {
@ -15,7 +15,6 @@ import {
} from '../../modules/helpers';
import { selectChat, selectChatMessages, selectChatOnlineCount } from '../../modules/selectors';
import renderText from './helpers/renderText';
import { pick } from '../../util/iteratees';
import useLang, { LangFn } from '../../hooks/useLang';
import Avatar from './Avatar';
@ -34,15 +33,15 @@ type OwnProps = {
noRtl?: boolean;
};
type StateProps = {
chat?: ApiChat;
onlineCount?: number;
areMessagesLoaded: boolean;
} & Pick<GlobalState, 'lastSyncTime'>;
type StateProps =
{
chat?: ApiChat;
onlineCount?: number;
areMessagesLoaded: boolean;
}
& Pick<GlobalState, 'lastSyncTime'>;
type DispatchProps = Pick<GlobalActions, 'loadFullChat' | 'openMediaViewer'>;
const GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
const GroupChatInfo: FC<OwnProps & StateProps> = ({
typingStatus,
avatarSize = 'medium',
withMediaViewer,
@ -55,9 +54,12 @@ const GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
onlineCount,
areMessagesLoaded,
lastSyncTime,
loadFullChat,
openMediaViewer,
}) => {
const {
loadFullChat,
openMediaViewer,
} = getDispatch();
const isSuperGroup = chat && isChatSuperGroup(chat);
const { id: chatId, isMin, isRestricted } = chat || {};
@ -164,5 +166,4 @@ export default memo(withGlobal<OwnProps>(
lastSyncTime, chat, onlineCount, areMessagesLoaded,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadFullChat', 'openMediaViewer']),
)(GroupChatInfo));

View File

@ -1,10 +1,8 @@
import React, { FC, useCallback } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiMessage } from '../../api/types';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import Link from '../ui/Link';
@ -15,11 +13,11 @@ type OwnProps = {
children: any;
};
type DispatchProps = Pick<GlobalActions, 'focusMessage'>;
const MessageLink: FC<OwnProps & DispatchProps> = ({
className, message, children, focusMessage,
const MessageLink: FC<OwnProps> = ({
className, message, children,
}) => {
const { focusMessage } = getDispatch();
const handleMessageClick = useCallback((): void => {
if (message) {
focusMessage({ chatId: message.chatId, messageId: message.id });
@ -35,7 +33,4 @@ const MessageLink: FC<OwnProps & DispatchProps> = ({
);
};
export default withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, ['focusMessage']),
)(MessageLink);
export default MessageLink;

View File

@ -1,7 +1,5 @@
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { selectChat, selectIsChatWithSelf, selectUser } from '../../modules/selectors';
import {
@ -12,7 +10,6 @@ import {
isChatSuperGroup,
isChatChannel,
} from '../../modules/helpers';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import renderText from './helpers/renderText';
@ -36,9 +33,7 @@ type StateProps = {
contactName?: string;
};
type DispatchProps = Pick<GlobalActions, 'pinMessage'>;
const PinMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
const PinMessageModal: FC<OwnProps & StateProps> = ({
isOpen,
messageId,
chatId,
@ -48,8 +43,9 @@ const PinMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
canPinForAll,
contactName,
onClose,
pinMessage,
}) => {
const { pinMessage } = getDispatch();
const handlePinMessageForAll = useCallback(() => {
pinMessage({
chatId, messageId, isUnpin: false,
@ -124,5 +120,4 @@ export default memo(withGlobal<OwnProps>(
contactName,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['pinMessage']),
)(PinMessageModal));

View File

@ -2,16 +2,15 @@ import { MouseEvent as ReactMouseEvent } from 'react';
import React, {
FC, useEffect, useCallback, memo,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiUser, ApiTypingStatus, ApiUserStatus } from '../../api/types';
import { GlobalActions, GlobalState } from '../../global/types';
import { GlobalState } from '../../global/types';
import { MediaViewerOrigin } from '../../types';
import { selectChatMessages, selectUser, selectUserStatus } from '../../modules/selectors';
import { getUserFullName, getUserStatus, isUserOnline } from '../../modules/helpers';
import renderText from './helpers/renderText';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import Avatar from './Avatar';
@ -32,17 +31,17 @@ type OwnProps = {
noRtl?: boolean;
};
type StateProps = {
user?: ApiUser;
userStatus?: ApiUserStatus;
isSavedMessages?: boolean;
areMessagesLoaded: boolean;
serverTimeOffset: number;
} & Pick<GlobalState, 'lastSyncTime'>;
type StateProps =
{
user?: ApiUser;
userStatus?: ApiUserStatus;
isSavedMessages?: boolean;
areMessagesLoaded: boolean;
serverTimeOffset: number;
}
& Pick<GlobalState, 'lastSyncTime'>;
type DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'openMediaViewer'>;
const PrivateChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
const PrivateChatInfo: FC<OwnProps & StateProps> = ({
typingStatus,
avatarSize = 'medium',
status,
@ -58,9 +57,12 @@ const PrivateChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
areMessagesLoaded,
lastSyncTime,
serverTimeOffset,
loadFullUser,
openMediaViewer,
}) => {
const {
loadFullUser,
openMediaViewer,
} = getDispatch();
const { id: userId } = user || {};
const fullName = getUserFullName(user);
@ -153,5 +155,4 @@ export default memo(withGlobal<OwnProps>(
lastSyncTime, user, userStatus, isSavedMessages, areMessagesLoaded, serverTimeOffset,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadFullUser', 'openMediaViewer']),
)(PrivateChatInfo));

View File

@ -1,10 +1,10 @@
import React, {
FC, useEffect, useCallback, memo, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiUser, ApiChat, ApiUserStatus } from '../../api/types';
import { GlobalActions, GlobalState } from '../../global/types';
import { GlobalState } from '../../global/types';
import { MediaViewerOrigin } from '../../types';
import { IS_TOUCH_ENV } from '../../util/environment';
@ -13,7 +13,6 @@ import {
getUserFullName, getUserStatus, isChatChannel, isUserOnline,
} from '../../modules/helpers';
import renderText from './helpers/renderText';
import { pick } from '../../util/iteratees';
import { captureEvents, SwipeDirection } from '../../util/captureEvents';
import buildClassName from '../../util/buildClassName';
import usePhotosPreload from './hooks/usePhotosPreload';
@ -30,18 +29,18 @@ type OwnProps = {
forceShowSelf?: boolean;
};
type StateProps = {
user?: ApiUser;
userStatus?: ApiUserStatus;
chat?: ApiChat;
isSavedMessages?: boolean;
animationLevel: 0 | 1 | 2;
serverTimeOffset: number;
} & Pick<GlobalState, 'connectionState'>;
type StateProps =
{
user?: ApiUser;
userStatus?: ApiUserStatus;
chat?: ApiChat;
isSavedMessages?: boolean;
animationLevel: 0 | 1 | 2;
serverTimeOffset: number;
}
& Pick<GlobalState, 'connectionState'>;
type DispatchProps = Pick<GlobalActions, 'loadFullUser' | 'openMediaViewer'>;
const ProfileInfo: FC<OwnProps & StateProps & DispatchProps> = ({
const ProfileInfo: FC<OwnProps & StateProps> = ({
forceShowSelf,
user,
userStatus,
@ -50,9 +49,12 @@ const ProfileInfo: FC<OwnProps & StateProps & DispatchProps> = ({
connectionState,
animationLevel,
serverTimeOffset,
loadFullUser,
openMediaViewer,
}) => {
const {
loadFullUser,
openMediaViewer,
} = getDispatch();
const lang = useLang();
const { id: userId } = user || {};
@ -246,5 +248,4 @@ export default memo(withGlobal<OwnProps>(
serverTimeOffset,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadFullUser', 'openMediaViewer']),
)(ProfileInfo));

View File

@ -3,13 +3,10 @@ import { ChangeEvent } from 'react';
import React, {
FC, memo, useCallback, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch } from '../../lib/teact/teactn';
import { ApiReportReason } from '../../api/types';
import { GlobalActions } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import Modal from '../ui/Modal';
@ -23,15 +20,16 @@ export type OwnProps = {
onClose: () => void;
};
type DispatchProps = Pick<GlobalActions, 'reportMessages' | 'exitMessageSelectMode'>;
const ReportMessageModal: FC<OwnProps & DispatchProps> = ({
const ReportMessageModal: FC<OwnProps> = ({
isOpen,
messageIds,
reportMessages,
exitMessageSelectMode,
onClose,
}) => {
const {
reportMessages,
exitMessageSelectMode,
} = getDispatch();
const [selectedReason, setSelectedReason] = useState<ApiReportReason>('spam');
const [description, setDescription] = useState('');
@ -91,8 +89,4 @@ const ReportMessageModal: FC<OwnProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
undefined, (setGlobal, actions): DispatchProps => pick(actions, [
'reportMessages', 'exitMessageSelectMode',
]),
)(ReportMessageModal));
export default memo(ReportMessageModal);

View File

@ -1,9 +1,6 @@
import React, { FC, useCallback, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import { selectChatMessage } from '../../modules/selectors';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
@ -21,16 +18,17 @@ export type StateProps = {
memberIds?: string[];
};
type DispatchProps = Pick<GlobalActions, 'openChat' | 'closeSeenByModal'>;
const CLOSE_ANIMATION_DURATION = 100;
const SeenByModal: FC<OwnProps & StateProps & DispatchProps> = ({
const SeenByModal: FC<OwnProps & StateProps> = ({
isOpen,
memberIds,
openChat,
closeSeenByModal,
}) => {
const {
openChat,
closeSeenByModal,
} = getDispatch();
const lang = useLang();
const handleClick = useCallback((userId: string) => {
@ -83,5 +81,4 @@ export default memo(withGlobal<OwnProps>(
memberIds: selectChatMessage(global, chatId, messageId)?.seenByUserIds,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['openChat', 'closeSeenByModal']),
)(SeenByModal));

View File

@ -1,13 +1,11 @@
import React, {
FC, memo, useCallback, useEffect, useRef,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiSticker, ApiStickerSet } from '../../api/types';
import { GlobalActions } from '../../global/types';
import { STICKER_SIZE_MODAL } from '../../config';
import { pick } from '../../util/iteratees';
import {
selectChat, selectCurrentMessageList, selectStickerSet, selectStickerSetByShortName,
} from '../../modules/selectors';
@ -35,21 +33,22 @@ type StateProps = {
stickerSet?: ApiStickerSet;
};
type DispatchProps = Pick<GlobalActions, 'loadStickers' | 'toggleStickerSet' | 'sendMessage'>;
const INTERSECTION_THROTTLE = 200;
const StickerSetModal: FC<OwnProps & StateProps & DispatchProps> = ({
const StickerSetModal: FC<OwnProps & StateProps> = ({
isOpen,
fromSticker,
stickerSetShortName,
stickerSet,
canSendStickers,
onClose,
loadStickers,
toggleStickerSet,
sendMessage,
}) => {
const {
loadStickers,
toggleStickerSet,
sendMessage,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
const lang = useLang();
@ -153,9 +152,4 @@ export default memo(withGlobal<OwnProps>(
: undefined,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadStickers',
'toggleStickerSet',
'sendMessage',
]),
)(StickerSetModal));

View File

@ -1,8 +1,8 @@
import React, { FC, useEffect } from '../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../lib/teact/teactn';
import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn';
import { ApiMediaFormat } from '../../api/types';
import { GlobalActions, GlobalState } from '../../global/types';
import { GlobalState } from '../../global/types';
import { getChatAvatarHash } from '../../modules/helpers/chats'; // Direct import for better module splitting
import useFlag from '../../hooks/useFlag';
@ -12,7 +12,6 @@ import { preloadImage } from '../../util/files';
import preloadFonts from '../../util/fonts';
import * as mediaLoader from '../../util/mediaLoader';
import { Bundles, loadModule } from '../../util/moduleLoader';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import './UiLoader.scss';
@ -28,14 +27,14 @@ type OwnProps = {
children: any;
};
type StateProps = Pick<GlobalState, 'uiReadyState' | 'shouldSkipHistoryAnimations'> & {
hasCustomBackground?: boolean;
hasCustomBackgroundColor: boolean;
isRightColumnShown?: boolean;
leftColumnWidth?: number;
};
type DispatchProps = Pick<GlobalActions, 'setIsUiReady'>;
type StateProps =
Pick<GlobalState, 'uiReadyState' | 'shouldSkipHistoryAnimations'>
& {
hasCustomBackground?: boolean;
hasCustomBackgroundColor: boolean;
isRightColumnShown?: boolean;
leftColumnWidth?: number;
};
const MAX_PRELOAD_DELAY = 700;
const SECOND_STATE_DELAY = 1000;
@ -77,7 +76,7 @@ const preloadTasks = {
authQrCode: preloadFonts,
};
const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
const UiLoader: FC<OwnProps & StateProps> = ({
page,
children,
hasCustomBackground,
@ -85,8 +84,9 @@ const UiLoader: FC<OwnProps & StateProps & DispatchProps> = ({
isRightColumnShown,
shouldSkipHistoryAnimations,
leftColumnWidth,
setIsUiReady,
}) => {
const { setIsUiReady } = getDispatch();
const [isReady, markReady] = useFlag();
const {
shouldRender: shouldRenderMask, transitionClassNames,
@ -171,5 +171,4 @@ export default withGlobal<OwnProps>(
leftColumnWidth: global.leftColumnWidth,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['setIsUiReady']),
)(UiLoader);

View File

@ -1,13 +1,11 @@
import React, { FC, useCallback } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiChat, ApiUser } from '../../api/types';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import Link from '../ui/Link';
import { getDispatch } from '../../lib/teact/teactn';
type OwnProps = {
className?: string;
@ -15,11 +13,11 @@ type OwnProps = {
children: any;
};
type DispatchProps = Pick<GlobalActions, 'openUserInfo'>;
const UserLink: FC<OwnProps & DispatchProps> = ({
className, sender, openUserInfo, children,
const UserLink: FC<OwnProps> = ({
className, sender, children,
}) => {
const { openUserInfo } = getDispatch();
const handleClick = useCallback(() => {
if (sender) {
openUserInfo({ id: sender.id });
@ -35,7 +33,4 @@ const UserLink: FC<OwnProps & DispatchProps> = ({
);
};
export default withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, ['openUserInfo']),
)(UserLink);
export default UserLink;

View File

@ -1,12 +1,10 @@
import React, {
FC, useCallback, memo, useMemo, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiChatFolder } from '../../api/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import Modal from '../ui/Modal';
@ -25,17 +23,16 @@ type StateProps = {
folderOrderedIds?: number[];
};
type DispatchProps = Pick<GlobalActions, 'editChatFolders'>;
const ChatFolderModal: FC<OwnProps & StateProps & DispatchProps> = ({
const ChatFolderModal: FC<OwnProps & StateProps> = ({
isOpen,
chatId,
foldersById,
folderOrderedIds,
onClose,
onCloseAnimationEnd,
editChatFolders,
}) => {
const { editChatFolders } = getDispatch();
const lang = useLang();
const initialSelectedFolderIds = useMemo(() => {
@ -106,5 +103,4 @@ export default memo(withGlobal<OwnProps>(
folderOrderedIds,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['editChatFolders']),
)(ChatFolderModal));

View File

@ -1,14 +1,12 @@
import React, {
FC, memo, useCallback, useEffect, useRef, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { LeftColumnContent, SettingsScreens } from '../../types';
import { LAYERS_ANIMATION_NAME } from '../../util/environment';
import captureEscKeyListener from '../../util/captureEscKeyListener';
import { pick } from '../../util/iteratees';
import useFoldersReducer from '../../hooks/reducers/useFoldersReducer';
import { useResize } from '../../hooks/useResize';
@ -28,11 +26,6 @@ type StateProps = {
leftColumnWidth?: number;
};
type DispatchProps = Pick<GlobalActions, (
'setGlobalSearchQuery' | 'setGlobalSearchChatId' | 'resetChatCreation' | 'setGlobalSearchDate' |
'loadPasswordInfo' | 'clearTwoFaError' | 'setLeftColumnWidth' | 'resetLeftColumnWidth'
)>;
enum ContentType {
Main,
// eslint-disable-next-line @typescript-eslint/no-shadow
@ -47,21 +40,24 @@ enum ContentType {
const RENDER_COUNT = Object.keys(ContentType).length / 2;
const RESET_TRANSITION_DELAY_MS = 250;
const LeftColumn: FC<StateProps & DispatchProps> = ({
const LeftColumn: FC<StateProps> = ({
searchQuery,
searchDate,
activeChatFolder,
shouldSkipHistoryAnimations,
leftColumnWidth,
setGlobalSearchQuery,
setGlobalSearchChatId,
resetChatCreation,
setGlobalSearchDate,
loadPasswordInfo,
clearTwoFaError,
setLeftColumnWidth,
resetLeftColumnWidth,
}) => {
const {
setGlobalSearchQuery,
setGlobalSearchChatId,
resetChatCreation,
setGlobalSearchDate,
loadPasswordInfo,
clearTwoFaError,
setLeftColumnWidth,
resetLeftColumnWidth,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const resizeRef = useRef<HTMLDivElement>(null);
const [content, setContent] = useState<LeftColumnContent>(LeftColumnContent.ChatList);
@ -374,8 +370,4 @@ export default memo(withGlobal(
searchQuery: query, searchDate: date, activeChatFolder, shouldSkipHistoryAnimations, leftColumnWidth,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setGlobalSearchQuery', 'setGlobalSearchChatId', 'resetChatCreation', 'setGlobalSearchDate',
'loadPasswordInfo', 'clearTwoFaError', 'setLeftColumnWidth', 'resetLeftColumnWidth',
]),
)(LeftColumn));

View File

@ -1,11 +1,10 @@
import React, {
FC, memo, useCallback, useLayoutEffect, useMemo, useRef,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import useLang, { LangFn } from '../../../hooks/useLang';
import { GlobalActions } from '../../../global/types';
import {
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus, ApiFormattedText, MAIN_THREAD_ID, ApiUserStatus,
} from '../../../api/types';
@ -36,7 +35,6 @@ import { renderActionMessageText } from '../../common/helpers/renderActionMessag
import renderText from '../../common/helpers/renderText';
import { fastRaf } from '../../../util/schedulers';
import buildClassName from '../../../util/buildClassName';
import { pick } from '../../../util/iteratees';
import useEnsureMessage from '../../../hooks/useEnsureMessage';
import useChatContextActions from '../../../hooks/useChatContextActions';
import useFlag from '../../../hooks/useFlag';
@ -83,11 +81,9 @@ type StateProps = {
lastSyncTime?: number;
};
type DispatchProps = Pick<GlobalActions, 'openChat' | 'focusLastMessage'>;
const ANIMATION_DURATION = 200;
const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
const Chat: FC<OwnProps & StateProps> = ({
style,
chatId,
folderId,
@ -110,9 +106,12 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
canScrollDown,
canChangeFolder,
lastSyncTime,
openChat,
focusLastMessage,
}) => {
const {
openChat,
focusLastMessage,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const ref = useRef<HTMLDivElement>(null);
@ -390,8 +389,4 @@ export default memo(withGlobal<OwnProps>(
...(actionTargetUserIds && { usersById }),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'openChat',
'focusLastMessage',
]),
)(Chat));

View File

@ -1,15 +1,15 @@
import React, {
FC, memo, useCallback, useEffect, useMemo, useRef,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { ApiChat, ApiChatFolder, ApiUser } from '../../../api/types';
import { GlobalActions, GlobalState } from '../../../global/types';
import { GlobalState } from '../../../global/types';
import { NotifyException, NotifySettings, SettingsScreens } from '../../../types';
import { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
import { IS_TOUCH_ENV } from '../../../util/environment';
import { buildCollectionByKey, pick } from '../../../util/iteratees';
import { buildCollectionByKey } from '../../../util/iteratees';
import { captureEvents, SwipeDirection } from '../../../util/captureEvents';
import { getFolderUnreadDialogs } from '../../../modules/helpers';
import { selectNotifyExceptions, selectNotifySettings } from '../../../modules/selectors';
@ -43,12 +43,10 @@ type StateProps = {
shouldSkipHistoryAnimations?: boolean;
};
type DispatchProps = Pick<GlobalActions, 'loadChatFolders' | 'setActiveChatFolder' | 'openChat'>;
const INFO_THROTTLE = 3000;
const SAVED_MESSAGES_HOTKEY = '0';
const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
const ChatFolders: FC<OwnProps & StateProps> = ({
allListIds,
chatsById,
usersById,
@ -62,10 +60,13 @@ const ChatFolders: FC<OwnProps & StateProps & DispatchProps> = ({
shouldSkipHistoryAnimations,
foldersDispatch,
onScreenSelect,
loadChatFolders,
setActiveChatFolder,
openChat,
}) => {
const {
loadChatFolders,
setActiveChatFolder,
openChat,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const transitionRef = useRef<HTMLDivElement>(null);
@ -267,9 +268,4 @@ export default memo(withGlobal<OwnProps>(
shouldSkipHistoryAnimations,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadChatFolders',
'setActiveChatFolder',
'openChat',
]),
)(ChatFolders));

View File

@ -1,9 +1,9 @@
import React, {
FC, memo, useMemo, useCallback, useEffect,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../../global/types';
import { GlobalState } from '../../../global/types';
import {
ApiChat, ApiChatFolder, ApiUser,
} from '../../../api/types';
@ -13,7 +13,7 @@ import { FolderEditDispatch } from '../../../hooks/reducers/useFoldersReducer';
import { ALL_CHATS_PRELOAD_DISABLED, CHAT_HEIGHT_PX, CHAT_LIST_SLICE } from '../../../config';
import { IS_ANDROID, IS_MAC_OS, IS_PWA } from '../../../util/environment';
import usePrevious from '../../../hooks/usePrevious';
import { mapValues, pick } from '../../../util/iteratees';
import { mapValues } from '../../../util/iteratees';
import {
getChatOrder, prepareChatList, prepareFolderListIds, reduceChatList,
} from '../../../modules/helpers';
@ -48,16 +48,12 @@ type StateProps = {
notifyExceptions?: Record<number, NotifyException>;
};
type DispatchProps = Pick<GlobalActions, (
'loadMoreChats' | 'preloadTopChatMessages' | 'preloadArchivedChats' | 'openChat' | 'openNextChat'
)>;
enum FolderTypeToListType {
'all' = 'active',
'archived' = 'archived',
}
const ChatList: FC<OwnProps & StateProps & DispatchProps> = ({
const ChatList: FC<OwnProps & StateProps> = ({
folderType,
folderId,
isActive,
@ -72,12 +68,15 @@ const ChatList: FC<OwnProps & StateProps & DispatchProps> = ({
notifyExceptions,
foldersDispatch,
onScreenSelect,
loadMoreChats,
preloadTopChatMessages,
preloadArchivedChats,
openChat,
openNextChat,
}) => {
const {
loadMoreChats,
preloadTopChatMessages,
preloadArchivedChats,
openChat,
openNextChat,
} = getDispatch();
const [currentListIds, currentPinnedIds] = useMemo(() => {
return folderType === 'folder' && chatFolder
? prepareFolderListIds(allListIds, chatsById, usersById, chatFolder, notifySettings, notifyExceptions)
@ -273,11 +272,4 @@ export default memo(withGlobal<OwnProps>(
}),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadMoreChats',
'preloadTopChatMessages',
'preloadArchivedChats',
'openChat',
'openNextChat',
]),
)(ChatList));

View File

@ -1,14 +1,12 @@
import React, {
FC, useEffect, useCallback, useMemo, memo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiUser, ApiUserStatus } from '../../../api/types';
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
import { throttle } from '../../../util/schedulers';
import { pick } from '../../../util/iteratees';
import { filterUsersByName, sortUserIds } from '../../../modules/helpers';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import useHistoryBack from '../../../hooks/useHistoryBack';
@ -31,11 +29,9 @@ type StateProps = {
serverTimeOffset: number;
};
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'openChat'>;
const runThrottled = throttle((cb) => cb(), 60000, true);
const ContactList: FC<OwnProps & StateProps & DispatchProps> = ({
const ContactList: FC<OwnProps & StateProps> = ({
isActive,
filter,
usersById,
@ -43,9 +39,12 @@ const ContactList: FC<OwnProps & StateProps & DispatchProps> = ({
contactIds,
serverTimeOffset,
onReset,
loadContactList,
openChat,
}) => {
const {
loadContactList,
openChat,
} = getDispatch();
// Due to the parent Transition, this component never gets unmounted,
// that's why we use throttled API call on every update.
useEffect(() => {
@ -108,5 +107,4 @@ export default memo(withGlobal<OwnProps>(
serverTimeOffset: global.serverTimeOffset,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadContactList', 'openChat']),
)(ContactList));

View File

@ -1,9 +1,8 @@
import React, {
FC, useCallback, useMemo, memo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { LeftColumnContent, ISettings } from '../../../types';
import { ApiChat } from '../../../api/types';
@ -12,7 +11,6 @@ import {
} from '../../../config';
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
import buildClassName from '../../../util/buildClassName';
import { pick } from '../../../util/iteratees';
import { isChatArchived } from '../../../modules/helpers';
import { formatDateToString } from '../../../util/dateFormat';
import { selectTheme } from '../../../modules/selectors';
@ -51,10 +49,6 @@ type StateProps = {
chatsById?: Record<string, ApiChat>;
};
type DispatchProps = Pick<GlobalActions, (
'openChat' | 'openTipsChat' | 'setGlobalSearchDate' | 'setGlobalSearchChatId' | 'setSettingOption'
)>;
const ANIMATION_LEVEL_OPTIONS = [0, 1, 2];
const PRODUCTION_HOSTNAME = 'web.telegram.org';
@ -62,14 +56,13 @@ const LEGACY_VERSION_URL = 'https://web.telegram.org/?legacy=1';
const WEBK_VERSION_URL = 'https://web.telegram.org/k/';
const PERMANENT_VERSION_KEY = 'kz_version';
const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
const LeftMainHeader: FC<OwnProps & StateProps> = ({
content,
contactsFilter,
onSearchQuery,
onSelectSettings,
onSelectContacts,
onSelectArchived,
setGlobalSearchChatId,
onReset,
searchQuery,
isLoading,
@ -80,11 +73,14 @@ const LeftMainHeader: FC<OwnProps & StateProps & DispatchProps> = ({
theme,
animationLevel,
chatsById,
openChat,
openTipsChat,
setGlobalSearchDate,
setSettingOption,
}) => {
const {
openChat,
openTipsChat,
setGlobalSearchDate,
setSettingOption, setGlobalSearchChatId,
} = getDispatch();
const lang = useLang();
const hasMenu = content === LeftColumnContent.ChatList;
const clearedDateSearchParam = { date: undefined };
@ -327,11 +323,4 @@ export default memo(withGlobal<OwnProps>(
animationLevel,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'openChat',
'openTipsChat',
'setGlobalSearchDate',
'setGlobalSearchChatId',
'setSettingOption',
]),
)(LeftMainHeader));

View File

@ -1,12 +1,11 @@
import React, {
FC, useCallback, useEffect, useMemo, memo,
} from '../../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, getGlobal, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiChat } from '../../../api/types';
import { pick, unique } from '../../../util/iteratees';
import { unique } from '../../../util/iteratees';
import { throttle } from '../../../util/schedulers';
import { filterUsersByName, isUserBot, sortChatIds } from '../../../modules/helpers';
import useLang from '../../../hooks/useLang';
@ -34,11 +33,9 @@ type StateProps = {
globalUserIds?: string[];
};
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'setGlobalSearchQuery'>;
const runThrottled = throttle((cb) => cb(), 60000, true);
const NewChatStep1: FC<OwnProps & StateProps & DispatchProps> = ({
const NewChatStep1: FC<OwnProps & StateProps> = ({
isChannel,
isActive,
selectedMemberIds,
@ -51,9 +48,12 @@ const NewChatStep1: FC<OwnProps & StateProps & DispatchProps> = ({
isSearching,
localUserIds,
globalUserIds,
loadContactList,
setGlobalSearchQuery,
}) => {
const {
loadContactList,
setGlobalSearchQuery,
} = getDispatch();
// Due to the parent Transition, this component never gets unmounted,
// that's why we use throttled API call on every update.
useEffect(() => {
@ -162,5 +162,4 @@ export default memo(withGlobal<OwnProps>(
localUserIds,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadContactList', 'setGlobalSearchQuery']),
)(NewChatStep1));

View File

@ -1,12 +1,10 @@
import React, {
FC, useState, useCallback, useEffect, memo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ChatCreationProgress } from '../../../types';
import { pick } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
@ -30,21 +28,22 @@ type StateProps = {
creationError?: string;
};
type DispatchProps = Pick<GlobalActions, 'createGroupChat' | 'createChannel'>;
// TODO @implement
const MAX_USERS_FOR_LEGACY_CHAT = 199; // Accounting for current user
const NewChatStep2: FC<OwnProps & StateProps & DispatchProps> = ({
const NewChatStep2: FC<OwnProps & StateProps > = ({
isChannel,
isActive,
memberIds,
onReset,
creationProgress,
creationError,
createGroupChat,
createChannel,
}) => {
const {
createGroupChat,
createChannel,
} = getDispatch();
const lang = useLang();
useHistoryBack(isActive, onReset);
@ -202,7 +201,4 @@ export default memo(withGlobal<OwnProps>(
creationError,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'createGroupChat', 'createChannel',
]),
)(NewChatStep2));

View File

@ -1,15 +1,13 @@
import React, {
FC, memo, useCallback, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { AudioOrigin, LoadMoreDirection } from '../../../types';
import { SLIDE_TRANSITION_DURATION } from '../../../config';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
import { pick } from '../../../util/iteratees';
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
import { getSenderName } from './helpers/getSenderName';
import { throttle } from '../../../util/schedulers';
@ -26,11 +24,9 @@ export type OwnProps = {
searchQuery?: string;
};
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'focusMessage' | 'openAudioPlayer')>;
const runThrottled = throttle((cb) => cb(), 500, true);
const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
const AudioResults: FC<OwnProps & StateProps> = ({
theme,
isVoice,
searchQuery,
@ -42,10 +38,13 @@ const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
foundIds,
lastSyncTime,
activeDownloads,
searchMessagesGlobal,
focusMessage,
openAudioPlayer,
}) => {
const {
searchMessagesGlobal,
focusMessage,
openAudioPlayer,
} = getDispatch();
const lang = useLang();
const currentType = isVoice ? 'voice' : 'audio';
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
@ -137,9 +136,4 @@ const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
export default memo(withGlobal<OwnProps>(
createMapStateToProps('audio'),
(setGlobal, actions): DispatchProps => pick(actions, [
'searchMessagesGlobal',
'focusMessage',
'openAudioPlayer',
]),
)(AudioResults));

View File

@ -1,9 +1,8 @@
import React, {
FC, memo, useCallback,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import {
ApiChat, ApiUser, ApiMessage, ApiMessageOutgoingStatus,
} from '../../../api/types';
@ -20,7 +19,6 @@ import {
} from '../../../modules/helpers';
import { selectChat, selectUser } from '../../../modules/selectors';
import renderText from '../../common/helpers/renderText';
import { pick } from '../../../util/iteratees';
import useMedia from '../../../hooks/useMedia';
import { formatPastTimeShort } from '../../../util/dateFormat';
import useLang, { LangFn } from '../../../hooks/useLang';
@ -46,17 +44,16 @@ type StateProps = {
lastSyncTime?: number;
};
type DispatchProps = Pick<GlobalActions, 'focusMessage'>;
const ChatMessage: FC<OwnProps & StateProps & DispatchProps> = ({
const ChatMessage: FC<OwnProps & StateProps> = ({
message,
searchQuery,
chatId,
chat,
privateChatUser,
focusMessage,
lastSyncTime,
}) => {
const { focusMessage } = getDispatch();
const mediaThumbnail = getMessageMediaThumbDataUri(message);
const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'micro'));
const isRoundVideo = Boolean(getMessageRoundVideo(message));
@ -140,7 +137,4 @@ export default memo(withGlobal<OwnProps>(
...(privateChatUserId && { privateChatUser: selectUser(global, privateChatUserId) }),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'focusMessage',
]),
)(ChatMessage));

View File

@ -1,13 +1,11 @@
import React, {
FC, memo, useCallback, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { ApiChat, ApiMessage } from '../../../api/types';
import { GlobalActions } from '../../../global/types';
import { LoadMoreDirection } from '../../../types';
import { pick } from '../../../util/iteratees';
import { getMessageSummaryText } from '../../../modules/helpers';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { throttle } from '../../../util/schedulers';
@ -34,11 +32,9 @@ type StateProps = {
lastSyncTime?: number;
};
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal')>;
const runThrottled = throttle((cb) => cb(), 500, true);
const ChatMessageResults: FC<OwnProps & StateProps & DispatchProps> = ({
const ChatMessageResults: FC<OwnProps & StateProps> = ({
searchQuery,
currentUserId,
dateSearchQuery,
@ -47,9 +43,10 @@ const ChatMessageResults: FC<OwnProps & StateProps & DispatchProps> = ({
chatsById,
fetchingStatus,
lastSyncTime,
searchMessagesGlobal,
onSearchDateSelect,
}) => {
const { searchMessagesGlobal } = getDispatch();
const lang = useLang();
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
@ -142,5 +139,4 @@ export default memo(withGlobal<OwnProps>(
lastSyncTime,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['searchMessagesGlobal']),
)(ChatMessageResults));

View File

@ -1,14 +1,13 @@
import React, {
FC, memo, useCallback, useMemo, useState,
} from '../../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, getGlobal, withGlobal } from '../../../lib/teact/teactn';
import { ApiChat, ApiMessage } from '../../../api/types';
import { GlobalActions } from '../../../global/types';
import { LoadMoreDirection } from '../../../types';
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
import { unique, pick } from '../../../util/iteratees';
import { unique } from '../../../util/iteratees';
import { getMessageSummaryText, sortChatIds, filterUsersByName } from '../../../modules/helpers';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { throttle } from '../../../util/schedulers';
@ -45,21 +44,21 @@ type StateProps = {
lastSyncTime?: number;
};
type DispatchProps = Pick<GlobalActions, (
'openChat' | 'addRecentlyFoundChatId' | 'searchMessagesGlobal' | 'setGlobalSearchChatId'
)>;
const MIN_QUERY_LENGTH_FOR_GLOBAL_SEARCH = 4;
const LESS_LIST_ITEMS_AMOUNT = 5;
const runThrottled = throttle((cb) => cb(), 500, true);
const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
const ChatResults: FC<OwnProps & StateProps> = ({
searchQuery, searchDate, dateSearchQuery, currentUserId,
localContactIds, localChatIds, localUserIds, globalChatIds, globalUserIds,
foundIds, globalMessagesByChatId, chatsById, fetchingStatus, lastSyncTime,
onReset, onSearchDateSelect, openChat, addRecentlyFoundChatId, searchMessagesGlobal, setGlobalSearchChatId,
onReset, onSearchDateSelect,
}) => {
const {
openChat, addRecentlyFoundChatId, searchMessagesGlobal, setGlobalSearchChatId,
} = getDispatch();
const lang = useLang();
const [shouldShowMoreLocal, setShouldShowMoreLocal] = useState<boolean>(false);
@ -306,10 +305,4 @@ export default memo(withGlobal<OwnProps>(
lastSyncTime,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'openChat',
'addRecentlyFoundChatId',
'searchMessagesGlobal',
'setGlobalSearchChatId',
]),
)(ChatResults));

View File

@ -1,16 +1,14 @@
import React, {
FC, memo, useCallback, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { ApiMessage } from '../../../api/types';
import { GlobalActions } from '../../../global/types';
import { LoadMoreDirection } from '../../../types';
import { SLIDE_TRANSITION_DURATION } from '../../../config';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
import { pick } from '../../../util/iteratees';
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
import { getSenderName } from './helpers/getSenderName';
import { throttle } from '../../../util/schedulers';
@ -27,12 +25,10 @@ export type OwnProps = {
searchQuery?: string;
};
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'focusMessage')>;
const CURRENT_TYPE = 'documents';
const runThrottled = throttle((cb) => cb(), 500, true);
const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
const FileResults: FC<OwnProps & StateProps> = ({
searchQuery,
searchChatId,
isLoading,
@ -42,9 +38,12 @@ const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
foundIds,
activeDownloads,
lastSyncTime,
searchMessagesGlobal,
focusMessage,
}) => {
const {
searchMessagesGlobal,
focusMessage,
} = getDispatch();
const lang = useLang();
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
@ -127,8 +126,4 @@ const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
export default memo(withGlobal<OwnProps>(
createMapStateToProps(CURRENT_TYPE),
(setGlobal, actions): DispatchProps => pick(actions, [
'searchMessagesGlobal',
'focusMessage',
]),
)(FileResults));

View File

@ -1,12 +1,10 @@
import React, {
FC, memo, useCallback, useState, useMemo, useRef,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { GlobalSearchContent } from '../../../types';
import { pick } from '../../../util/iteratees';
import { parseDateString } from '../../../util/dateFormat';
import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation';
import useLang from '../../../hooks/useLang';
@ -35,8 +33,6 @@ type StateProps = {
chatId?: string;
};
type DispatchProps = Pick<GlobalActions, ('setGlobalSearchContent' | 'setGlobalSearchDate')>;
const TABS = [
{ type: GlobalSearchContent.ChatList, title: 'SearchAllChatsShort' },
{ type: GlobalSearchContent.Media, title: 'SharedMediaTab2' },
@ -53,16 +49,19 @@ const CHAT_TABS = [
const TRANSITION_RENDER_COUNT = Object.keys(GlobalSearchContent).length / 2;
const LeftSearch: FC<OwnProps & StateProps & DispatchProps> = ({
const LeftSearch: FC<OwnProps & StateProps> = ({
searchQuery,
searchDate,
isActive,
currentContent = GlobalSearchContent.ChatList,
chatId,
setGlobalSearchContent,
setGlobalSearchDate,
onReset,
}) => {
const {
setGlobalSearchContent,
setGlobalSearchDate,
} = getDispatch();
const lang = useLang();
const [activeTab, setActiveTab] = useState(currentContent);
const dateSearchQuery = useMemo(() => parseDateString(searchQuery), [searchQuery]);
@ -149,5 +148,4 @@ export default memo(withGlobal<OwnProps>(
return { currentContent, chatId };
},
(setGlobal, actions): DispatchProps => pick(actions, ['setGlobalSearchContent', 'setGlobalSearchDate']),
)(LeftSearch));

View File

@ -1,15 +1,13 @@
import React, {
FC, memo, useCallback, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { LoadMoreDirection } from '../../../types';
import { SLIDE_TRANSITION_DURATION } from '../../../config';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
import { pick } from '../../../util/iteratees';
import { formatMonthAndYear, toYearMonth } from '../../../util/dateFormat';
import { getSenderName } from './helpers/getSenderName';
import { throttle } from '../../../util/schedulers';
@ -25,12 +23,10 @@ export type OwnProps = {
searchQuery?: string;
};
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'focusMessage')>;
const CURRENT_TYPE = 'links';
const runThrottled = throttle((cb) => cb(), 500, true);
const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
const LinkResults: FC<OwnProps & StateProps> = ({
searchQuery,
searchChatId,
isLoading,
@ -39,9 +35,12 @@ const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
globalMessagesByChatId,
foundIds,
lastSyncTime,
searchMessagesGlobal,
focusMessage,
}) => {
const {
searchMessagesGlobal,
focusMessage,
} = getDispatch();
const lang = useLang();
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
if (lastSyncTime && direction === LoadMoreDirection.Backwards) {
@ -122,8 +121,4 @@ const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
export default memo(withGlobal<OwnProps>(
createMapStateToProps(CURRENT_TYPE),
(setGlobal, actions): DispatchProps => pick(actions, [
'searchMessagesGlobal',
'focusMessage',
]),
)(LinkResults));

View File

@ -1,15 +1,13 @@
import React, {
FC, memo, useCallback, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { LoadMoreDirection, MediaViewerOrigin } from '../../../types';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import { SLIDE_TRANSITION_DURATION } from '../../../config';
import { createMapStateToProps, StateProps } from './helpers/createMapStateToProps';
import { pick } from '../../../util/iteratees';
import buildClassName from '../../../util/buildClassName';
import { throttle } from '../../../util/schedulers';
import useLang from '../../../hooks/useLang';
@ -25,21 +23,22 @@ export type OwnProps = {
searchQuery?: string;
};
type DispatchProps = Pick<GlobalActions, ('searchMessagesGlobal' | 'openMediaViewer')>;
const CURRENT_TYPE = 'media';
const runThrottled = throttle((cb) => cb(), 500, true);
const MediaResults: FC<OwnProps & StateProps & DispatchProps> = ({
const MediaResults: FC<OwnProps & StateProps> = ({
searchQuery,
searchChatId,
isLoading,
globalMessagesByChatId,
foundIds,
lastSyncTime,
searchMessagesGlobal,
openMediaViewer,
}) => {
const {
searchMessagesGlobal,
openMediaViewer,
} = getDispatch();
const lang = useLang();
const handleLoadMore = useCallback(({ direction }: { direction: LoadMoreDirection }) => {
@ -133,8 +132,4 @@ const MediaResults: FC<OwnProps & StateProps & DispatchProps> = ({
export default memo(withGlobal<OwnProps>(
createMapStateToProps(CURRENT_TYPE),
(setGlobal, actions): DispatchProps => pick(actions, [
'searchMessagesGlobal',
'openMediaViewer',
]),
)(MediaResults));

View File

@ -1,15 +1,13 @@
import React, {
FC, useEffect, useCallback, useRef, memo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiUser } from '../../../api/types';
import { getUserFirstOrLastName } from '../../../modules/helpers';
import renderText from '../../common/helpers/renderText';
import { throttle } from '../../../util/schedulers';
import { pick } from '../../../util/iteratees';
import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
import useLang from '../../../hooks/useLang';
@ -29,20 +27,20 @@ type StateProps = {
recentlyFoundChatIds?: string[];
};
type DispatchProps = Pick<GlobalActions, (
'loadTopUsers' | 'loadContactList' | 'openChat' | 'addRecentlyFoundChatId' | 'clearRecentlyFoundChats'
)>;
const SEARCH_CLOSE_TIMEOUT_MS = 250;
const NBSP = '\u00A0';
const runThrottled = throttle((cb) => cb(), 60000, true);
const RecentContacts: FC<OwnProps & StateProps & DispatchProps> = ({
const RecentContacts: FC<OwnProps & StateProps> = ({
topUserIds, usersById, recentlyFoundChatIds,
onReset, loadTopUsers, loadContactList, openChat,
addRecentlyFoundChatId, clearRecentlyFoundChats,
onReset,
}) => {
const {
loadTopUsers, loadContactList, openChat,
addRecentlyFoundChatId, clearRecentlyFoundChats,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const topUsersRef = useRef<HTMLDivElement>(null);
@ -122,11 +120,4 @@ export default memo(withGlobal<OwnProps>(
recentlyFoundChatIds,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadTopUsers',
'loadContactList',
'openChat',
'addRecentlyFoundChatId',
'clearRecentlyFoundChats',
]),
)(RecentContacts));

View File

@ -1,13 +1,12 @@
import React, {
FC, useMemo, useState, memo, useRef, useCallback, useEffect,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiUser } from '../../../api/types';
import { filterUsersByName, getUserFullName } from '../../../modules/helpers';
import { pick, unique } from '../../../util/iteratees';
import { unique } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import ChatOrUserPicker from '../../common/ChatOrUserPicker';
@ -25,9 +24,7 @@ type StateProps = {
currentUserId?: string;
};
type DispatchProps = Pick<GlobalActions, 'loadContactList' | 'setUserSearchQuery' | 'blockContact'>;
const BlockUserModal: FC<OwnProps & StateProps & DispatchProps> = ({
const BlockUserModal: FC<OwnProps & StateProps> = ({
usersById,
blockedIds,
contactIds,
@ -35,10 +32,13 @@ const BlockUserModal: FC<OwnProps & StateProps & DispatchProps> = ({
currentUserId,
isOpen,
onClose,
loadContactList,
setUserSearchQuery,
blockContact,
}) => {
const {
loadContactList,
setUserSearchQuery,
blockContact,
} = getDispatch();
const lang = useLang();
const [filter, setFilter] = useState('');
// eslint-disable-next-line no-null/no-null
@ -110,7 +110,4 @@ export default memo(withGlobal<OwnProps>(
currentUserId,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadContactList', 'setUserSearchQuery', 'blockContact',
]),
)(BlockUserModal));

View File

@ -1,7 +1,6 @@
import React, { FC, memo, useCallback } from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens, ISettings } from '../../../types';
import { AUTODOWNLOAD_FILESIZE_MB_LIMITS } from '../../../config';
@ -36,11 +35,7 @@ type StateProps = Pick<ISettings, (
'autoLoadFileMaxSizeMb'
)>;
type DispatchProps = Pick<GlobalActions, (
'setSettingOption'
)>;
const SettingsDataStorage: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsDataStorage: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -59,8 +54,9 @@ const SettingsDataStorage: FC<OwnProps & StateProps & DispatchProps> = ({
canAutoPlayGifs,
canAutoPlayVideos,
autoLoadFileMaxSizeMb,
setSettingOption,
}) => {
const { setSettingOption } = getDispatch();
const lang = useLang();
useHistoryBack(isActive, onReset, onScreenSelect, SettingsScreens.General);
@ -193,7 +189,4 @@ export default memo(withGlobal<OwnProps>(
'autoLoadFileMaxSizeMb',
]);
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setSettingOption',
]),
)(SettingsDataStorage));

View File

@ -2,14 +2,12 @@ import { ChangeEvent } from 'react';
import React, {
FC, useState, useCallback, memo, useEffect, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { ApiMediaFormat } from '../../../api/types';
import { GlobalActions } from '../../../global/types';
import { ProfileEditProgress, SettingsScreens } from '../../../types';
import { throttle } from '../../../util/schedulers';
import { pick } from '../../../util/iteratees';
import { selectUser } from '../../../modules/selectors';
import { getChatAvatarHash } from '../../../modules/helpers';
import useMedia from '../../../hooks/useMedia';
@ -39,10 +37,6 @@ type StateProps = {
isUsernameAvailable?: boolean;
};
type DispatchProps = Pick<GlobalActions, (
'loadCurrentUser' | 'updateProfile' | 'checkUsername'
)>;
const runThrottled = throttle((cb) => cb(), 60000, true);
const MAX_BIO_LENGTH = 70;
@ -50,7 +44,7 @@ const MAX_BIO_LENGTH = 70;
const ERROR_FIRST_NAME_MISSING = 'Please provide your first name';
const ERROR_BIO_TOO_LONG = 'Bio can\' be longer than 70 characters';
const SettingsEditProfile: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsEditProfile: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -61,10 +55,13 @@ const SettingsEditProfile: FC<OwnProps & StateProps & DispatchProps> = ({
currentUsername,
progress,
isUsernameAvailable,
loadCurrentUser,
updateProfile,
checkUsername,
}) => {
const {
loadCurrentUser,
updateProfile,
checkUsername,
} = getDispatch();
const lang = useLang();
const [isUsernameTouched, setIsUsernameTouched] = useState(false);
@ -286,9 +283,4 @@ export default memo(withGlobal<OwnProps>(
isUsernameAvailable,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadCurrentUser',
'updateProfile',
'checkUsername',
]),
)(SettingsEditProfile));

View File

@ -1,9 +1,8 @@
import React, {
FC, useCallback, memo, useEffect, useRef, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens, ISettings, TimeFormat } from '../../../types';
import { ApiSticker, ApiStickerSet } from '../../../api/types';
@ -28,21 +27,18 @@ type OwnProps = {
onReset: () => void;
};
type StateProps = Pick<ISettings, (
'messageTextSize' |
'animationLevel' |
'messageSendKeyCombo' |
'shouldSuggestStickers' |
'shouldLoopStickers' |
'timeFormat'
)> & {
stickerSetIds?: string[];
stickerSetsById?: Record<string, ApiStickerSet>;
};
type DispatchProps = Pick<GlobalActions, (
'setSettingOption' | 'loadStickerSets' | 'loadAddedStickers'
)>;
type StateProps =
Pick<ISettings, (
'messageTextSize' |
'animationLevel' |
'messageSendKeyCombo' |
'shouldSuggestStickers' |
'shouldLoopStickers' |
'timeFormat'
)> & {
stickerSetIds?: string[];
stickerSetsById?: Record<string, ApiStickerSet>;
};
const ANIMATION_LEVEL_OPTIONS = [
'Solid and Steady',
@ -58,7 +54,7 @@ const TIME_FORMAT_OPTIONS: IRadioOption[] = [{
value: '24h',
}];
const SettingsGeneral: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsGeneral: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -70,10 +66,13 @@ const SettingsGeneral: FC<OwnProps & StateProps & DispatchProps> = ({
shouldSuggestStickers,
shouldLoopStickers,
timeFormat,
setSettingOption,
loadStickerSets,
loadAddedStickers,
}) => {
const {
setSettingOption,
loadStickerSets,
loadAddedStickers,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const stickerSettingsRef = useRef<HTMLDivElement>(null);
const { observe: observeIntersectionForCovers } = useIntersectionObserver({ rootRef: stickerSettingsRef });
@ -252,7 +251,4 @@ export default memo(withGlobal<OwnProps>(
stickerSetsById: global.stickers.setsById,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setSettingOption', 'loadStickerSets', 'loadAddedStickers',
]),
)(SettingsGeneral));

View File

@ -1,14 +1,12 @@
import React, {
FC, memo, useEffect, useCallback, useRef,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens, ThemeKey, UPLOADING_WALLPAPER_SLUG } from '../../../types';
import { ApiWallpaper } from '../../../api/types';
import { DARK_THEME_PATTERN_COLOR, DEFAULT_PATTERN_COLOR } from '../../../config';
import { pick } from '../../../util/iteratees';
import { throttle } from '../../../util/schedulers';
import { openSystemFilesDialog } from '../../../util/systemFilesDialog';
import { getAverageColor, getPatternColor, rgb2hex } from '../../../util/colors';
@ -36,15 +34,11 @@ type StateProps = {
theme: ThemeKey;
};
type DispatchProps = Pick<GlobalActions, (
'loadWallpapers' | 'uploadWallpaper' | 'setThemeSettings'
)>;
const SUPPORTED_TYPES = 'image/jpeg';
const runThrottled = throttle((cb) => cb(), 60000, true);
const SettingsGeneralBackground: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsGeneralBackground: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -52,10 +46,13 @@ const SettingsGeneralBackground: FC<OwnProps & StateProps & DispatchProps> = ({
isBlurred,
loadedWallpapers,
theme,
loadWallpapers,
uploadWallpaper,
setThemeSettings,
}) => {
const {
loadWallpapers,
uploadWallpaper,
setThemeSettings,
} = getDispatch();
const themeRef = useRef<string>();
themeRef.current = theme;
// Due to the parent Transition, this component never gets unmounted,
@ -177,7 +174,4 @@ export default memo(withGlobal<OwnProps>(
theme,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadWallpapers', 'uploadWallpaper', 'setThemeSettings',
]),
)(SettingsGeneralBackground));

View File

@ -2,9 +2,8 @@ import { ChangeEvent, MutableRefObject, RefObject } from 'react';
import React, {
FC, memo, useCallback, useEffect, useRef, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens, ThemeKey } from '../../../types';
import { pick } from '../../../util/iteratees';
@ -32,8 +31,6 @@ type StateProps = {
theme: ThemeKey;
};
type DispatchProps = Pick<GlobalActions, 'setThemeSettings'>;
interface CanvasRects {
colorRect: {
offsetLeft: number;
@ -53,14 +50,15 @@ const PREDEFINED_COLORS = [
'#ccd0af', '#a6a997', '#7a7072', '#fdd7af', '#fdb76e', '#dd8851',
];
const SettingsGeneralBackground: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsGeneralBackground: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
theme,
backgroundColor,
setThemeSettings,
}) => {
const { setThemeSettings } = getDispatch();
const themeRef = useRef<string>();
themeRef.current = theme;
// eslint-disable-next-line no-null/no-null
@ -358,5 +356,4 @@ export default memo(withGlobal<OwnProps>(
theme,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['setThemeSettings']),
)(SettingsGeneralBackground));

View File

@ -1,13 +1,11 @@
import React, {
FC, memo, useCallback, useMemo, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens } from '../../../types';
import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment';
import { pick } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import DropdownMenu from '../../ui/DropdownMenu';
@ -23,17 +21,18 @@ type OwnProps = {
onScreenSelect: (screen: SettingsScreens) => void;
};
type DispatchProps = Pick<GlobalActions, 'signOut' | 'deleteChatFolder'>;
const SettingsHeader: FC<OwnProps & DispatchProps> = ({
const SettingsHeader: FC<OwnProps> = ({
currentScreen,
editedFolderId,
onReset,
onSaveFilter,
signOut,
deleteChatFolder,
onScreenSelect,
}) => {
const {
signOut,
deleteChatFolder,
} = getDispatch();
const [isSignOutDialogOpen, setIsSignOutDialogOpen] = useState(false);
const [isDeleteFolderDialogOpen, setIsDeleteFolderDialogOpen] = useState(false);
@ -263,7 +262,4 @@ const SettingsHeader: FC<OwnProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, ['signOut', 'deleteChatFolder']),
)(SettingsHeader));
export default memo(SettingsHeader);

View File

@ -1,14 +1,12 @@
import React, {
FC, memo, useCallback, useEffect, useMemo, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ISettings, LangCode, SettingsScreens } from '../../../types';
import { ApiLanguage } from '../../../api/types';
import { setLanguage } from '../../../util/langProvider';
import { pick } from '../../../util/iteratees';
import RadioGroup from '../../ui/RadioGroup';
import Loading from '../../ui/Loading';
@ -23,17 +21,18 @@ type OwnProps = {
type StateProps = Pick<ISettings, 'languages' | 'language'>;
type DispatchProps = Pick<GlobalActions, 'loadLanguages' | 'setSettingOption'>;
const SettingsLanguage: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsLanguage: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
languages,
language,
loadLanguages,
setSettingOption,
}) => {
const {
loadLanguages,
setSettingOption,
} = getDispatch();
const [selectedLanguage, setSelectedLanguage] = useState<string>(language);
const [isLoading, markIsLoading, unmarkIsLoading] = useFlag();
@ -96,7 +95,4 @@ export default memo(withGlobal<OwnProps>(
language: global.settings.byKey.language,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadLanguages', 'setSettingOption',
]),
)(SettingsLanguage));

View File

@ -1,12 +1,10 @@
import React, { FC, memo, useEffect } from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens } from '../../../types';
import { ApiUser } from '../../../api/types';
import { selectUser } from '../../../modules/selectors';
import { pick } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
@ -25,16 +23,15 @@ type StateProps = {
lastSyncTime?: number;
};
type DispatchProps = Pick<GlobalActions, 'loadProfilePhotos'>;
const SettingsMain: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsMain: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
loadProfilePhotos,
currentUser,
lastSyncTime,
}) => {
const { loadProfilePhotos } = getDispatch();
const lang = useLang();
const profileId = currentUser?.id;
@ -111,5 +108,4 @@ export default memo(withGlobal<OwnProps>(
lastSyncTime,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadProfilePhotos']),
)(SettingsMain));

View File

@ -3,12 +3,10 @@ import useDebounce from '../../../hooks/useDebounce';
import React, {
FC, memo, useCallback, useEffect,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { SettingsScreens } from '../../../types';
import { pick } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
import { playNotifySound } from '../../../util/notifications';
@ -35,12 +33,7 @@ type StateProps = {
notificationSoundVolume: number;
};
type DispatchProps = Pick<GlobalActions, (
'loadNotificationSettings' | 'updateContactSignUpNotification' |
'updateNotificationSettings' | 'updateWebNotificationSettings'
)>;
const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsNotifications: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -54,11 +47,14 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
hasPushNotifications,
hasWebNotifications,
notificationSoundVolume,
loadNotificationSettings,
updateContactSignUpNotification,
updateNotificationSettings,
updateWebNotificationSettings,
}) => {
const {
loadNotificationSettings,
updateContactSignUpNotification,
updateNotificationSettings,
updateWebNotificationSettings,
} = getDispatch();
useEffect(() => {
loadNotificationSettings();
}, [loadNotificationSettings]);
@ -147,7 +143,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
// eslint-disable-next-line max-len
subLabel={lang(hasPrivateChatsNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
checked={hasPrivateChatsNotifications}
onChange={(e) => { handleSettingsChange(e, 'contact', 'silent'); }}
onChange={(e) => {
handleSettingsChange(e, 'contact', 'silent');
}}
/>
<Checkbox
label={lang('MessagePreview')}
@ -155,7 +153,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
// eslint-disable-next-line max-len
subLabel={lang(hasPrivateChatsMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
checked={hasPrivateChatsMessagePreview}
onChange={(e) => { handleSettingsChange(e, 'contact', 'showPreviews'); }}
onChange={(e) => {
handleSettingsChange(e, 'contact', 'showPreviews');
}}
/>
</div>
@ -166,14 +166,18 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
label={lang('NotificationsForGroups')}
subLabel={lang(hasGroupNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
checked={hasGroupNotifications}
onChange={(e) => { handleSettingsChange(e, 'group', 'silent'); }}
onChange={(e) => {
handleSettingsChange(e, 'group', 'silent');
}}
/>
<Checkbox
label={lang('MessagePreview')}
disabled={!hasGroupNotifications}
subLabel={lang(hasGroupMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
checked={hasGroupMessagePreview}
onChange={(e) => { handleSettingsChange(e, 'group', 'showPreviews'); }}
onChange={(e) => {
handleSettingsChange(e, 'group', 'showPreviews');
}}
/>
</div>
@ -185,7 +189,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
// eslint-disable-next-line max-len
subLabel={lang(hasBroadcastNotifications ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
checked={hasBroadcastNotifications}
onChange={(e) => { handleSettingsChange(e, 'broadcast', 'silent'); }}
onChange={(e) => {
handleSettingsChange(e, 'broadcast', 'silent');
}}
/>
<Checkbox
label={lang('MessagePreview')}
@ -193,7 +199,9 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
// eslint-disable-next-line max-len
subLabel={lang(hasBroadcastMessagePreview ? 'UserInfo.NotificationsEnabled' : 'UserInfo.NotificationsDisabled')}
checked={hasBroadcastMessagePreview}
onChange={(e) => { handleSettingsChange(e, 'broadcast', 'showPreviews'); }}
onChange={(e) => {
handleSettingsChange(e, 'broadcast', 'showPreviews');
}}
/>
</div>
@ -210,23 +218,19 @@ const SettingsNotifications: FC<OwnProps & StateProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>((global): StateProps => {
return {
hasPrivateChatsNotifications: Boolean(global.settings.byKey.hasPrivateChatsNotifications),
hasPrivateChatsMessagePreview: Boolean(global.settings.byKey.hasPrivateChatsMessagePreview),
hasGroupNotifications: Boolean(global.settings.byKey.hasGroupNotifications),
hasGroupMessagePreview: Boolean(global.settings.byKey.hasGroupMessagePreview),
hasBroadcastNotifications: Boolean(global.settings.byKey.hasBroadcastNotifications),
hasBroadcastMessagePreview: Boolean(global.settings.byKey.hasBroadcastMessagePreview),
hasContactJoinedNotifications: Boolean(global.settings.byKey.hasContactJoinedNotifications),
hasWebNotifications: global.settings.byKey.hasWebNotifications,
hasPushNotifications: global.settings.byKey.hasPushNotifications,
notificationSoundVolume: global.settings.byKey.notificationSoundVolume,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadNotificationSettings',
'updateContactSignUpNotification',
'updateNotificationSettings',
'updateWebNotificationSettings',
]))(SettingsNotifications));
export default memo(withGlobal<OwnProps>(
(global): StateProps => {
return {
hasPrivateChatsNotifications: Boolean(global.settings.byKey.hasPrivateChatsNotifications),
hasPrivateChatsMessagePreview: Boolean(global.settings.byKey.hasPrivateChatsMessagePreview),
hasGroupNotifications: Boolean(global.settings.byKey.hasGroupNotifications),
hasGroupMessagePreview: Boolean(global.settings.byKey.hasGroupMessagePreview),
hasBroadcastNotifications: Boolean(global.settings.byKey.hasBroadcastNotifications),
hasBroadcastMessagePreview: Boolean(global.settings.byKey.hasBroadcastMessagePreview),
hasContactJoinedNotifications: Boolean(global.settings.byKey.hasContactJoinedNotifications),
hasWebNotifications: global.settings.byKey.hasWebNotifications,
hasPushNotifications: global.settings.byKey.hasPushNotifications,
notificationSoundVolume: global.settings.byKey.notificationSoundVolume,
};
},
)(SettingsNotifications));

View File

@ -1,10 +1,8 @@
import React, { FC, memo, useEffect } from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { PrivacyVisibility, SettingsScreens } from '../../../types';
import { pick } from '../../../util/iteratees';
import useLang from '../../../hooks/useLang';
import useHistoryBack from '../../../hooks/useHistoryBack';
@ -30,11 +28,7 @@ type StateProps = {
visibilityPrivacyGroupChats?: PrivacyVisibility;
};
type DispatchProps = Pick<GlobalActions, (
'loadBlockedContacts' | 'loadAuthorizations' | 'loadPrivacySettings' | 'loadContentSettings' | 'updateContentSettings'
)>;
const SettingsPrivacy: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsPrivacy: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -48,12 +42,16 @@ const SettingsPrivacy: FC<OwnProps & StateProps & DispatchProps> = ({
visibilityPrivacyProfilePhoto,
visibilityPrivacyForwarding,
visibilityPrivacyGroupChats,
loadPrivacySettings,
loadBlockedContacts,
loadAuthorizations,
loadContentSettings,
updateContentSettings,
}) => {
const {
loadPrivacySettings,
loadBlockedContacts,
loadAuthorizations,
loadContentSettings,
updateContentSettings,
} = getDispatch();
useEffect(() => {
loadBlockedContacts();
loadAuthorizations();
@ -234,7 +232,4 @@ export default memo(withGlobal<OwnProps>(
visibilityPrivacyGroupChats: privacy.chatInvite?.visibility,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadBlockedContacts', 'loadAuthorizations', 'loadPrivacySettings', 'loadContentSettings', 'updateContentSettings',
]),
)(SettingsPrivacy));

View File

@ -1,13 +1,11 @@
import React, {
FC, memo, useCallback, useEffect, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiSession } from '../../../api/types';
import { SettingsScreens } from '../../../types';
import { pick } from '../../../util/iteratees';
import { formatPastTimeShort } from '../../../util/dateFormat';
import useFlag from '../../../hooks/useFlag';
import useLang from '../../../hooks/useLang';
@ -26,19 +24,18 @@ type StateProps = {
activeSessions: ApiSession[];
};
type DispatchProps = Pick<GlobalActions, (
'loadAuthorizations' | 'terminateAuthorization' | 'terminateAllAuthorizations'
)>;
const SettingsPrivacyActiveSessions: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsPrivacyActiveSessions: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
activeSessions,
loadAuthorizations,
terminateAuthorization,
terminateAllAuthorizations,
}) => {
const {
loadAuthorizations,
terminateAuthorization,
terminateAllAuthorizations,
} = getDispatch();
const [isConfirmTerminateAllDialogOpen, openConfirmTerminateAllDialog, closeConfirmTerminateAllDialog] = useFlag();
useEffect(() => {
loadAuthorizations();
@ -162,7 +159,4 @@ export default memo(withGlobal<OwnProps>(
activeSessions: global.activeSessions,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadAuthorizations', 'terminateAuthorization', 'terminateAllAuthorizations',
]),
)(SettingsPrivacyActiveSessions));

View File

@ -1,15 +1,13 @@
import React, {
FC, memo, useCallback,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiChat, ApiCountryCode, ApiUser } from '../../../api/types';
import { SettingsScreens } from '../../../types';
import { CHAT_HEIGHT_PX } from '../../../config';
import { formatPhoneNumberWithCode } from '../../../util/phoneNumber';
import { pick } from '../../../util/iteratees';
import {
getChatTitle, getUserFullName, isUserId,
} from '../../../modules/helpers';
@ -38,9 +36,7 @@ type StateProps = {
phoneCodeList: ApiCountryCode[];
};
type DispatchProps = Pick<GlobalActions, 'unblockContact'>;
const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -48,8 +44,9 @@ const SettingsPrivacyBlockedUsers: FC<OwnProps & StateProps & DispatchProps> = (
usersByIds,
blockedIds,
phoneCodeList,
unblockContact,
}) => {
const { unblockContact } = getDispatch();
const lang = useLang();
const [isBlockUserModalOpen, openBlockUserModal, closeBlockUserModal] = useFlag();
const handleUnblockClick = useCallback((contactId: string) => {
@ -158,5 +155,4 @@ export default memo(withGlobal<OwnProps>(
phoneCodeList,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['unblockContact']),
)(SettingsPrivacyBlockedUsers));

View File

@ -1,14 +1,12 @@
import React, {
FC, memo, useCallback, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiChat, ApiUser } from '../../../api/types';
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
import useLang from '../../../hooks/useLang';
import { pick } from '../../../util/iteratees';
import useHistoryBack from '../../../hooks/useHistoryBack';
import ListItem from '../../ui/ListItem';
@ -22,14 +20,13 @@ type OwnProps = {
onReset: () => void;
};
type StateProps = Partial<ApiPrivacySettings> & {
chatsById?: Record<string, ApiChat>;
usersById?: Record<string, ApiUser>;
};
type StateProps =
Partial<ApiPrivacySettings> & {
chatsById?: Record<string, ApiChat>;
usersById?: Record<string, ApiUser>;
};
type DispatchProps = Pick<GlobalActions, 'setPrivacyVisibility'>;
const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsPrivacyVisibility: FC<OwnProps & StateProps> = ({
screen,
isActive,
onScreenSelect,
@ -40,8 +37,9 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
blockUserIds,
blockChatIds,
chatsById,
setPrivacyVisibility,
}) => {
const { setPrivacyVisibility } = getDispatch();
const lang = useLang();
const visibilityOptions = useMemo(() => {
@ -178,7 +176,9 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
<ListItem
narrow
icon="add-user"
onClick={() => { onScreenSelect(allowedContactsScreen); }}
onClick={() => {
onScreenSelect(allowedContactsScreen);
}}
>
<div className="multiline-menu-item full-size">
{allowedCount > 0 && <span className="date" dir="auto">+{allowedCount}</span>}
@ -191,7 +191,9 @@ const SettingsPrivacyVisibility: FC<OwnProps & StateProps & DispatchProps> = ({
<ListItem
narrow
icon="delete-user"
onClick={() => { onScreenSelect(deniedContactsScreen); }}
onClick={() => {
onScreenSelect(deniedContactsScreen);
}}
>
<div className="multiline-menu-item full-size">
{blockCount > 0 && <span className="date" dir="auto">&minus;{blockCount}</span>}
@ -245,5 +247,4 @@ export default memo(withGlobal<OwnProps>(
chatsById,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['setPrivacyVisibility']),
)(SettingsPrivacyVisibility));

View File

@ -1,14 +1,13 @@
import React, {
FC, memo, useCallback, useMemo, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../../global/types';
import { GlobalState } from '../../../global/types';
import { ApiChat } from '../../../api/types';
import { ApiPrivacySettings, SettingsScreens } from '../../../types';
import useLang from '../../../hooks/useLang';
import { pick } from '../../../util/iteratees';
import searchWords from '../../../util/searchWords';
import { getPrivacyKey } from './helper/privacy';
import {
@ -37,9 +36,7 @@ type StateProps = {
settings?: ApiPrivacySettings;
};
type DispatchProps = Pick<GlobalActions, 'setPrivacySettings'>;
const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps> = ({
currentUserId,
isAllowList,
screen,
@ -49,11 +46,12 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
orderedPinnedIds,
archivedListIds,
archivedPinnedIds,
setPrivacySettings,
isActive,
onScreenSelect,
onReset,
}) => {
const { setPrivacySettings } = getDispatch();
const lang = useLang();
const selectedContactIds = useMemo(() => {
@ -105,8 +103,8 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
((isUserId(chat.id) && chat.id !== currentUserId) || isChatGroup(chat))
&& (
!searchQuery
|| searchWords(getChatTitle(lang, chat), searchQuery)
|| selectedContactIds.includes(chat.id)
|| searchWords(getChatTitle(lang, chat), searchQuery)
|| selectedContactIds.includes(chat.id)
)
))
.map(({ id }) => id);
@ -196,5 +194,4 @@ export default memo(withGlobal<OwnProps>(
settings: getCurrentPrivacySettings(global, screen),
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['setPrivacySettings']),
)(SettingsPrivacyVisibilityExceptionList));

View File

@ -1,14 +1,12 @@
import React, {
FC, memo, useMemo, useCallback,
} from '../../../../lib/teact/teact';
import { withGlobal } from '../../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../../lib/teact/teactn';
import { GlobalActions } from '../../../../global/types';
import { ApiChat } from '../../../../api/types';
import { SettingsScreens } from '../../../../types';
import useLang from '../../../../hooks/useLang';
import { pick } from '../../../../util/iteratees';
import searchWords from '../../../../util/searchWords';
import { prepareChatList, getChatTitle } from '../../../../modules/helpers';
import {
@ -39,9 +37,7 @@ type StateProps = {
archivedPinnedIds?: string[];
};
type DispatchProps = Pick<GlobalActions, 'loadMoreChats'>;
const SettingsFoldersChatFilters: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsFoldersChatFilters: FC<OwnProps & StateProps> = ({
isActive,
onScreenSelect,
onReset,
@ -53,8 +49,9 @@ const SettingsFoldersChatFilters: FC<OwnProps & StateProps & DispatchProps> = ({
orderedPinnedIds,
archivedListIds,
archivedPinnedIds,
loadMoreChats,
}) => {
const { loadMoreChats } = getDispatch();
const { chatFilter } = state;
const { selectedChatIds, selectedChatTypes } = selectChatFilters(state, mode, true);
@ -180,5 +177,4 @@ export default memo(withGlobal<OwnProps>(
archivedListIds: listIds.archived,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadMoreChats']),
)(SettingsFoldersChatFilters));

View File

@ -1,13 +1,12 @@
import React, {
FC, memo, useCallback, useEffect, useMemo, useState,
} from '../../../../lib/teact/teact';
import { withGlobal } from '../../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../../lib/teact/teactn';
import { GlobalActions } from '../../../../global/types';
import { SettingsScreens } from '../../../../types';
import { STICKER_SIZE_FOLDER_SETTINGS } from '../../../../config';
import { findIntersectionWithSet, pick } from '../../../../util/iteratees';
import { findIntersectionWithSet } from '../../../../util/iteratees';
import { isUserId } from '../../../../modules/helpers';
import getAnimationData from '../../../common/helpers/animatedAssets';
import {
@ -45,8 +44,6 @@ type StateProps = {
loadedArchivedChatIds?: string[];
};
type DispatchProps = Pick<GlobalActions, 'editChatFolder' | 'addChatFolder' | 'loadMoreChats'>;
const SUBMIT_TIMEOUT = 500;
const INITIAL_CHATS_LIMIT = 5;
@ -54,7 +51,7 @@ const INITIAL_CHATS_LIMIT = 5;
const ERROR_NO_TITLE = 'Please provide a title for this folder.';
const ERROR_NO_CHATS = 'ChatList.Filter.Error.Empty';
const SettingsFoldersEdit: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsFoldersEdit: FC<OwnProps & StateProps> = ({
state,
dispatch,
onAddIncludedChats,
@ -65,10 +62,13 @@ const SettingsFoldersEdit: FC<OwnProps & StateProps & DispatchProps> = ({
onBack,
loadedActiveChatIds,
loadedArchivedChatIds,
editChatFolder,
addChatFolder,
loadMoreChats,
}) => {
const {
editChatFolder,
addChatFolder,
loadMoreChats,
} = getDispatch();
const [animationData, setAnimationData] = useState<Record<string, any>>();
const [isAnimationLoaded, setIsAnimationLoaded] = useState(false);
const handleAnimationLoad = useCallback(() => setIsAnimationLoaded(true), []);
@ -322,5 +322,4 @@ export default memo(withGlobal<OwnProps>(
loadedArchivedChatIds: listIds.archived,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['editChatFolder', 'addChatFolder', 'loadMoreChats']),
)(SettingsFoldersEdit));

View File

@ -1,14 +1,13 @@
import React, {
FC, memo, useMemo, useCallback, useState, useEffect,
} from '../../../../lib/teact/teact';
import { withGlobal } from '../../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../../../global/types';
import { GlobalState } from '../../../../global/types';
import { ApiChatFolder, ApiChat, ApiUser } from '../../../../api/types';
import { NotifyException, NotifySettings, SettingsScreens } from '../../../../types';
import { STICKER_SIZE_FOLDER_SETTINGS } from '../../../../config';
import { pick } from '../../../../util/iteratees';
import { selectNotifyExceptions, selectNotifySettings } from '../../../../modules/selectors';
import { throttle } from '../../../../util/schedulers';
import getAnimationData from '../../../common/helpers/animatedAssets';
@ -40,13 +39,11 @@ type StateProps = {
notifyExceptions?: Record<number, NotifyException>;
};
type DispatchProps = Pick<GlobalActions, 'loadRecommendedChatFolders' | 'addChatFolder' | 'showDialog'>;
const runThrottledForLoadRecommended = throttle((cb) => cb(), 60000, true);
const MAX_ALLOWED_FOLDERS = 10;
const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsFoldersMain: FC<OwnProps & StateProps> = ({
isActive,
allListIds,
chatsById,
@ -60,10 +57,13 @@ const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
onEditFolder,
onScreenSelect,
onReset,
loadRecommendedChatFolders,
addChatFolder,
showDialog,
}) => {
const {
loadRecommendedChatFolders,
addChatFolder,
showDialog,
} = getDispatch();
const [animationData, setAnimationData] = useState<Record<string, any>>();
const [isAnimationLoaded, setIsAnimationLoaded] = useState(false);
const handleAnimationLoad = useCallback(() => setIsAnimationLoaded(true), []);
@ -250,5 +250,4 @@ export default memo(withGlobal<OwnProps>(
notifyExceptions: selectNotifyExceptions(global),
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadRecommendedChatFolders', 'addChatFolder', 'showDialog']),
)(SettingsFoldersMain));

View File

@ -1,12 +1,11 @@
import React, {
FC, memo, useCallback, useEffect,
} from '../../../../lib/teact/teact';
import { withGlobal } from '../../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../../lib/teact/teactn';
import { GlobalActions, GlobalState } from '../../../../global/types';
import { GlobalState } from '../../../../global/types';
import { SettingsScreens } from '../../../../types';
import { pick } from '../../../../util/iteratees';
import { TwoFaDispatch, TwoFaState } from '../../../../hooks/reducers/useTwoFaReducer';
import useLang from '../../../../hooks/useLang';
@ -29,12 +28,7 @@ export type OwnProps = {
type StateProps = GlobalState['twoFaSettings'];
type DispatchProps = Pick<GlobalActions, (
'updatePassword' | 'updateRecoveryEmail' | 'clearPassword' | 'provideTwoFaEmailCode' |
'checkPassword' | 'clearTwoFaError'
)>;
const SettingsTwoFa: FC<OwnProps & StateProps & DispatchProps> = ({
const SettingsTwoFa: FC<OwnProps & StateProps> = ({
currentScreen,
shownScreen,
state,
@ -46,13 +40,16 @@ const SettingsTwoFa: FC<OwnProps & StateProps & DispatchProps> = ({
isActive,
onScreenSelect,
onReset,
updatePassword,
checkPassword,
clearTwoFaError,
updateRecoveryEmail,
provideTwoFaEmailCode,
clearPassword,
}) => {
const {
updatePassword,
checkPassword,
clearTwoFaError,
updateRecoveryEmail,
provideTwoFaEmailCode,
clearPassword,
} = getDispatch();
useEffect(() => {
if (waitingEmailCodeLength) {
if (currentScreen === SettingsScreens.TwoFaNewPasswordEmail) {
@ -435,8 +432,4 @@ const SettingsTwoFa: FC<OwnProps & StateProps & DispatchProps> = ({
export default memo(withGlobal<OwnProps>(
(global): StateProps => ({ ...global.twoFaSettings }),
(setGlobal, actions): DispatchProps => pick(actions, [
'updatePassword', 'updateRecoveryEmail', 'clearPassword', 'provideTwoFaEmailCode',
'checkPassword', 'clearTwoFaError',
]),
)(SettingsTwoFa));

View File

@ -1,7 +1,6 @@
import React, { FC, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiError, ApiInviteInfo } from '../../api/types';
import getReadableErrorText from '../../util/getReadableErrorText';
@ -18,9 +17,9 @@ type StateProps = {
dialogs: (ApiError | ApiInviteInfo)[];
};
type DispatchProps = Pick<GlobalActions, 'dismissDialog' | 'acceptInviteConfirmation'>;
const Dialogs: FC<StateProps> = ({ dialogs }) => {
const { dismissDialog, acceptInviteConfirmation } = getDispatch();
const Dialogs: FC<StateProps & DispatchProps> = ({ dialogs, dismissDialog, acceptInviteConfirmation }) => {
const lang = useLang();
if (!dialogs.length) {
@ -104,5 +103,4 @@ function getErrorHeader(error: ApiError) {
export default memo(withGlobal(
(global): StateProps => pick(global, ['dialogs']),
(setGlobal, actions): DispatchProps => pick(actions, ['dismissDialog', 'acceptInviteConfirmation']),
)(Dialogs));

View File

@ -1,7 +1,7 @@
import { FC, memo, useEffect } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions, Thread } from '../../global/types';
import { Thread } from '../../global/types';
import { ApiMediaFormat, ApiMessage } from '../../api/types';
import * as mediaLoader from '../../util/mediaLoader';
@ -9,7 +9,6 @@ import download from '../../util/download';
import {
getMessageContentFilename, getMessageMediaHash,
} from '../../modules/helpers';
import { pick } from '../../util/iteratees';
type StateProps = {
activeDownloads: Record<number, number[]>;
@ -19,15 +18,14 @@ type StateProps = {
}>;
};
type DispatchProps = Pick<GlobalActions, 'cancelMessageMediaDownload'>;
const startedDownloads = new Set<string>();
const DownloadManager: FC<StateProps & DispatchProps> = ({
const DownloadManager: FC<StateProps> = ({
activeDownloads,
messages,
cancelMessageMediaDownload,
}) => {
const { cancelMessageMediaDownload } = getDispatch();
useEffect(() => {
Object.entries(activeDownloads).forEach(([chatId, messageIds]) => {
const activeMessages = messageIds.map((id) => messages[Number(chatId)].byId[id]);
@ -77,5 +75,4 @@ export default memo(withGlobal(
messages,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['cancelMessageMediaDownload']),
)(DownloadManager));

View File

@ -1,9 +1,8 @@
import React, {
FC, useMemo, useState, memo, useRef, useCallback,
} from '../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../lib/teact/teactn';
import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiChat, MAIN_THREAD_ID } from '../../api/types';
import {
@ -12,7 +11,7 @@ import {
getCanPostInChat,
sortChatIds,
} from '../../modules/helpers';
import { pick, unique } from '../../util/iteratees';
import { unique } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
@ -31,9 +30,7 @@ type StateProps = {
currentUserId?: string;
};
type DispatchProps = Pick<GlobalActions, 'setForwardChatId' | 'exitForwardMode' | 'loadMoreChats'>;
const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
const ForwardPicker: FC<OwnProps & StateProps> = ({
chatsById,
activeListIds,
archivedListIds,
@ -41,10 +38,13 @@ const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
contactIds,
currentUserId,
isOpen,
setForwardChatId,
exitForwardMode,
loadMoreChats,
}) => {
const {
setForwardChatId,
exitForwardMode,
loadMoreChats,
} = getDispatch();
const lang = useLang();
const [filter, setFilter] = useState('');
// eslint-disable-next-line no-null/no-null
@ -120,5 +120,4 @@ export default memo(withGlobal<OwnProps>(
currentUserId,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['setForwardChatId', 'exitForwardMode', 'loadMoreChats']),
)(ForwardPicker));

View File

@ -1,9 +1,6 @@
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import CalendarModal from '../common/CalendarModal';
@ -16,11 +13,11 @@ type StateProps = {
selectedAt?: number;
};
type DispatchProps = Pick<GlobalActions, 'searchMessagesByDate' | 'closeHistoryCalendar'>;
const HistoryCalendar: FC<OwnProps & StateProps & DispatchProps> = ({
isOpen, selectedAt, searchMessagesByDate, closeHistoryCalendar,
const HistoryCalendar: FC<OwnProps & StateProps> = ({
isOpen, selectedAt,
}) => {
const { searchMessagesByDate, closeHistoryCalendar } = getDispatch();
const handleJumpToDate = useCallback((date: Date) => {
searchMessagesByDate({ timestamp: date.valueOf() / 1000 });
closeHistoryCalendar();
@ -44,7 +41,4 @@ export default memo(withGlobal<OwnProps>(
(global): StateProps => {
return { selectedAt: global.historyCalendarSelectedAt };
},
(setGlobal, actions): DispatchProps => pick(actions, [
'searchMessagesByDate', 'closeHistoryCalendar',
]),
)(HistoryCalendar));

View File

@ -1,17 +1,15 @@
import React, {
FC, useEffect, memo, useCallback,
} from '../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../lib/teact/teactn';
import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn';
import { LangCode } from '../../types';
import { GlobalActions } from '../../global/types';
import { ApiMessage } from '../../api/types';
import '../../modules/actions/all';
import {
BASE_EMOJI_KEYWORD_LANG, DEBUG, INACTIVE_MARKER, PAGE_TITLE,
} from '../../config';
import { pick } from '../../util/iteratees';
import {
selectChatMessage,
selectCountNotMutedUnread,
@ -72,12 +70,6 @@ type StateProps = {
isCallFallbackConfirmOpen: boolean;
};
type DispatchProps = Pick<GlobalActions, (
'loadAnimatedEmojis' | 'loadNotificationSettings' | 'loadNotificationExceptions' | 'updateIsOnline' |
'loadTopInlineBots' | 'loadEmojiKeywords' | 'openStickerSetShortName' |
'loadCountryList' | 'ensureTimeFormat' | 'checkVersionNotification'
)>;
const NOTIFICATION_INTERVAL = 1000;
let notificationInterval: number | undefined;
@ -85,7 +77,7 @@ let notificationInterval: number | undefined;
// eslint-disable-next-line @typescript-eslint/naming-convention
let DEBUG_isLogged = false;
const Main: FC<StateProps & DispatchProps> = ({
const Main: FC<StateProps> = ({
lastSyncTime,
isLeftColumnShown,
isRightColumnShown,
@ -104,17 +96,20 @@ const Main: FC<StateProps & DispatchProps> = ({
language,
wasTimeFormatSetManually,
isCallFallbackConfirmOpen,
loadAnimatedEmojis,
loadNotificationSettings,
loadNotificationExceptions,
updateIsOnline,
loadTopInlineBots,
loadEmojiKeywords,
loadCountryList,
ensureTimeFormat,
openStickerSetShortName,
checkVersionNotification,
}) => {
const {
loadAnimatedEmojis,
loadNotificationSettings,
loadNotificationExceptions,
updateIsOnline,
loadTopInlineBots,
loadEmojiKeywords,
loadCountryList,
ensureTimeFormat,
openStickerSetShortName,
checkVersionNotification,
} = getDispatch();
if (DEBUG && !DEBUG_isLogged) {
DEBUG_isLogged = true;
// eslint-disable-next-line no-console
@ -362,9 +357,4 @@ export default memo(withGlobal(
isCallFallbackConfirmOpen: Boolean(global.groupCalls.isFallbackConfirmOpen),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadAnimatedEmojis', 'loadNotificationSettings', 'loadNotificationExceptions', 'updateIsOnline',
'loadTopInlineBots', 'loadEmojiKeywords', 'openStickerSetShortName', 'loadCountryList', 'ensureTimeFormat',
'checkVersionNotification',
]),
)(Main));

View File

@ -1,7 +1,6 @@
import React, { FC, memo } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiNotification } from '../../api/types';
import { pick } from '../../util/iteratees';
@ -13,9 +12,9 @@ type StateProps = {
notifications: ApiNotification[];
};
type DispatchProps = Pick<GlobalActions, 'dismissNotification'>;
const Notifications: FC<StateProps> = ({ notifications }) => {
const { dismissNotification } = getDispatch();
const Notifications: FC<StateProps & DispatchProps> = ({ notifications, dismissNotification }) => {
if (!notifications.length) {
return undefined;
}
@ -34,5 +33,4 @@ const Notifications: FC<StateProps & DispatchProps> = ({ notifications, dismissN
export default memo(withGlobal(
(global): StateProps => pick(global, ['notifications']),
(setGlobal, actions): DispatchProps => pick(actions, ['dismissNotification']),
)(Notifications));

View File

@ -1,9 +1,6 @@
import React, { FC, memo, useCallback } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { pick } from '../../util/iteratees';
import { ensureProtocol } from '../../util/ensureProtocol';
import renderText from '../common/helpers/renderText';
import useLang from '../../hooks/useLang';
@ -15,9 +12,9 @@ export type OwnProps = {
url?: string;
};
type DispatchProps = Pick<GlobalActions, 'toggleSafeLinkModal'>;
const SafeLinkModal: FC<OwnProps> = ({ url }) => {
const { toggleSafeLinkModal } = getDispatch();
const SafeLinkModal: FC<OwnProps & DispatchProps> = ({ url, toggleSafeLinkModal }) => {
const lang = useLang();
const handleOpen = useCallback(() => {
@ -43,7 +40,4 @@ const SafeLinkModal: FC<OwnProps & DispatchProps> = ({ url, toggleSafeLinkModal
);
};
export default memo(withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, ['toggleSafeLinkModal']),
)(SafeLinkModal));
export default memo(SafeLinkModal);

View File

@ -1,9 +1,8 @@
import React, {
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import {
ApiChat, ApiDimensions, ApiMediaFormat, ApiMessage, ApiUser,
} from '../../api/types';
@ -51,7 +50,6 @@ import { stopCurrentAudio } from '../../util/audioPlayer';
import captureEscKeyListener from '../../util/captureEscKeyListener';
import { captureEvents } from '../../util/captureEvents';
import { IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../util/environment';
import { pick } from '../../util/iteratees';
import windowSize from '../../util/windowSize';
import { AVATAR_FULL_DIMENSIONS, MEDIA_VIEWER_MEDIA_QUERY } from '../common/helpers/mediaDimensions';
import { renderMessageText } from '../common/helpers/renderMessageText';
@ -83,11 +81,9 @@ type StateProps = {
animationLevel: 0 | 1 | 2;
};
type DispatchProps = Pick<GlobalActions, 'openMediaViewer' | 'closeMediaViewer' | 'openForwardMenu' | 'focusMessage'>;
const ANIMATION_DURATION = 350;
const MediaViewer: FC<StateProps & DispatchProps> = ({
const MediaViewer: FC<StateProps> = ({
chatId,
threadId,
messageId,
@ -98,12 +94,15 @@ const MediaViewer: FC<StateProps & DispatchProps> = ({
message,
chatMessages,
collectionIds,
openMediaViewer,
closeMediaViewer,
openForwardMenu,
focusMessage,
animationLevel,
}) => {
const {
openMediaViewer,
closeMediaViewer,
openForwardMenu,
focusMessage,
} = getDispatch();
const isOpen = Boolean(avatarOwner || messageId);
const isFromSharedMedia = origin === MediaViewerOrigin.SharedMedia;
@ -641,7 +640,4 @@ export default memo(withGlobal(
animationLevel,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'openMediaViewer', 'closeMediaViewer', 'openForwardMenu', 'focusMessage',
]),
)(MediaViewer));

View File

@ -4,9 +4,8 @@ import React, {
useCallback,
useMemo,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiMessage } from '../../api/types';
import { IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
@ -14,7 +13,6 @@ import { getMessageMediaHash } from '../../modules/helpers';
import useLang from '../../hooks/useLang';
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
import { selectIsDownloading } from '../../modules/selectors';
import { pick } from '../../util/iteratees';
import Button from '../ui/Button';
import DropdownMenu from '../ui/DropdownMenu';
@ -39,9 +37,7 @@ type OwnProps = {
onZoomToggle: NoneToVoidFunction;
};
type DispatchProps = Pick<GlobalActions, 'downloadMessageMedia' | 'cancelMessageMediaDownload'>;
const MediaViewerActions: FC<OwnProps & StateProps & DispatchProps> = ({
const MediaViewerActions: FC<OwnProps & StateProps> = ({
mediaData,
isVideo,
isZoomed,
@ -52,9 +48,12 @@ const MediaViewerActions: FC<OwnProps & StateProps & DispatchProps> = ({
onCloseMediaViewer,
onForward,
onZoomToggle,
downloadMessageMedia,
cancelMessageMediaDownload,
}) => {
const {
downloadMessageMedia,
cancelMessageMediaDownload,
} = getDispatch();
const { loadProgress: downloadProgress } = useMediaWithLoadProgress(
message && getMessageMediaHash(message, 'download'),
!isDownloading,
@ -193,8 +192,4 @@ export default memo(withGlobal<OwnProps>(
isDownloading,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'downloadMessageMedia',
'cancelMessageMediaDownload',
]),
)(MediaViewerActions));

View File

@ -1,7 +1,6 @@
import React, { FC, useCallback } from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiChat, ApiMessage, ApiUser } from '../../api/types';
import { getSenderTitle, isUserId } from '../../modules/helpers';
@ -13,7 +12,6 @@ import {
selectSender,
selectUser,
} from '../../modules/selectors';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import Avatar from '../common/Avatar';
@ -31,17 +29,18 @@ type StateProps = {
message?: ApiMessage;
};
type DispatchProps = Pick<GlobalActions, 'closeMediaViewer' | 'focusMessage'>;
const SenderInfo: FC<OwnProps & StateProps & DispatchProps> = ({
const SenderInfo: FC<OwnProps & StateProps> = ({
chatId,
messageId,
sender,
isAvatar,
message,
closeMediaViewer,
focusMessage,
}) => {
const {
closeMediaViewer,
focusMessage,
} = getDispatch();
const handleFocusMessage = useCallback(() => {
closeMediaViewer();
focusMessage({ chatId, messageId });
@ -95,5 +94,4 @@ export default withGlobal<OwnProps>(
sender: message && selectSender(global, message),
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['closeMediaViewer', 'focusMessage']),
)(SenderInfo);

View File

@ -1,10 +1,9 @@
import React, {
FC, useCallback, useEffect, useMemo,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { AudioOrigin } from '../../types';
import { GlobalActions } from '../../global/types';
import {
ApiAudio, ApiChat, ApiMessage, ApiUser,
} from '../../api/types';
@ -16,7 +15,6 @@ import {
getMediaDuration, getMessageContent, getMessageMediaHash, getSenderTitle, isMessageLocal,
} from '../../modules/helpers';
import { selectChat, selectSender } from '../../modules/selectors';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import { makeTrackId } from '../../util/audioPlayer';
import { clearMediaSession } from '../../util/mediaSession';
@ -47,17 +45,9 @@ type StateProps = {
isMuted: boolean;
};
type DispatchProps = Pick<GlobalActions, (
'focusMessage' |
'closeAudioPlayer' |
'setAudioPlayerVolume' |
'setAudioPlayerPlaybackRate' |
'setAudioPlayerMuted'
)>;
const FAST_PLAYBACK_RATE = 1.8;
const AudioPlayer: FC<OwnProps & StateProps & DispatchProps> = ({
const AudioPlayer: FC<OwnProps & StateProps> = ({
message,
className,
noUi,
@ -66,12 +56,15 @@ const AudioPlayer: FC<OwnProps & StateProps & DispatchProps> = ({
volume,
playbackRate,
isMuted,
setAudioPlayerVolume,
setAudioPlayerPlaybackRate,
setAudioPlayerMuted,
focusMessage,
closeAudioPlayer,
}) => {
const {
setAudioPlayerVolume,
setAudioPlayerPlaybackRate,
setAudioPlayerMuted,
focusMessage,
closeAudioPlayer,
} = getDispatch();
const lang = useLang();
const { audio, voice, video } = getMessageContent(message);
const isVoice = Boolean(voice || video);
@ -293,8 +286,4 @@ export default withGlobal<OwnProps>(
isMuted,
};
},
(setGlobal, actions): DispatchProps => pick(
actions,
['focusMessage', 'closeAudioPlayer', 'setAudioPlayerVolume', 'setAudioPlayerPlaybackRate', 'setAudioPlayerMuted'],
),
)(AudioPlayer);

View File

@ -1,12 +1,10 @@
import React, {
FC, memo, useCallback, useEffect, useRef,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiSticker, ApiUpdateConnectionStateType } from '../../api/types';
import { pick } from '../../util/iteratees';
import { selectChat } from '../../modules/selectors';
import { useIntersectionObserver } from '../../hooks/useIntersectionObserver';
import useLang from '../../hooks/useLang';
@ -26,18 +24,19 @@ type StateProps = {
connectionState?: ApiUpdateConnectionStateType;
};
type DispatchProps = Pick<GlobalActions, 'loadGreetingStickers' | 'sendMessage' | 'markMessageListRead'>;
const INTERSECTION_DEBOUNCE_MS = 200;
const ContactGreeting: FC<OwnProps & StateProps & DispatchProps> = ({
const ContactGreeting: FC<OwnProps & StateProps> = ({
sticker,
connectionState,
lastUnreadMessageId,
loadGreetingStickers,
sendMessage,
markMessageListRead,
}) => {
const {
loadGreetingStickers,
sendMessage,
markMessageListRead,
} = getDispatch();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
@ -110,7 +109,4 @@ export default memo(withGlobal<OwnProps>(
connectionState: global.connectionState,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadGreetingStickers', 'sendMessage', 'markMessageListRead',
]),
)(ContactGreeting));

View File

@ -1,9 +1,7 @@
import React, {
FC, useCallback, memo, useEffect,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { selectCanDeleteSelectedMessages, selectCurrentChat, selectUser } from '../../modules/selectors';
import {
@ -14,7 +12,6 @@ import {
isChatSuperGroup,
} from '../../modules/helpers';
import renderText from '../common/helpers/renderText';
import { pick } from '../../util/iteratees';
import useLang from '../../hooks/useLang';
import usePrevious from '../../hooks/usePrevious';
@ -35,9 +32,7 @@ type StateProps = {
willDeleteForAll?: boolean;
};
type DispatchProps = Pick<GlobalActions, 'deleteMessages' | 'exitMessageSelectMode' | 'deleteScheduledMessages'>;
const DeleteSelectedMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
const DeleteSelectedMessageModal: FC<OwnProps & StateProps> = ({
isOpen,
isSchedule,
selectedMessageIds,
@ -46,10 +41,13 @@ const DeleteSelectedMessageModal: FC<OwnProps & StateProps & DispatchProps> = ({
willDeleteForCurrentUserOnly,
willDeleteForAll,
onClose,
deleteMessages,
deleteScheduledMessages,
exitMessageSelectMode,
}) => {
const {
deleteMessages,
deleteScheduledMessages,
exitMessageSelectMode,
} = getDispatch();
const prevIsOpen = usePrevious(isOpen);
const handleDeleteMessageForAll = useCallback(() => {
@ -130,9 +128,4 @@ export default memo(withGlobal<OwnProps>(
willDeleteForAll,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'deleteMessages',
'deleteScheduledMessages',
'exitMessageSelectMode',
]),
)(DeleteSelectedMessageModal));

View File

@ -5,14 +5,13 @@ import React, {
useCallback,
useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions, MessageListType } from '../../global/types';
import { MessageListType } from '../../global/types';
import { MAIN_THREAD_ID } from '../../api/types';
import { IAnchorPosition } from '../../types';
import { ARE_CALLS_SUPPORTED, IS_SINGLE_COLUMN_LAYOUT } from '../../util/environment';
import { pick } from '../../util/iteratees';
import {
isChatBasicGroup, isChatChannel, isChatSuperGroup, isUserId,
} from '../../modules/helpers';
@ -52,14 +51,10 @@ interface StateProps {
canCreateVoiceChat?: boolean;
}
type DispatchProps = Pick<GlobalActions, (
'joinChannel' | 'sendBotCommand' | 'openLocalTextSearch' | 'restartBot' | 'openCallFallbackConfirm'
)>;
// Chrome breaks layout when focusing input during transition
const SEARCH_FOCUS_DELAY_MS = 400;
const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
const HeaderActions: FC<OwnProps & StateProps> = ({
chatId,
threadId,
noMenu,
@ -75,12 +70,15 @@ const HeaderActions: FC<OwnProps & StateProps & DispatchProps> = ({
canCreateVoiceChat,
isRightColumnShown,
canExpandActions,
joinChannel,
sendBotCommand,
openLocalTextSearch,
restartBot,
openCallFallbackConfirm,
}) => {
const {
joinChannel,
sendBotCommand,
openLocalTextSearch,
restartBot,
openCallFallbackConfirm,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const menuButtonRef = useRef<HTMLButtonElement>(null);
const [isMenuOpen, setIsMenuOpen] = useState(false);
@ -275,7 +273,4 @@ export default memo(withGlobal<OwnProps>(
canCreateVoiceChat,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'joinChannel', 'sendBotCommand', 'openLocalTextSearch', 'restartBot', 'openCallFallbackConfirm',
]),
)(HeaderActions));

View File

@ -1,9 +1,8 @@
import React, {
FC, memo, useCallback, useEffect, useState,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions } from '../../global/types';
import { ApiChat } from '../../api/types';
import { IAnchorPosition } from '../../types';
@ -12,7 +11,6 @@ import { disableScrolling, enableScrolling } from '../../util/scrollLock';
import {
selectChat, selectNotifySettings, selectNotifyExceptions, selectUser,
} from '../../modules/selectors';
import { pick } from '../../util/iteratees';
import {
isUserId, getCanDeleteChat, selectIsChatMuted, getCanAddContact,
} from '../../modules/helpers';
@ -26,11 +24,6 @@ import DeleteChatModal from '../common/DeleteChatModal';
import './HeaderMenuContainer.scss';
type DispatchProps = Pick<GlobalActions, (
'updateChatMutedState' | 'enterMessageSelectMode' | 'sendBotCommand' | 'restartBot' | 'openLinkedChat' |
'joinGroupCall' | 'createGroupCall' | 'addContact' | 'openCallFallbackConfirm'
)>;
export type OwnProps = {
chatId: string;
threadId: number;
@ -62,7 +55,7 @@ type StateProps = {
hasLinkedChat?: boolean;
};
const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
const HeaderMenuContainer: FC<OwnProps & StateProps> = ({
chatId,
isOpen,
withExtraActions,
@ -87,16 +80,19 @@ const HeaderMenuContainer: FC<OwnProps & StateProps & DispatchProps> = ({
onSearchClick,
onClose,
onCloseAnimationEnd,
updateChatMutedState,
enterMessageSelectMode,
sendBotCommand,
restartBot,
joinGroupCall,
createGroupCall,
openLinkedChat,
addContact,
openCallFallbackConfirm,
}) => {
const {
updateChatMutedState,
enterMessageSelectMode,
sendBotCommand,
restartBot,
joinGroupCall,
createGroupCall,
openLinkedChat,
addContact,
openCallFallbackConfirm,
} = getDispatch();
const [isMenuOpen, setIsMenuOpen] = useState(true);
const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
const { x, y } = anchor;
@ -313,15 +309,4 @@ export default memo(withGlobal<OwnProps>(
hasLinkedChat: Boolean(chat?.fullInfo?.linkedChatId),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'updateChatMutedState',
'enterMessageSelectMode',
'sendBotCommand',
'restartBot',
'joinGroupCall',
'createGroupCall',
'openLinkedChat',
'addContact',
'openCallFallbackConfirm',
]),
)(HeaderMenuContainer));

View File

@ -1,12 +1,12 @@
import React, {
FC, memo, useCallback, useEffect, useMemo, useRef, useState,
} from '../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../lib/teact/teactn';
import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn';
import {
ApiMessage, ApiRestrictionReason, MAIN_THREAD_ID,
} from '../../api/types';
import { GlobalActions, MessageListType } from '../../global/types';
import { MessageListType } from '../../global/types';
import { LoadMoreDirection } from '../../types';
import { ANIMATION_END_DELAY, LOCAL_MESSAGE_ID_BASE, MESSAGE_LIST_SLICE } from '../../config';
@ -32,7 +32,7 @@ import {
isChatWithRepliesBot,
isChatGroup,
} from '../../modules/helpers';
import { orderBy, pick } from '../../util/iteratees';
import { orderBy } from '../../util/iteratees';
import { fastRaf, debounce, onTickEnd } from '../../util/schedulers';
import useLayoutEffectWithPrevDeps from '../../hooks/useLayoutEffectWithPrevDeps';
import useEffectWithPrevDeps from '../../hooks/useEffectWithPrevDeps';
@ -91,8 +91,6 @@ type StateProps = {
hasLinkedChat?: boolean;
};
type DispatchProps = Pick<GlobalActions, 'loadViewportMessages' | 'setScrollOffset' | 'openHistoryCalendar'>;
const BOTTOM_THRESHOLD = 20;
const UNREAD_DIVIDER_TOP = 10;
const UNREAD_DIVIDER_TOP_WITH_TOOLS = 60;
@ -104,7 +102,7 @@ const UNREAD_DIVIDER_CLASS = 'unread-divider';
const runDebouncedForScroll = debounce((cb) => cb(), SCROLL_DEBOUNCE, false);
const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
const MessageList: FC<OwnProps & StateProps> = ({
chatId,
threadId,
type,
@ -129,15 +127,14 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
restrictionReason,
focusingId,
isSelectModeActive,
loadViewportMessages,
setScrollOffset,
lastMessage,
botDescription,
threadTopMessageId,
hasLinkedChat,
withBottomShift,
openHistoryCalendar,
}) => {
const { loadViewportMessages, setScrollOffset } = getDispatch();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
@ -530,7 +527,6 @@ const MessageList: FC<OwnProps & StateProps & DispatchProps> = ({
noAppearanceAnimation={!messageGroups || !shouldAnimateAppearanceRef.current}
onFabToggle={onFabToggle}
onNotchToggle={onNotchToggle}
openHistoryCalendar={openHistoryCalendar}
/>
) : (
<Loading color="white" />
@ -602,9 +598,4 @@ export default memo(withGlobal<OwnProps>(
...(withLastMessageWhenPreloading && { lastMessage }),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadViewportMessages',
'setScrollOffset',
'openHistoryCalendar',
]),
)(MessageList));

View File

@ -16,6 +16,7 @@ import useMessageObservers from './hooks/useMessageObservers';
import Message from './message/Message';
import ActionMessage from './ActionMessage';
import { getDispatch } from '../../lib/teact/teactn';
interface OwnProps {
messageIds: number[];
@ -39,7 +40,6 @@ interface OwnProps {
noAppearanceAnimation: boolean;
onFabToggle: AnyToVoidFunction;
onNotchToggle: AnyToVoidFunction;
openHistoryCalendar: Function;
}
const UNREAD_DIVIDER_CLASS = 'unread-divider';
@ -66,8 +66,9 @@ const MessageListContent: FC<OwnProps> = ({
noAppearanceAnimation,
onFabToggle,
onNotchToggle,
openHistoryCalendar,
}) => {
const { openHistoryCalendar } = getDispatch();
const {
observeIntersectionForMedia,
observeIntersectionForReading,

View File

@ -1,9 +1,9 @@
import React, {
FC, memo, useCallback, useEffect,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions, MessageListType } from '../../global/types';
import { MessageListType } from '../../global/types';
import {
selectCanDeleteSelectedMessages,
@ -12,7 +12,6 @@ import {
selectCurrentMessageList,
selectSelectedMessagesCount,
} from '../../modules/selectors';
import { pick } from '../../util/iteratees';
import useFlag from '../../hooks/useFlag';
import captureKeyboardListeners from '../../util/captureKeyboardListeners';
import buildClassName from '../../util/buildClassName';
@ -41,11 +40,7 @@ type StateProps = {
selectedMessageIds?: number[];
};
type DispatchProps = Pick<GlobalActions, (
'exitMessageSelectMode' | 'openForwardMenuForSelectedMessages' | 'downloadSelectedMessages'
)>;
const MessageSelectToolbar: FC<OwnProps & StateProps & DispatchProps> = ({
const MessageSelectToolbar: FC<OwnProps & StateProps> = ({
canPost,
isActive,
messageListType,
@ -55,10 +50,13 @@ const MessageSelectToolbar: FC<OwnProps & StateProps & DispatchProps> = ({
canReportMessages,
canDownloadMessages,
selectedMessageIds,
exitMessageSelectMode,
openForwardMenuForSelectedMessages,
downloadSelectedMessages,
}) => {
const {
exitMessageSelectMode,
openForwardMenuForSelectedMessages,
downloadSelectedMessages,
} = getDispatch();
const [isDeleteModalOpen, openDeleteModal, closeDeleteModal] = useFlag();
const [isReportModalOpen, openReportModal, closeReportModal] = useFlag();
@ -171,7 +169,4 @@ export default memo(withGlobal<OwnProps>(
selectedMessageIds,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'exitMessageSelectMode', 'openForwardMenuForSelectedMessages', 'downloadSelectedMessages',
]),
)(MessageSelectToolbar));

View File

@ -1,10 +1,10 @@
import React, {
FC, useEffect, useState, memo, useMemo, useCallback,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiChatBannedRights, MAIN_THREAD_ID } from '../../api/types';
import { GlobalActions, MessageListType, MessageList as GlobalMessageList } from '../../global/types';
import { MessageListType, MessageList as GlobalMessageList } from '../../global/types';
import { ThemeKey } from '../../types';
import {
@ -43,7 +43,6 @@ import {
getCanPostInChat, getMessageSendingRestrictionReason, isChatChannel, isChatSuperGroup, isUserId,
} from '../../modules/helpers';
import captureEscKeyListener from '../../util/captureEscKeyListener';
import { pick } from '../../util/iteratees';
import buildClassName from '../../util/buildClassName';
import { createMessageHash } from '../../util/routing';
import useCustomBackground from '../../hooks/useCustomBackground';
@ -104,18 +103,13 @@ type StateProps = {
canRestartBot?: boolean;
};
type DispatchProps = Pick<GlobalActions, (
'openChat' | 'unpinAllMessages' | 'loadUser' | 'closeLocalTextSearch' | 'exitMessageSelectMode' |
'closePaymentModal' | 'clearReceipt' | 'joinChannel' | 'sendBotCommand' | 'restartBot'
)>;
const CLOSE_ANIMATION_DURATION = IS_SINGLE_COLUMN_LAYOUT ? 450 + ANIMATION_END_DELAY : undefined;
function isImage(item: DataTransferItem) {
return item.kind === 'file' && item.type && SUPPORTED_IMAGE_CONTENT_TYPES.has(item.type);
}
const MiddleColumn: FC<StateProps & DispatchProps> = ({
const MiddleColumn: FC<StateProps> = ({
chatId,
threadId,
messageListType,
@ -146,17 +140,20 @@ const MiddleColumn: FC<StateProps & DispatchProps> = ({
canSubscribe,
canStartBot,
canRestartBot,
openChat,
unpinAllMessages,
loadUser,
closeLocalTextSearch,
exitMessageSelectMode,
closePaymentModal,
clearReceipt,
joinChannel,
sendBotCommand,
restartBot,
}) => {
const {
openChat,
unpinAllMessages,
loadUser,
closeLocalTextSearch,
exitMessageSelectMode,
closePaymentModal,
clearReceipt,
joinChannel,
sendBotCommand,
restartBot,
} = getDispatch();
const { width: windowWidth } = useWindowSize();
const lang = useLang();
@ -588,10 +585,6 @@ export default memo(withGlobal(
canRestartBot,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'openChat', 'unpinAllMessages', 'loadUser', 'closeLocalTextSearch', 'exitMessageSelectMode',
'closePaymentModal', 'clearReceipt', 'joinChannel', 'sendBotCommand', 'restartBot',
]),
)(MiddleColumn));
function useIsReady(

View File

@ -1,10 +1,10 @@
import React, {
FC, useCallback, useMemo, memo, useEffect, useRef, useState,
} from '../../lib/teact/teact';
import { getGlobal, withGlobal } from '../../lib/teact/teactn';
import { getDispatch, getGlobal, withGlobal } from '../../lib/teact/teactn';
import cycleRestrict from '../../util/cycleRestrict';
import { GlobalActions, MessageListType } from '../../global/types';
import { MessageListType } from '../../global/types';
import {
ApiMessage,
ApiChat,
@ -48,7 +48,6 @@ import useEnsureMessage from '../../hooks/useEnsureMessage';
import useWindowSize from '../../hooks/useWindowSize';
import useShowTransition from '../../hooks/useShowTransition';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import { pick } from '../../util/iteratees';
import { formatIntegerCompact } from '../../util/textFormat';
import buildClassName from '../../util/buildClassName';
import useLang from '../../hooks/useLang';
@ -96,12 +95,7 @@ type StateProps = {
connectionState?: ApiUpdateConnectionStateType;
};
type DispatchProps = Pick<GlobalActions, (
'openChatWithInfo' | 'pinMessage' | 'focusMessage' | 'openChat' | 'openPreviousChat' | 'loadPinnedMessages' |
'toggleLeftColumn' | 'exitMessageSelectMode'
)>;
const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
const MiddleHeader: FC<OwnProps & StateProps> = ({
chatId,
threadId,
messageListType,
@ -124,15 +118,18 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
shouldSkipHistoryAnimations,
currentTransitionKey,
connectionState,
openChatWithInfo,
pinMessage,
focusMessage,
openChat,
openPreviousChat,
loadPinnedMessages,
toggleLeftColumn,
exitMessageSelectMode,
}) => {
const {
openChatWithInfo,
pinMessage,
focusMessage,
openChat,
openPreviousChat,
loadPinnedMessages,
toggleLeftColumn,
exitMessageSelectMode,
} = getDispatch();
const lang = useLang();
const isBackButtonActive = useRef(true);
@ -523,14 +520,4 @@ export default memo(withGlobal<OwnProps>(
return state;
},
(setGlobal, actions): DispatchProps => pick(actions, [
'openChatWithInfo',
'pinMessage',
'focusMessage',
'openChat',
'openPreviousChat',
'loadPinnedMessages',
'toggleLeftColumn',
'exitMessageSelectMode',
]),
)(MiddleHeader));

View File

@ -1,14 +1,12 @@
import React, {
FC, memo, useCallback, useEffect, useRef, useState, useLayoutEffect,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { ApiChat } from '../../api/types';
import { GlobalActions } from '../../global/types';
import { debounce } from '../../util/schedulers';
import { selectCurrentTextSearch, selectCurrentChat } from '../../modules/selectors';
import { pick } from '../../util/iteratees';
import { getDayStartAt } from '../../util/dateFormat';
import Button from '../ui/Button';
@ -29,26 +27,24 @@ type StateProps = {
isHistoryCalendarOpen?: boolean;
};
type DispatchProps = Pick<GlobalActions, (
'setLocalTextSearchQuery' | 'searchTextMessagesLocal' | 'closeLocalTextSearch' | 'openHistoryCalendar' |
'focusMessage'
)>;
const runDebouncedForSearch = debounce((cb) => cb(), 200, false);
const MobileSearchFooter: FC<StateProps & DispatchProps> = ({
const MobileSearchFooter: FC<StateProps> = ({
isActive,
chat,
query,
totalCount,
foundIds,
isHistoryCalendarOpen,
setLocalTextSearchQuery,
searchTextMessagesLocal,
focusMessage,
closeLocalTextSearch,
openHistoryCalendar,
}) => {
const {
setLocalTextSearchQuery,
searchTextMessagesLocal,
focusMessage,
closeLocalTextSearch,
openHistoryCalendar,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLInputElement>(null);
const [focusedIndex, setFocusedIndex] = useState(0);
@ -218,11 +214,4 @@ export default memo(withGlobal<OwnProps>(
isHistoryCalendarOpen: Boolean(global.historyCalendarSelectedAt),
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setLocalTextSearchQuery',
'searchTextMessagesLocal',
'focusMessage',
'closeLocalTextSearch',
'openHistoryCalendar',
]),
)(MobileSearchFooter));

View File

@ -1,15 +1,14 @@
import React, {
FC, useCallback, memo, useRef,
} from '../../lib/teact/teact';
import { withGlobal } from '../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../lib/teact/teactn';
import { GlobalActions, MessageListType } from '../../global/types';
import { MessageListType } from '../../global/types';
import { MAIN_THREAD_ID } from '../../api/types';
import { selectChat, selectCurrentMessageList } from '../../modules/selectors';
import { formatIntegerCompact } from '../../util/textFormat';
import buildClassName from '../../util/buildClassName';
import { pick } from '../../util/iteratees';
import fastSmoothScroll from '../../util/fastSmoothScroll';
import useLang from '../../hooks/useLang';
@ -28,18 +27,17 @@ type StateProps = {
unreadCount?: number;
};
type DispatchProps = Pick<GlobalActions, 'focusNextReply'>;
const FOCUS_MARGIN = 20;
const ScrollDownButton: FC<OwnProps & StateProps & DispatchProps> = ({
const ScrollDownButton: FC<OwnProps & StateProps> = ({
isShown,
canPost,
messageListType,
unreadCount,
withExtraShift,
focusNextReply,
}) => {
const { focusNextReply } = getDispatch();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
const elementRef = useRef<HTMLDivElement>(null);
@ -104,5 +102,4 @@ export default memo(withGlobal<OwnProps>(
unreadCount: chat && threadId === MAIN_THREAD_ID && messageListType === 'thread' ? chat.unreadCount : undefined,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['focusNextReply']),
)(ScrollDownButton));

View File

@ -1,17 +1,15 @@
import React, { FC, memo, useCallback } from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiBotCommand } from '../../../api/types';
import { IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV } from '../../../util/environment';
import { pick } from '../../../util/iteratees';
import useMouseInside from '../../../hooks/useMouseInside';
import Menu from '../../ui/Menu';
import BotCommand from './BotCommand';
import './BotCommandMenu.scss';
import { getDispatch } from '../../../lib/teact/teactn';
export type OwnProps = {
isOpen: boolean;
@ -19,11 +17,11 @@ export type OwnProps = {
onClose: NoneToVoidFunction;
};
type DispatchProps = Pick<GlobalActions, 'sendBotCommand'>;
const BotCommandMenu: FC<OwnProps & DispatchProps> = ({
isOpen, botCommands, onClose, sendBotCommand,
const BotCommandMenu: FC<OwnProps> = ({
isOpen, botCommands, onClose,
}) => {
const { sendBotCommand } = getDispatch();
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose, undefined, IS_SINGLE_COLUMN_LAYOUT);
const handleClick = useCallback((botCommand: ApiBotCommand) => {
@ -57,7 +55,4 @@ const BotCommandMenu: FC<OwnProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, ['sendBotCommand']),
)(BotCommandMenu));
export default memo(BotCommandMenu);

View File

@ -1,12 +1,10 @@
import React, {
FC, useCallback, useEffect, useRef, memo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { ApiBotCommand, ApiUser } from '../../../api/types';
import { GlobalActions } from '../../../global/types';
import { pick } from '../../../util/iteratees';
import buildClassName from '../../../util/buildClassName';
import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
import useShowTransition from '../../../hooks/useShowTransition';
@ -29,17 +27,16 @@ type StateProps = {
usersById: Record<string, ApiUser>;
};
type DispatchProps = Pick<GlobalActions, 'sendBotCommand'>;
const BotCommandTooltip: FC<OwnProps & StateProps & DispatchProps> = ({
const BotCommandTooltip: FC<OwnProps & StateProps> = ({
usersById,
isOpen,
withUsername,
botCommands,
onClick,
onClose,
sendBotCommand,
}) => {
const { sendBotCommand } = getDispatch();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
@ -102,5 +99,4 @@ export default memo(withGlobal<OwnProps>(
(global): StateProps => ({
usersById: global.users.byId,
}),
(setGlobal, actions): DispatchProps => pick(actions, ['sendBotCommand']),
)(BotCommandTooltip));

View File

@ -1,11 +1,9 @@
import React, { FC, memo, useEffect } from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiMessage } from '../../../api/types';
import { IS_TOUCH_ENV } from '../../../util/environment';
import { pick } from '../../../util/iteratees';
import { selectChatMessage, selectCurrentMessageList } from '../../../modules/selectors';
import useMouseInside from '../../../hooks/useMouseInside';
import useFlag from '../../../hooks/useFlag';
@ -25,11 +23,11 @@ type StateProps = {
message?: ApiMessage;
};
type DispatchProps = Pick<GlobalActions, ('clickInlineButton')>;
const BotKeyboardMenu: FC<OwnProps & StateProps & DispatchProps> = ({
isOpen, message, onClose, clickInlineButton,
const BotKeyboardMenu: FC<OwnProps & StateProps> = ({
isOpen, message, onClose,
}) => {
const { clickInlineButton } = getDispatch();
const [handleMouseEnter, handleMouseLeave] = useMouseInside(isOpen, onClose);
const { isKeyboardSingleUse } = message || {};
const [forceOpen, markForceOpen, unmarkForceOpen] = useFlag(true);
@ -87,7 +85,4 @@ export default memo(withGlobal<OwnProps>(
return { message: selectChatMessage(global, chatId, messageId) };
},
(setGlobal, actions): DispatchProps => pick(actions, [
'clickInlineButton',
]),
)(BotKeyboardMenu));

View File

@ -1,9 +1,9 @@
import React, {
FC, memo, useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions, GlobalState, MessageListType } from '../../../global/types';
import { GlobalState, MessageListType } from '../../../global/types';
import {
ApiAttachment,
ApiBotInlineResult,
@ -52,7 +52,6 @@ import buildAttachment from './helpers/buildAttachment';
import renderText from '../../common/helpers/renderText';
import insertHtmlInSelection from '../../../util/insertHtmlInSelection';
import deleteLastCharacterOutsideSelection from '../../../util/deleteLastCharacterOutsideSelection';
import { pick } from '../../../util/iteratees';
import buildClassName from '../../../util/buildClassName';
import windowSize from '../../../util/windowSize';
import { isSelectionInsideInput } from './helpers/selection';
@ -142,13 +141,6 @@ type StateProps =
}
& Pick<GlobalState, 'connectionState'>;
type DispatchProps = Pick<GlobalActions, (
'sendMessage' | 'editMessage' | 'saveDraft' | 'forwardMessages' |
'clearDraft' | 'showDialog' | 'setStickerSearchQuery' | 'setGifSearchQuery' |
'openPollModal' | 'closePollModal' | 'loadScheduledHistory' | 'openChat' |
'addRecentEmoji' | 'sendInlineBotResult'
)>;
enum MainButtonState {
Send = 'send',
Record = 'record',
@ -167,7 +159,7 @@ const SENDING_ANIMATION_DURATION = 350;
// eslint-disable-next-line max-len
const APPENDIX = '<svg width="9" height="20" xmlns="http://www.w3.org/2000/svg"><defs><filter x="-50%" y="-14.7%" width="200%" height="141.2%" filterUnits="objectBoundingBox" id="a"><feOffset dy="1" in="SourceAlpha" result="shadowOffsetOuter1"/><feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"/><feColorMatrix values="0 0 0 0 0.0621962482 0 0 0 0 0.138574144 0 0 0 0 0.185037364 0 0 0 0.15 0" in="shadowBlurOuter1"/></filter></defs><g fill="none" fill-rule="evenodd"><path d="M6 17H0V0c.193 2.84.876 5.767 2.05 8.782.904 2.325 2.446 4.485 4.625 6.48A1 1 0 016 17z" fill="#000" filter="url(#a)"/><path d="M6 17H0V0c.193 2.84.876 5.767 2.05 8.782.904 2.325 2.446 4.485 4.625 6.48A1 1 0 016 17z" fill="#FFF" class="corner"/></g></svg>';
const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
const Composer: FC<OwnProps & StateProps> = ({
dropAreaState,
shouldSchedule,
canScheduleUntilOnline,
@ -205,21 +197,22 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
isInlineBotLoading,
botCommands,
chatBotCommands,
sendMessage,
editMessage,
saveDraft,
clearDraft,
showDialog,
setStickerSearchQuery,
setGifSearchQuery,
forwardMessages,
openPollModal,
closePollModal,
loadScheduledHistory,
openChat,
addRecentEmoji,
sendInlineBotResult,
}) => {
const {
sendMessage,
clearDraft,
showDialog,
setStickerSearchQuery,
setGifSearchQuery,
forwardMessages,
openPollModal,
closePollModal,
loadScheduledHistory,
openChat,
addRecentEmoji,
sendInlineBotResult,
} = getDispatch();
const lang = useLang();
// eslint-disable-next-line no-null/no-null
@ -428,8 +421,8 @@ const Composer: FC<OwnProps & StateProps & DispatchProps> = ({
};
}, [chatId, resetComposer, stopRecordingVoiceRef]);
const handleEditComplete = useEditing(htmlRef, setHtml, editingMessage, resetComposer, openDeleteModal, editMessage);
useDraft(draft, chatId, threadId, html, htmlRef, setHtml, editingMessage, saveDraft, clearDraft);
const handleEditComplete = useEditing(htmlRef, setHtml, editingMessage, resetComposer, openDeleteModal);
useDraft(draft, chatId, threadId, html, htmlRef, setHtml, editingMessage);
useClipboardPaste(insertTextAndUpdateCursor, setAttachments, editingMessage);
const handleFileSelect = useCallback(async (files: File[], isQuick: boolean) => {
@ -1111,20 +1104,4 @@ export default memo(withGlobal<OwnProps>(
botCommands: chatBot && chatBot.fullInfo ? (chatBot.fullInfo.botCommands || false) : undefined,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'sendMessage',
'editMessage',
'saveDraft',
'clearDraft',
'showDialog',
'setStickerSearchQuery',
'setGifSearchQuery',
'forwardMessages',
'openPollModal',
'closePollModal',
'loadScheduledHistory',
'openChat',
'addRecentEmoji',
'sendInlineBotResult',
]),
)(Composer));

View File

@ -1,9 +1,8 @@
import React, {
FC, memo, useCallback, useEffect,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiChat, ApiMessage, ApiUser } from '../../../api/types';
import {
@ -19,7 +18,6 @@ import {
selectEditingMessage,
} from '../../../modules/selectors';
import captureEscKeyListener from '../../../util/captureEscKeyListener';
import { pick } from '../../../util/iteratees';
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
import useShowTransition from '../../../hooks/useShowTransition';
import buildClassName from '../../../util/buildClassName';
@ -39,22 +37,23 @@ type StateProps = {
forwardedMessagesCount?: number;
};
type DispatchProps = Pick<GlobalActions, 'setReplyingToId' | 'setEditingId' | 'focusMessage' | 'exitForwardMode'>;
const FORWARD_RENDERING_DELAY = 300;
const ComposerEmbeddedMessage: FC<StateProps & DispatchProps> = ({
const ComposerEmbeddedMessage: FC<StateProps> = ({
replyingToId,
editingId,
message,
sender,
shouldAnimate,
forwardedMessagesCount,
setReplyingToId,
setEditingId,
focusMessage,
exitForwardMode,
}) => {
const {
setReplyingToId,
setEditingId,
focusMessage,
exitForwardMode,
} = getDispatch();
const isShown = Boolean(
((replyingToId || editingId) && message)
|| (sender && forwardedMessagesCount),
@ -166,10 +165,4 @@ export default memo(withGlobal(
forwardedMessagesCount: isForwarding ? forwardMessageIds!.length : undefined,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'setReplyingToId',
'setEditingId',
'focusMessage',
'exitForwardMode',
]),
)(ComposerEmbeddedMessage));

View File

@ -1,15 +1,13 @@
import React, {
FC, useEffect, memo, useRef,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiVideo } from '../../../api/types';
import { SLIDE_TRANSITION_DURATION } from '../../../config';
import { IS_TOUCH_ENV } from '../../../util/environment';
import buildClassName from '../../../util/buildClassName';
import { pick } from '../../../util/iteratees';
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
@ -29,18 +27,17 @@ type StateProps = {
savedGifs?: ApiVideo[];
};
type DispatchProps = Pick<GlobalActions, 'loadSavedGifs'>;
const INTERSECTION_DEBOUNCE = 300;
const GifPicker: FC<OwnProps & StateProps & DispatchProps> = ({
const GifPicker: FC<OwnProps & StateProps> = ({
className,
loadAndPlay,
canSendGifs,
savedGifs,
onGifSelect,
loadSavedGifs,
}) => {
const { loadSavedGifs } = getDispatch();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
@ -88,5 +85,4 @@ export default memo(withGlobal<OwnProps>(
savedGifs: global.gifs.saved.gifs,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['loadSavedGifs']),
)(GifPicker));

View File

@ -1,9 +1,7 @@
import React, {
FC, memo, useCallback, useEffect, useRef,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiBotInlineMediaResult, ApiBotInlineResult, ApiBotInlineSwitchPm } from '../../../api/types';
import { IAllowedAttachmentOptions } from '../../../modules/helpers';
import { LoadMoreDirection } from '../../../types';
@ -13,7 +11,6 @@ import setTooltipItemVisible from '../../../util/setTooltipItemVisible';
import buildClassName from '../../../util/buildClassName';
import useShowTransition from '../../../hooks/useShowTransition';
import { throttle } from '../../../util/schedulers';
import { pick } from '../../../util/iteratees';
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
import usePrevious from '../../../hooks/usePrevious';
import { useKeyboardNavigation } from './hooks/useKeyboardNavigation';
@ -26,6 +23,7 @@ import ListItem from '../../ui/ListItem';
import InfiniteScroll from '../../ui/InfiniteScroll';
import './InlineBotTooltip.scss';
import { getDispatch } from '../../../lib/teact/teactn';
const INTERSECTION_DEBOUNCE_MS = 200;
const runThrottled = throttle((cb) => cb(), 500, true);
@ -42,9 +40,7 @@ export type OwnProps = {
onClose: NoneToVoidFunction;
};
type DispatchProps = Pick<GlobalActions, ('startBot' | 'openChat' | 'sendInlineBotResult')>;
const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
const InlineBotTooltip: FC<OwnProps> = ({
isOpen,
botId,
isGallery,
@ -52,10 +48,13 @@ const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
switchPm,
loadMore,
onClose,
openChat,
startBot,
onSelectResult,
}) => {
const {
openChat,
startBot,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
@ -196,9 +195,4 @@ const InlineBotTooltip: FC<OwnProps & DispatchProps> = ({
);
};
export default memo(withGlobal<OwnProps>(
undefined,
(setGlobal, actions): DispatchProps => pick(actions, [
'startBot', 'openChat', 'sendInlineBotResult',
]),
)(InlineBotTooltip));
export default memo(InlineBotTooltip);

View File

@ -2,9 +2,8 @@ import { ChangeEvent } from 'react';
import React, {
FC, useEffect, useRef, memo, useState, useCallback,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { IAnchorPosition, ISettings } from '../../../types';
import { EDITABLE_INPUT_ID } from '../../../config';
@ -12,7 +11,6 @@ import { selectReplyingToId } from '../../../modules/selectors';
import { debounce } from '../../../util/schedulers';
import focusEditableElement from '../../../util/focusEditableElement';
import buildClassName from '../../../util/buildClassName';
import { pick } from '../../../util/iteratees';
import {
IS_ANDROID, IS_EMOJI_SUPPORTED, IS_IOS, IS_SINGLE_COLUMN_LAYOUT, IS_TOUCH_ENV,
} from '../../../util/environment';
@ -56,8 +54,6 @@ type StateProps = {
messageSendKeyCombo?: ISettings['messageSendKeyCombo'];
};
type DispatchProps = Pick<GlobalActions, 'editLastMessage' | 'replyToNextMessage'>;
const MAX_INPUT_HEIGHT = IS_SINGLE_COLUMN_LAYOUT ? 256 : 416;
const TAB_INDEX_PRIORITY_TIMEOUT = 2000;
const TEXT_FORMATTER_SAFE_AREA_PX = 90;
@ -77,7 +73,7 @@ function clearSelection() {
}
}
const MessageInput: FC<OwnProps & StateProps & DispatchProps> = ({
const MessageInput: FC<OwnProps & StateProps> = ({
id,
chatId,
isAttachmentModalInput,
@ -94,9 +90,12 @@ const MessageInput: FC<OwnProps & StateProps & DispatchProps> = ({
replyingToId,
noTabCapture,
messageSendKeyCombo,
editLastMessage,
replyToNextMessage,
}) => {
const {
editLastMessage,
replyToNextMessage,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const inputRef = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null
@ -420,5 +419,4 @@ export default memo(withGlobal<OwnProps>(
noTabCapture: global.isPollModalOpen || global.payment.isPaymentModalOpen,
};
},
(setGlobal, actions): DispatchProps => pick(actions, ['editLastMessage', 'replyToNextMessage']),
)(MessageInput));

View File

@ -1,9 +1,8 @@
import React, {
FC, useState, useEffect, memo, useRef, useMemo, useCallback,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiStickerSet, ApiSticker } from '../../../api/types';
import { StickerSetOrRecent } from '../../../types';
@ -12,7 +11,6 @@ import { IS_TOUCH_ENV } from '../../../util/environment';
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
import fastSmoothScroll from '../../../util/fastSmoothScroll';
import buildClassName from '../../../util/buildClassName';
import { pick } from '../../../util/iteratees';
import fastSmoothScrollHorizontal from '../../../util/fastSmoothScrollHorizontal';
import useAsyncRendering from '../../right/hooks/useAsyncRendering';
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
@ -43,18 +41,13 @@ type StateProps = {
shouldPlay?: boolean;
};
type DispatchProps = Pick<GlobalActions, (
'loadStickerSets' | 'loadRecentStickers' | 'loadFavoriteStickers' |
'addRecentSticker' | 'loadAddedStickers' | 'unfaveSticker'
)>;
const SMOOTH_SCROLL_DISTANCE = 500;
const HEADER_BUTTON_WIDTH = 52; // px (including margin)
const STICKER_INTERSECTION_THROTTLE = 200;
const stickerSetIntersections: boolean[] = [];
const StickerPicker: FC<OwnProps & StateProps & DispatchProps> = ({
const StickerPicker: FC<OwnProps & StateProps> = ({
className,
loadAndPlay,
canSendStickers,
@ -64,13 +57,16 @@ const StickerPicker: FC<OwnProps & StateProps & DispatchProps> = ({
stickerSetsById,
shouldPlay,
onStickerSelect,
loadStickerSets,
loadRecentStickers,
loadFavoriteStickers,
loadAddedStickers,
addRecentSticker,
unfaveSticker,
}) => {
const {
loadStickerSets,
loadRecentStickers,
loadFavoriteStickers,
loadAddedStickers,
addRecentSticker,
unfaveSticker,
} = getDispatch();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
// eslint-disable-next-line no-null/no-null
@ -296,12 +292,4 @@ export default memo(withGlobal<OwnProps>(
shouldPlay: global.settings.byKey.shouldLoopStickers,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadStickerSets',
'loadRecentStickers',
'loadFavoriteStickers',
'loadAddedStickers',
'addRecentSticker',
'unfaveSticker',
]),
)(StickerPicker));

View File

@ -1,16 +1,14 @@
import React, {
FC, memo, useEffect, useRef,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { ApiSticker } from '../../../api/types';
import { GlobalActions } from '../../../global/types';
import { STICKER_SIZE_PICKER } from '../../../config';
import { IS_TOUCH_ENV } from '../../../util/environment';
import buildClassName from '../../../util/buildClassName';
import captureEscKeyListener from '../../../util/captureEscKeyListener';
import { pick } from '../../../util/iteratees';
import { useIntersectionObserver } from '../../../hooks/useIntersectionObserver';
import useShowTransition from '../../../hooks/useShowTransition';
import usePrevious from '../../../hooks/usePrevious';
@ -29,16 +27,15 @@ type StateProps = {
stickers?: ApiSticker[];
};
type DispatchProps = Pick<GlobalActions, 'clearStickersForEmoji'>;
const INTERSECTION_THROTTLE = 200;
const StickerTooltip: FC<OwnProps & StateProps & DispatchProps> = ({
const StickerTooltip: FC<OwnProps & StateProps> = ({
isOpen,
onStickerSelect,
stickers,
clearStickersForEmoji,
}) => {
const { clearStickersForEmoji } = getDispatch();
// eslint-disable-next-line no-null/no-null
const containerRef = useRef<HTMLDivElement>(null);
const { shouldRender, transitionClassNames } = useShowTransition(isOpen, undefined, undefined, false);
@ -96,5 +93,4 @@ export default memo(withGlobal<OwnProps>(
return { stickers };
},
(setGlobal, actions): DispatchProps => pick(actions, ['clearStickersForEmoji']),
)(StickerTooltip));

View File

@ -1,15 +1,13 @@
import React, {
FC, memo, useEffect, useMemo,
} from '../../../lib/teact/teact';
import { withGlobal } from '../../../lib/teact/teactn';
import { getDispatch, withGlobal } from '../../../lib/teact/teactn';
import { GlobalActions } from '../../../global/types';
import { ApiMessage, ApiMessageEntityTypes, ApiWebPage } from '../../../api/types';
import { ISettings } from '../../../types';
import { RE_LINK_TEMPLATE } from '../../../config';
import { selectNoWebPage, selectTheme } from '../../../modules/selectors';
import { pick } from '../../../util/iteratees';
import parseMessageInput from '../../../util/parseMessageInput';
import useOnChange from '../../../hooks/useOnChange';
import useShowTransition from '../../../hooks/useShowTransition';
@ -33,11 +31,10 @@ type StateProps = {
noWebPage?: boolean;
theme: ISettings['theme'];
};
type DispatchProps = Pick<GlobalActions, 'loadWebPagePreview' | 'clearWebPagePreview' | 'toggleMessageWebPage'>;
const RE_LINK = new RegExp(RE_LINK_TEMPLATE, 'i');
const WebPagePreview: FC<OwnProps & StateProps & DispatchProps> = ({
const WebPagePreview: FC<OwnProps & StateProps> = ({
chatId,
threadId,
messageText,
@ -45,10 +42,13 @@ const WebPagePreview: FC<OwnProps & StateProps & DispatchProps> = ({
webPagePreview,
noWebPage,
theme,
loadWebPagePreview,
clearWebPagePreview,
toggleMessageWebPage,
}) => {
const {
loadWebPagePreview,
clearWebPagePreview,
toggleMessageWebPage,
} = getDispatch();
const link = useMemo(() => {
const { text, entities } = parseMessageInput(messageText);
@ -121,7 +121,4 @@ export default memo(withGlobal<OwnProps>(
noWebPage,
};
},
(setGlobal, actions): DispatchProps => pick(actions, [
'loadWebPagePreview', 'clearWebPagePreview', 'toggleMessageWebPage',
]),
)(WebPagePreview));

View File

@ -1,7 +1,7 @@
import { useCallback, useEffect, useMemo } from '../../../../lib/teact/teact';
import { getDispatch } from '../../../../lib/teact/teactn';
import { ApiFormattedText, ApiMessage } from '../../../../api/types';
import { GlobalActions } from '../../../../global/types';
import { DRAFT_DEBOUNCE, EDITABLE_INPUT_ID } from '../../../../config';
import usePrevious from '../../../../hooks/usePrevious';
@ -25,9 +25,9 @@ export default (
htmlRef: { current: string },
setHtml: (html: string) => void,
editedMessage: ApiMessage | undefined,
saveDraft: GlobalActions['saveDraft'],
clearDraft: GlobalActions['clearDraft'],
) => {
const { saveDraft, clearDraft } = getDispatch();
const updateDraft = useCallback((draftChatId: string, draftThreadId: number) => {
if (htmlRef.current.length && !editedMessage) {
saveDraft({ chatId: draftChatId, threadId: draftThreadId, draft: parseMessageInput(htmlRef.current!) });

Some files were not shown because too many files have changed in this diff Show More